Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
wine-mirror
GitHub Repository: wine-mirror/wine
Path: blob/master/libs/tiff/libtiff/tif_zip.c
4391 views
1
/*
2
* Copyright (c) 1995-1997 Sam Leffler
3
* Copyright (c) 1995-1997 Silicon Graphics, Inc.
4
*
5
* Permission to use, copy, modify, distribute, and sell this software and
6
* its documentation for any purpose is hereby granted without fee, provided
7
* that (i) the above copyright notices and this permission notice appear in
8
* all copies of the software and related documentation, and (ii) the names of
9
* Sam Leffler and Silicon Graphics may not be used in any advertising or
10
* publicity relating to the software without the specific, prior written
11
* permission of Sam Leffler and Silicon Graphics.
12
*
13
* THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
14
* EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
15
* WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
16
*
17
* IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
18
* ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
19
* OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
20
* WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
21
* LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
22
* OF THIS SOFTWARE.
23
*/
24
25
#include "tiffiop.h"
26
#ifdef ZIP_SUPPORT
27
/*
28
* TIFF Library.
29
*
30
* ZIP (aka Deflate) Compression Support
31
*
32
* This file is an interface to the zlib library written by
33
* Jean-loup Gailly and Mark Adler. You must use version 1.0 or later
34
* of the library.
35
*
36
* Optionally, libdeflate (https://github.com/ebiggers/libdeflate) may be used
37
* to do the compression and decompression, but only for whole strips and tiles.
38
* For scanline access, zlib will be sued as a fallback.
39
*/
40
#include "tif_predict.h"
41
#include "zlib.h"
42
43
#if LIBDEFLATE_SUPPORT
44
#include "libdeflate.h"
45
#endif
46
#define LIBDEFLATE_MAX_COMPRESSION_LEVEL 12
47
48
#include <stdio.h>
49
50
/*
51
* Sigh, ZLIB_VERSION is defined as a string so there's no
52
* way to do a proper check here. Instead we guess based
53
* on the presence of #defines that were added between the
54
* 0.95 and 1.0 distributions.
55
*/
56
#if !defined(Z_NO_COMPRESSION) || !defined(Z_DEFLATED)
57
#error "Antiquated ZLIB software; you must use version 1.0 or later"
58
#endif
59
60
#define SAFE_MSG(sp) ((sp)->stream.msg == NULL ? "" : (sp)->stream.msg)
61
62
/*
63
* State block for each open TIFF
64
* file using ZIP compression/decompression.
65
*/
66
typedef struct
67
{
68
TIFFPredictorState predict;
69
z_stream stream;
70
int read_error; /* whether a read error has occurred, and which should cause
71
further reads in the same strip/tile to be aborted */
72
int zipquality; /* compression level */
73
int state; /* state flags */
74
int subcodec; /* DEFLATE_SUBCODEC_ZLIB or DEFLATE_SUBCODEC_LIBDEFLATE */
75
#if LIBDEFLATE_SUPPORT
76
int libdeflate_state; /* -1 = until first time ZIPEncode() / ZIPDecode() is
77
called, 0 = use zlib, 1 = use libdeflate */
78
struct libdeflate_decompressor *libdeflate_dec;
79
struct libdeflate_compressor *libdeflate_enc;
80
#endif
81
#define ZSTATE_INIT_DECODE 0x01
82
#define ZSTATE_INIT_ENCODE 0x02
83
84
TIFFVGetMethod vgetparent; /* super-class method */
85
TIFFVSetMethod vsetparent; /* super-class method */
86
} ZIPState;
87
88
#define GetZIPState(tif) ((ZIPState *)(tif)->tif_data)
89
#define ZIPDecoderState(tif) GetZIPState(tif)
90
#define ZIPEncoderState(tif) GetZIPState(tif)
91
92
static int ZIPEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s);
93
static int ZIPDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s);
94
95
static int ZIPFixupTags(TIFF *tif)
96
{
97
(void)tif;
98
return (1);
99
}
100
101
static int ZIPSetupDecode(TIFF *tif)
102
{
103
static const char module[] = "ZIPSetupDecode";
104
ZIPState *sp = ZIPDecoderState(tif);
105
106
assert(sp != NULL);
107
108
/* if we were last encoding, terminate this mode */
109
if (sp->state & ZSTATE_INIT_ENCODE)
110
{
111
deflateEnd(&sp->stream);
112
sp->state = 0;
113
}
114
115
/* This function can possibly be called several times by */
116
/* PredictorSetupDecode() if this function succeeds but */
117
/* PredictorSetup() fails */
118
if ((sp->state & ZSTATE_INIT_DECODE) == 0 &&
119
inflateInit(&sp->stream) != Z_OK)
120
{
121
TIFFErrorExtR(tif, module, "%s", SAFE_MSG(sp));
122
return (0);
123
}
124
else
125
{
126
sp->state |= ZSTATE_INIT_DECODE;
127
return (1);
128
}
129
}
130
131
/*
132
* Setup state for decoding a strip.
133
*/
134
static int ZIPPreDecode(TIFF *tif, uint16_t s)
135
{
136
ZIPState *sp = ZIPDecoderState(tif);
137
138
(void)s;
139
assert(sp != NULL);
140
141
if ((sp->state & ZSTATE_INIT_DECODE) == 0)
142
tif->tif_setupdecode(tif);
143
144
#if LIBDEFLATE_SUPPORT
145
sp->libdeflate_state = -1;
146
#endif
147
sp->stream.next_in = tif->tif_rawdata;
148
assert(sizeof(sp->stream.avail_in) == 4); /* if this assert gets raised,
149
we need to simplify this code to reflect a ZLib that is likely updated
150
to deal with 8byte memory sizes, though this code will respond
151
appropriately even before we simplify it */
152
sp->stream.avail_in = (uint64_t)tif->tif_rawcc < 0xFFFFFFFFU
153
? (uInt)tif->tif_rawcc
154
: 0xFFFFFFFFU;
155
if (inflateReset(&sp->stream) == Z_OK)
156
{
157
sp->read_error = 0;
158
return 1;
159
}
160
return 0;
161
}
162
163
static int ZIPDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
164
{
165
static const char module[] = "ZIPDecode";
166
ZIPState *sp = ZIPDecoderState(tif);
167
168
(void)s;
169
assert(sp != NULL);
170
assert(sp->state == ZSTATE_INIT_DECODE);
171
172
if (sp->read_error)
173
{
174
memset(op, 0, (size_t)occ);
175
TIFFErrorExtR(tif, module,
176
"ZIPDecode: Scanline %" PRIu32 " cannot be read due to "
177
"previous error",
178
tif->tif_row);
179
return 0;
180
}
181
182
#if LIBDEFLATE_SUPPORT
183
if (sp->libdeflate_state == 1)
184
return 0;
185
186
/* If we have libdeflate support and we are asked to read a whole */
187
/* strip/tile, then go for using it */
188
do
189
{
190
TIFFDirectory *td = &tif->tif_dir;
191
192
if (sp->libdeflate_state == 0)
193
break;
194
if (sp->subcodec == DEFLATE_SUBCODEC_ZLIB)
195
break;
196
197
/* Check if we are in the situation where we can use libdeflate */
198
if (isTiled(tif))
199
{
200
if (TIFFTileSize64(tif) != (uint64_t)occ)
201
break;
202
}
203
else
204
{
205
uint32_t strip_height = td->td_imagelength - tif->tif_row;
206
if (strip_height > td->td_rowsperstrip)
207
strip_height = td->td_rowsperstrip;
208
if (TIFFVStripSize64(tif, strip_height) != (uint64_t)occ)
209
break;
210
}
211
212
/* Check for overflow */
213
if ((size_t)tif->tif_rawcc != (uint64_t)tif->tif_rawcc)
214
break;
215
if ((size_t)occ != (uint64_t)occ)
216
break;
217
218
/* Go for decompression using libdeflate */
219
{
220
enum libdeflate_result res;
221
if (sp->libdeflate_dec == NULL)
222
{
223
sp->libdeflate_dec = libdeflate_alloc_decompressor();
224
if (sp->libdeflate_dec == NULL)
225
{
226
break;
227
}
228
}
229
230
sp->libdeflate_state = 1;
231
232
res = libdeflate_zlib_decompress(sp->libdeflate_dec, tif->tif_rawcp,
233
(size_t)tif->tif_rawcc, op,
234
(size_t)occ, NULL);
235
236
tif->tif_rawcp += tif->tif_rawcc;
237
tif->tif_rawcc = 0;
238
239
/* We accept LIBDEFLATE_INSUFFICIENT_SPACE has a return */
240
/* There are odd files in the wild where the last strip, when */
241
/* it is smaller in height than td_rowsperstrip, actually contains
242
*/
243
/* data for td_rowsperstrip lines. Just ignore that silently. */
244
if (res != LIBDEFLATE_SUCCESS &&
245
res != LIBDEFLATE_INSUFFICIENT_SPACE)
246
{
247
memset(op, 0, (size_t)occ);
248
TIFFErrorExtR(tif, module, "Decoding error at scanline %lu",
249
(unsigned long)tif->tif_row);
250
sp->read_error = 1;
251
return 0;
252
}
253
254
return 1;
255
}
256
} while (0);
257
sp->libdeflate_state = 0;
258
#endif /* LIBDEFLATE_SUPPORT */
259
260
sp->stream.next_in = tif->tif_rawcp;
261
262
sp->stream.next_out = op;
263
assert(sizeof(sp->stream.avail_out) == 4); /* if this assert gets raised,
264
we need to simplify this code to reflect a ZLib that is likely updated
265
to deal with 8byte memory sizes, though this code will respond
266
appropriately even before we simplify it */
267
do
268
{
269
int state;
270
uInt avail_in_before = (uint64_t)tif->tif_rawcc <= 0xFFFFFFFFU
271
? (uInt)tif->tif_rawcc
272
: 0xFFFFFFFFU;
273
uInt avail_out_before =
274
(uint64_t)occ < 0xFFFFFFFFU ? (uInt)occ : 0xFFFFFFFFU;
275
sp->stream.avail_in = avail_in_before;
276
sp->stream.avail_out = avail_out_before;
277
/* coverity[overrun-buffer-arg] */
278
state = inflate(&sp->stream, Z_PARTIAL_FLUSH);
279
tif->tif_rawcc -= (avail_in_before - sp->stream.avail_in);
280
occ -= (avail_out_before - sp->stream.avail_out);
281
if (state == Z_STREAM_END)
282
break;
283
if (state == Z_DATA_ERROR)
284
{
285
memset(sp->stream.next_out, 0, sp->stream.avail_out);
286
TIFFErrorExtR(tif, module, "Decoding error at scanline %lu, %s",
287
(unsigned long)tif->tif_row, SAFE_MSG(sp));
288
sp->read_error = 1;
289
return (0);
290
}
291
if (state != Z_OK)
292
{
293
memset(sp->stream.next_out, 0, sp->stream.avail_out);
294
TIFFErrorExtR(tif, module, "ZLib error: %s", SAFE_MSG(sp));
295
sp->read_error = 1;
296
return (0);
297
}
298
} while (occ > 0);
299
if (occ != 0)
300
{
301
TIFFErrorExtR(tif, module,
302
"Not enough data at scanline %lu (short %" PRIu64
303
" bytes)",
304
(unsigned long)tif->tif_row, (uint64_t)occ);
305
memset(sp->stream.next_out, 0, sp->stream.avail_out);
306
sp->read_error = 1;
307
return (0);
308
}
309
310
tif->tif_rawcp = sp->stream.next_in;
311
312
return (1);
313
}
314
315
static int ZIPSetupEncode(TIFF *tif)
316
{
317
static const char module[] = "ZIPSetupEncode";
318
ZIPState *sp = ZIPEncoderState(tif);
319
int cappedQuality;
320
321
assert(sp != NULL);
322
if (sp->state & ZSTATE_INIT_DECODE)
323
{
324
inflateEnd(&sp->stream);
325
sp->state = 0;
326
}
327
328
cappedQuality = sp->zipquality;
329
if (cappedQuality > Z_BEST_COMPRESSION)
330
cappedQuality = Z_BEST_COMPRESSION;
331
332
if (deflateInit(&sp->stream, cappedQuality) != Z_OK)
333
{
334
TIFFErrorExtR(tif, module, "%s", SAFE_MSG(sp));
335
return (0);
336
}
337
else
338
{
339
sp->state |= ZSTATE_INIT_ENCODE;
340
return (1);
341
}
342
}
343
344
/*
345
* Reset encoding state at the start of a strip.
346
*/
347
static int ZIPPreEncode(TIFF *tif, uint16_t s)
348
{
349
ZIPState *sp = ZIPEncoderState(tif);
350
351
(void)s;
352
assert(sp != NULL);
353
if (sp->state != ZSTATE_INIT_ENCODE)
354
tif->tif_setupencode(tif);
355
356
#if LIBDEFLATE_SUPPORT
357
sp->libdeflate_state = -1;
358
#endif
359
sp->stream.next_out = tif->tif_rawdata;
360
assert(sizeof(sp->stream.avail_out) == 4); /* if this assert gets raised,
361
we need to simplify this code to reflect a ZLib that is likely updated
362
to deal with 8byte memory sizes, though this code will respond
363
appropriately even before we simplify it */
364
sp->stream.avail_out = (uint64_t)tif->tif_rawdatasize <= 0xFFFFFFFFU
365
? (uInt)tif->tif_rawdatasize
366
: 0xFFFFFFFFU;
367
return (deflateReset(&sp->stream) == Z_OK);
368
}
369
370
/*
371
* Encode a chunk of pixels.
372
*/
373
static int ZIPEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s)
374
{
375
static const char module[] = "ZIPEncode";
376
ZIPState *sp = ZIPEncoderState(tif);
377
378
assert(sp != NULL);
379
assert(sp->state == ZSTATE_INIT_ENCODE);
380
381
(void)s;
382
383
#if LIBDEFLATE_SUPPORT
384
if (sp->libdeflate_state == 1)
385
return 0;
386
387
/* If we have libdeflate support and we are asked to write a whole */
388
/* strip/tile, then go for using it */
389
do
390
{
391
TIFFDirectory *td = &tif->tif_dir;
392
393
if (sp->libdeflate_state == 0)
394
break;
395
if (sp->subcodec == DEFLATE_SUBCODEC_ZLIB)
396
break;
397
398
/* Libdeflate does not support the 0-compression level */
399
if (sp->zipquality == Z_NO_COMPRESSION)
400
break;
401
402
/* Check if we are in the situation where we can use libdeflate */
403
if (isTiled(tif))
404
{
405
if (TIFFTileSize64(tif) != (uint64_t)cc)
406
break;
407
}
408
else
409
{
410
uint32_t strip_height = td->td_imagelength - tif->tif_row;
411
if (strip_height > td->td_rowsperstrip)
412
strip_height = td->td_rowsperstrip;
413
if (TIFFVStripSize64(tif, strip_height) != (uint64_t)cc)
414
break;
415
}
416
417
/* Check for overflow */
418
if ((size_t)tif->tif_rawdatasize != (uint64_t)tif->tif_rawdatasize)
419
break;
420
if ((size_t)cc != (uint64_t)cc)
421
break;
422
423
/* Go for compression using libdeflate */
424
{
425
size_t nCompressedBytes;
426
if (sp->libdeflate_enc == NULL)
427
{
428
/* To get results as good as zlib, we asked for an extra */
429
/* level of compression */
430
sp->libdeflate_enc = libdeflate_alloc_compressor(
431
sp->zipquality == Z_DEFAULT_COMPRESSION ? 7
432
: sp->zipquality >= 6 && sp->zipquality <= 9
433
? sp->zipquality + 1
434
: sp->zipquality);
435
if (sp->libdeflate_enc == NULL)
436
{
437
TIFFErrorExtR(tif, module, "Cannot allocate compressor");
438
break;
439
}
440
}
441
442
/* Make sure the output buffer is large enough for the worse case.
443
*/
444
/* In TIFFWriteBufferSetup(), when libtiff allocates the buffer */
445
/* we've taken a 10% margin over the uncompressed size, which should
446
*/
447
/* be large enough even for the the worse case scenario. */
448
if (libdeflate_zlib_compress_bound(sp->libdeflate_enc, (size_t)cc) >
449
(size_t)tif->tif_rawdatasize)
450
{
451
break;
452
}
453
454
sp->libdeflate_state = 1;
455
nCompressedBytes = libdeflate_zlib_compress(
456
sp->libdeflate_enc, bp, (size_t)cc, tif->tif_rawdata,
457
(size_t)tif->tif_rawdatasize);
458
459
if (nCompressedBytes == 0)
460
{
461
TIFFErrorExtR(tif, module, "Encoder error at scanline %lu",
462
(unsigned long)tif->tif_row);
463
return 0;
464
}
465
466
tif->tif_rawcc = nCompressedBytes;
467
468
if (!TIFFFlushData1(tif))
469
return 0;
470
471
return 1;
472
}
473
} while (0);
474
sp->libdeflate_state = 0;
475
#endif /* LIBDEFLATE_SUPPORT */
476
477
sp->stream.next_in = bp;
478
assert(sizeof(sp->stream.avail_in) == 4); /* if this assert gets raised,
479
we need to simplify this code to reflect a ZLib that is likely updated
480
to deal with 8byte memory sizes, though this code will respond
481
appropriately even before we simplify it */
482
do
483
{
484
uInt avail_in_before =
485
(uint64_t)cc <= 0xFFFFFFFFU ? (uInt)cc : 0xFFFFFFFFU;
486
sp->stream.avail_in = avail_in_before;
487
/* coverity[overrun-buffer-arg] */
488
if (deflate(&sp->stream, Z_NO_FLUSH) != Z_OK)
489
{
490
TIFFErrorExtR(tif, module, "Encoder error: %s", SAFE_MSG(sp));
491
return (0);
492
}
493
if (sp->stream.avail_out == 0)
494
{
495
tif->tif_rawcc = tif->tif_rawdatasize;
496
if (!TIFFFlushData1(tif))
497
return 0;
498
sp->stream.next_out = tif->tif_rawdata;
499
sp->stream.avail_out = (uint64_t)tif->tif_rawdatasize <= 0xFFFFFFFFU
500
? (uInt)tif->tif_rawdatasize
501
: 0xFFFFFFFFU;
502
}
503
cc -= (avail_in_before - sp->stream.avail_in);
504
} while (cc > 0);
505
return (1);
506
}
507
508
/*
509
* Finish off an encoded strip by flushing the last
510
* string and tacking on an End Of Information code.
511
*/
512
static int ZIPPostEncode(TIFF *tif)
513
{
514
static const char module[] = "ZIPPostEncode";
515
ZIPState *sp = ZIPEncoderState(tif);
516
int state;
517
518
#if LIBDEFLATE_SUPPORT
519
if (sp->libdeflate_state == 1)
520
return 1;
521
#endif
522
523
sp->stream.avail_in = 0;
524
do
525
{
526
state = deflate(&sp->stream, Z_FINISH);
527
switch (state)
528
{
529
case Z_STREAM_END:
530
case Z_OK:
531
if ((tmsize_t)sp->stream.avail_out != tif->tif_rawdatasize)
532
{
533
tif->tif_rawcc =
534
tif->tif_rawdatasize - sp->stream.avail_out;
535
if (!TIFFFlushData1(tif))
536
return 0;
537
sp->stream.next_out = tif->tif_rawdata;
538
sp->stream.avail_out =
539
(uint64_t)tif->tif_rawdatasize <= 0xFFFFFFFFU
540
? (uInt)tif->tif_rawdatasize
541
: 0xFFFFFFFFU;
542
}
543
break;
544
default:
545
TIFFErrorExtR(tif, module, "ZLib error: %s", SAFE_MSG(sp));
546
return (0);
547
}
548
} while (state != Z_STREAM_END);
549
return (1);
550
}
551
552
static void ZIPCleanup(TIFF *tif)
553
{
554
ZIPState *sp = GetZIPState(tif);
555
556
assert(sp != 0);
557
558
(void)TIFFPredictorCleanup(tif);
559
560
tif->tif_tagmethods.vgetfield = sp->vgetparent;
561
tif->tif_tagmethods.vsetfield = sp->vsetparent;
562
563
if (sp->state & ZSTATE_INIT_ENCODE)
564
{
565
deflateEnd(&sp->stream);
566
sp->state = 0;
567
}
568
else if (sp->state & ZSTATE_INIT_DECODE)
569
{
570
inflateEnd(&sp->stream);
571
sp->state = 0;
572
}
573
574
#if LIBDEFLATE_SUPPORT
575
if (sp->libdeflate_dec)
576
libdeflate_free_decompressor(sp->libdeflate_dec);
577
if (sp->libdeflate_enc)
578
libdeflate_free_compressor(sp->libdeflate_enc);
579
#endif
580
581
_TIFFfreeExt(tif, sp);
582
tif->tif_data = NULL;
583
584
_TIFFSetDefaultCompressionState(tif);
585
}
586
587
static int ZIPVSetField(TIFF *tif, uint32_t tag, va_list ap)
588
{
589
static const char module[] = "ZIPVSetField";
590
ZIPState *sp = GetZIPState(tif);
591
592
switch (tag)
593
{
594
case TIFFTAG_ZIPQUALITY:
595
sp->zipquality = (int)va_arg(ap, int);
596
if (sp->zipquality < Z_DEFAULT_COMPRESSION ||
597
sp->zipquality > LIBDEFLATE_MAX_COMPRESSION_LEVEL)
598
{
599
TIFFErrorExtR(
600
tif, module,
601
"Invalid ZipQuality value. Should be in [-1,%d] range",
602
LIBDEFLATE_MAX_COMPRESSION_LEVEL);
603
return 0;
604
}
605
606
if (sp->state & ZSTATE_INIT_ENCODE)
607
{
608
int cappedQuality = sp->zipquality;
609
if (cappedQuality > Z_BEST_COMPRESSION)
610
cappedQuality = Z_BEST_COMPRESSION;
611
if (deflateParams(&sp->stream, cappedQuality,
612
Z_DEFAULT_STRATEGY) != Z_OK)
613
{
614
TIFFErrorExtR(tif, module, "ZLib error: %s", SAFE_MSG(sp));
615
return (0);
616
}
617
}
618
619
#if LIBDEFLATE_SUPPORT
620
if (sp->libdeflate_enc)
621
{
622
libdeflate_free_compressor(sp->libdeflate_enc);
623
sp->libdeflate_enc = NULL;
624
}
625
#endif
626
627
return (1);
628
629
case TIFFTAG_DEFLATE_SUBCODEC:
630
sp->subcodec = (int)va_arg(ap, int);
631
if (sp->subcodec != DEFLATE_SUBCODEC_ZLIB &&
632
sp->subcodec != DEFLATE_SUBCODEC_LIBDEFLATE)
633
{
634
TIFFErrorExtR(tif, module, "Invalid DeflateCodec value.");
635
return 0;
636
}
637
#if !LIBDEFLATE_SUPPORT
638
if (sp->subcodec == DEFLATE_SUBCODEC_LIBDEFLATE)
639
{
640
TIFFErrorExtR(tif, module,
641
"DeflateCodec = DEFLATE_SUBCODEC_LIBDEFLATE "
642
"unsupported in this build");
643
return 0;
644
}
645
#endif
646
return 1;
647
648
default:
649
return (*sp->vsetparent)(tif, tag, ap);
650
}
651
/*NOTREACHED*/
652
}
653
654
static int ZIPVGetField(TIFF *tif, uint32_t tag, va_list ap)
655
{
656
ZIPState *sp = GetZIPState(tif);
657
658
switch (tag)
659
{
660
case TIFFTAG_ZIPQUALITY:
661
*va_arg(ap, int *) = sp->zipquality;
662
break;
663
664
case TIFFTAG_DEFLATE_SUBCODEC:
665
*va_arg(ap, int *) = sp->subcodec;
666
break;
667
668
default:
669
return (*sp->vgetparent)(tif, tag, ap);
670
}
671
return (1);
672
}
673
674
static const TIFFField zipFields[] = {
675
{TIFFTAG_ZIPQUALITY, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT,
676
TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, TRUE, FALSE, "", NULL},
677
{TIFFTAG_DEFLATE_SUBCODEC, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT,
678
TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, TRUE, FALSE, "", NULL},
679
};
680
681
static void *TIFF_zalloc(void *opaque, unsigned int items, unsigned int size)
682
{
683
static const char module[] = "TIFF_zalloc";
684
TIFF *tif = opaque;
685
686
if (items > ~(size_t)0 / size)
687
{
688
TIFFErrorExtR(tif, module, "Overflow");
689
return NULL;
690
}
691
692
return _TIFFmallocExt(tif, items * size);
693
}
694
695
static void TIFF_zfree(void *opaque, void *ptr)
696
{
697
_TIFFfreeExt((TIFF *)opaque, ptr);
698
}
699
700
int TIFFInitZIP(TIFF *tif, int scheme)
701
{
702
static const char module[] = "TIFFInitZIP";
703
ZIPState *sp;
704
705
assert((scheme == COMPRESSION_DEFLATE) ||
706
(scheme == COMPRESSION_ADOBE_DEFLATE));
707
#ifdef NDEBUG
708
(void)scheme;
709
#endif
710
711
/*
712
* Merge codec-specific tag information.
713
*/
714
if (!_TIFFMergeFields(tif, zipFields, TIFFArrayCount(zipFields)))
715
{
716
TIFFErrorExtR(tif, module,
717
"Merging Deflate codec-specific tags failed");
718
return 0;
719
}
720
721
/*
722
* Allocate state block so tag methods have storage to record values.
723
*/
724
tif->tif_data = (uint8_t *)_TIFFcallocExt(tif, sizeof(ZIPState), 1);
725
if (tif->tif_data == NULL)
726
goto bad;
727
sp = GetZIPState(tif);
728
sp->stream.zalloc = TIFF_zalloc;
729
sp->stream.zfree = TIFF_zfree;
730
sp->stream.opaque = tif;
731
sp->stream.data_type = Z_BINARY;
732
733
/*
734
* Override parent get/set field methods.
735
*/
736
sp->vgetparent = tif->tif_tagmethods.vgetfield;
737
tif->tif_tagmethods.vgetfield = ZIPVGetField; /* hook for codec tags */
738
sp->vsetparent = tif->tif_tagmethods.vsetfield;
739
tif->tif_tagmethods.vsetfield = ZIPVSetField; /* hook for codec tags */
740
741
/* Default values for codec-specific fields */
742
sp->zipquality = Z_DEFAULT_COMPRESSION; /* default comp. level */
743
sp->state = 0;
744
#if LIBDEFLATE_SUPPORT
745
sp->subcodec = DEFLATE_SUBCODEC_LIBDEFLATE;
746
#else
747
sp->subcodec = DEFLATE_SUBCODEC_ZLIB;
748
#endif
749
750
/*
751
* Install codec methods.
752
*/
753
tif->tif_fixuptags = ZIPFixupTags;
754
tif->tif_setupdecode = ZIPSetupDecode;
755
tif->tif_predecode = ZIPPreDecode;
756
tif->tif_decoderow = ZIPDecode;
757
tif->tif_decodestrip = ZIPDecode;
758
tif->tif_decodetile = ZIPDecode;
759
tif->tif_setupencode = ZIPSetupEncode;
760
tif->tif_preencode = ZIPPreEncode;
761
tif->tif_postencode = ZIPPostEncode;
762
tif->tif_encoderow = ZIPEncode;
763
tif->tif_encodestrip = ZIPEncode;
764
tif->tif_encodetile = ZIPEncode;
765
tif->tif_cleanup = ZIPCleanup;
766
/*
767
* Setup predictor setup.
768
*/
769
(void)TIFFPredictorInit(tif);
770
return (1);
771
bad:
772
TIFFErrorExtR(tif, module, "No space for ZIP state block");
773
return (0);
774
}
775
#endif /* ZIP_SUPPORT */
776
777