Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Tetragramm
GitHub Repository: Tetragramm/opencv
Path: blob/master/3rdparty/libtiff/tif_predict.c
16337 views
1
/* $Id: tif_predict.c,v 1.44 2017-06-18 10:31:50 erouault Exp $ */
2
3
/*
4
* Copyright (c) 1988-1997 Sam Leffler
5
* Copyright (c) 1991-1997 Silicon Graphics, Inc.
6
*
7
* Permission to use, copy, modify, distribute, and sell this software and
8
* its documentation for any purpose is hereby granted without fee, provided
9
* that (i) the above copyright notices and this permission notice appear in
10
* all copies of the software and related documentation, and (ii) the names of
11
* Sam Leffler and Silicon Graphics may not be used in any advertising or
12
* publicity relating to the software without the specific, prior written
13
* permission of Sam Leffler and Silicon Graphics.
14
*
15
* THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
16
* EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
17
* WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
18
*
19
* IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
20
* ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
21
* OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
22
* WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
23
* LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
24
* OF THIS SOFTWARE.
25
*/
26
27
/*
28
* TIFF Library.
29
*
30
* Predictor Tag Support (used by multiple codecs).
31
*/
32
#include "tiffiop.h"
33
#include "tif_predict.h"
34
35
#define PredictorState(tif) ((TIFFPredictorState*) (tif)->tif_data)
36
37
static int horAcc8(TIFF* tif, uint8* cp0, tmsize_t cc);
38
static int horAcc16(TIFF* tif, uint8* cp0, tmsize_t cc);
39
static int horAcc32(TIFF* tif, uint8* cp0, tmsize_t cc);
40
static int swabHorAcc16(TIFF* tif, uint8* cp0, tmsize_t cc);
41
static int swabHorAcc32(TIFF* tif, uint8* cp0, tmsize_t cc);
42
static int horDiff8(TIFF* tif, uint8* cp0, tmsize_t cc);
43
static int horDiff16(TIFF* tif, uint8* cp0, tmsize_t cc);
44
static int horDiff32(TIFF* tif, uint8* cp0, tmsize_t cc);
45
static int swabHorDiff16(TIFF* tif, uint8* cp0, tmsize_t cc);
46
static int swabHorDiff32(TIFF* tif, uint8* cp0, tmsize_t cc);
47
static int fpAcc(TIFF* tif, uint8* cp0, tmsize_t cc);
48
static int fpDiff(TIFF* tif, uint8* cp0, tmsize_t cc);
49
static int PredictorDecodeRow(TIFF* tif, uint8* op0, tmsize_t occ0, uint16 s);
50
static int PredictorDecodeTile(TIFF* tif, uint8* op0, tmsize_t occ0, uint16 s);
51
static int PredictorEncodeRow(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s);
52
static int PredictorEncodeTile(TIFF* tif, uint8* bp0, tmsize_t cc0, uint16 s);
53
54
static int
55
PredictorSetup(TIFF* tif)
56
{
57
static const char module[] = "PredictorSetup";
58
59
TIFFPredictorState* sp = PredictorState(tif);
60
TIFFDirectory* td = &tif->tif_dir;
61
62
switch (sp->predictor) /* no differencing */
63
{
64
case PREDICTOR_NONE:
65
return 1;
66
case PREDICTOR_HORIZONTAL:
67
if (td->td_bitspersample != 8
68
&& td->td_bitspersample != 16
69
&& td->td_bitspersample != 32) {
70
TIFFErrorExt(tif->tif_clientdata, module,
71
"Horizontal differencing \"Predictor\" not supported with %d-bit samples",
72
td->td_bitspersample);
73
return 0;
74
}
75
break;
76
case PREDICTOR_FLOATINGPOINT:
77
if (td->td_sampleformat != SAMPLEFORMAT_IEEEFP) {
78
TIFFErrorExt(tif->tif_clientdata, module,
79
"Floating point \"Predictor\" not supported with %d data format",
80
td->td_sampleformat);
81
return 0;
82
}
83
if (td->td_bitspersample != 16
84
&& td->td_bitspersample != 24
85
&& td->td_bitspersample != 32
86
&& td->td_bitspersample != 64) { /* Should 64 be allowed? */
87
TIFFErrorExt(tif->tif_clientdata, module,
88
"Floating point \"Predictor\" not supported with %d-bit samples",
89
td->td_bitspersample);
90
return 0;
91
}
92
break;
93
default:
94
TIFFErrorExt(tif->tif_clientdata, module,
95
"\"Predictor\" value %d not supported",
96
sp->predictor);
97
return 0;
98
}
99
sp->stride = (td->td_planarconfig == PLANARCONFIG_CONTIG ?
100
td->td_samplesperpixel : 1);
101
/*
102
* Calculate the scanline/tile-width size in bytes.
103
*/
104
if (isTiled(tif))
105
sp->rowsize = TIFFTileRowSize(tif);
106
else
107
sp->rowsize = TIFFScanlineSize(tif);
108
if (sp->rowsize == 0)
109
return 0;
110
111
return 1;
112
}
113
114
static int
115
PredictorSetupDecode(TIFF* tif)
116
{
117
TIFFPredictorState* sp = PredictorState(tif);
118
TIFFDirectory* td = &tif->tif_dir;
119
120
/* Note: when PredictorSetup() fails, the effets of setupdecode() */
121
/* will not be "cancelled" so setupdecode() might be robust to */
122
/* be called several times. */
123
if (!(*sp->setupdecode)(tif) || !PredictorSetup(tif))
124
return 0;
125
126
if (sp->predictor == 2) {
127
switch (td->td_bitspersample) {
128
case 8: sp->decodepfunc = horAcc8; break;
129
case 16: sp->decodepfunc = horAcc16; break;
130
case 32: sp->decodepfunc = horAcc32; break;
131
}
132
/*
133
* Override default decoding method with one that does the
134
* predictor stuff.
135
*/
136
if( tif->tif_decoderow != PredictorDecodeRow )
137
{
138
sp->decoderow = tif->tif_decoderow;
139
tif->tif_decoderow = PredictorDecodeRow;
140
sp->decodestrip = tif->tif_decodestrip;
141
tif->tif_decodestrip = PredictorDecodeTile;
142
sp->decodetile = tif->tif_decodetile;
143
tif->tif_decodetile = PredictorDecodeTile;
144
}
145
146
/*
147
* If the data is horizontally differenced 16-bit data that
148
* requires byte-swapping, then it must be byte swapped before
149
* the accumulation step. We do this with a special-purpose
150
* routine and override the normal post decoding logic that
151
* the library setup when the directory was read.
152
*/
153
if (tif->tif_flags & TIFF_SWAB) {
154
if (sp->decodepfunc == horAcc16) {
155
sp->decodepfunc = swabHorAcc16;
156
tif->tif_postdecode = _TIFFNoPostDecode;
157
} else if (sp->decodepfunc == horAcc32) {
158
sp->decodepfunc = swabHorAcc32;
159
tif->tif_postdecode = _TIFFNoPostDecode;
160
}
161
}
162
}
163
164
else if (sp->predictor == 3) {
165
sp->decodepfunc = fpAcc;
166
/*
167
* Override default decoding method with one that does the
168
* predictor stuff.
169
*/
170
if( tif->tif_decoderow != PredictorDecodeRow )
171
{
172
sp->decoderow = tif->tif_decoderow;
173
tif->tif_decoderow = PredictorDecodeRow;
174
sp->decodestrip = tif->tif_decodestrip;
175
tif->tif_decodestrip = PredictorDecodeTile;
176
sp->decodetile = tif->tif_decodetile;
177
tif->tif_decodetile = PredictorDecodeTile;
178
}
179
/*
180
* The data should not be swapped outside of the floating
181
* point predictor, the accumulation routine should return
182
* byres in the native order.
183
*/
184
if (tif->tif_flags & TIFF_SWAB) {
185
tif->tif_postdecode = _TIFFNoPostDecode;
186
}
187
/*
188
* Allocate buffer to keep the decoded bytes before
189
* rearranging in the right order
190
*/
191
}
192
193
return 1;
194
}
195
196
static int
197
PredictorSetupEncode(TIFF* tif)
198
{
199
TIFFPredictorState* sp = PredictorState(tif);
200
TIFFDirectory* td = &tif->tif_dir;
201
202
if (!(*sp->setupencode)(tif) || !PredictorSetup(tif))
203
return 0;
204
205
if (sp->predictor == 2) {
206
switch (td->td_bitspersample) {
207
case 8: sp->encodepfunc = horDiff8; break;
208
case 16: sp->encodepfunc = horDiff16; break;
209
case 32: sp->encodepfunc = horDiff32; break;
210
}
211
/*
212
* Override default encoding method with one that does the
213
* predictor stuff.
214
*/
215
if( tif->tif_encoderow != PredictorEncodeRow )
216
{
217
sp->encoderow = tif->tif_encoderow;
218
tif->tif_encoderow = PredictorEncodeRow;
219
sp->encodestrip = tif->tif_encodestrip;
220
tif->tif_encodestrip = PredictorEncodeTile;
221
sp->encodetile = tif->tif_encodetile;
222
tif->tif_encodetile = PredictorEncodeTile;
223
}
224
225
/*
226
* If the data is horizontally differenced 16-bit data that
227
* requires byte-swapping, then it must be byte swapped after
228
* the differentiation step. We do this with a special-purpose
229
* routine and override the normal post decoding logic that
230
* the library setup when the directory was read.
231
*/
232
if (tif->tif_flags & TIFF_SWAB) {
233
if (sp->encodepfunc == horDiff16) {
234
sp->encodepfunc = swabHorDiff16;
235
tif->tif_postdecode = _TIFFNoPostDecode;
236
} else if (sp->encodepfunc == horDiff32) {
237
sp->encodepfunc = swabHorDiff32;
238
tif->tif_postdecode = _TIFFNoPostDecode;
239
}
240
}
241
}
242
243
else if (sp->predictor == 3) {
244
sp->encodepfunc = fpDiff;
245
/*
246
* Override default encoding method with one that does the
247
* predictor stuff.
248
*/
249
if( tif->tif_encoderow != PredictorEncodeRow )
250
{
251
sp->encoderow = tif->tif_encoderow;
252
tif->tif_encoderow = PredictorEncodeRow;
253
sp->encodestrip = tif->tif_encodestrip;
254
tif->tif_encodestrip = PredictorEncodeTile;
255
sp->encodetile = tif->tif_encodetile;
256
tif->tif_encodetile = PredictorEncodeTile;
257
}
258
}
259
260
return 1;
261
}
262
263
#define REPEAT4(n, op) \
264
switch (n) { \
265
default: { \
266
tmsize_t i; for (i = n-4; i > 0; i--) { op; } } /*-fallthrough*/ \
267
case 4: op; /*-fallthrough*/ \
268
case 3: op; /*-fallthrough*/ \
269
case 2: op; /*-fallthrough*/ \
270
case 1: op; /*-fallthrough*/ \
271
case 0: ; \
272
}
273
274
/* Remarks related to C standard compliance in all below functions : */
275
/* - to avoid any undefined behaviour, we only operate on unsigned types */
276
/* since the behaviour of "overflows" is defined (wrap over) */
277
/* - when storing into the byte stream, we explicitly mask with 0xff so */
278
/* as to make icc -check=conversions happy (not necessary by the standard) */
279
280
TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW
281
static int
282
horAcc8(TIFF* tif, uint8* cp0, tmsize_t cc)
283
{
284
tmsize_t stride = PredictorState(tif)->stride;
285
286
unsigned char* cp = (unsigned char*) cp0;
287
if((cc%stride)!=0)
288
{
289
TIFFErrorExt(tif->tif_clientdata, "horAcc8",
290
"%s", "(cc%stride)!=0");
291
return 0;
292
}
293
294
if (cc > stride) {
295
/*
296
* Pipeline the most common cases.
297
*/
298
if (stride == 3) {
299
unsigned int cr = cp[0];
300
unsigned int cg = cp[1];
301
unsigned int cb = cp[2];
302
cc -= 3;
303
cp += 3;
304
while (cc>0) {
305
cp[0] = (unsigned char) ((cr += cp[0]) & 0xff);
306
cp[1] = (unsigned char) ((cg += cp[1]) & 0xff);
307
cp[2] = (unsigned char) ((cb += cp[2]) & 0xff);
308
cc -= 3;
309
cp += 3;
310
}
311
} else if (stride == 4) {
312
unsigned int cr = cp[0];
313
unsigned int cg = cp[1];
314
unsigned int cb = cp[2];
315
unsigned int ca = cp[3];
316
cc -= 4;
317
cp += 4;
318
while (cc>0) {
319
cp[0] = (unsigned char) ((cr += cp[0]) & 0xff);
320
cp[1] = (unsigned char) ((cg += cp[1]) & 0xff);
321
cp[2] = (unsigned char) ((cb += cp[2]) & 0xff);
322
cp[3] = (unsigned char) ((ca += cp[3]) & 0xff);
323
cc -= 4;
324
cp += 4;
325
}
326
} else {
327
cc -= stride;
328
do {
329
REPEAT4(stride, cp[stride] =
330
(unsigned char) ((cp[stride] + *cp) & 0xff); cp++)
331
cc -= stride;
332
} while (cc>0);
333
}
334
}
335
return 1;
336
}
337
338
static int
339
swabHorAcc16(TIFF* tif, uint8* cp0, tmsize_t cc)
340
{
341
uint16* wp = (uint16*) cp0;
342
tmsize_t wc = cc / 2;
343
344
TIFFSwabArrayOfShort(wp, wc);
345
return horAcc16(tif, cp0, cc);
346
}
347
348
TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW
349
static int
350
horAcc16(TIFF* tif, uint8* cp0, tmsize_t cc)
351
{
352
tmsize_t stride = PredictorState(tif)->stride;
353
uint16* wp = (uint16*) cp0;
354
tmsize_t wc = cc / 2;
355
356
if((cc%(2*stride))!=0)
357
{
358
TIFFErrorExt(tif->tif_clientdata, "horAcc16",
359
"%s", "cc%(2*stride))!=0");
360
return 0;
361
}
362
363
if (wc > stride) {
364
wc -= stride;
365
do {
366
REPEAT4(stride, wp[stride] = (uint16)(((unsigned int)wp[stride] + (unsigned int)wp[0]) & 0xffff); wp++)
367
wc -= stride;
368
} while (wc > 0);
369
}
370
return 1;
371
}
372
373
static int
374
swabHorAcc32(TIFF* tif, uint8* cp0, tmsize_t cc)
375
{
376
uint32* wp = (uint32*) cp0;
377
tmsize_t wc = cc / 4;
378
379
TIFFSwabArrayOfLong(wp, wc);
380
return horAcc32(tif, cp0, cc);
381
}
382
383
TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW
384
static int
385
horAcc32(TIFF* tif, uint8* cp0, tmsize_t cc)
386
{
387
tmsize_t stride = PredictorState(tif)->stride;
388
uint32* wp = (uint32*) cp0;
389
tmsize_t wc = cc / 4;
390
391
if((cc%(4*stride))!=0)
392
{
393
TIFFErrorExt(tif->tif_clientdata, "horAcc32",
394
"%s", "cc%(4*stride))!=0");
395
return 0;
396
}
397
398
if (wc > stride) {
399
wc -= stride;
400
do {
401
REPEAT4(stride, wp[stride] += wp[0]; wp++)
402
wc -= stride;
403
} while (wc > 0);
404
}
405
return 1;
406
}
407
408
/*
409
* Floating point predictor accumulation routine.
410
*/
411
static int
412
fpAcc(TIFF* tif, uint8* cp0, tmsize_t cc)
413
{
414
tmsize_t stride = PredictorState(tif)->stride;
415
uint32 bps = tif->tif_dir.td_bitspersample / 8;
416
tmsize_t wc = cc / bps;
417
tmsize_t count = cc;
418
uint8 *cp = (uint8 *) cp0;
419
uint8 *tmp;
420
421
if(cc%(bps*stride)!=0)
422
{
423
TIFFErrorExt(tif->tif_clientdata, "fpAcc",
424
"%s", "cc%(bps*stride))!=0");
425
return 0;
426
}
427
428
tmp = (uint8 *)_TIFFmalloc(cc);
429
if (!tmp)
430
return 0;
431
432
while (count > stride) {
433
REPEAT4(stride, cp[stride] =
434
(unsigned char) ((cp[stride] + cp[0]) & 0xff); cp++)
435
count -= stride;
436
}
437
438
_TIFFmemcpy(tmp, cp0, cc);
439
cp = (uint8 *) cp0;
440
for (count = 0; count < wc; count++) {
441
uint32 byte;
442
for (byte = 0; byte < bps; byte++) {
443
#if WORDS_BIGENDIAN
444
cp[bps * count + byte] = tmp[byte * wc + count];
445
#else
446
cp[bps * count + byte] =
447
tmp[(bps - byte - 1) * wc + count];
448
#endif
449
}
450
}
451
_TIFFfree(tmp);
452
return 1;
453
}
454
455
/*
456
* Decode a scanline and apply the predictor routine.
457
*/
458
static int
459
PredictorDecodeRow(TIFF* tif, uint8* op0, tmsize_t occ0, uint16 s)
460
{
461
TIFFPredictorState *sp = PredictorState(tif);
462
463
assert(sp != NULL);
464
assert(sp->decoderow != NULL);
465
assert(sp->decodepfunc != NULL);
466
467
if ((*sp->decoderow)(tif, op0, occ0, s)) {
468
return (*sp->decodepfunc)(tif, op0, occ0);
469
} else
470
return 0;
471
}
472
473
/*
474
* Decode a tile/strip and apply the predictor routine.
475
* Note that horizontal differencing must be done on a
476
* row-by-row basis. The width of a "row" has already
477
* been calculated at pre-decode time according to the
478
* strip/tile dimensions.
479
*/
480
static int
481
PredictorDecodeTile(TIFF* tif, uint8* op0, tmsize_t occ0, uint16 s)
482
{
483
TIFFPredictorState *sp = PredictorState(tif);
484
485
assert(sp != NULL);
486
assert(sp->decodetile != NULL);
487
488
if ((*sp->decodetile)(tif, op0, occ0, s)) {
489
tmsize_t rowsize = sp->rowsize;
490
assert(rowsize > 0);
491
if((occ0%rowsize) !=0)
492
{
493
TIFFErrorExt(tif->tif_clientdata, "PredictorDecodeTile",
494
"%s", "occ0%rowsize != 0");
495
return 0;
496
}
497
assert(sp->decodepfunc != NULL);
498
while (occ0 > 0) {
499
if( !(*sp->decodepfunc)(tif, op0, rowsize) )
500
return 0;
501
occ0 -= rowsize;
502
op0 += rowsize;
503
}
504
return 1;
505
} else
506
return 0;
507
}
508
509
TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW
510
static int
511
horDiff8(TIFF* tif, uint8* cp0, tmsize_t cc)
512
{
513
TIFFPredictorState* sp = PredictorState(tif);
514
tmsize_t stride = sp->stride;
515
unsigned char* cp = (unsigned char*) cp0;
516
517
if((cc%stride)!=0)
518
{
519
TIFFErrorExt(tif->tif_clientdata, "horDiff8",
520
"%s", "(cc%stride)!=0");
521
return 0;
522
}
523
524
if (cc > stride) {
525
cc -= stride;
526
/*
527
* Pipeline the most common cases.
528
*/
529
if (stride == 3) {
530
unsigned int r1, g1, b1;
531
unsigned int r2 = cp[0];
532
unsigned int g2 = cp[1];
533
unsigned int b2 = cp[2];
534
do {
535
r1 = cp[3]; cp[3] = (unsigned char)((r1-r2)&0xff); r2 = r1;
536
g1 = cp[4]; cp[4] = (unsigned char)((g1-g2)&0xff); g2 = g1;
537
b1 = cp[5]; cp[5] = (unsigned char)((b1-b2)&0xff); b2 = b1;
538
cp += 3;
539
} while ((cc -= 3) > 0);
540
} else if (stride == 4) {
541
unsigned int r1, g1, b1, a1;
542
unsigned int r2 = cp[0];
543
unsigned int g2 = cp[1];
544
unsigned int b2 = cp[2];
545
unsigned int a2 = cp[3];
546
do {
547
r1 = cp[4]; cp[4] = (unsigned char)((r1-r2)&0xff); r2 = r1;
548
g1 = cp[5]; cp[5] = (unsigned char)((g1-g2)&0xff); g2 = g1;
549
b1 = cp[6]; cp[6] = (unsigned char)((b1-b2)&0xff); b2 = b1;
550
a1 = cp[7]; cp[7] = (unsigned char)((a1-a2)&0xff); a2 = a1;
551
cp += 4;
552
} while ((cc -= 4) > 0);
553
} else {
554
cp += cc - 1;
555
do {
556
REPEAT4(stride, cp[stride] = (unsigned char)((cp[stride] - cp[0])&0xff); cp--)
557
} while ((cc -= stride) > 0);
558
}
559
}
560
return 1;
561
}
562
563
TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW
564
static int
565
horDiff16(TIFF* tif, uint8* cp0, tmsize_t cc)
566
{
567
TIFFPredictorState* sp = PredictorState(tif);
568
tmsize_t stride = sp->stride;
569
uint16 *wp = (uint16*) cp0;
570
tmsize_t wc = cc/2;
571
572
if((cc%(2*stride))!=0)
573
{
574
TIFFErrorExt(tif->tif_clientdata, "horDiff8",
575
"%s", "(cc%(2*stride))!=0");
576
return 0;
577
}
578
579
if (wc > stride) {
580
wc -= stride;
581
wp += wc - 1;
582
do {
583
REPEAT4(stride, wp[stride] = (uint16)(((unsigned int)wp[stride] - (unsigned int)wp[0]) & 0xffff); wp--)
584
wc -= stride;
585
} while (wc > 0);
586
}
587
return 1;
588
}
589
590
static int
591
swabHorDiff16(TIFF* tif, uint8* cp0, tmsize_t cc)
592
{
593
uint16* wp = (uint16*) cp0;
594
tmsize_t wc = cc / 2;
595
596
if( !horDiff16(tif, cp0, cc) )
597
return 0;
598
599
TIFFSwabArrayOfShort(wp, wc);
600
return 1;
601
}
602
603
TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW
604
static int
605
horDiff32(TIFF* tif, uint8* cp0, tmsize_t cc)
606
{
607
TIFFPredictorState* sp = PredictorState(tif);
608
tmsize_t stride = sp->stride;
609
uint32 *wp = (uint32*) cp0;
610
tmsize_t wc = cc/4;
611
612
if((cc%(4*stride))!=0)
613
{
614
TIFFErrorExt(tif->tif_clientdata, "horDiff32",
615
"%s", "(cc%(4*stride))!=0");
616
return 0;
617
}
618
619
if (wc > stride) {
620
wc -= stride;
621
wp += wc - 1;
622
do {
623
REPEAT4(stride, wp[stride] -= wp[0]; wp--)
624
wc -= stride;
625
} while (wc > 0);
626
}
627
return 1;
628
}
629
630
static int
631
swabHorDiff32(TIFF* tif, uint8* cp0, tmsize_t cc)
632
{
633
uint32* wp = (uint32*) cp0;
634
tmsize_t wc = cc / 4;
635
636
if( !horDiff32(tif, cp0, cc) )
637
return 0;
638
639
TIFFSwabArrayOfLong(wp, wc);
640
return 1;
641
}
642
643
/*
644
* Floating point predictor differencing routine.
645
*/
646
TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW
647
static int
648
fpDiff(TIFF* tif, uint8* cp0, tmsize_t cc)
649
{
650
tmsize_t stride = PredictorState(tif)->stride;
651
uint32 bps = tif->tif_dir.td_bitspersample / 8;
652
tmsize_t wc = cc / bps;
653
tmsize_t count;
654
uint8 *cp = (uint8 *) cp0;
655
uint8 *tmp;
656
657
if((cc%(bps*stride))!=0)
658
{
659
TIFFErrorExt(tif->tif_clientdata, "fpDiff",
660
"%s", "(cc%(bps*stride))!=0");
661
return 0;
662
}
663
664
tmp = (uint8 *)_TIFFmalloc(cc);
665
if (!tmp)
666
return 0;
667
668
_TIFFmemcpy(tmp, cp0, cc);
669
for (count = 0; count < wc; count++) {
670
uint32 byte;
671
for (byte = 0; byte < bps; byte++) {
672
#if WORDS_BIGENDIAN
673
cp[byte * wc + count] = tmp[bps * count + byte];
674
#else
675
cp[(bps - byte - 1) * wc + count] =
676
tmp[bps * count + byte];
677
#endif
678
}
679
}
680
_TIFFfree(tmp);
681
682
cp = (uint8 *) cp0;
683
cp += cc - stride - 1;
684
for (count = cc; count > stride; count -= stride)
685
REPEAT4(stride, cp[stride] = (unsigned char)((cp[stride] - cp[0])&0xff); cp--)
686
return 1;
687
}
688
689
static int
690
PredictorEncodeRow(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s)
691
{
692
TIFFPredictorState *sp = PredictorState(tif);
693
694
assert(sp != NULL);
695
assert(sp->encodepfunc != NULL);
696
assert(sp->encoderow != NULL);
697
698
/* XXX horizontal differencing alters user's data XXX */
699
if( !(*sp->encodepfunc)(tif, bp, cc) )
700
return 0;
701
return (*sp->encoderow)(tif, bp, cc, s);
702
}
703
704
static int
705
PredictorEncodeTile(TIFF* tif, uint8* bp0, tmsize_t cc0, uint16 s)
706
{
707
static const char module[] = "PredictorEncodeTile";
708
TIFFPredictorState *sp = PredictorState(tif);
709
uint8 *working_copy;
710
tmsize_t cc = cc0, rowsize;
711
unsigned char* bp;
712
int result_code;
713
714
assert(sp != NULL);
715
assert(sp->encodepfunc != NULL);
716
assert(sp->encodetile != NULL);
717
718
/*
719
* Do predictor manipulation in a working buffer to avoid altering
720
* the callers buffer. http://trac.osgeo.org/gdal/ticket/1965
721
*/
722
working_copy = (uint8*) _TIFFmalloc(cc0);
723
if( working_copy == NULL )
724
{
725
TIFFErrorExt(tif->tif_clientdata, module,
726
"Out of memory allocating " TIFF_SSIZE_FORMAT " byte temp buffer.",
727
cc0 );
728
return 0;
729
}
730
memcpy( working_copy, bp0, cc0 );
731
bp = working_copy;
732
733
rowsize = sp->rowsize;
734
assert(rowsize > 0);
735
if((cc0%rowsize)!=0)
736
{
737
TIFFErrorExt(tif->tif_clientdata, "PredictorEncodeTile",
738
"%s", "(cc0%rowsize)!=0");
739
_TIFFfree( working_copy );
740
return 0;
741
}
742
while (cc > 0) {
743
(*sp->encodepfunc)(tif, bp, rowsize);
744
cc -= rowsize;
745
bp += rowsize;
746
}
747
result_code = (*sp->encodetile)(tif, working_copy, cc0, s);
748
749
_TIFFfree( working_copy );
750
751
return result_code;
752
}
753
754
#define FIELD_PREDICTOR (FIELD_CODEC+0) /* XXX */
755
756
static const TIFFField predictFields[] = {
757
{ TIFFTAG_PREDICTOR, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UINT16, FIELD_PREDICTOR, FALSE, FALSE, "Predictor", NULL },
758
};
759
760
static int
761
PredictorVSetField(TIFF* tif, uint32 tag, va_list ap)
762
{
763
TIFFPredictorState *sp = PredictorState(tif);
764
765
assert(sp != NULL);
766
assert(sp->vsetparent != NULL);
767
768
switch (tag) {
769
case TIFFTAG_PREDICTOR:
770
sp->predictor = (uint16) va_arg(ap, uint16_vap);
771
TIFFSetFieldBit(tif, FIELD_PREDICTOR);
772
break;
773
default:
774
return (*sp->vsetparent)(tif, tag, ap);
775
}
776
tif->tif_flags |= TIFF_DIRTYDIRECT;
777
return 1;
778
}
779
780
static int
781
PredictorVGetField(TIFF* tif, uint32 tag, va_list ap)
782
{
783
TIFFPredictorState *sp = PredictorState(tif);
784
785
assert(sp != NULL);
786
assert(sp->vgetparent != NULL);
787
788
switch (tag) {
789
case TIFFTAG_PREDICTOR:
790
*va_arg(ap, uint16*) = (uint16)sp->predictor;
791
break;
792
default:
793
return (*sp->vgetparent)(tif, tag, ap);
794
}
795
return 1;
796
}
797
798
static void
799
PredictorPrintDir(TIFF* tif, FILE* fd, long flags)
800
{
801
TIFFPredictorState* sp = PredictorState(tif);
802
803
(void) flags;
804
if (TIFFFieldSet(tif,FIELD_PREDICTOR)) {
805
fprintf(fd, " Predictor: ");
806
switch (sp->predictor) {
807
case 1: fprintf(fd, "none "); break;
808
case 2: fprintf(fd, "horizontal differencing "); break;
809
case 3: fprintf(fd, "floating point predictor "); break;
810
}
811
fprintf(fd, "%d (0x%x)\n", sp->predictor, sp->predictor);
812
}
813
if (sp->printdir)
814
(*sp->printdir)(tif, fd, flags);
815
}
816
817
int
818
TIFFPredictorInit(TIFF* tif)
819
{
820
TIFFPredictorState* sp = PredictorState(tif);
821
822
assert(sp != 0);
823
824
/*
825
* Merge codec-specific tag information.
826
*/
827
if (!_TIFFMergeFields(tif, predictFields,
828
TIFFArrayCount(predictFields))) {
829
TIFFErrorExt(tif->tif_clientdata, "TIFFPredictorInit",
830
"Merging Predictor codec-specific tags failed");
831
return 0;
832
}
833
834
/*
835
* Override parent get/set field methods.
836
*/
837
sp->vgetparent = tif->tif_tagmethods.vgetfield;
838
tif->tif_tagmethods.vgetfield =
839
PredictorVGetField;/* hook for predictor tag */
840
sp->vsetparent = tif->tif_tagmethods.vsetfield;
841
tif->tif_tagmethods.vsetfield =
842
PredictorVSetField;/* hook for predictor tag */
843
sp->printdir = tif->tif_tagmethods.printdir;
844
tif->tif_tagmethods.printdir =
845
PredictorPrintDir; /* hook for predictor tag */
846
847
sp->setupdecode = tif->tif_setupdecode;
848
tif->tif_setupdecode = PredictorSetupDecode;
849
sp->setupencode = tif->tif_setupencode;
850
tif->tif_setupencode = PredictorSetupEncode;
851
852
sp->predictor = 1; /* default value */
853
sp->encodepfunc = NULL; /* no predictor routine */
854
sp->decodepfunc = NULL; /* no predictor routine */
855
return 1;
856
}
857
858
int
859
TIFFPredictorCleanup(TIFF* tif)
860
{
861
TIFFPredictorState* sp = PredictorState(tif);
862
863
assert(sp != 0);
864
865
tif->tif_tagmethods.vgetfield = sp->vgetparent;
866
tif->tif_tagmethods.vsetfield = sp->vsetparent;
867
tif->tif_tagmethods.printdir = sp->printdir;
868
tif->tif_setupdecode = sp->setupdecode;
869
tif->tif_setupencode = sp->setupencode;
870
871
return 1;
872
}
873
874
/* vim: set ts=8 sts=8 sw=8 noet: */
875
/*
876
* Local Variables:
877
* mode: c
878
* c-basic-offset: 8
879
* fill-column: 78
880
* End:
881
*/
882
883