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