xref: /aosp_15_r20/external/dng_sdk/source/dng_lossless_jpeg.cpp (revision fd1fabb72dbdf09ea7034f531e6f8e9f57334c8d)
1*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
2*fd1fabb7SAndroid Build Coastguard Worker // Copyright 2006-2007 Adobe Systems Incorporated
3*fd1fabb7SAndroid Build Coastguard Worker // All Rights Reserved.
4*fd1fabb7SAndroid Build Coastguard Worker //
5*fd1fabb7SAndroid Build Coastguard Worker // NOTICE:  Adobe permits you to use, modify, and distribute this file in
6*fd1fabb7SAndroid Build Coastguard Worker // accordance with the terms of the Adobe license agreement accompanying it.
7*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
8*fd1fabb7SAndroid Build Coastguard Worker 
9*fd1fabb7SAndroid Build Coastguard Worker /* $Id: //mondo/dng_sdk_1_4/dng_sdk/source/dng_lossless_jpeg.cpp#2 $ */
10*fd1fabb7SAndroid Build Coastguard Worker /* $DateTime: 2012/06/01 07:28:57 $ */
11*fd1fabb7SAndroid Build Coastguard Worker /* $Change: 832715 $ */
12*fd1fabb7SAndroid Build Coastguard Worker /* $Author: tknoll $ */
13*fd1fabb7SAndroid Build Coastguard Worker 
14*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
15*fd1fabb7SAndroid Build Coastguard Worker 
16*fd1fabb7SAndroid Build Coastguard Worker // Lossless JPEG code adapted from:
17*fd1fabb7SAndroid Build Coastguard Worker 
18*fd1fabb7SAndroid Build Coastguard Worker /* Copyright (C) 1991, 1992, Thomas G. Lane.
19*fd1fabb7SAndroid Build Coastguard Worker  * Part of the Independent JPEG Group's software.
20*fd1fabb7SAndroid Build Coastguard Worker  * See the file Copyright for more details.
21*fd1fabb7SAndroid Build Coastguard Worker  *
22*fd1fabb7SAndroid Build Coastguard Worker  * Copyright (c) 1993 Brian C. Smith, The Regents of the University
23*fd1fabb7SAndroid Build Coastguard Worker  * of California
24*fd1fabb7SAndroid Build Coastguard Worker  * All rights reserved.
25*fd1fabb7SAndroid Build Coastguard Worker  *
26*fd1fabb7SAndroid Build Coastguard Worker  * Copyright (c) 1994 Kongji Huang and Brian C. Smith.
27*fd1fabb7SAndroid Build Coastguard Worker  * Cornell University
28*fd1fabb7SAndroid Build Coastguard Worker  * All rights reserved.
29*fd1fabb7SAndroid Build Coastguard Worker  *
30*fd1fabb7SAndroid Build Coastguard Worker  * Permission to use, copy, modify, and distribute this software and its
31*fd1fabb7SAndroid Build Coastguard Worker  * documentation for any purpose, without fee, and without written agreement is
32*fd1fabb7SAndroid Build Coastguard Worker  * hereby granted, provided that the above copyright notice and the following
33*fd1fabb7SAndroid Build Coastguard Worker  * two paragraphs appear in all copies of this software.
34*fd1fabb7SAndroid Build Coastguard Worker  *
35*fd1fabb7SAndroid Build Coastguard Worker  * IN NO EVENT SHALL CORNELL UNIVERSITY BE LIABLE TO ANY PARTY FOR
36*fd1fabb7SAndroid Build Coastguard Worker  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
37*fd1fabb7SAndroid Build Coastguard Worker  * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF CORNELL
38*fd1fabb7SAndroid Build Coastguard Worker  * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39*fd1fabb7SAndroid Build Coastguard Worker  *
40*fd1fabb7SAndroid Build Coastguard Worker  * CORNELL UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
41*fd1fabb7SAndroid Build Coastguard Worker  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
42*fd1fabb7SAndroid Build Coastguard Worker  * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
43*fd1fabb7SAndroid Build Coastguard Worker  * ON AN "AS IS" BASIS, AND CORNELL UNIVERSITY HAS NO OBLIGATION TO
44*fd1fabb7SAndroid Build Coastguard Worker  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
45*fd1fabb7SAndroid Build Coastguard Worker  */
46*fd1fabb7SAndroid Build Coastguard Worker 
47*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
48*fd1fabb7SAndroid Build Coastguard Worker 
49*fd1fabb7SAndroid Build Coastguard Worker #include "dng_lossless_jpeg.h"
50*fd1fabb7SAndroid Build Coastguard Worker 
51*fd1fabb7SAndroid Build Coastguard Worker #include "dng_assertions.h"
52*fd1fabb7SAndroid Build Coastguard Worker #include "dng_exceptions.h"
53*fd1fabb7SAndroid Build Coastguard Worker #include "dng_memory.h"
54*fd1fabb7SAndroid Build Coastguard Worker #include "dng_stream.h"
55*fd1fabb7SAndroid Build Coastguard Worker #include "dng_tag_codes.h"
56*fd1fabb7SAndroid Build Coastguard Worker 
57*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
58*fd1fabb7SAndroid Build Coastguard Worker 
59*fd1fabb7SAndroid Build Coastguard Worker // This module contains routines that should be as fast as possible, even
60*fd1fabb7SAndroid Build Coastguard Worker // at the expense of slight code size increases.
61*fd1fabb7SAndroid Build Coastguard Worker 
62*fd1fabb7SAndroid Build Coastguard Worker #include "dng_fast_module.h"
63*fd1fabb7SAndroid Build Coastguard Worker 
64*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
65*fd1fabb7SAndroid Build Coastguard Worker 
66*fd1fabb7SAndroid Build Coastguard Worker // The qSupportCanon_sRAW stuff not actually required for DNG support, but
67*fd1fabb7SAndroid Build Coastguard Worker // only included to allow this code to be used on Canon sRAW files.
68*fd1fabb7SAndroid Build Coastguard Worker 
69*fd1fabb7SAndroid Build Coastguard Worker #ifndef qSupportCanon_sRAW
70*fd1fabb7SAndroid Build Coastguard Worker #define qSupportCanon_sRAW 1
71*fd1fabb7SAndroid Build Coastguard Worker #endif
72*fd1fabb7SAndroid Build Coastguard Worker 
73*fd1fabb7SAndroid Build Coastguard Worker // The qSupportHasselblad_3FR stuff not actually required for DNG support, but
74*fd1fabb7SAndroid Build Coastguard Worker // only included to allow this code to be used on Hasselblad 3FR files.
75*fd1fabb7SAndroid Build Coastguard Worker 
76*fd1fabb7SAndroid Build Coastguard Worker #ifndef qSupportHasselblad_3FR
77*fd1fabb7SAndroid Build Coastguard Worker #define qSupportHasselblad_3FR 1
78*fd1fabb7SAndroid Build Coastguard Worker #endif
79*fd1fabb7SAndroid Build Coastguard Worker 
80*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
81*fd1fabb7SAndroid Build Coastguard Worker 
82*fd1fabb7SAndroid Build Coastguard Worker /*
83*fd1fabb7SAndroid Build Coastguard Worker  * One of the following structures is created for each huffman coding
84*fd1fabb7SAndroid Build Coastguard Worker  * table.  We use the same structure for encoding and decoding, so there
85*fd1fabb7SAndroid Build Coastguard Worker  * may be some extra fields for encoding that aren't used in the decoding
86*fd1fabb7SAndroid Build Coastguard Worker  * and vice-versa.
87*fd1fabb7SAndroid Build Coastguard Worker  */
88*fd1fabb7SAndroid Build Coastguard Worker 
89*fd1fabb7SAndroid Build Coastguard Worker struct HuffmanTable
90*fd1fabb7SAndroid Build Coastguard Worker 	{
91*fd1fabb7SAndroid Build Coastguard Worker 
92*fd1fabb7SAndroid Build Coastguard Worker     /*
93*fd1fabb7SAndroid Build Coastguard Worker      * These two fields directly represent the contents of a JPEG DHT
94*fd1fabb7SAndroid Build Coastguard Worker      * marker
95*fd1fabb7SAndroid Build Coastguard Worker      */
96*fd1fabb7SAndroid Build Coastguard Worker     uint8 bits[17];
97*fd1fabb7SAndroid Build Coastguard Worker     uint8 huffval[256];
98*fd1fabb7SAndroid Build Coastguard Worker 
99*fd1fabb7SAndroid Build Coastguard Worker     /*
100*fd1fabb7SAndroid Build Coastguard Worker      * The remaining fields are computed from the above to allow more
101*fd1fabb7SAndroid Build Coastguard Worker      * efficient coding and decoding.  These fields should be considered
102*fd1fabb7SAndroid Build Coastguard Worker      * private to the Huffman compression & decompression modules.
103*fd1fabb7SAndroid Build Coastguard Worker      */
104*fd1fabb7SAndroid Build Coastguard Worker 
105*fd1fabb7SAndroid Build Coastguard Worker     uint16 mincode[17];
106*fd1fabb7SAndroid Build Coastguard Worker     int32 maxcode[18];
107*fd1fabb7SAndroid Build Coastguard Worker     int16 valptr[17];
108*fd1fabb7SAndroid Build Coastguard Worker     int32 numbits[256];
109*fd1fabb7SAndroid Build Coastguard Worker     int32 value[256];
110*fd1fabb7SAndroid Build Coastguard Worker 
111*fd1fabb7SAndroid Build Coastguard Worker     uint16 ehufco[256];
112*fd1fabb7SAndroid Build Coastguard Worker     int8 ehufsi[256];
113*fd1fabb7SAndroid Build Coastguard Worker 
114*fd1fabb7SAndroid Build Coastguard Worker 	};
115*fd1fabb7SAndroid Build Coastguard Worker 
116*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
117*fd1fabb7SAndroid Build Coastguard Worker 
118*fd1fabb7SAndroid Build Coastguard Worker // Computes the derived fields in the Huffman table structure.
119*fd1fabb7SAndroid Build Coastguard Worker 
FixHuffTbl(HuffmanTable * htbl)120*fd1fabb7SAndroid Build Coastguard Worker static void FixHuffTbl (HuffmanTable *htbl)
121*fd1fabb7SAndroid Build Coastguard Worker 	{
122*fd1fabb7SAndroid Build Coastguard Worker 
123*fd1fabb7SAndroid Build Coastguard Worker 	int32 l;
124*fd1fabb7SAndroid Build Coastguard Worker 	int32 i;
125*fd1fabb7SAndroid Build Coastguard Worker 
126*fd1fabb7SAndroid Build Coastguard Worker 	const uint32 bitMask [] =
127*fd1fabb7SAndroid Build Coastguard Worker 		{
128*fd1fabb7SAndroid Build Coastguard Worker 		0xffffffff, 0x7fffffff, 0x3fffffff, 0x1fffffff,
129*fd1fabb7SAndroid Build Coastguard Worker         0x0fffffff, 0x07ffffff, 0x03ffffff, 0x01ffffff,
130*fd1fabb7SAndroid Build Coastguard Worker         0x00ffffff, 0x007fffff, 0x003fffff, 0x001fffff,
131*fd1fabb7SAndroid Build Coastguard Worker         0x000fffff, 0x0007ffff, 0x0003ffff, 0x0001ffff,
132*fd1fabb7SAndroid Build Coastguard Worker         0x0000ffff, 0x00007fff, 0x00003fff, 0x00001fff,
133*fd1fabb7SAndroid Build Coastguard Worker         0x00000fff, 0x000007ff, 0x000003ff, 0x000001ff,
134*fd1fabb7SAndroid Build Coastguard Worker         0x000000ff, 0x0000007f, 0x0000003f, 0x0000001f,
135*fd1fabb7SAndroid Build Coastguard Worker         0x0000000f, 0x00000007, 0x00000003, 0x00000001
136*fd1fabb7SAndroid Build Coastguard Worker         };
137*fd1fabb7SAndroid Build Coastguard Worker 
138*fd1fabb7SAndroid Build Coastguard Worker     // Figure C.1: make table of Huffman code length for each symbol
139*fd1fabb7SAndroid Build Coastguard Worker     // Note that this is in code-length order.
140*fd1fabb7SAndroid Build Coastguard Worker 
141*fd1fabb7SAndroid Build Coastguard Worker 	int8 huffsize [257];
142*fd1fabb7SAndroid Build Coastguard Worker 
143*fd1fabb7SAndroid Build Coastguard Worker     int32 p = 0;
144*fd1fabb7SAndroid Build Coastguard Worker 
145*fd1fabb7SAndroid Build Coastguard Worker 	for (l = 1; l <= 16; l++)
146*fd1fabb7SAndroid Build Coastguard Worker     	{
147*fd1fabb7SAndroid Build Coastguard Worker 
148*fd1fabb7SAndroid Build Coastguard Worker         for (i = 1; i <= (int32) htbl->bits [l]; i++)
149*fd1fabb7SAndroid Build Coastguard Worker             huffsize [p++] = (int8) l;
150*fd1fabb7SAndroid Build Coastguard Worker 
151*fd1fabb7SAndroid Build Coastguard Worker     	}
152*fd1fabb7SAndroid Build Coastguard Worker 
153*fd1fabb7SAndroid Build Coastguard Worker     huffsize [p] = 0;
154*fd1fabb7SAndroid Build Coastguard Worker 
155*fd1fabb7SAndroid Build Coastguard Worker     int32 lastp = p;
156*fd1fabb7SAndroid Build Coastguard Worker 
157*fd1fabb7SAndroid Build Coastguard Worker 	// Figure C.2: generate the codes themselves
158*fd1fabb7SAndroid Build Coastguard Worker 	// Note that this is in code-length order.
159*fd1fabb7SAndroid Build Coastguard Worker 
160*fd1fabb7SAndroid Build Coastguard Worker 	uint16 huffcode [257];
161*fd1fabb7SAndroid Build Coastguard Worker 
162*fd1fabb7SAndroid Build Coastguard Worker 	uint16 code = 0;
163*fd1fabb7SAndroid Build Coastguard Worker 
164*fd1fabb7SAndroid Build Coastguard Worker     int32 si = huffsize [0];
165*fd1fabb7SAndroid Build Coastguard Worker 
166*fd1fabb7SAndroid Build Coastguard Worker     p = 0;
167*fd1fabb7SAndroid Build Coastguard Worker 
168*fd1fabb7SAndroid Build Coastguard Worker     while (huffsize [p])
169*fd1fabb7SAndroid Build Coastguard Worker     	{
170*fd1fabb7SAndroid Build Coastguard Worker 
171*fd1fabb7SAndroid Build Coastguard Worker         while (((int32) huffsize [p]) == si)
172*fd1fabb7SAndroid Build Coastguard Worker         	{
173*fd1fabb7SAndroid Build Coastguard Worker             huffcode [p++] = code;
174*fd1fabb7SAndroid Build Coastguard Worker             code++;
175*fd1fabb7SAndroid Build Coastguard Worker         	}
176*fd1fabb7SAndroid Build Coastguard Worker 
177*fd1fabb7SAndroid Build Coastguard Worker         code <<= 1;
178*fd1fabb7SAndroid Build Coastguard Worker 
179*fd1fabb7SAndroid Build Coastguard Worker         si++;
180*fd1fabb7SAndroid Build Coastguard Worker 
181*fd1fabb7SAndroid Build Coastguard Worker     	}
182*fd1fabb7SAndroid Build Coastguard Worker 
183*fd1fabb7SAndroid Build Coastguard Worker     // Figure C.3: generate encoding tables
184*fd1fabb7SAndroid Build Coastguard Worker     // These are code and size indexed by symbol value
185*fd1fabb7SAndroid Build Coastguard Worker     // Set any codeless symbols to have code length 0; this allows
186*fd1fabb7SAndroid Build Coastguard Worker     // EmitBits to detect any attempt to emit such symbols.
187*fd1fabb7SAndroid Build Coastguard Worker 
188*fd1fabb7SAndroid Build Coastguard Worker     memset (htbl->ehufsi, 0, sizeof (htbl->ehufsi));
189*fd1fabb7SAndroid Build Coastguard Worker 
190*fd1fabb7SAndroid Build Coastguard Worker     for (p = 0; p < lastp; p++)
191*fd1fabb7SAndroid Build Coastguard Worker     	{
192*fd1fabb7SAndroid Build Coastguard Worker 
193*fd1fabb7SAndroid Build Coastguard Worker         htbl->ehufco [htbl->huffval [p]] = huffcode [p];
194*fd1fabb7SAndroid Build Coastguard Worker         htbl->ehufsi [htbl->huffval [p]] = huffsize [p];
195*fd1fabb7SAndroid Build Coastguard Worker 
196*fd1fabb7SAndroid Build Coastguard Worker     	}
197*fd1fabb7SAndroid Build Coastguard Worker 
198*fd1fabb7SAndroid Build Coastguard Worker 	// Figure F.15: generate decoding tables
199*fd1fabb7SAndroid Build Coastguard Worker 
200*fd1fabb7SAndroid Build Coastguard Worker 	p = 0;
201*fd1fabb7SAndroid Build Coastguard Worker 
202*fd1fabb7SAndroid Build Coastguard Worker     for (l = 1; l <= 16; l++)
203*fd1fabb7SAndroid Build Coastguard Worker     	{
204*fd1fabb7SAndroid Build Coastguard Worker 
205*fd1fabb7SAndroid Build Coastguard Worker         if (htbl->bits [l])
206*fd1fabb7SAndroid Build Coastguard Worker         	{
207*fd1fabb7SAndroid Build Coastguard Worker 
208*fd1fabb7SAndroid Build Coastguard Worker             htbl->valptr  [l] = (int16) p;
209*fd1fabb7SAndroid Build Coastguard Worker             htbl->mincode [l] = huffcode [p];
210*fd1fabb7SAndroid Build Coastguard Worker 
211*fd1fabb7SAndroid Build Coastguard Worker             p += htbl->bits [l];
212*fd1fabb7SAndroid Build Coastguard Worker 
213*fd1fabb7SAndroid Build Coastguard Worker             htbl->maxcode [l] = huffcode [p - 1];
214*fd1fabb7SAndroid Build Coastguard Worker 
215*fd1fabb7SAndroid Build Coastguard Worker         	}
216*fd1fabb7SAndroid Build Coastguard Worker 
217*fd1fabb7SAndroid Build Coastguard Worker         else
218*fd1fabb7SAndroid Build Coastguard Worker         	{
219*fd1fabb7SAndroid Build Coastguard Worker             htbl->maxcode [l] = -1;
220*fd1fabb7SAndroid Build Coastguard Worker         	}
221*fd1fabb7SAndroid Build Coastguard Worker 
222*fd1fabb7SAndroid Build Coastguard Worker     	}
223*fd1fabb7SAndroid Build Coastguard Worker 
224*fd1fabb7SAndroid Build Coastguard Worker     // We put in this value to ensure HuffDecode terminates.
225*fd1fabb7SAndroid Build Coastguard Worker 
226*fd1fabb7SAndroid Build Coastguard Worker     htbl->maxcode[17] = 0xFFFFFL;
227*fd1fabb7SAndroid Build Coastguard Worker 
228*fd1fabb7SAndroid Build Coastguard Worker     // Build the numbits, value lookup tables.
229*fd1fabb7SAndroid Build Coastguard Worker     // These table allow us to gather 8 bits from the bits stream,
230*fd1fabb7SAndroid Build Coastguard Worker     // and immediately lookup the size and value of the huffman codes.
231*fd1fabb7SAndroid Build Coastguard Worker     // If size is zero, it means that more than 8 bits are in the huffman
232*fd1fabb7SAndroid Build Coastguard Worker     // code (this happens about 3-4% of the time).
233*fd1fabb7SAndroid Build Coastguard Worker 
234*fd1fabb7SAndroid Build Coastguard Worker     memset (htbl->numbits, 0, sizeof (htbl->numbits));
235*fd1fabb7SAndroid Build Coastguard Worker 
236*fd1fabb7SAndroid Build Coastguard Worker 	for (p = 0; p < lastp; p++)
237*fd1fabb7SAndroid Build Coastguard Worker 		{
238*fd1fabb7SAndroid Build Coastguard Worker 
239*fd1fabb7SAndroid Build Coastguard Worker         int32 size = huffsize [p];
240*fd1fabb7SAndroid Build Coastguard Worker 
241*fd1fabb7SAndroid Build Coastguard Worker         if (size <= 8)
242*fd1fabb7SAndroid Build Coastguard Worker         	{
243*fd1fabb7SAndroid Build Coastguard Worker 
244*fd1fabb7SAndroid Build Coastguard Worker             int32 value = htbl->huffval [p];
245*fd1fabb7SAndroid Build Coastguard Worker 
246*fd1fabb7SAndroid Build Coastguard Worker             code = huffcode [p];
247*fd1fabb7SAndroid Build Coastguard Worker 
248*fd1fabb7SAndroid Build Coastguard Worker             int32 ll = code << (8  -size);
249*fd1fabb7SAndroid Build Coastguard Worker 
250*fd1fabb7SAndroid Build Coastguard Worker      		int32 ul = (size < 8 ? ll | bitMask [24 + size]
251*fd1fabb7SAndroid Build Coastguard Worker      						     : ll);
252*fd1fabb7SAndroid Build Coastguard Worker             if (ul >= static_cast<int32>(sizeof(htbl->numbits) / sizeof(htbl->numbits[0])) ||
253*fd1fabb7SAndroid Build Coastguard Worker                 ul >= static_cast<int32>(sizeof(htbl->value) / sizeof(htbl->value[0])))
254*fd1fabb7SAndroid Build Coastguard Worker                 {
255*fd1fabb7SAndroid Build Coastguard Worker                 ThrowBadFormat ();
256*fd1fabb7SAndroid Build Coastguard Worker                 }
257*fd1fabb7SAndroid Build Coastguard Worker 
258*fd1fabb7SAndroid Build Coastguard Worker             for (i = ll; i <= ul; i++)
259*fd1fabb7SAndroid Build Coastguard Worker             	{
260*fd1fabb7SAndroid Build Coastguard Worker                 htbl->numbits [i] = size;
261*fd1fabb7SAndroid Build Coastguard Worker                 htbl->value   [i] = value;
262*fd1fabb7SAndroid Build Coastguard Worker            		}
263*fd1fabb7SAndroid Build Coastguard Worker 
264*fd1fabb7SAndroid Build Coastguard Worker 			}
265*fd1fabb7SAndroid Build Coastguard Worker 
266*fd1fabb7SAndroid Build Coastguard Worker 		}
267*fd1fabb7SAndroid Build Coastguard Worker 
268*fd1fabb7SAndroid Build Coastguard Worker 	}
269*fd1fabb7SAndroid Build Coastguard Worker 
270*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
271*fd1fabb7SAndroid Build Coastguard Worker 
272*fd1fabb7SAndroid Build Coastguard Worker /*
273*fd1fabb7SAndroid Build Coastguard Worker  * The following structure stores basic information about one component.
274*fd1fabb7SAndroid Build Coastguard Worker  */
275*fd1fabb7SAndroid Build Coastguard Worker 
276*fd1fabb7SAndroid Build Coastguard Worker struct JpegComponentInfo
277*fd1fabb7SAndroid Build Coastguard Worker 	{
278*fd1fabb7SAndroid Build Coastguard Worker 
279*fd1fabb7SAndroid Build Coastguard Worker     /*
280*fd1fabb7SAndroid Build Coastguard Worker      * These values are fixed over the whole image.
281*fd1fabb7SAndroid Build Coastguard Worker      * They are read from the SOF marker.
282*fd1fabb7SAndroid Build Coastguard Worker      */
283*fd1fabb7SAndroid Build Coastguard Worker     int16 componentId;		/* identifier for this component (0..255) */
284*fd1fabb7SAndroid Build Coastguard Worker     int16 componentIndex;	/* its index in SOF or cPtr->compInfo[]   */
285*fd1fabb7SAndroid Build Coastguard Worker 
286*fd1fabb7SAndroid Build Coastguard Worker     /*
287*fd1fabb7SAndroid Build Coastguard Worker      * Downsampling is not normally used in lossless JPEG, although
288*fd1fabb7SAndroid Build Coastguard Worker      * it is permitted by the JPEG standard (DIS). We set all sampling
289*fd1fabb7SAndroid Build Coastguard Worker      * factors to 1 in this program.
290*fd1fabb7SAndroid Build Coastguard Worker      */
291*fd1fabb7SAndroid Build Coastguard Worker     int16 hSampFactor;		/* horizontal sampling factor */
292*fd1fabb7SAndroid Build Coastguard Worker     int16 vSampFactor;		/* vertical sampling factor   */
293*fd1fabb7SAndroid Build Coastguard Worker 
294*fd1fabb7SAndroid Build Coastguard Worker     /*
295*fd1fabb7SAndroid Build Coastguard Worker      * Huffman table selector (0..3). The value may vary
296*fd1fabb7SAndroid Build Coastguard Worker      * between scans. It is read from the SOS marker.
297*fd1fabb7SAndroid Build Coastguard Worker      */
298*fd1fabb7SAndroid Build Coastguard Worker     int16 dcTblNo;
299*fd1fabb7SAndroid Build Coastguard Worker 
300*fd1fabb7SAndroid Build Coastguard Worker 	};
301*fd1fabb7SAndroid Build Coastguard Worker 
302*fd1fabb7SAndroid Build Coastguard Worker /*
303*fd1fabb7SAndroid Build Coastguard Worker  * One of the following structures is used to pass around the
304*fd1fabb7SAndroid Build Coastguard Worker  * decompression information.
305*fd1fabb7SAndroid Build Coastguard Worker  */
306*fd1fabb7SAndroid Build Coastguard Worker 
307*fd1fabb7SAndroid Build Coastguard Worker struct DecompressInfo
308*fd1fabb7SAndroid Build Coastguard Worker 	{
309*fd1fabb7SAndroid Build Coastguard Worker 
310*fd1fabb7SAndroid Build Coastguard Worker     /*
311*fd1fabb7SAndroid Build Coastguard Worker      * Image width, height, and image data precision (bits/sample)
312*fd1fabb7SAndroid Build Coastguard Worker      * These fields are set by ReadFileHeader or ReadScanHeader
313*fd1fabb7SAndroid Build Coastguard Worker      */
314*fd1fabb7SAndroid Build Coastguard Worker     int32 imageWidth;
315*fd1fabb7SAndroid Build Coastguard Worker     int32 imageHeight;
316*fd1fabb7SAndroid Build Coastguard Worker     int32 dataPrecision;
317*fd1fabb7SAndroid Build Coastguard Worker 
318*fd1fabb7SAndroid Build Coastguard Worker     /*
319*fd1fabb7SAndroid Build Coastguard Worker      * compInfo[i] describes component that appears i'th in SOF
320*fd1fabb7SAndroid Build Coastguard Worker      * numComponents is the # of color components in JPEG image.
321*fd1fabb7SAndroid Build Coastguard Worker      */
322*fd1fabb7SAndroid Build Coastguard Worker     JpegComponentInfo *compInfo;
323*fd1fabb7SAndroid Build Coastguard Worker     int16 numComponents;
324*fd1fabb7SAndroid Build Coastguard Worker 
325*fd1fabb7SAndroid Build Coastguard Worker     /*
326*fd1fabb7SAndroid Build Coastguard Worker      * *curCompInfo[i] describes component that appears i'th in SOS.
327*fd1fabb7SAndroid Build Coastguard Worker      * compsInScan is the # of color components in current scan.
328*fd1fabb7SAndroid Build Coastguard Worker      */
329*fd1fabb7SAndroid Build Coastguard Worker     JpegComponentInfo *curCompInfo[4];
330*fd1fabb7SAndroid Build Coastguard Worker     int16 compsInScan;
331*fd1fabb7SAndroid Build Coastguard Worker 
332*fd1fabb7SAndroid Build Coastguard Worker     /*
333*fd1fabb7SAndroid Build Coastguard Worker      * MCUmembership[i] indexes the i'th component of MCU into the
334*fd1fabb7SAndroid Build Coastguard Worker      * curCompInfo array.
335*fd1fabb7SAndroid Build Coastguard Worker      */
336*fd1fabb7SAndroid Build Coastguard Worker     int16 MCUmembership[10];
337*fd1fabb7SAndroid Build Coastguard Worker 
338*fd1fabb7SAndroid Build Coastguard Worker     /*
339*fd1fabb7SAndroid Build Coastguard Worker      * ptrs to Huffman coding tables, or NULL if not defined
340*fd1fabb7SAndroid Build Coastguard Worker      */
341*fd1fabb7SAndroid Build Coastguard Worker     HuffmanTable *dcHuffTblPtrs[4];
342*fd1fabb7SAndroid Build Coastguard Worker 
343*fd1fabb7SAndroid Build Coastguard Worker     /*
344*fd1fabb7SAndroid Build Coastguard Worker      * prediction selection value (PSV) and point transform parameter (Pt)
345*fd1fabb7SAndroid Build Coastguard Worker      */
346*fd1fabb7SAndroid Build Coastguard Worker     int32 Ss;
347*fd1fabb7SAndroid Build Coastguard Worker     int32 Pt;
348*fd1fabb7SAndroid Build Coastguard Worker 
349*fd1fabb7SAndroid Build Coastguard Worker     /*
350*fd1fabb7SAndroid Build Coastguard Worker      * In lossless JPEG, restart interval shall be an integer
351*fd1fabb7SAndroid Build Coastguard Worker      * multiple of the number of MCU in a MCU row.
352*fd1fabb7SAndroid Build Coastguard Worker      */
353*fd1fabb7SAndroid Build Coastguard Worker     int32 restartInterval;/* MCUs per restart interval, 0 = no restart */
354*fd1fabb7SAndroid Build Coastguard Worker     int32 restartInRows; /*if > 0, MCU rows per restart interval; 0 = no restart*/
355*fd1fabb7SAndroid Build Coastguard Worker 
356*fd1fabb7SAndroid Build Coastguard Worker     /*
357*fd1fabb7SAndroid Build Coastguard Worker      * these fields are private data for the entropy decoder
358*fd1fabb7SAndroid Build Coastguard Worker      */
359*fd1fabb7SAndroid Build Coastguard Worker     int32 restartRowsToGo;	/* MCUs rows left in this restart interval */
360*fd1fabb7SAndroid Build Coastguard Worker     int16 nextRestartNum;	/* # of next RSTn marker (0..7) */
361*fd1fabb7SAndroid Build Coastguard Worker 
362*fd1fabb7SAndroid Build Coastguard Worker 	};
363*fd1fabb7SAndroid Build Coastguard Worker 
364*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
365*fd1fabb7SAndroid Build Coastguard Worker 
366*fd1fabb7SAndroid Build Coastguard Worker // An MCU (minimum coding unit) is an array of samples.
367*fd1fabb7SAndroid Build Coastguard Worker 
368*fd1fabb7SAndroid Build Coastguard Worker typedef uint16 ComponentType; 		// the type of image components
369*fd1fabb7SAndroid Build Coastguard Worker 
370*fd1fabb7SAndroid Build Coastguard Worker typedef ComponentType *MCU;  		// MCU - array of samples
371*fd1fabb7SAndroid Build Coastguard Worker 
372*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
373*fd1fabb7SAndroid Build Coastguard Worker 
374*fd1fabb7SAndroid Build Coastguard Worker class dng_lossless_decoder
375*fd1fabb7SAndroid Build Coastguard Worker 	{
376*fd1fabb7SAndroid Build Coastguard Worker 
377*fd1fabb7SAndroid Build Coastguard Worker 	private:
378*fd1fabb7SAndroid Build Coastguard Worker 
379*fd1fabb7SAndroid Build Coastguard Worker 		dng_stream *fStream;		// Input data.
380*fd1fabb7SAndroid Build Coastguard Worker 
381*fd1fabb7SAndroid Build Coastguard Worker 		dng_spooler *fSpooler;		// Output data.
382*fd1fabb7SAndroid Build Coastguard Worker 
383*fd1fabb7SAndroid Build Coastguard Worker 		bool fBug16;				// Decode data with the "16-bit" bug.
384*fd1fabb7SAndroid Build Coastguard Worker 
385*fd1fabb7SAndroid Build Coastguard Worker 		dng_memory_data huffmanBuffer [4];
386*fd1fabb7SAndroid Build Coastguard Worker 
387*fd1fabb7SAndroid Build Coastguard Worker 		dng_memory_data compInfoBuffer;
388*fd1fabb7SAndroid Build Coastguard Worker 
389*fd1fabb7SAndroid Build Coastguard Worker 		DecompressInfo info;
390*fd1fabb7SAndroid Build Coastguard Worker 
391*fd1fabb7SAndroid Build Coastguard Worker 		dng_memory_data mcuBuffer1;
392*fd1fabb7SAndroid Build Coastguard Worker 		dng_memory_data mcuBuffer2;
393*fd1fabb7SAndroid Build Coastguard Worker 		dng_memory_data mcuBuffer3;
394*fd1fabb7SAndroid Build Coastguard Worker 		dng_memory_data mcuBuffer4;
395*fd1fabb7SAndroid Build Coastguard Worker 
396*fd1fabb7SAndroid Build Coastguard Worker 		MCU *mcuROW1;
397*fd1fabb7SAndroid Build Coastguard Worker 		MCU *mcuROW2;
398*fd1fabb7SAndroid Build Coastguard Worker 
399*fd1fabb7SAndroid Build Coastguard Worker 		uint64 getBuffer;			// current bit-extraction buffer
400*fd1fabb7SAndroid Build Coastguard Worker 		int32 bitsLeft;				// # of unused bits in it
401*fd1fabb7SAndroid Build Coastguard Worker 
402*fd1fabb7SAndroid Build Coastguard Worker 		#if qSupportHasselblad_3FR
403*fd1fabb7SAndroid Build Coastguard Worker 		bool fHasselblad3FR;
404*fd1fabb7SAndroid Build Coastguard Worker 		#endif
405*fd1fabb7SAndroid Build Coastguard Worker 
406*fd1fabb7SAndroid Build Coastguard Worker 	public:
407*fd1fabb7SAndroid Build Coastguard Worker 
408*fd1fabb7SAndroid Build Coastguard Worker 		dng_lossless_decoder (dng_stream *stream,
409*fd1fabb7SAndroid Build Coastguard Worker 						      dng_spooler *spooler,
410*fd1fabb7SAndroid Build Coastguard Worker 						      bool bug16);
411*fd1fabb7SAndroid Build Coastguard Worker 
412*fd1fabb7SAndroid Build Coastguard Worker 		void StartRead (uint32 &imageWidth,
413*fd1fabb7SAndroid Build Coastguard Worker 						uint32 &imageHeight,
414*fd1fabb7SAndroid Build Coastguard Worker 						uint32 &imageChannels);
415*fd1fabb7SAndroid Build Coastguard Worker 
416*fd1fabb7SAndroid Build Coastguard Worker 		void FinishRead ();
417*fd1fabb7SAndroid Build Coastguard Worker 
418*fd1fabb7SAndroid Build Coastguard Worker 	private:
419*fd1fabb7SAndroid Build Coastguard Worker 
GetJpegChar()420*fd1fabb7SAndroid Build Coastguard Worker 		uint8 GetJpegChar ()
421*fd1fabb7SAndroid Build Coastguard Worker 			{
422*fd1fabb7SAndroid Build Coastguard Worker 			return fStream->Get_uint8 ();
423*fd1fabb7SAndroid Build Coastguard Worker 			}
424*fd1fabb7SAndroid Build Coastguard Worker 
UnGetJpegChar()425*fd1fabb7SAndroid Build Coastguard Worker 		void UnGetJpegChar ()
426*fd1fabb7SAndroid Build Coastguard Worker 			{
427*fd1fabb7SAndroid Build Coastguard Worker 			fStream->SetReadPosition (fStream->Position () - 1);
428*fd1fabb7SAndroid Build Coastguard Worker 			}
429*fd1fabb7SAndroid Build Coastguard Worker 
430*fd1fabb7SAndroid Build Coastguard Worker 		uint16 Get2bytes ();
431*fd1fabb7SAndroid Build Coastguard Worker 
432*fd1fabb7SAndroid Build Coastguard Worker 		void SkipVariable ();
433*fd1fabb7SAndroid Build Coastguard Worker 
434*fd1fabb7SAndroid Build Coastguard Worker 		void GetDht ();
435*fd1fabb7SAndroid Build Coastguard Worker 
436*fd1fabb7SAndroid Build Coastguard Worker 		void GetDri ();
437*fd1fabb7SAndroid Build Coastguard Worker 
438*fd1fabb7SAndroid Build Coastguard Worker 		void GetApp0 ();
439*fd1fabb7SAndroid Build Coastguard Worker 
440*fd1fabb7SAndroid Build Coastguard Worker 		void GetSof (int32 code);
441*fd1fabb7SAndroid Build Coastguard Worker 
442*fd1fabb7SAndroid Build Coastguard Worker 		void GetSos ();
443*fd1fabb7SAndroid Build Coastguard Worker 
444*fd1fabb7SAndroid Build Coastguard Worker 		void GetSoi ();
445*fd1fabb7SAndroid Build Coastguard Worker 
446*fd1fabb7SAndroid Build Coastguard Worker 		int32 NextMarker ();
447*fd1fabb7SAndroid Build Coastguard Worker 
448*fd1fabb7SAndroid Build Coastguard Worker 		JpegMarker ProcessTables ();
449*fd1fabb7SAndroid Build Coastguard Worker 
450*fd1fabb7SAndroid Build Coastguard Worker 		void ReadFileHeader ();
451*fd1fabb7SAndroid Build Coastguard Worker 
452*fd1fabb7SAndroid Build Coastguard Worker 		int32 ReadScanHeader ();
453*fd1fabb7SAndroid Build Coastguard Worker 
454*fd1fabb7SAndroid Build Coastguard Worker 		void DecoderStructInit ();
455*fd1fabb7SAndroid Build Coastguard Worker 
456*fd1fabb7SAndroid Build Coastguard Worker 		void HuffDecoderInit ();
457*fd1fabb7SAndroid Build Coastguard Worker 
458*fd1fabb7SAndroid Build Coastguard Worker 		void ProcessRestart ();
459*fd1fabb7SAndroid Build Coastguard Worker 
460*fd1fabb7SAndroid Build Coastguard Worker 		int32 QuickPredict (int32 col,
461*fd1fabb7SAndroid Build Coastguard Worker 						    int32 curComp,
462*fd1fabb7SAndroid Build Coastguard Worker 						    MCU *curRowBuf,
463*fd1fabb7SAndroid Build Coastguard Worker 						    MCU *prevRowBuf);
464*fd1fabb7SAndroid Build Coastguard Worker 
465*fd1fabb7SAndroid Build Coastguard Worker 		void FillBitBuffer (int32 nbits);
466*fd1fabb7SAndroid Build Coastguard Worker 
467*fd1fabb7SAndroid Build Coastguard Worker 		int32 show_bits8 ();
468*fd1fabb7SAndroid Build Coastguard Worker 
469*fd1fabb7SAndroid Build Coastguard Worker 		void flush_bits (int32 nbits);
470*fd1fabb7SAndroid Build Coastguard Worker 
471*fd1fabb7SAndroid Build Coastguard Worker 		int32 get_bits (int32 nbits);
472*fd1fabb7SAndroid Build Coastguard Worker 
473*fd1fabb7SAndroid Build Coastguard Worker 		int32 get_bit ();
474*fd1fabb7SAndroid Build Coastguard Worker 
475*fd1fabb7SAndroid Build Coastguard Worker 		int32 HuffDecode (HuffmanTable *htbl);
476*fd1fabb7SAndroid Build Coastguard Worker 
477*fd1fabb7SAndroid Build Coastguard Worker 		void HuffExtend (int32 &x, int32 s);
478*fd1fabb7SAndroid Build Coastguard Worker 
479*fd1fabb7SAndroid Build Coastguard Worker 		void PmPutRow (MCU *buf,
480*fd1fabb7SAndroid Build Coastguard Worker 					   int32 numComp,
481*fd1fabb7SAndroid Build Coastguard Worker 					   int32 numCol,
482*fd1fabb7SAndroid Build Coastguard Worker 					   int32 row);
483*fd1fabb7SAndroid Build Coastguard Worker 
484*fd1fabb7SAndroid Build Coastguard Worker 		void DecodeFirstRow (MCU *curRowBuf);
485*fd1fabb7SAndroid Build Coastguard Worker 
486*fd1fabb7SAndroid Build Coastguard Worker 		void DecodeImage ();
487*fd1fabb7SAndroid Build Coastguard Worker 
488*fd1fabb7SAndroid Build Coastguard Worker 		// Hidden copy constructor and assignment operator.
489*fd1fabb7SAndroid Build Coastguard Worker 
490*fd1fabb7SAndroid Build Coastguard Worker 		dng_lossless_decoder (const dng_lossless_decoder &decoder);
491*fd1fabb7SAndroid Build Coastguard Worker 
492*fd1fabb7SAndroid Build Coastguard Worker 		dng_lossless_decoder & operator= (const dng_lossless_decoder &decoder);
493*fd1fabb7SAndroid Build Coastguard Worker 
494*fd1fabb7SAndroid Build Coastguard Worker 	};
495*fd1fabb7SAndroid Build Coastguard Worker 
496*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
497*fd1fabb7SAndroid Build Coastguard Worker 
dng_lossless_decoder(dng_stream * stream,dng_spooler * spooler,bool bug16)498*fd1fabb7SAndroid Build Coastguard Worker dng_lossless_decoder::dng_lossless_decoder (dng_stream *stream,
499*fd1fabb7SAndroid Build Coastguard Worker 									        dng_spooler *spooler,
500*fd1fabb7SAndroid Build Coastguard Worker 									        bool bug16)
501*fd1fabb7SAndroid Build Coastguard Worker 
502*fd1fabb7SAndroid Build Coastguard Worker 	:	fStream  (stream )
503*fd1fabb7SAndroid Build Coastguard Worker 	,	fSpooler (spooler)
504*fd1fabb7SAndroid Build Coastguard Worker 	,	fBug16   (bug16  )
505*fd1fabb7SAndroid Build Coastguard Worker 
506*fd1fabb7SAndroid Build Coastguard Worker 	,	compInfoBuffer ()
507*fd1fabb7SAndroid Build Coastguard Worker 	,	info           ()
508*fd1fabb7SAndroid Build Coastguard Worker 	,	mcuBuffer1     ()
509*fd1fabb7SAndroid Build Coastguard Worker 	,	mcuBuffer2     ()
510*fd1fabb7SAndroid Build Coastguard Worker 	,	mcuBuffer3     ()
511*fd1fabb7SAndroid Build Coastguard Worker 	,	mcuBuffer4     ()
512*fd1fabb7SAndroid Build Coastguard Worker 	,	mcuROW1		   (NULL)
513*fd1fabb7SAndroid Build Coastguard Worker 	,	mcuROW2		   (NULL)
514*fd1fabb7SAndroid Build Coastguard Worker 	,	getBuffer      (0)
515*fd1fabb7SAndroid Build Coastguard Worker 	,	bitsLeft	   (0)
516*fd1fabb7SAndroid Build Coastguard Worker 
517*fd1fabb7SAndroid Build Coastguard Worker 	#if qSupportHasselblad_3FR
518*fd1fabb7SAndroid Build Coastguard Worker 	,	fHasselblad3FR (false)
519*fd1fabb7SAndroid Build Coastguard Worker 	#endif
520*fd1fabb7SAndroid Build Coastguard Worker 
521*fd1fabb7SAndroid Build Coastguard Worker 	{
522*fd1fabb7SAndroid Build Coastguard Worker 
523*fd1fabb7SAndroid Build Coastguard Worker 	memset (&info, 0, sizeof (info));
524*fd1fabb7SAndroid Build Coastguard Worker 
525*fd1fabb7SAndroid Build Coastguard Worker 	}
526*fd1fabb7SAndroid Build Coastguard Worker 
527*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
528*fd1fabb7SAndroid Build Coastguard Worker 
Get2bytes()529*fd1fabb7SAndroid Build Coastguard Worker uint16 dng_lossless_decoder::Get2bytes ()
530*fd1fabb7SAndroid Build Coastguard Worker 	{
531*fd1fabb7SAndroid Build Coastguard Worker 
532*fd1fabb7SAndroid Build Coastguard Worker     uint16 a = GetJpegChar ();
533*fd1fabb7SAndroid Build Coastguard Worker 
534*fd1fabb7SAndroid Build Coastguard Worker     return (uint16) ((a << 8) + GetJpegChar ());
535*fd1fabb7SAndroid Build Coastguard Worker 
536*fd1fabb7SAndroid Build Coastguard Worker 	}
537*fd1fabb7SAndroid Build Coastguard Worker 
538*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
539*fd1fabb7SAndroid Build Coastguard Worker 
540*fd1fabb7SAndroid Build Coastguard Worker /*
541*fd1fabb7SAndroid Build Coastguard Worker  *--------------------------------------------------------------
542*fd1fabb7SAndroid Build Coastguard Worker  *
543*fd1fabb7SAndroid Build Coastguard Worker  * SkipVariable --
544*fd1fabb7SAndroid Build Coastguard Worker  *
545*fd1fabb7SAndroid Build Coastguard Worker  *	Skip over an unknown or uninteresting variable-length marker
546*fd1fabb7SAndroid Build Coastguard Worker  *
547*fd1fabb7SAndroid Build Coastguard Worker  * Results:
548*fd1fabb7SAndroid Build Coastguard Worker  *	None.
549*fd1fabb7SAndroid Build Coastguard Worker  *
550*fd1fabb7SAndroid Build Coastguard Worker  * Side effects:
551*fd1fabb7SAndroid Build Coastguard Worker  *	Bitstream is parsed over marker.
552*fd1fabb7SAndroid Build Coastguard Worker  *
553*fd1fabb7SAndroid Build Coastguard Worker  *
554*fd1fabb7SAndroid Build Coastguard Worker  *--------------------------------------------------------------
555*fd1fabb7SAndroid Build Coastguard Worker  */
556*fd1fabb7SAndroid Build Coastguard Worker 
SkipVariable()557*fd1fabb7SAndroid Build Coastguard Worker void dng_lossless_decoder::SkipVariable ()
558*fd1fabb7SAndroid Build Coastguard Worker 	{
559*fd1fabb7SAndroid Build Coastguard Worker 
560*fd1fabb7SAndroid Build Coastguard Worker     uint32 length = Get2bytes () - 2;
561*fd1fabb7SAndroid Build Coastguard Worker 
562*fd1fabb7SAndroid Build Coastguard Worker     fStream->Skip (length);
563*fd1fabb7SAndroid Build Coastguard Worker 
564*fd1fabb7SAndroid Build Coastguard Worker 	}
565*fd1fabb7SAndroid Build Coastguard Worker 
566*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
567*fd1fabb7SAndroid Build Coastguard Worker 
568*fd1fabb7SAndroid Build Coastguard Worker /*
569*fd1fabb7SAndroid Build Coastguard Worker  *--------------------------------------------------------------
570*fd1fabb7SAndroid Build Coastguard Worker  *
571*fd1fabb7SAndroid Build Coastguard Worker  * GetDht --
572*fd1fabb7SAndroid Build Coastguard Worker  *
573*fd1fabb7SAndroid Build Coastguard Worker  *	Process a DHT marker
574*fd1fabb7SAndroid Build Coastguard Worker  *
575*fd1fabb7SAndroid Build Coastguard Worker  * Results:
576*fd1fabb7SAndroid Build Coastguard Worker  *	None
577*fd1fabb7SAndroid Build Coastguard Worker  *
578*fd1fabb7SAndroid Build Coastguard Worker  * Side effects:
579*fd1fabb7SAndroid Build Coastguard Worker  *	A huffman table is read.
580*fd1fabb7SAndroid Build Coastguard Worker  *	Exits on error.
581*fd1fabb7SAndroid Build Coastguard Worker  *
582*fd1fabb7SAndroid Build Coastguard Worker  *--------------------------------------------------------------
583*fd1fabb7SAndroid Build Coastguard Worker  */
584*fd1fabb7SAndroid Build Coastguard Worker 
GetDht()585*fd1fabb7SAndroid Build Coastguard Worker void dng_lossless_decoder::GetDht ()
586*fd1fabb7SAndroid Build Coastguard Worker 	{
587*fd1fabb7SAndroid Build Coastguard Worker 
588*fd1fabb7SAndroid Build Coastguard Worker     int32 length = Get2bytes () - 2;
589*fd1fabb7SAndroid Build Coastguard Worker 
590*fd1fabb7SAndroid Build Coastguard Worker     while (length > 0)
591*fd1fabb7SAndroid Build Coastguard Worker     	{
592*fd1fabb7SAndroid Build Coastguard Worker 
593*fd1fabb7SAndroid Build Coastguard Worker 		int32 index = GetJpegChar ();
594*fd1fabb7SAndroid Build Coastguard Worker 
595*fd1fabb7SAndroid Build Coastguard Worker 		if (index < 0 || index >= 4)
596*fd1fabb7SAndroid Build Coastguard Worker 			{
597*fd1fabb7SAndroid Build Coastguard Worker 		    ThrowBadFormat ();
598*fd1fabb7SAndroid Build Coastguard Worker 			}
599*fd1fabb7SAndroid Build Coastguard Worker 
600*fd1fabb7SAndroid Build Coastguard Worker 		HuffmanTable *&htblptr = info.dcHuffTblPtrs [index];
601*fd1fabb7SAndroid Build Coastguard Worker 
602*fd1fabb7SAndroid Build Coastguard Worker 		if (htblptr == NULL)
603*fd1fabb7SAndroid Build Coastguard Worker 			{
604*fd1fabb7SAndroid Build Coastguard Worker 
605*fd1fabb7SAndroid Build Coastguard Worker 			huffmanBuffer [index] . Allocate (sizeof (HuffmanTable));
606*fd1fabb7SAndroid Build Coastguard Worker 
607*fd1fabb7SAndroid Build Coastguard Worker 		    htblptr = (HuffmanTable *) huffmanBuffer [index] . Buffer ();
608*fd1fabb7SAndroid Build Coastguard Worker 
609*fd1fabb7SAndroid Build Coastguard Worker 			}
610*fd1fabb7SAndroid Build Coastguard Worker 
611*fd1fabb7SAndroid Build Coastguard Worker 		htblptr->bits [0] = 0;
612*fd1fabb7SAndroid Build Coastguard Worker 
613*fd1fabb7SAndroid Build Coastguard Worker 	    int32 count = 0;
614*fd1fabb7SAndroid Build Coastguard Worker 
615*fd1fabb7SAndroid Build Coastguard Worker 		for (int32 i = 1; i <= 16; i++)
616*fd1fabb7SAndroid Build Coastguard Worker 			{
617*fd1fabb7SAndroid Build Coastguard Worker 
618*fd1fabb7SAndroid Build Coastguard Worker 		    htblptr->bits [i] = GetJpegChar ();
619*fd1fabb7SAndroid Build Coastguard Worker 
620*fd1fabb7SAndroid Build Coastguard Worker 		    count += htblptr->bits [i];
621*fd1fabb7SAndroid Build Coastguard Worker 
622*fd1fabb7SAndroid Build Coastguard Worker 			}
623*fd1fabb7SAndroid Build Coastguard Worker 
624*fd1fabb7SAndroid Build Coastguard Worker 		if (count > 256)
625*fd1fabb7SAndroid Build Coastguard Worker 			{
626*fd1fabb7SAndroid Build Coastguard Worker 		    ThrowBadFormat ();
627*fd1fabb7SAndroid Build Coastguard Worker 			}
628*fd1fabb7SAndroid Build Coastguard Worker 
629*fd1fabb7SAndroid Build Coastguard Worker 		for (int32 j = 0; j < count; j++)
630*fd1fabb7SAndroid Build Coastguard Worker 			{
631*fd1fabb7SAndroid Build Coastguard Worker 
632*fd1fabb7SAndroid Build Coastguard Worker 		    htblptr->huffval [j] = GetJpegChar ();
633*fd1fabb7SAndroid Build Coastguard Worker 
634*fd1fabb7SAndroid Build Coastguard Worker 		    }
635*fd1fabb7SAndroid Build Coastguard Worker 
636*fd1fabb7SAndroid Build Coastguard Worker 		length -= 1 + 16 + count;
637*fd1fabb7SAndroid Build Coastguard Worker 
638*fd1fabb7SAndroid Build Coastguard Worker 	    }
639*fd1fabb7SAndroid Build Coastguard Worker 
640*fd1fabb7SAndroid Build Coastguard Worker 	}
641*fd1fabb7SAndroid Build Coastguard Worker 
642*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
643*fd1fabb7SAndroid Build Coastguard Worker 
644*fd1fabb7SAndroid Build Coastguard Worker /*
645*fd1fabb7SAndroid Build Coastguard Worker  *--------------------------------------------------------------
646*fd1fabb7SAndroid Build Coastguard Worker  *
647*fd1fabb7SAndroid Build Coastguard Worker  * GetDri --
648*fd1fabb7SAndroid Build Coastguard Worker  *
649*fd1fabb7SAndroid Build Coastguard Worker  *	Process a DRI marker
650*fd1fabb7SAndroid Build Coastguard Worker  *
651*fd1fabb7SAndroid Build Coastguard Worker  * Results:
652*fd1fabb7SAndroid Build Coastguard Worker  *	None
653*fd1fabb7SAndroid Build Coastguard Worker  *
654*fd1fabb7SAndroid Build Coastguard Worker  * Side effects:
655*fd1fabb7SAndroid Build Coastguard Worker  *	Exits on error.
656*fd1fabb7SAndroid Build Coastguard Worker  *	Bitstream is parsed.
657*fd1fabb7SAndroid Build Coastguard Worker  *
658*fd1fabb7SAndroid Build Coastguard Worker  *--------------------------------------------------------------
659*fd1fabb7SAndroid Build Coastguard Worker  */
660*fd1fabb7SAndroid Build Coastguard Worker 
GetDri()661*fd1fabb7SAndroid Build Coastguard Worker void dng_lossless_decoder::GetDri ()
662*fd1fabb7SAndroid Build Coastguard Worker 	{
663*fd1fabb7SAndroid Build Coastguard Worker 
664*fd1fabb7SAndroid Build Coastguard Worker     if (Get2bytes () != 4)
665*fd1fabb7SAndroid Build Coastguard Worker     	{
666*fd1fabb7SAndroid Build Coastguard Worker 		ThrowBadFormat ();
667*fd1fabb7SAndroid Build Coastguard Worker 		}
668*fd1fabb7SAndroid Build Coastguard Worker 
669*fd1fabb7SAndroid Build Coastguard Worker     info.restartInterval = Get2bytes ();
670*fd1fabb7SAndroid Build Coastguard Worker 
671*fd1fabb7SAndroid Build Coastguard Worker 	}
672*fd1fabb7SAndroid Build Coastguard Worker 
673*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
674*fd1fabb7SAndroid Build Coastguard Worker 
675*fd1fabb7SAndroid Build Coastguard Worker /*
676*fd1fabb7SAndroid Build Coastguard Worker  *--------------------------------------------------------------
677*fd1fabb7SAndroid Build Coastguard Worker  *
678*fd1fabb7SAndroid Build Coastguard Worker  * GetApp0 --
679*fd1fabb7SAndroid Build Coastguard Worker  *
680*fd1fabb7SAndroid Build Coastguard Worker  *	Process an APP0 marker.
681*fd1fabb7SAndroid Build Coastguard Worker  *
682*fd1fabb7SAndroid Build Coastguard Worker  * Results:
683*fd1fabb7SAndroid Build Coastguard Worker  *	None
684*fd1fabb7SAndroid Build Coastguard Worker  *
685*fd1fabb7SAndroid Build Coastguard Worker  * Side effects:
686*fd1fabb7SAndroid Build Coastguard Worker  *	Bitstream is parsed
687*fd1fabb7SAndroid Build Coastguard Worker  *
688*fd1fabb7SAndroid Build Coastguard Worker  *--------------------------------------------------------------
689*fd1fabb7SAndroid Build Coastguard Worker  */
690*fd1fabb7SAndroid Build Coastguard Worker 
GetApp0()691*fd1fabb7SAndroid Build Coastguard Worker void dng_lossless_decoder::GetApp0 ()
692*fd1fabb7SAndroid Build Coastguard Worker 	{
693*fd1fabb7SAndroid Build Coastguard Worker 
694*fd1fabb7SAndroid Build Coastguard Worker 	SkipVariable ();
695*fd1fabb7SAndroid Build Coastguard Worker 
696*fd1fabb7SAndroid Build Coastguard Worker 	}
697*fd1fabb7SAndroid Build Coastguard Worker 
698*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
699*fd1fabb7SAndroid Build Coastguard Worker 
700*fd1fabb7SAndroid Build Coastguard Worker /*
701*fd1fabb7SAndroid Build Coastguard Worker  *--------------------------------------------------------------
702*fd1fabb7SAndroid Build Coastguard Worker  *
703*fd1fabb7SAndroid Build Coastguard Worker  * GetSof --
704*fd1fabb7SAndroid Build Coastguard Worker  *
705*fd1fabb7SAndroid Build Coastguard Worker  *	Process a SOFn marker
706*fd1fabb7SAndroid Build Coastguard Worker  *
707*fd1fabb7SAndroid Build Coastguard Worker  * Results:
708*fd1fabb7SAndroid Build Coastguard Worker  *	None.
709*fd1fabb7SAndroid Build Coastguard Worker  *
710*fd1fabb7SAndroid Build Coastguard Worker  * Side effects:
711*fd1fabb7SAndroid Build Coastguard Worker  *	Bitstream is parsed
712*fd1fabb7SAndroid Build Coastguard Worker  *	Exits on error
713*fd1fabb7SAndroid Build Coastguard Worker  *	info structure is filled in
714*fd1fabb7SAndroid Build Coastguard Worker  *
715*fd1fabb7SAndroid Build Coastguard Worker  *--------------------------------------------------------------
716*fd1fabb7SAndroid Build Coastguard Worker  */
717*fd1fabb7SAndroid Build Coastguard Worker 
GetSof(int32)718*fd1fabb7SAndroid Build Coastguard Worker void dng_lossless_decoder::GetSof (int32 /*code*/)
719*fd1fabb7SAndroid Build Coastguard Worker 	{
720*fd1fabb7SAndroid Build Coastguard Worker 
721*fd1fabb7SAndroid Build Coastguard Worker     int32 length = Get2bytes ();
722*fd1fabb7SAndroid Build Coastguard Worker 
723*fd1fabb7SAndroid Build Coastguard Worker     info.dataPrecision = GetJpegChar ();
724*fd1fabb7SAndroid Build Coastguard Worker     info.imageHeight   = Get2bytes   ();
725*fd1fabb7SAndroid Build Coastguard Worker     info.imageWidth    = Get2bytes   ();
726*fd1fabb7SAndroid Build Coastguard Worker     info.numComponents = GetJpegChar ();
727*fd1fabb7SAndroid Build Coastguard Worker 
728*fd1fabb7SAndroid Build Coastguard Worker     // We don't support files in which the image height is initially
729*fd1fabb7SAndroid Build Coastguard Worker     // specified as 0 and is later redefined by DNL.  As long as we
730*fd1fabb7SAndroid Build Coastguard Worker     // have to check that, might as well have a general sanity check.
731*fd1fabb7SAndroid Build Coastguard Worker 
732*fd1fabb7SAndroid Build Coastguard Worker     if ((info.imageHeight   <= 0) ||
733*fd1fabb7SAndroid Build Coastguard Worker 		(info.imageWidth    <= 0) ||
734*fd1fabb7SAndroid Build Coastguard Worker 		(info.numComponents <= 0))
735*fd1fabb7SAndroid Build Coastguard Worker 		{
736*fd1fabb7SAndroid Build Coastguard Worker 		ThrowBadFormat ();
737*fd1fabb7SAndroid Build Coastguard Worker     	}
738*fd1fabb7SAndroid Build Coastguard Worker 
739*fd1fabb7SAndroid Build Coastguard Worker 	// Lossless JPEG specifies data precision to be from 2 to 16 bits/sample.
740*fd1fabb7SAndroid Build Coastguard Worker 
741*fd1fabb7SAndroid Build Coastguard Worker 	const int32 MinPrecisionBits = 2;
742*fd1fabb7SAndroid Build Coastguard Worker 	const int32 MaxPrecisionBits = 16;
743*fd1fabb7SAndroid Build Coastguard Worker 
744*fd1fabb7SAndroid Build Coastguard Worker     if ((info.dataPrecision < MinPrecisionBits) ||
745*fd1fabb7SAndroid Build Coastguard Worker         (info.dataPrecision > MaxPrecisionBits))
746*fd1fabb7SAndroid Build Coastguard Worker         {
747*fd1fabb7SAndroid Build Coastguard Worker 		ThrowBadFormat ();
748*fd1fabb7SAndroid Build Coastguard Worker     	}
749*fd1fabb7SAndroid Build Coastguard Worker 
750*fd1fabb7SAndroid Build Coastguard Worker     // Check length of tag.
751*fd1fabb7SAndroid Build Coastguard Worker 
752*fd1fabb7SAndroid Build Coastguard Worker     if (length != (info.numComponents * 3 + 8))
753*fd1fabb7SAndroid Build Coastguard Worker     	{
754*fd1fabb7SAndroid Build Coastguard Worker 		ThrowBadFormat ();
755*fd1fabb7SAndroid Build Coastguard Worker     	}
756*fd1fabb7SAndroid Build Coastguard Worker 
757*fd1fabb7SAndroid Build Coastguard Worker     // Allocate per component info.
758*fd1fabb7SAndroid Build Coastguard Worker 
759*fd1fabb7SAndroid Build Coastguard Worker     // We can cast info.numComponents to a uint32 because the check above
760*fd1fabb7SAndroid Build Coastguard Worker     // guarantees that it cannot be negative.
761*fd1fabb7SAndroid Build Coastguard Worker     compInfoBuffer.Allocate (static_cast<uint32> (info.numComponents),
762*fd1fabb7SAndroid Build Coastguard Worker                              sizeof (JpegComponentInfo));
763*fd1fabb7SAndroid Build Coastguard Worker 
764*fd1fabb7SAndroid Build Coastguard Worker     info.compInfo = (JpegComponentInfo *) compInfoBuffer.Buffer ();
765*fd1fabb7SAndroid Build Coastguard Worker 
766*fd1fabb7SAndroid Build Coastguard Worker     // Read in the per compent info.
767*fd1fabb7SAndroid Build Coastguard Worker 
768*fd1fabb7SAndroid Build Coastguard Worker     for (int32 ci = 0; ci < info.numComponents; ci++)
769*fd1fabb7SAndroid Build Coastguard Worker     	{
770*fd1fabb7SAndroid Build Coastguard Worker 
771*fd1fabb7SAndroid Build Coastguard Worker    		JpegComponentInfo *compptr = &info.compInfo [ci];
772*fd1fabb7SAndroid Build Coastguard Worker 
773*fd1fabb7SAndroid Build Coastguard Worker 		compptr->componentIndex = (int16) ci;
774*fd1fabb7SAndroid Build Coastguard Worker 
775*fd1fabb7SAndroid Build Coastguard Worker 		compptr->componentId = GetJpegChar ();
776*fd1fabb7SAndroid Build Coastguard Worker 
777*fd1fabb7SAndroid Build Coastguard Worker     	int32 c = GetJpegChar ();
778*fd1fabb7SAndroid Build Coastguard Worker 
779*fd1fabb7SAndroid Build Coastguard Worker 		compptr->hSampFactor = (int16) ((c >> 4) & 15);
780*fd1fabb7SAndroid Build Coastguard Worker 		compptr->vSampFactor = (int16) ((c     ) & 15);
781*fd1fabb7SAndroid Build Coastguard Worker 
782*fd1fabb7SAndroid Build Coastguard Worker         (void) GetJpegChar ();   /* skip Tq */
783*fd1fabb7SAndroid Build Coastguard Worker 
784*fd1fabb7SAndroid Build Coastguard Worker     	}
785*fd1fabb7SAndroid Build Coastguard Worker 
786*fd1fabb7SAndroid Build Coastguard Worker 	}
787*fd1fabb7SAndroid Build Coastguard Worker 
788*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
789*fd1fabb7SAndroid Build Coastguard Worker 
790*fd1fabb7SAndroid Build Coastguard Worker /*
791*fd1fabb7SAndroid Build Coastguard Worker  *--------------------------------------------------------------
792*fd1fabb7SAndroid Build Coastguard Worker  *
793*fd1fabb7SAndroid Build Coastguard Worker  * GetSos --
794*fd1fabb7SAndroid Build Coastguard Worker  *
795*fd1fabb7SAndroid Build Coastguard Worker  *	Process a SOS marker
796*fd1fabb7SAndroid Build Coastguard Worker  *
797*fd1fabb7SAndroid Build Coastguard Worker  * Results:
798*fd1fabb7SAndroid Build Coastguard Worker  *	None.
799*fd1fabb7SAndroid Build Coastguard Worker  *
800*fd1fabb7SAndroid Build Coastguard Worker  * Side effects:
801*fd1fabb7SAndroid Build Coastguard Worker  *	Bitstream is parsed.
802*fd1fabb7SAndroid Build Coastguard Worker  *	Exits on error.
803*fd1fabb7SAndroid Build Coastguard Worker  *
804*fd1fabb7SAndroid Build Coastguard Worker  *--------------------------------------------------------------
805*fd1fabb7SAndroid Build Coastguard Worker  */
806*fd1fabb7SAndroid Build Coastguard Worker 
GetSos()807*fd1fabb7SAndroid Build Coastguard Worker void dng_lossless_decoder::GetSos ()
808*fd1fabb7SAndroid Build Coastguard Worker 	{
809*fd1fabb7SAndroid Build Coastguard Worker 
810*fd1fabb7SAndroid Build Coastguard Worker     int32 length = Get2bytes ();
811*fd1fabb7SAndroid Build Coastguard Worker 
812*fd1fabb7SAndroid Build Coastguard Worker     // Get the number of image components.
813*fd1fabb7SAndroid Build Coastguard Worker 
814*fd1fabb7SAndroid Build Coastguard Worker     int32 n = GetJpegChar ();
815*fd1fabb7SAndroid Build Coastguard Worker     info.compsInScan = (int16) n;
816*fd1fabb7SAndroid Build Coastguard Worker 
817*fd1fabb7SAndroid Build Coastguard Worker     // Check length.
818*fd1fabb7SAndroid Build Coastguard Worker 
819*fd1fabb7SAndroid Build Coastguard Worker     length -= 3;
820*fd1fabb7SAndroid Build Coastguard Worker 
821*fd1fabb7SAndroid Build Coastguard Worker     if (length != (n * 2 + 3) || n < 1 || n > 4)
822*fd1fabb7SAndroid Build Coastguard Worker     	{
823*fd1fabb7SAndroid Build Coastguard Worker 		ThrowBadFormat ();
824*fd1fabb7SAndroid Build Coastguard Worker 		}
825*fd1fabb7SAndroid Build Coastguard Worker 
826*fd1fabb7SAndroid Build Coastguard Worker 	// Find index and huffman table for each component.
827*fd1fabb7SAndroid Build Coastguard Worker 
828*fd1fabb7SAndroid Build Coastguard Worker     for (int32 i = 0; i < n; i++)
829*fd1fabb7SAndroid Build Coastguard Worker     	{
830*fd1fabb7SAndroid Build Coastguard Worker 
831*fd1fabb7SAndroid Build Coastguard Worker  		int32 cc = GetJpegChar ();
832*fd1fabb7SAndroid Build Coastguard Worker 		int32 c  = GetJpegChar ();
833*fd1fabb7SAndroid Build Coastguard Worker 
834*fd1fabb7SAndroid Build Coastguard Worker  		int32 ci;
835*fd1fabb7SAndroid Build Coastguard Worker 
836*fd1fabb7SAndroid Build Coastguard Worker 		for (ci = 0; ci < info.numComponents; ci++)
837*fd1fabb7SAndroid Build Coastguard Worker 			{
838*fd1fabb7SAndroid Build Coastguard Worker 
839*fd1fabb7SAndroid Build Coastguard Worker 		    if (cc == info.compInfo[ci].componentId)
840*fd1fabb7SAndroid Build Coastguard Worker 		    	{
841*fd1fabb7SAndroid Build Coastguard Worker 				break;
842*fd1fabb7SAndroid Build Coastguard Worker 		    	}
843*fd1fabb7SAndroid Build Coastguard Worker 
844*fd1fabb7SAndroid Build Coastguard Worker 		    }
845*fd1fabb7SAndroid Build Coastguard Worker 
846*fd1fabb7SAndroid Build Coastguard Worker 		if (ci >= info.numComponents)
847*fd1fabb7SAndroid Build Coastguard Worker 			{
848*fd1fabb7SAndroid Build Coastguard Worker 		    ThrowBadFormat ();
849*fd1fabb7SAndroid Build Coastguard Worker 			}
850*fd1fabb7SAndroid Build Coastguard Worker 
851*fd1fabb7SAndroid Build Coastguard Worker     	JpegComponentInfo *compptr = &info.compInfo [ci];
852*fd1fabb7SAndroid Build Coastguard Worker 
853*fd1fabb7SAndroid Build Coastguard Worker 		info.curCompInfo [i] = compptr;
854*fd1fabb7SAndroid Build Coastguard Worker 
855*fd1fabb7SAndroid Build Coastguard Worker 		compptr->dcTblNo = (int16) ((c >> 4) & 15);
856*fd1fabb7SAndroid Build Coastguard Worker 
857*fd1fabb7SAndroid Build Coastguard Worker 	    }
858*fd1fabb7SAndroid Build Coastguard Worker 
859*fd1fabb7SAndroid Build Coastguard Worker     // Get the PSV, skip Se, and get the point transform parameter.
860*fd1fabb7SAndroid Build Coastguard Worker 
861*fd1fabb7SAndroid Build Coastguard Worker     info.Ss = GetJpegChar ();
862*fd1fabb7SAndroid Build Coastguard Worker 
863*fd1fabb7SAndroid Build Coastguard Worker     (void) GetJpegChar ();
864*fd1fabb7SAndroid Build Coastguard Worker 
865*fd1fabb7SAndroid Build Coastguard Worker     info.Pt = GetJpegChar () & 0x0F;
866*fd1fabb7SAndroid Build Coastguard Worker 
867*fd1fabb7SAndroid Build Coastguard Worker 	}
868*fd1fabb7SAndroid Build Coastguard Worker 
869*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
870*fd1fabb7SAndroid Build Coastguard Worker 
871*fd1fabb7SAndroid Build Coastguard Worker /*
872*fd1fabb7SAndroid Build Coastguard Worker  *--------------------------------------------------------------
873*fd1fabb7SAndroid Build Coastguard Worker  *
874*fd1fabb7SAndroid Build Coastguard Worker  * GetSoi --
875*fd1fabb7SAndroid Build Coastguard Worker  *
876*fd1fabb7SAndroid Build Coastguard Worker  *	Process an SOI marker
877*fd1fabb7SAndroid Build Coastguard Worker  *
878*fd1fabb7SAndroid Build Coastguard Worker  * Results:
879*fd1fabb7SAndroid Build Coastguard Worker  *	None.
880*fd1fabb7SAndroid Build Coastguard Worker  *
881*fd1fabb7SAndroid Build Coastguard Worker  * Side effects:
882*fd1fabb7SAndroid Build Coastguard Worker  *	Bitstream is parsed.
883*fd1fabb7SAndroid Build Coastguard Worker  *	Exits on error.
884*fd1fabb7SAndroid Build Coastguard Worker  *
885*fd1fabb7SAndroid Build Coastguard Worker  *--------------------------------------------------------------
886*fd1fabb7SAndroid Build Coastguard Worker  */
887*fd1fabb7SAndroid Build Coastguard Worker 
GetSoi()888*fd1fabb7SAndroid Build Coastguard Worker void dng_lossless_decoder::GetSoi ()
889*fd1fabb7SAndroid Build Coastguard Worker 	{
890*fd1fabb7SAndroid Build Coastguard Worker 
891*fd1fabb7SAndroid Build Coastguard Worker     // Reset all parameters that are defined to be reset by SOI
892*fd1fabb7SAndroid Build Coastguard Worker 
893*fd1fabb7SAndroid Build Coastguard Worker     info.restartInterval = 0;
894*fd1fabb7SAndroid Build Coastguard Worker 
895*fd1fabb7SAndroid Build Coastguard Worker 	}
896*fd1fabb7SAndroid Build Coastguard Worker 
897*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
898*fd1fabb7SAndroid Build Coastguard Worker 
899*fd1fabb7SAndroid Build Coastguard Worker /*
900*fd1fabb7SAndroid Build Coastguard Worker  *--------------------------------------------------------------
901*fd1fabb7SAndroid Build Coastguard Worker  *
902*fd1fabb7SAndroid Build Coastguard Worker  * NextMarker --
903*fd1fabb7SAndroid Build Coastguard Worker  *
904*fd1fabb7SAndroid Build Coastguard Worker  *      Find the next JPEG marker Note that the output might not
905*fd1fabb7SAndroid Build Coastguard Worker  *	be a valid marker code but it will never be 0 or FF
906*fd1fabb7SAndroid Build Coastguard Worker  *
907*fd1fabb7SAndroid Build Coastguard Worker  * Results:
908*fd1fabb7SAndroid Build Coastguard Worker  *	The marker found.
909*fd1fabb7SAndroid Build Coastguard Worker  *
910*fd1fabb7SAndroid Build Coastguard Worker  * Side effects:
911*fd1fabb7SAndroid Build Coastguard Worker  *	Bitstream is parsed.
912*fd1fabb7SAndroid Build Coastguard Worker  *
913*fd1fabb7SAndroid Build Coastguard Worker  *--------------------------------------------------------------
914*fd1fabb7SAndroid Build Coastguard Worker  */
915*fd1fabb7SAndroid Build Coastguard Worker 
NextMarker()916*fd1fabb7SAndroid Build Coastguard Worker int32 dng_lossless_decoder::NextMarker ()
917*fd1fabb7SAndroid Build Coastguard Worker 	{
918*fd1fabb7SAndroid Build Coastguard Worker 
919*fd1fabb7SAndroid Build Coastguard Worker     int32 c;
920*fd1fabb7SAndroid Build Coastguard Worker 
921*fd1fabb7SAndroid Build Coastguard Worker     do
922*fd1fabb7SAndroid Build Coastguard Worker     	{
923*fd1fabb7SAndroid Build Coastguard Worker 
924*fd1fabb7SAndroid Build Coastguard Worker 		// skip any non-FF bytes
925*fd1fabb7SAndroid Build Coastguard Worker 
926*fd1fabb7SAndroid Build Coastguard Worker 		do
927*fd1fabb7SAndroid Build Coastguard Worker 			{
928*fd1fabb7SAndroid Build Coastguard Worker 	   		c = GetJpegChar ();
929*fd1fabb7SAndroid Build Coastguard Worker 			}
930*fd1fabb7SAndroid Build Coastguard Worker 		while (c != 0xFF);
931*fd1fabb7SAndroid Build Coastguard Worker 
932*fd1fabb7SAndroid Build Coastguard Worker 		// skip any duplicate FFs, since extra FFs are legal
933*fd1fabb7SAndroid Build Coastguard Worker 
934*fd1fabb7SAndroid Build Coastguard Worker 		do
935*fd1fabb7SAndroid Build Coastguard Worker 			{
936*fd1fabb7SAndroid Build Coastguard Worker 			c = GetJpegChar();
937*fd1fabb7SAndroid Build Coastguard Worker 			}
938*fd1fabb7SAndroid Build Coastguard Worker 		while (c == 0xFF);
939*fd1fabb7SAndroid Build Coastguard Worker 
940*fd1fabb7SAndroid Build Coastguard Worker 		}
941*fd1fabb7SAndroid Build Coastguard Worker 	while (c == 0);		// repeat if it was a stuffed FF/00
942*fd1fabb7SAndroid Build Coastguard Worker 
943*fd1fabb7SAndroid Build Coastguard Worker     return c;
944*fd1fabb7SAndroid Build Coastguard Worker 
945*fd1fabb7SAndroid Build Coastguard Worker 	}
946*fd1fabb7SAndroid Build Coastguard Worker 
947*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
948*fd1fabb7SAndroid Build Coastguard Worker 
949*fd1fabb7SAndroid Build Coastguard Worker /*
950*fd1fabb7SAndroid Build Coastguard Worker  *--------------------------------------------------------------
951*fd1fabb7SAndroid Build Coastguard Worker  *
952*fd1fabb7SAndroid Build Coastguard Worker  * ProcessTables --
953*fd1fabb7SAndroid Build Coastguard Worker  *
954*fd1fabb7SAndroid Build Coastguard Worker  *	Scan and process JPEG markers that can appear in any order
955*fd1fabb7SAndroid Build Coastguard Worker  *	Return when an SOI, EOI, SOFn, or SOS is found
956*fd1fabb7SAndroid Build Coastguard Worker  *
957*fd1fabb7SAndroid Build Coastguard Worker  * Results:
958*fd1fabb7SAndroid Build Coastguard Worker  *	The marker found.
959*fd1fabb7SAndroid Build Coastguard Worker  *
960*fd1fabb7SAndroid Build Coastguard Worker  * Side effects:
961*fd1fabb7SAndroid Build Coastguard Worker  *	Bitstream is parsed.
962*fd1fabb7SAndroid Build Coastguard Worker  *
963*fd1fabb7SAndroid Build Coastguard Worker  *--------------------------------------------------------------
964*fd1fabb7SAndroid Build Coastguard Worker  */
965*fd1fabb7SAndroid Build Coastguard Worker 
ProcessTables()966*fd1fabb7SAndroid Build Coastguard Worker JpegMarker dng_lossless_decoder::ProcessTables ()
967*fd1fabb7SAndroid Build Coastguard Worker 	{
968*fd1fabb7SAndroid Build Coastguard Worker 
969*fd1fabb7SAndroid Build Coastguard Worker     while (true)
970*fd1fabb7SAndroid Build Coastguard Worker     	{
971*fd1fabb7SAndroid Build Coastguard Worker 
972*fd1fabb7SAndroid Build Coastguard Worker 		int32 c = NextMarker ();
973*fd1fabb7SAndroid Build Coastguard Worker 
974*fd1fabb7SAndroid Build Coastguard Worker 		switch (c)
975*fd1fabb7SAndroid Build Coastguard Worker 			{
976*fd1fabb7SAndroid Build Coastguard Worker 
977*fd1fabb7SAndroid Build Coastguard Worker 			case M_SOF0:
978*fd1fabb7SAndroid Build Coastguard Worker 			case M_SOF1:
979*fd1fabb7SAndroid Build Coastguard Worker 			case M_SOF2:
980*fd1fabb7SAndroid Build Coastguard Worker 			case M_SOF3:
981*fd1fabb7SAndroid Build Coastguard Worker 			case M_SOF5:
982*fd1fabb7SAndroid Build Coastguard Worker 			case M_SOF6:
983*fd1fabb7SAndroid Build Coastguard Worker 			case M_SOF7:
984*fd1fabb7SAndroid Build Coastguard Worker 			case M_JPG:
985*fd1fabb7SAndroid Build Coastguard Worker 			case M_SOF9:
986*fd1fabb7SAndroid Build Coastguard Worker 			case M_SOF10:
987*fd1fabb7SAndroid Build Coastguard Worker 			case M_SOF11:
988*fd1fabb7SAndroid Build Coastguard Worker 			case M_SOF13:
989*fd1fabb7SAndroid Build Coastguard Worker 			case M_SOF14:
990*fd1fabb7SAndroid Build Coastguard Worker 			case M_SOF15:
991*fd1fabb7SAndroid Build Coastguard Worker 			case M_SOI:
992*fd1fabb7SAndroid Build Coastguard Worker 			case M_EOI:
993*fd1fabb7SAndroid Build Coastguard Worker 			case M_SOS:
994*fd1fabb7SAndroid Build Coastguard Worker 			    return (JpegMarker) c;
995*fd1fabb7SAndroid Build Coastguard Worker 
996*fd1fabb7SAndroid Build Coastguard Worker 			case M_DHT:
997*fd1fabb7SAndroid Build Coastguard Worker 			    GetDht ();
998*fd1fabb7SAndroid Build Coastguard Worker 			    break;
999*fd1fabb7SAndroid Build Coastguard Worker 
1000*fd1fabb7SAndroid Build Coastguard Worker 			case M_DQT:
1001*fd1fabb7SAndroid Build Coastguard Worker 			    break;
1002*fd1fabb7SAndroid Build Coastguard Worker 
1003*fd1fabb7SAndroid Build Coastguard Worker 			case M_DRI:
1004*fd1fabb7SAndroid Build Coastguard Worker 			    GetDri ();
1005*fd1fabb7SAndroid Build Coastguard Worker 			    break;
1006*fd1fabb7SAndroid Build Coastguard Worker 
1007*fd1fabb7SAndroid Build Coastguard Worker 			case M_APP0:
1008*fd1fabb7SAndroid Build Coastguard Worker 			    GetApp0 ();
1009*fd1fabb7SAndroid Build Coastguard Worker 			    break;
1010*fd1fabb7SAndroid Build Coastguard Worker 
1011*fd1fabb7SAndroid Build Coastguard Worker 			case M_RST0:	// these are all parameterless
1012*fd1fabb7SAndroid Build Coastguard Worker 			case M_RST1:
1013*fd1fabb7SAndroid Build Coastguard Worker 			case M_RST2:
1014*fd1fabb7SAndroid Build Coastguard Worker 			case M_RST3:
1015*fd1fabb7SAndroid Build Coastguard Worker 			case M_RST4:
1016*fd1fabb7SAndroid Build Coastguard Worker 			case M_RST5:
1017*fd1fabb7SAndroid Build Coastguard Worker 			case M_RST6:
1018*fd1fabb7SAndroid Build Coastguard Worker 			case M_RST7:
1019*fd1fabb7SAndroid Build Coastguard Worker 			case M_TEM:
1020*fd1fabb7SAndroid Build Coastguard Worker 			    break;
1021*fd1fabb7SAndroid Build Coastguard Worker 
1022*fd1fabb7SAndroid Build Coastguard Worker 			default:		// must be DNL, DHP, EXP, APPn, JPGn, COM, or RESn
1023*fd1fabb7SAndroid Build Coastguard Worker 			    SkipVariable ();
1024*fd1fabb7SAndroid Build Coastguard Worker 			    break;
1025*fd1fabb7SAndroid Build Coastguard Worker 
1026*fd1fabb7SAndroid Build Coastguard Worker 			}
1027*fd1fabb7SAndroid Build Coastguard Worker 
1028*fd1fabb7SAndroid Build Coastguard Worker     	}
1029*fd1fabb7SAndroid Build Coastguard Worker 
1030*fd1fabb7SAndroid Build Coastguard Worker     	return M_ERROR;
1031*fd1fabb7SAndroid Build Coastguard Worker 	}
1032*fd1fabb7SAndroid Build Coastguard Worker 
1033*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
1034*fd1fabb7SAndroid Build Coastguard Worker 
1035*fd1fabb7SAndroid Build Coastguard Worker /*
1036*fd1fabb7SAndroid Build Coastguard Worker  *--------------------------------------------------------------
1037*fd1fabb7SAndroid Build Coastguard Worker  *
1038*fd1fabb7SAndroid Build Coastguard Worker  * ReadFileHeader --
1039*fd1fabb7SAndroid Build Coastguard Worker  *
1040*fd1fabb7SAndroid Build Coastguard Worker  *	Initialize and read the stream header (everything through
1041*fd1fabb7SAndroid Build Coastguard Worker  *	the SOF marker).
1042*fd1fabb7SAndroid Build Coastguard Worker  *
1043*fd1fabb7SAndroid Build Coastguard Worker  * Results:
1044*fd1fabb7SAndroid Build Coastguard Worker  *	None
1045*fd1fabb7SAndroid Build Coastguard Worker  *
1046*fd1fabb7SAndroid Build Coastguard Worker  * Side effects:
1047*fd1fabb7SAndroid Build Coastguard Worker  *	Exit on error.
1048*fd1fabb7SAndroid Build Coastguard Worker  *
1049*fd1fabb7SAndroid Build Coastguard Worker  *--------------------------------------------------------------
1050*fd1fabb7SAndroid Build Coastguard Worker  */
1051*fd1fabb7SAndroid Build Coastguard Worker 
ReadFileHeader()1052*fd1fabb7SAndroid Build Coastguard Worker void dng_lossless_decoder::ReadFileHeader ()
1053*fd1fabb7SAndroid Build Coastguard Worker 	{
1054*fd1fabb7SAndroid Build Coastguard Worker 
1055*fd1fabb7SAndroid Build Coastguard Worker     // Demand an SOI marker at the start of the stream --- otherwise it's
1056*fd1fabb7SAndroid Build Coastguard Worker     // probably not a JPEG stream at all.
1057*fd1fabb7SAndroid Build Coastguard Worker 
1058*fd1fabb7SAndroid Build Coastguard Worker     int32 c  = GetJpegChar ();
1059*fd1fabb7SAndroid Build Coastguard Worker     int32 c2 = GetJpegChar ();
1060*fd1fabb7SAndroid Build Coastguard Worker 
1061*fd1fabb7SAndroid Build Coastguard Worker     if ((c != 0xFF) || (c2 != M_SOI))
1062*fd1fabb7SAndroid Build Coastguard Worker     	{
1063*fd1fabb7SAndroid Build Coastguard Worker 		ThrowBadFormat ();
1064*fd1fabb7SAndroid Build Coastguard Worker     	}
1065*fd1fabb7SAndroid Build Coastguard Worker 
1066*fd1fabb7SAndroid Build Coastguard Worker     // OK, process SOI
1067*fd1fabb7SAndroid Build Coastguard Worker 
1068*fd1fabb7SAndroid Build Coastguard Worker     GetSoi ();
1069*fd1fabb7SAndroid Build Coastguard Worker 
1070*fd1fabb7SAndroid Build Coastguard Worker     // Process markers until SOF
1071*fd1fabb7SAndroid Build Coastguard Worker 
1072*fd1fabb7SAndroid Build Coastguard Worker     c = ProcessTables ();
1073*fd1fabb7SAndroid Build Coastguard Worker 
1074*fd1fabb7SAndroid Build Coastguard Worker     switch (c)
1075*fd1fabb7SAndroid Build Coastguard Worker     	{
1076*fd1fabb7SAndroid Build Coastguard Worker 
1077*fd1fabb7SAndroid Build Coastguard Worker 		case M_SOF0:
1078*fd1fabb7SAndroid Build Coastguard Worker 		case M_SOF1:
1079*fd1fabb7SAndroid Build Coastguard Worker 		case M_SOF3:
1080*fd1fabb7SAndroid Build Coastguard Worker 			GetSof (c);
1081*fd1fabb7SAndroid Build Coastguard Worker 			break;
1082*fd1fabb7SAndroid Build Coastguard Worker 
1083*fd1fabb7SAndroid Build Coastguard Worker     	default:
1084*fd1fabb7SAndroid Build Coastguard Worker 			ThrowBadFormat ();
1085*fd1fabb7SAndroid Build Coastguard Worker 			break;
1086*fd1fabb7SAndroid Build Coastguard Worker 
1087*fd1fabb7SAndroid Build Coastguard Worker     	}
1088*fd1fabb7SAndroid Build Coastguard Worker 
1089*fd1fabb7SAndroid Build Coastguard Worker 	}
1090*fd1fabb7SAndroid Build Coastguard Worker 
1091*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
1092*fd1fabb7SAndroid Build Coastguard Worker 
1093*fd1fabb7SAndroid Build Coastguard Worker /*
1094*fd1fabb7SAndroid Build Coastguard Worker  *--------------------------------------------------------------
1095*fd1fabb7SAndroid Build Coastguard Worker  *
1096*fd1fabb7SAndroid Build Coastguard Worker  * ReadScanHeader --
1097*fd1fabb7SAndroid Build Coastguard Worker  *
1098*fd1fabb7SAndroid Build Coastguard Worker  *	Read the start of a scan (everything through the SOS marker).
1099*fd1fabb7SAndroid Build Coastguard Worker  *
1100*fd1fabb7SAndroid Build Coastguard Worker  * Results:
1101*fd1fabb7SAndroid Build Coastguard Worker  *	1 if find SOS, 0 if find EOI
1102*fd1fabb7SAndroid Build Coastguard Worker  *
1103*fd1fabb7SAndroid Build Coastguard Worker  * Side effects:
1104*fd1fabb7SAndroid Build Coastguard Worker  *	Bitstream is parsed, may exit on errors.
1105*fd1fabb7SAndroid Build Coastguard Worker  *
1106*fd1fabb7SAndroid Build Coastguard Worker  *--------------------------------------------------------------
1107*fd1fabb7SAndroid Build Coastguard Worker  */
1108*fd1fabb7SAndroid Build Coastguard Worker 
ReadScanHeader()1109*fd1fabb7SAndroid Build Coastguard Worker int32 dng_lossless_decoder::ReadScanHeader ()
1110*fd1fabb7SAndroid Build Coastguard Worker 	{
1111*fd1fabb7SAndroid Build Coastguard Worker 
1112*fd1fabb7SAndroid Build Coastguard Worker     // Process markers until SOS or EOI
1113*fd1fabb7SAndroid Build Coastguard Worker 
1114*fd1fabb7SAndroid Build Coastguard Worker     int32 c = ProcessTables ();
1115*fd1fabb7SAndroid Build Coastguard Worker 
1116*fd1fabb7SAndroid Build Coastguard Worker     switch (c)
1117*fd1fabb7SAndroid Build Coastguard Worker     	{
1118*fd1fabb7SAndroid Build Coastguard Worker 
1119*fd1fabb7SAndroid Build Coastguard Worker 		case M_SOS:
1120*fd1fabb7SAndroid Build Coastguard Worker 			GetSos ();
1121*fd1fabb7SAndroid Build Coastguard Worker 			return 1;
1122*fd1fabb7SAndroid Build Coastguard Worker 
1123*fd1fabb7SAndroid Build Coastguard Worker     	case M_EOI:
1124*fd1fabb7SAndroid Build Coastguard Worker 			return 0;
1125*fd1fabb7SAndroid Build Coastguard Worker 
1126*fd1fabb7SAndroid Build Coastguard Worker     	default:
1127*fd1fabb7SAndroid Build Coastguard Worker 			ThrowBadFormat ();
1128*fd1fabb7SAndroid Build Coastguard Worker 			break;
1129*fd1fabb7SAndroid Build Coastguard Worker 
1130*fd1fabb7SAndroid Build Coastguard Worker     	}
1131*fd1fabb7SAndroid Build Coastguard Worker 
1132*fd1fabb7SAndroid Build Coastguard Worker     return 0;
1133*fd1fabb7SAndroid Build Coastguard Worker 
1134*fd1fabb7SAndroid Build Coastguard Worker 	}
1135*fd1fabb7SAndroid Build Coastguard Worker 
1136*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
1137*fd1fabb7SAndroid Build Coastguard Worker 
1138*fd1fabb7SAndroid Build Coastguard Worker /*
1139*fd1fabb7SAndroid Build Coastguard Worker  *--------------------------------------------------------------
1140*fd1fabb7SAndroid Build Coastguard Worker  *
1141*fd1fabb7SAndroid Build Coastguard Worker  * DecoderStructInit --
1142*fd1fabb7SAndroid Build Coastguard Worker  *
1143*fd1fabb7SAndroid Build Coastguard Worker  *	Initalize the rest of the fields in the decompression
1144*fd1fabb7SAndroid Build Coastguard Worker  *	structure.
1145*fd1fabb7SAndroid Build Coastguard Worker  *
1146*fd1fabb7SAndroid Build Coastguard Worker  * Results:
1147*fd1fabb7SAndroid Build Coastguard Worker  *	None.
1148*fd1fabb7SAndroid Build Coastguard Worker  *
1149*fd1fabb7SAndroid Build Coastguard Worker  * Side effects:
1150*fd1fabb7SAndroid Build Coastguard Worker  *	None.
1151*fd1fabb7SAndroid Build Coastguard Worker  *
1152*fd1fabb7SAndroid Build Coastguard Worker  *--------------------------------------------------------------
1153*fd1fabb7SAndroid Build Coastguard Worker  */
1154*fd1fabb7SAndroid Build Coastguard Worker 
DecoderStructInit()1155*fd1fabb7SAndroid Build Coastguard Worker void dng_lossless_decoder::DecoderStructInit ()
1156*fd1fabb7SAndroid Build Coastguard Worker 	{
1157*fd1fabb7SAndroid Build Coastguard Worker 
1158*fd1fabb7SAndroid Build Coastguard Worker 	int32 ci;
1159*fd1fabb7SAndroid Build Coastguard Worker 
1160*fd1fabb7SAndroid Build Coastguard Worker 	#if qSupportCanon_sRAW
1161*fd1fabb7SAndroid Build Coastguard Worker 
1162*fd1fabb7SAndroid Build Coastguard Worker 	bool canon_sRAW = (info.numComponents == 3) &&
1163*fd1fabb7SAndroid Build Coastguard Worker 					  (info.compInfo [0].hSampFactor == 2) &&
1164*fd1fabb7SAndroid Build Coastguard Worker 					  (info.compInfo [1].hSampFactor == 1) &&
1165*fd1fabb7SAndroid Build Coastguard Worker 					  (info.compInfo [2].hSampFactor == 1) &&
1166*fd1fabb7SAndroid Build Coastguard Worker 					  (info.compInfo [0].vSampFactor == 1) &&
1167*fd1fabb7SAndroid Build Coastguard Worker 					  (info.compInfo [1].vSampFactor == 1) &&
1168*fd1fabb7SAndroid Build Coastguard Worker 					  (info.compInfo [2].vSampFactor == 1) &&
1169*fd1fabb7SAndroid Build Coastguard Worker 					  (info.dataPrecision == 15) &&
1170*fd1fabb7SAndroid Build Coastguard Worker 					  (info.Ss == 1) &&
1171*fd1fabb7SAndroid Build Coastguard Worker 					  ((info.imageWidth & 1) == 0);
1172*fd1fabb7SAndroid Build Coastguard Worker 
1173*fd1fabb7SAndroid Build Coastguard Worker 	bool canon_sRAW2 = (info.numComponents == 3) &&
1174*fd1fabb7SAndroid Build Coastguard Worker 					   (info.compInfo [0].hSampFactor == 2) &&
1175*fd1fabb7SAndroid Build Coastguard Worker 					   (info.compInfo [1].hSampFactor == 1) &&
1176*fd1fabb7SAndroid Build Coastguard Worker 					   (info.compInfo [2].hSampFactor == 1) &&
1177*fd1fabb7SAndroid Build Coastguard Worker 					   (info.compInfo [0].vSampFactor == 2) &&
1178*fd1fabb7SAndroid Build Coastguard Worker 					   (info.compInfo [1].vSampFactor == 1) &&
1179*fd1fabb7SAndroid Build Coastguard Worker 					   (info.compInfo [2].vSampFactor == 1) &&
1180*fd1fabb7SAndroid Build Coastguard Worker 					   (info.dataPrecision == 15) &&
1181*fd1fabb7SAndroid Build Coastguard Worker 					   (info.Ss == 1) &&
1182*fd1fabb7SAndroid Build Coastguard Worker 					   ((info.imageWidth  & 1) == 0) &&
1183*fd1fabb7SAndroid Build Coastguard Worker 					   ((info.imageHeight & 1) == 0);
1184*fd1fabb7SAndroid Build Coastguard Worker 
1185*fd1fabb7SAndroid Build Coastguard Worker 	if (!canon_sRAW && !canon_sRAW2)
1186*fd1fabb7SAndroid Build Coastguard Worker 
1187*fd1fabb7SAndroid Build Coastguard Worker 	#endif
1188*fd1fabb7SAndroid Build Coastguard Worker 
1189*fd1fabb7SAndroid Build Coastguard Worker 		{
1190*fd1fabb7SAndroid Build Coastguard Worker 
1191*fd1fabb7SAndroid Build Coastguard Worker 		// Check sampling factor validity.
1192*fd1fabb7SAndroid Build Coastguard Worker 
1193*fd1fabb7SAndroid Build Coastguard Worker 		for (ci = 0; ci < info.numComponents; ci++)
1194*fd1fabb7SAndroid Build Coastguard Worker 			{
1195*fd1fabb7SAndroid Build Coastguard Worker 
1196*fd1fabb7SAndroid Build Coastguard Worker 			JpegComponentInfo *compPtr = &info.compInfo [ci];
1197*fd1fabb7SAndroid Build Coastguard Worker 
1198*fd1fabb7SAndroid Build Coastguard Worker 			if (compPtr->hSampFactor != 1 ||
1199*fd1fabb7SAndroid Build Coastguard Worker 				compPtr->vSampFactor != 1)
1200*fd1fabb7SAndroid Build Coastguard Worker 				{
1201*fd1fabb7SAndroid Build Coastguard Worker 				ThrowBadFormat ();
1202*fd1fabb7SAndroid Build Coastguard Worker 				}
1203*fd1fabb7SAndroid Build Coastguard Worker 
1204*fd1fabb7SAndroid Build Coastguard Worker 			}
1205*fd1fabb7SAndroid Build Coastguard Worker 
1206*fd1fabb7SAndroid Build Coastguard Worker 		}
1207*fd1fabb7SAndroid Build Coastguard Worker 
1208*fd1fabb7SAndroid Build Coastguard Worker     // Prepare array describing MCU composition.
1209*fd1fabb7SAndroid Build Coastguard Worker 
1210*fd1fabb7SAndroid Build Coastguard Worker 	if (info.compsInScan < 0 || info.compsInScan > 4)
1211*fd1fabb7SAndroid Build Coastguard Worker 		{
1212*fd1fabb7SAndroid Build Coastguard Worker     	ThrowBadFormat ();
1213*fd1fabb7SAndroid Build Coastguard Worker 		}
1214*fd1fabb7SAndroid Build Coastguard Worker 
1215*fd1fabb7SAndroid Build Coastguard Worker 	for (ci = 0; ci < info.compsInScan; ci++)
1216*fd1fabb7SAndroid Build Coastguard Worker 		{
1217*fd1fabb7SAndroid Build Coastguard Worker         info.MCUmembership [ci] = (int16) ci;
1218*fd1fabb7SAndroid Build Coastguard Worker 		}
1219*fd1fabb7SAndroid Build Coastguard Worker 
1220*fd1fabb7SAndroid Build Coastguard Worker 	// Initialize mucROW1 and mcuROW2 which buffer two rows of
1221*fd1fabb7SAndroid Build Coastguard Worker     // pixels for predictor calculation.
1222*fd1fabb7SAndroid Build Coastguard Worker 
1223*fd1fabb7SAndroid Build Coastguard Worker 	// This multiplication cannot overflow because info.compsInScan is
1224*fd1fabb7SAndroid Build Coastguard Worker 	// guaranteed to be between 0 and 4 inclusive (see checks above).
1225*fd1fabb7SAndroid Build Coastguard Worker 	int32 mcuSize = info.compsInScan * (uint32) sizeof (ComponentType);
1226*fd1fabb7SAndroid Build Coastguard Worker 
1227*fd1fabb7SAndroid Build Coastguard Worker 	mcuBuffer1.Allocate (info.imageWidth, sizeof (MCU));
1228*fd1fabb7SAndroid Build Coastguard Worker 	mcuBuffer2.Allocate (info.imageWidth, sizeof (MCU));
1229*fd1fabb7SAndroid Build Coastguard Worker 
1230*fd1fabb7SAndroid Build Coastguard Worker 	mcuROW1 = (MCU *) mcuBuffer1.Buffer ();
1231*fd1fabb7SAndroid Build Coastguard Worker 	mcuROW2 = (MCU *) mcuBuffer2.Buffer ();
1232*fd1fabb7SAndroid Build Coastguard Worker 
1233*fd1fabb7SAndroid Build Coastguard Worker 	mcuBuffer3.Allocate (info.imageWidth, mcuSize);
1234*fd1fabb7SAndroid Build Coastguard Worker 	mcuBuffer4.Allocate (info.imageWidth, mcuSize);
1235*fd1fabb7SAndroid Build Coastguard Worker 
1236*fd1fabb7SAndroid Build Coastguard Worker  	mcuROW1 [0] = (ComponentType *) mcuBuffer3.Buffer ();
1237*fd1fabb7SAndroid Build Coastguard Worker  	mcuROW2 [0] = (ComponentType *) mcuBuffer4.Buffer ();
1238*fd1fabb7SAndroid Build Coastguard Worker 
1239*fd1fabb7SAndroid Build Coastguard Worker  	for (int32 j = 1; j < info.imageWidth; j++)
1240*fd1fabb7SAndroid Build Coastguard Worker  		{
1241*fd1fabb7SAndroid Build Coastguard Worker 
1242*fd1fabb7SAndroid Build Coastguard Worker  		mcuROW1 [j] = mcuROW1 [j - 1] + info.compsInScan;
1243*fd1fabb7SAndroid Build Coastguard Worker  		mcuROW2 [j] = mcuROW2 [j - 1] + info.compsInScan;
1244*fd1fabb7SAndroid Build Coastguard Worker 
1245*fd1fabb7SAndroid Build Coastguard Worker  		}
1246*fd1fabb7SAndroid Build Coastguard Worker 
1247*fd1fabb7SAndroid Build Coastguard Worker 	}
1248*fd1fabb7SAndroid Build Coastguard Worker 
1249*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
1250*fd1fabb7SAndroid Build Coastguard Worker 
1251*fd1fabb7SAndroid Build Coastguard Worker /*
1252*fd1fabb7SAndroid Build Coastguard Worker  *--------------------------------------------------------------
1253*fd1fabb7SAndroid Build Coastguard Worker  *
1254*fd1fabb7SAndroid Build Coastguard Worker  * HuffDecoderInit --
1255*fd1fabb7SAndroid Build Coastguard Worker  *
1256*fd1fabb7SAndroid Build Coastguard Worker  *	Initialize for a Huffman-compressed scan.
1257*fd1fabb7SAndroid Build Coastguard Worker  *	This is invoked after reading the SOS marker.
1258*fd1fabb7SAndroid Build Coastguard Worker  *
1259*fd1fabb7SAndroid Build Coastguard Worker  * Results:
1260*fd1fabb7SAndroid Build Coastguard Worker  *	None
1261*fd1fabb7SAndroid Build Coastguard Worker  *
1262*fd1fabb7SAndroid Build Coastguard Worker  * Side effects:
1263*fd1fabb7SAndroid Build Coastguard Worker  *	None.
1264*fd1fabb7SAndroid Build Coastguard Worker  *
1265*fd1fabb7SAndroid Build Coastguard Worker  *--------------------------------------------------------------
1266*fd1fabb7SAndroid Build Coastguard Worker  */
1267*fd1fabb7SAndroid Build Coastguard Worker 
HuffDecoderInit()1268*fd1fabb7SAndroid Build Coastguard Worker void dng_lossless_decoder::HuffDecoderInit ()
1269*fd1fabb7SAndroid Build Coastguard Worker 	{
1270*fd1fabb7SAndroid Build Coastguard Worker 
1271*fd1fabb7SAndroid Build Coastguard Worker     // Initialize bit parser state
1272*fd1fabb7SAndroid Build Coastguard Worker 
1273*fd1fabb7SAndroid Build Coastguard Worker  	getBuffer = 0;
1274*fd1fabb7SAndroid Build Coastguard Worker     bitsLeft  = 0;
1275*fd1fabb7SAndroid Build Coastguard Worker 
1276*fd1fabb7SAndroid Build Coastguard Worker     // Prepare Huffman tables.
1277*fd1fabb7SAndroid Build Coastguard Worker 
1278*fd1fabb7SAndroid Build Coastguard Worker     for (int16 ci = 0; ci < info.compsInScan; ci++)
1279*fd1fabb7SAndroid Build Coastguard Worker     	{
1280*fd1fabb7SAndroid Build Coastguard Worker 
1281*fd1fabb7SAndroid Build Coastguard Worker 		JpegComponentInfo *compptr = info.curCompInfo [ci];
1282*fd1fabb7SAndroid Build Coastguard Worker 
1283*fd1fabb7SAndroid Build Coastguard Worker 		// Make sure requested tables are present
1284*fd1fabb7SAndroid Build Coastguard Worker 
1285*fd1fabb7SAndroid Build Coastguard Worker 		if (compptr->dcTblNo < 0 || compptr->dcTblNo > 3)
1286*fd1fabb7SAndroid Build Coastguard Worker 			{
1287*fd1fabb7SAndroid Build Coastguard Worker 			ThrowBadFormat ();
1288*fd1fabb7SAndroid Build Coastguard Worker 			}
1289*fd1fabb7SAndroid Build Coastguard Worker 
1290*fd1fabb7SAndroid Build Coastguard Worker 		if (info.dcHuffTblPtrs [compptr->dcTblNo] == NULL)
1291*fd1fabb7SAndroid Build Coastguard Worker 			{
1292*fd1fabb7SAndroid Build Coastguard Worker 	    	ThrowBadFormat ();
1293*fd1fabb7SAndroid Build Coastguard Worker 			}
1294*fd1fabb7SAndroid Build Coastguard Worker 
1295*fd1fabb7SAndroid Build Coastguard Worker 		// Compute derived values for Huffman tables.
1296*fd1fabb7SAndroid Build Coastguard Worker 		// We may do this more than once for same table, but it's not a
1297*fd1fabb7SAndroid Build Coastguard Worker 		// big deal
1298*fd1fabb7SAndroid Build Coastguard Worker 
1299*fd1fabb7SAndroid Build Coastguard Worker 		FixHuffTbl (info.dcHuffTblPtrs [compptr->dcTblNo]);
1300*fd1fabb7SAndroid Build Coastguard Worker 
1301*fd1fabb7SAndroid Build Coastguard Worker 	    }
1302*fd1fabb7SAndroid Build Coastguard Worker 
1303*fd1fabb7SAndroid Build Coastguard Worker    	// Initialize restart stuff
1304*fd1fabb7SAndroid Build Coastguard Worker 
1305*fd1fabb7SAndroid Build Coastguard Worker 	info.restartInRows   = info.restartInterval / info.imageWidth;
1306*fd1fabb7SAndroid Build Coastguard Worker     info.restartRowsToGo = info.restartInRows;
1307*fd1fabb7SAndroid Build Coastguard Worker     info.nextRestartNum  = 0;
1308*fd1fabb7SAndroid Build Coastguard Worker 
1309*fd1fabb7SAndroid Build Coastguard Worker 	}
1310*fd1fabb7SAndroid Build Coastguard Worker 
1311*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
1312*fd1fabb7SAndroid Build Coastguard Worker 
1313*fd1fabb7SAndroid Build Coastguard Worker /*
1314*fd1fabb7SAndroid Build Coastguard Worker  *--------------------------------------------------------------
1315*fd1fabb7SAndroid Build Coastguard Worker  *
1316*fd1fabb7SAndroid Build Coastguard Worker  * ProcessRestart --
1317*fd1fabb7SAndroid Build Coastguard Worker  *
1318*fd1fabb7SAndroid Build Coastguard Worker  *	Check for a restart marker & resynchronize decoder.
1319*fd1fabb7SAndroid Build Coastguard Worker  *
1320*fd1fabb7SAndroid Build Coastguard Worker  * Results:
1321*fd1fabb7SAndroid Build Coastguard Worker  *	None.
1322*fd1fabb7SAndroid Build Coastguard Worker  *
1323*fd1fabb7SAndroid Build Coastguard Worker  * Side effects:
1324*fd1fabb7SAndroid Build Coastguard Worker  *	BitStream is parsed, bit buffer is reset, etc.
1325*fd1fabb7SAndroid Build Coastguard Worker  *
1326*fd1fabb7SAndroid Build Coastguard Worker  *--------------------------------------------------------------
1327*fd1fabb7SAndroid Build Coastguard Worker  */
1328*fd1fabb7SAndroid Build Coastguard Worker 
ProcessRestart()1329*fd1fabb7SAndroid Build Coastguard Worker void dng_lossless_decoder::ProcessRestart ()
1330*fd1fabb7SAndroid Build Coastguard Worker 	{
1331*fd1fabb7SAndroid Build Coastguard Worker 
1332*fd1fabb7SAndroid Build Coastguard Worker 	// Throw away and unused odd bits in the bit buffer.
1333*fd1fabb7SAndroid Build Coastguard Worker 
1334*fd1fabb7SAndroid Build Coastguard Worker 	fStream->SetReadPosition (fStream->Position () - bitsLeft / 8);
1335*fd1fabb7SAndroid Build Coastguard Worker 
1336*fd1fabb7SAndroid Build Coastguard Worker 	bitsLeft  = 0;
1337*fd1fabb7SAndroid Build Coastguard Worker 	getBuffer = 0;
1338*fd1fabb7SAndroid Build Coastguard Worker 
1339*fd1fabb7SAndroid Build Coastguard Worker    	// Scan for next JPEG marker
1340*fd1fabb7SAndroid Build Coastguard Worker 
1341*fd1fabb7SAndroid Build Coastguard Worker     int32 c;
1342*fd1fabb7SAndroid Build Coastguard Worker 
1343*fd1fabb7SAndroid Build Coastguard Worker     do
1344*fd1fabb7SAndroid Build Coastguard Worker     	{
1345*fd1fabb7SAndroid Build Coastguard Worker 
1346*fd1fabb7SAndroid Build Coastguard Worker 		// skip any non-FF bytes
1347*fd1fabb7SAndroid Build Coastguard Worker 
1348*fd1fabb7SAndroid Build Coastguard Worker 		do
1349*fd1fabb7SAndroid Build Coastguard Worker 			{
1350*fd1fabb7SAndroid Build Coastguard Worker 	    	c = GetJpegChar ();
1351*fd1fabb7SAndroid Build Coastguard Worker 			}
1352*fd1fabb7SAndroid Build Coastguard Worker 		while (c != 0xFF);
1353*fd1fabb7SAndroid Build Coastguard Worker 
1354*fd1fabb7SAndroid Build Coastguard Worker 		// skip any duplicate FFs
1355*fd1fabb7SAndroid Build Coastguard Worker 
1356*fd1fabb7SAndroid Build Coastguard Worker 		do
1357*fd1fabb7SAndroid Build Coastguard Worker 			{
1358*fd1fabb7SAndroid Build Coastguard Worker 			c = GetJpegChar ();
1359*fd1fabb7SAndroid Build Coastguard Worker 			}
1360*fd1fabb7SAndroid Build Coastguard Worker 		while (c == 0xFF);
1361*fd1fabb7SAndroid Build Coastguard Worker 
1362*fd1fabb7SAndroid Build Coastguard Worker     	}
1363*fd1fabb7SAndroid Build Coastguard Worker     while (c == 0);		// repeat if it was a stuffed FF/00
1364*fd1fabb7SAndroid Build Coastguard Worker 
1365*fd1fabb7SAndroid Build Coastguard Worker     // Verify correct restart code.
1366*fd1fabb7SAndroid Build Coastguard Worker 
1367*fd1fabb7SAndroid Build Coastguard Worker     if (c != (M_RST0 + info.nextRestartNum))
1368*fd1fabb7SAndroid Build Coastguard Worker     	{
1369*fd1fabb7SAndroid Build Coastguard Worker 		ThrowBadFormat ();
1370*fd1fabb7SAndroid Build Coastguard Worker     	}
1371*fd1fabb7SAndroid Build Coastguard Worker 
1372*fd1fabb7SAndroid Build Coastguard Worker     // Update restart state.
1373*fd1fabb7SAndroid Build Coastguard Worker 
1374*fd1fabb7SAndroid Build Coastguard Worker     info.restartRowsToGo = info.restartInRows;
1375*fd1fabb7SAndroid Build Coastguard Worker     info.nextRestartNum  = (info.nextRestartNum + 1) & 7;
1376*fd1fabb7SAndroid Build Coastguard Worker 
1377*fd1fabb7SAndroid Build Coastguard Worker 	}
1378*fd1fabb7SAndroid Build Coastguard Worker 
1379*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
1380*fd1fabb7SAndroid Build Coastguard Worker 
1381*fd1fabb7SAndroid Build Coastguard Worker /*
1382*fd1fabb7SAndroid Build Coastguard Worker  *--------------------------------------------------------------
1383*fd1fabb7SAndroid Build Coastguard Worker  *
1384*fd1fabb7SAndroid Build Coastguard Worker  * QuickPredict --
1385*fd1fabb7SAndroid Build Coastguard Worker  *
1386*fd1fabb7SAndroid Build Coastguard Worker  *      Calculate the predictor for sample curRowBuf[col][curComp].
1387*fd1fabb7SAndroid Build Coastguard Worker  *	It does not handle the special cases at image edges, such
1388*fd1fabb7SAndroid Build Coastguard Worker  *      as first row and first column of a scan. We put the special
1389*fd1fabb7SAndroid Build Coastguard Worker  *	case checkings outside so that the computations in main
1390*fd1fabb7SAndroid Build Coastguard Worker  *	loop can be simpler. This has enhenced the performance
1391*fd1fabb7SAndroid Build Coastguard Worker  *	significantly.
1392*fd1fabb7SAndroid Build Coastguard Worker  *
1393*fd1fabb7SAndroid Build Coastguard Worker  * Results:
1394*fd1fabb7SAndroid Build Coastguard Worker  *      predictor is passed out.
1395*fd1fabb7SAndroid Build Coastguard Worker  *
1396*fd1fabb7SAndroid Build Coastguard Worker  * Side effects:
1397*fd1fabb7SAndroid Build Coastguard Worker  *      None.
1398*fd1fabb7SAndroid Build Coastguard Worker  *
1399*fd1fabb7SAndroid Build Coastguard Worker  *--------------------------------------------------------------
1400*fd1fabb7SAndroid Build Coastguard Worker  */
1401*fd1fabb7SAndroid Build Coastguard Worker 
QuickPredict(int32 col,int32 curComp,MCU * curRowBuf,MCU * prevRowBuf)1402*fd1fabb7SAndroid Build Coastguard Worker inline int32 dng_lossless_decoder::QuickPredict (int32 col,
1403*fd1fabb7SAndroid Build Coastguard Worker 						 				         int32 curComp,
1404*fd1fabb7SAndroid Build Coastguard Worker 						 				         MCU *curRowBuf,
1405*fd1fabb7SAndroid Build Coastguard Worker 						 				         MCU *prevRowBuf)
1406*fd1fabb7SAndroid Build Coastguard Worker 	{
1407*fd1fabb7SAndroid Build Coastguard Worker 
1408*fd1fabb7SAndroid Build Coastguard Worker     int32 diag  = prevRowBuf [col - 1] [curComp];
1409*fd1fabb7SAndroid Build Coastguard Worker     int32 upper = prevRowBuf [col    ] [curComp];
1410*fd1fabb7SAndroid Build Coastguard Worker     int32 left  = curRowBuf  [col - 1] [curComp];
1411*fd1fabb7SAndroid Build Coastguard Worker 
1412*fd1fabb7SAndroid Build Coastguard Worker     switch (info.Ss)
1413*fd1fabb7SAndroid Build Coastguard Worker     	{
1414*fd1fabb7SAndroid Build Coastguard Worker 
1415*fd1fabb7SAndroid Build Coastguard Worker 		case 0:
1416*fd1fabb7SAndroid Build Coastguard Worker 			return 0;
1417*fd1fabb7SAndroid Build Coastguard Worker 
1418*fd1fabb7SAndroid Build Coastguard Worker 		case 1:
1419*fd1fabb7SAndroid Build Coastguard Worker 			return left;
1420*fd1fabb7SAndroid Build Coastguard Worker 
1421*fd1fabb7SAndroid Build Coastguard Worker 		case 2:
1422*fd1fabb7SAndroid Build Coastguard Worker 			return upper;
1423*fd1fabb7SAndroid Build Coastguard Worker 
1424*fd1fabb7SAndroid Build Coastguard Worker 		case 3:
1425*fd1fabb7SAndroid Build Coastguard Worker 			return diag;
1426*fd1fabb7SAndroid Build Coastguard Worker 
1427*fd1fabb7SAndroid Build Coastguard Worker 		case 4:
1428*fd1fabb7SAndroid Build Coastguard Worker 			return left + upper - diag;
1429*fd1fabb7SAndroid Build Coastguard Worker 
1430*fd1fabb7SAndroid Build Coastguard Worker 		case 5:
1431*fd1fabb7SAndroid Build Coastguard Worker 			return left + ((upper - diag) >> 1);
1432*fd1fabb7SAndroid Build Coastguard Worker 
1433*fd1fabb7SAndroid Build Coastguard Worker 		case 6:
1434*fd1fabb7SAndroid Build Coastguard Worker        		return upper + ((left - diag) >> 1);
1435*fd1fabb7SAndroid Build Coastguard Worker 
1436*fd1fabb7SAndroid Build Coastguard Worker 		case 7:
1437*fd1fabb7SAndroid Build Coastguard Worker             return (left + upper) >> 1;
1438*fd1fabb7SAndroid Build Coastguard Worker 
1439*fd1fabb7SAndroid Build Coastguard Worker 		default:
1440*fd1fabb7SAndroid Build Coastguard Worker 			{
1441*fd1fabb7SAndroid Build Coastguard Worker 			ThrowBadFormat ();
1442*fd1fabb7SAndroid Build Coastguard Worker             return 0;
1443*fd1fabb7SAndroid Build Coastguard Worker             }
1444*fd1fabb7SAndroid Build Coastguard Worker 
1445*fd1fabb7SAndroid Build Coastguard Worker      	}
1446*fd1fabb7SAndroid Build Coastguard Worker 
1447*fd1fabb7SAndroid Build Coastguard Worker 	}
1448*fd1fabb7SAndroid Build Coastguard Worker 
1449*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
1450*fd1fabb7SAndroid Build Coastguard Worker 
1451*fd1fabb7SAndroid Build Coastguard Worker /*
1452*fd1fabb7SAndroid Build Coastguard Worker  *--------------------------------------------------------------
1453*fd1fabb7SAndroid Build Coastguard Worker  *
1454*fd1fabb7SAndroid Build Coastguard Worker  * FillBitBuffer --
1455*fd1fabb7SAndroid Build Coastguard Worker  *
1456*fd1fabb7SAndroid Build Coastguard Worker  *	Load up the bit buffer with at least nbits
1457*fd1fabb7SAndroid Build Coastguard Worker  *	Process any stuffed bytes at this time.
1458*fd1fabb7SAndroid Build Coastguard Worker  *
1459*fd1fabb7SAndroid Build Coastguard Worker  * Results:
1460*fd1fabb7SAndroid Build Coastguard Worker  *	None
1461*fd1fabb7SAndroid Build Coastguard Worker  *
1462*fd1fabb7SAndroid Build Coastguard Worker  * Side effects:
1463*fd1fabb7SAndroid Build Coastguard Worker  *	The bitwise global variables are updated.
1464*fd1fabb7SAndroid Build Coastguard Worker  *
1465*fd1fabb7SAndroid Build Coastguard Worker  *--------------------------------------------------------------
1466*fd1fabb7SAndroid Build Coastguard Worker  */
1467*fd1fabb7SAndroid Build Coastguard Worker 
FillBitBuffer(int32 nbits)1468*fd1fabb7SAndroid Build Coastguard Worker inline void dng_lossless_decoder::FillBitBuffer (int32 nbits)
1469*fd1fabb7SAndroid Build Coastguard Worker 	{
1470*fd1fabb7SAndroid Build Coastguard Worker 
1471*fd1fabb7SAndroid Build Coastguard Worker 	const int32 kMinGetBits = sizeof (uint32) * 8 - 7;
1472*fd1fabb7SAndroid Build Coastguard Worker 
1473*fd1fabb7SAndroid Build Coastguard Worker 	#if qSupportHasselblad_3FR
1474*fd1fabb7SAndroid Build Coastguard Worker 
1475*fd1fabb7SAndroid Build Coastguard Worker 	if (fHasselblad3FR)
1476*fd1fabb7SAndroid Build Coastguard Worker 		{
1477*fd1fabb7SAndroid Build Coastguard Worker 
1478*fd1fabb7SAndroid Build Coastguard Worker 		while (bitsLeft < kMinGetBits)
1479*fd1fabb7SAndroid Build Coastguard Worker 			{
1480*fd1fabb7SAndroid Build Coastguard Worker 
1481*fd1fabb7SAndroid Build Coastguard Worker 			int32 c0 = GetJpegChar ();
1482*fd1fabb7SAndroid Build Coastguard Worker 			int32 c1 = GetJpegChar ();
1483*fd1fabb7SAndroid Build Coastguard Worker 			int32 c2 = GetJpegChar ();
1484*fd1fabb7SAndroid Build Coastguard Worker 			int32 c3 = GetJpegChar ();
1485*fd1fabb7SAndroid Build Coastguard Worker 
1486*fd1fabb7SAndroid Build Coastguard Worker 			getBuffer = (getBuffer << 8) | c3;
1487*fd1fabb7SAndroid Build Coastguard Worker 			getBuffer = (getBuffer << 8) | c2;
1488*fd1fabb7SAndroid Build Coastguard Worker 			getBuffer = (getBuffer << 8) | c1;
1489*fd1fabb7SAndroid Build Coastguard Worker 			getBuffer = (getBuffer << 8) | c0;
1490*fd1fabb7SAndroid Build Coastguard Worker 
1491*fd1fabb7SAndroid Build Coastguard Worker 			bitsLeft += 32;
1492*fd1fabb7SAndroid Build Coastguard Worker 
1493*fd1fabb7SAndroid Build Coastguard Worker 			}
1494*fd1fabb7SAndroid Build Coastguard Worker 
1495*fd1fabb7SAndroid Build Coastguard Worker 		return;
1496*fd1fabb7SAndroid Build Coastguard Worker 
1497*fd1fabb7SAndroid Build Coastguard Worker 		}
1498*fd1fabb7SAndroid Build Coastguard Worker 
1499*fd1fabb7SAndroid Build Coastguard Worker 	#endif
1500*fd1fabb7SAndroid Build Coastguard Worker 
1501*fd1fabb7SAndroid Build Coastguard Worker     while (bitsLeft < kMinGetBits)
1502*fd1fabb7SAndroid Build Coastguard Worker     	{
1503*fd1fabb7SAndroid Build Coastguard Worker 
1504*fd1fabb7SAndroid Build Coastguard Worker 		int32 c = GetJpegChar ();
1505*fd1fabb7SAndroid Build Coastguard Worker 
1506*fd1fabb7SAndroid Build Coastguard Worker 		// If it's 0xFF, check and discard stuffed zero byte
1507*fd1fabb7SAndroid Build Coastguard Worker 
1508*fd1fabb7SAndroid Build Coastguard Worker 		if (c == 0xFF)
1509*fd1fabb7SAndroid Build Coastguard Worker 			{
1510*fd1fabb7SAndroid Build Coastguard Worker 
1511*fd1fabb7SAndroid Build Coastguard Worker 			int32 c2 = GetJpegChar ();
1512*fd1fabb7SAndroid Build Coastguard Worker 
1513*fd1fabb7SAndroid Build Coastguard Worker 	    	if (c2 != 0)
1514*fd1fabb7SAndroid Build Coastguard Worker 	    		{
1515*fd1fabb7SAndroid Build Coastguard Worker 
1516*fd1fabb7SAndroid Build Coastguard Worker 				// Oops, it's actually a marker indicating end of
1517*fd1fabb7SAndroid Build Coastguard Worker 				// compressed data.  Better put it back for use later.
1518*fd1fabb7SAndroid Build Coastguard Worker 
1519*fd1fabb7SAndroid Build Coastguard Worker 				UnGetJpegChar ();
1520*fd1fabb7SAndroid Build Coastguard Worker 				UnGetJpegChar ();
1521*fd1fabb7SAndroid Build Coastguard Worker 
1522*fd1fabb7SAndroid Build Coastguard Worker 				// There should be enough bits still left in the data
1523*fd1fabb7SAndroid Build Coastguard Worker 				// segment; if so, just break out of the while loop.
1524*fd1fabb7SAndroid Build Coastguard Worker 
1525*fd1fabb7SAndroid Build Coastguard Worker 				if (bitsLeft >= nbits)
1526*fd1fabb7SAndroid Build Coastguard Worker 				    break;
1527*fd1fabb7SAndroid Build Coastguard Worker 
1528*fd1fabb7SAndroid Build Coastguard Worker 				// Uh-oh.  Corrupted data: stuff zeroes into the data
1529*fd1fabb7SAndroid Build Coastguard Worker 				// stream, since this sometimes occurs when we are on the
1530*fd1fabb7SAndroid Build Coastguard Worker 				// last show_bits8 during decoding of the Huffman
1531*fd1fabb7SAndroid Build Coastguard Worker 				// segment.
1532*fd1fabb7SAndroid Build Coastguard Worker 
1533*fd1fabb7SAndroid Build Coastguard Worker 				c = 0;
1534*fd1fabb7SAndroid Build Coastguard Worker 
1535*fd1fabb7SAndroid Build Coastguard Worker 	    		}
1536*fd1fabb7SAndroid Build Coastguard Worker 
1537*fd1fabb7SAndroid Build Coastguard Worker 			}
1538*fd1fabb7SAndroid Build Coastguard Worker 
1539*fd1fabb7SAndroid Build Coastguard Worker 		getBuffer = (getBuffer << 8) | c;
1540*fd1fabb7SAndroid Build Coastguard Worker 
1541*fd1fabb7SAndroid Build Coastguard Worker 		bitsLeft += 8;
1542*fd1fabb7SAndroid Build Coastguard Worker 
1543*fd1fabb7SAndroid Build Coastguard Worker    		}
1544*fd1fabb7SAndroid Build Coastguard Worker 
1545*fd1fabb7SAndroid Build Coastguard Worker 	}
1546*fd1fabb7SAndroid Build Coastguard Worker 
1547*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
1548*fd1fabb7SAndroid Build Coastguard Worker 
show_bits8()1549*fd1fabb7SAndroid Build Coastguard Worker inline int32 dng_lossless_decoder::show_bits8 ()
1550*fd1fabb7SAndroid Build Coastguard Worker 	{
1551*fd1fabb7SAndroid Build Coastguard Worker 
1552*fd1fabb7SAndroid Build Coastguard Worker 	if (bitsLeft < 8)
1553*fd1fabb7SAndroid Build Coastguard Worker 		FillBitBuffer (8);
1554*fd1fabb7SAndroid Build Coastguard Worker 
1555*fd1fabb7SAndroid Build Coastguard Worker 	return (int32) ((getBuffer >> (bitsLeft - 8)) & 0xff);
1556*fd1fabb7SAndroid Build Coastguard Worker 
1557*fd1fabb7SAndroid Build Coastguard Worker 	}
1558*fd1fabb7SAndroid Build Coastguard Worker 
1559*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
1560*fd1fabb7SAndroid Build Coastguard Worker 
flush_bits(int32 nbits)1561*fd1fabb7SAndroid Build Coastguard Worker inline void dng_lossless_decoder::flush_bits (int32 nbits)
1562*fd1fabb7SAndroid Build Coastguard Worker 	{
1563*fd1fabb7SAndroid Build Coastguard Worker 
1564*fd1fabb7SAndroid Build Coastguard Worker 	bitsLeft -= nbits;
1565*fd1fabb7SAndroid Build Coastguard Worker 
1566*fd1fabb7SAndroid Build Coastguard Worker 	}
1567*fd1fabb7SAndroid Build Coastguard Worker 
1568*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
1569*fd1fabb7SAndroid Build Coastguard Worker 
get_bits(int32 nbits)1570*fd1fabb7SAndroid Build Coastguard Worker inline int32 dng_lossless_decoder::get_bits (int32 nbits)
1571*fd1fabb7SAndroid Build Coastguard Worker 	{
1572*fd1fabb7SAndroid Build Coastguard Worker 
1573*fd1fabb7SAndroid Build Coastguard Worker 	if (nbits > 16)
1574*fd1fabb7SAndroid Build Coastguard Worker 		{
1575*fd1fabb7SAndroid Build Coastguard Worker 		ThrowBadFormat ();
1576*fd1fabb7SAndroid Build Coastguard Worker 		}
1577*fd1fabb7SAndroid Build Coastguard Worker 
1578*fd1fabb7SAndroid Build Coastguard Worker 	if (bitsLeft < nbits)
1579*fd1fabb7SAndroid Build Coastguard Worker 		FillBitBuffer (nbits);
1580*fd1fabb7SAndroid Build Coastguard Worker 
1581*fd1fabb7SAndroid Build Coastguard Worker 	return (int32) ((getBuffer >> (bitsLeft -= nbits)) & (0x0FFFF >> (16 - nbits)));
1582*fd1fabb7SAndroid Build Coastguard Worker 
1583*fd1fabb7SAndroid Build Coastguard Worker 	}
1584*fd1fabb7SAndroid Build Coastguard Worker 
1585*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
1586*fd1fabb7SAndroid Build Coastguard Worker 
get_bit()1587*fd1fabb7SAndroid Build Coastguard Worker inline int32 dng_lossless_decoder::get_bit ()
1588*fd1fabb7SAndroid Build Coastguard Worker 	{
1589*fd1fabb7SAndroid Build Coastguard Worker 
1590*fd1fabb7SAndroid Build Coastguard Worker 	if (!bitsLeft)
1591*fd1fabb7SAndroid Build Coastguard Worker 		FillBitBuffer (1);
1592*fd1fabb7SAndroid Build Coastguard Worker 
1593*fd1fabb7SAndroid Build Coastguard Worker 	return (int32) ((getBuffer >> (--bitsLeft)) & 1);
1594*fd1fabb7SAndroid Build Coastguard Worker 
1595*fd1fabb7SAndroid Build Coastguard Worker 	}
1596*fd1fabb7SAndroid Build Coastguard Worker 
1597*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
1598*fd1fabb7SAndroid Build Coastguard Worker 
1599*fd1fabb7SAndroid Build Coastguard Worker /*
1600*fd1fabb7SAndroid Build Coastguard Worker  *--------------------------------------------------------------
1601*fd1fabb7SAndroid Build Coastguard Worker  *
1602*fd1fabb7SAndroid Build Coastguard Worker  * HuffDecode --
1603*fd1fabb7SAndroid Build Coastguard Worker  *
1604*fd1fabb7SAndroid Build Coastguard Worker  *	Taken from Figure F.16: extract next coded symbol from
1605*fd1fabb7SAndroid Build Coastguard Worker  *	input stream.  This should becode a macro.
1606*fd1fabb7SAndroid Build Coastguard Worker  *
1607*fd1fabb7SAndroid Build Coastguard Worker  * Results:
1608*fd1fabb7SAndroid Build Coastguard Worker  *	Next coded symbol
1609*fd1fabb7SAndroid Build Coastguard Worker  *
1610*fd1fabb7SAndroid Build Coastguard Worker  * Side effects:
1611*fd1fabb7SAndroid Build Coastguard Worker  *	Bitstream is parsed.
1612*fd1fabb7SAndroid Build Coastguard Worker  *
1613*fd1fabb7SAndroid Build Coastguard Worker  *--------------------------------------------------------------
1614*fd1fabb7SAndroid Build Coastguard Worker  */
1615*fd1fabb7SAndroid Build Coastguard Worker 
HuffDecode(HuffmanTable * htbl)1616*fd1fabb7SAndroid Build Coastguard Worker inline int32 dng_lossless_decoder::HuffDecode (HuffmanTable *htbl)
1617*fd1fabb7SAndroid Build Coastguard Worker 	{
1618*fd1fabb7SAndroid Build Coastguard Worker 
1619*fd1fabb7SAndroid Build Coastguard Worker 	if (htbl == nullptr) {
1620*fd1fabb7SAndroid Build Coastguard Worker 		ThrowBadFormat ();
1621*fd1fabb7SAndroid Build Coastguard Worker 	}
1622*fd1fabb7SAndroid Build Coastguard Worker 
1623*fd1fabb7SAndroid Build Coastguard Worker     // If the huffman code is less than 8 bits, we can use the fast
1624*fd1fabb7SAndroid Build Coastguard Worker     // table lookup to get its value.  It's more than 8 bits about
1625*fd1fabb7SAndroid Build Coastguard Worker     // 3-4% of the time.
1626*fd1fabb7SAndroid Build Coastguard Worker 
1627*fd1fabb7SAndroid Build Coastguard Worker     int32 code = show_bits8 ();
1628*fd1fabb7SAndroid Build Coastguard Worker 
1629*fd1fabb7SAndroid Build Coastguard Worker     if (htbl->numbits [code])
1630*fd1fabb7SAndroid Build Coastguard Worker     	{
1631*fd1fabb7SAndroid Build Coastguard Worker 
1632*fd1fabb7SAndroid Build Coastguard Worker 		flush_bits (htbl->numbits [code]);
1633*fd1fabb7SAndroid Build Coastguard Worker 
1634*fd1fabb7SAndroid Build Coastguard Worker 		return htbl->value [code];
1635*fd1fabb7SAndroid Build Coastguard Worker 
1636*fd1fabb7SAndroid Build Coastguard Worker     	}
1637*fd1fabb7SAndroid Build Coastguard Worker 
1638*fd1fabb7SAndroid Build Coastguard Worker     else
1639*fd1fabb7SAndroid Build Coastguard Worker     	{
1640*fd1fabb7SAndroid Build Coastguard Worker 
1641*fd1fabb7SAndroid Build Coastguard Worker 		flush_bits (8);
1642*fd1fabb7SAndroid Build Coastguard Worker 
1643*fd1fabb7SAndroid Build Coastguard Worker 		int32 l = 8;
1644*fd1fabb7SAndroid Build Coastguard Worker 
1645*fd1fabb7SAndroid Build Coastguard Worker 		while (code > htbl->maxcode [l])
1646*fd1fabb7SAndroid Build Coastguard Worker 			{
1647*fd1fabb7SAndroid Build Coastguard Worker 	    	code = (code << 1) | get_bit ();
1648*fd1fabb7SAndroid Build Coastguard Worker 	    	l++;
1649*fd1fabb7SAndroid Build Coastguard Worker 			}
1650*fd1fabb7SAndroid Build Coastguard Worker 
1651*fd1fabb7SAndroid Build Coastguard Worker 		// With garbage input we may reach the sentinel value l = 17.
1652*fd1fabb7SAndroid Build Coastguard Worker 
1653*fd1fabb7SAndroid Build Coastguard Worker 		if (l > 16)
1654*fd1fabb7SAndroid Build Coastguard Worker 			{
1655*fd1fabb7SAndroid Build Coastguard Worker 	    	return 0;		// fake a zero as the safest result
1656*fd1fabb7SAndroid Build Coastguard Worker 			}
1657*fd1fabb7SAndroid Build Coastguard Worker 		else
1658*fd1fabb7SAndroid Build Coastguard Worker 			{
1659*fd1fabb7SAndroid Build Coastguard Worker 	    	return htbl->huffval [htbl->valptr [l] +
1660*fd1fabb7SAndroid Build Coastguard Worker 	    						  ((int32) (code - htbl->mincode [l]))];
1661*fd1fabb7SAndroid Build Coastguard Worker 			}
1662*fd1fabb7SAndroid Build Coastguard Worker 
1663*fd1fabb7SAndroid Build Coastguard Worker    		}
1664*fd1fabb7SAndroid Build Coastguard Worker 
1665*fd1fabb7SAndroid Build Coastguard Worker 	}
1666*fd1fabb7SAndroid Build Coastguard Worker 
1667*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
1668*fd1fabb7SAndroid Build Coastguard Worker 
1669*fd1fabb7SAndroid Build Coastguard Worker /*
1670*fd1fabb7SAndroid Build Coastguard Worker  *--------------------------------------------------------------
1671*fd1fabb7SAndroid Build Coastguard Worker  *
1672*fd1fabb7SAndroid Build Coastguard Worker  * HuffExtend --
1673*fd1fabb7SAndroid Build Coastguard Worker  *
1674*fd1fabb7SAndroid Build Coastguard Worker  *	Code and table for Figure F.12: extend sign bit
1675*fd1fabb7SAndroid Build Coastguard Worker  *
1676*fd1fabb7SAndroid Build Coastguard Worker  * Results:
1677*fd1fabb7SAndroid Build Coastguard Worker  *	The extended value.
1678*fd1fabb7SAndroid Build Coastguard Worker  *
1679*fd1fabb7SAndroid Build Coastguard Worker  * Side effects:
1680*fd1fabb7SAndroid Build Coastguard Worker  *	None.
1681*fd1fabb7SAndroid Build Coastguard Worker  *
1682*fd1fabb7SAndroid Build Coastguard Worker  *--------------------------------------------------------------
1683*fd1fabb7SAndroid Build Coastguard Worker  */
1684*fd1fabb7SAndroid Build Coastguard Worker 
HuffExtend(int32 & x,int32 s)1685*fd1fabb7SAndroid Build Coastguard Worker inline void dng_lossless_decoder::HuffExtend (int32 &x, int32 s)
1686*fd1fabb7SAndroid Build Coastguard Worker 	{
1687*fd1fabb7SAndroid Build Coastguard Worker 
1688*fd1fabb7SAndroid Build Coastguard Worker 	if (x < (0x08000 >> (16 - s)))
1689*fd1fabb7SAndroid Build Coastguard Worker 		{
1690*fd1fabb7SAndroid Build Coastguard Worker 		x += -(1 << s) + 1;
1691*fd1fabb7SAndroid Build Coastguard Worker 		}
1692*fd1fabb7SAndroid Build Coastguard Worker 
1693*fd1fabb7SAndroid Build Coastguard Worker 	}
1694*fd1fabb7SAndroid Build Coastguard Worker 
1695*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
1696*fd1fabb7SAndroid Build Coastguard Worker 
1697*fd1fabb7SAndroid Build Coastguard Worker // Called from DecodeImage () to write one row.
1698*fd1fabb7SAndroid Build Coastguard Worker 
PmPutRow(MCU * buf,int32 numComp,int32 numCol,int32)1699*fd1fabb7SAndroid Build Coastguard Worker void dng_lossless_decoder::PmPutRow (MCU *buf,
1700*fd1fabb7SAndroid Build Coastguard Worker 								     int32 numComp,
1701*fd1fabb7SAndroid Build Coastguard Worker 								     int32 numCol,
1702*fd1fabb7SAndroid Build Coastguard Worker 								     int32 /* row */)
1703*fd1fabb7SAndroid Build Coastguard Worker 	{
1704*fd1fabb7SAndroid Build Coastguard Worker 
1705*fd1fabb7SAndroid Build Coastguard Worker 	uint16 *sPtr = &buf [0] [0];
1706*fd1fabb7SAndroid Build Coastguard Worker 
1707*fd1fabb7SAndroid Build Coastguard Worker 	uint32 pixels = numCol * numComp;
1708*fd1fabb7SAndroid Build Coastguard Worker 
1709*fd1fabb7SAndroid Build Coastguard Worker 	fSpooler->Spool (sPtr, pixels * (uint32) sizeof (uint16));
1710*fd1fabb7SAndroid Build Coastguard Worker 
1711*fd1fabb7SAndroid Build Coastguard Worker 	}
1712*fd1fabb7SAndroid Build Coastguard Worker 
1713*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
1714*fd1fabb7SAndroid Build Coastguard Worker 
1715*fd1fabb7SAndroid Build Coastguard Worker /*
1716*fd1fabb7SAndroid Build Coastguard Worker  *--------------------------------------------------------------
1717*fd1fabb7SAndroid Build Coastguard Worker  *
1718*fd1fabb7SAndroid Build Coastguard Worker  * DecodeFirstRow --
1719*fd1fabb7SAndroid Build Coastguard Worker  *
1720*fd1fabb7SAndroid Build Coastguard Worker  *	Decode the first raster line of samples at the start of
1721*fd1fabb7SAndroid Build Coastguard Worker  *      the scan and at the beginning of each restart interval.
1722*fd1fabb7SAndroid Build Coastguard Worker  *	This includes modifying the component value so the real
1723*fd1fabb7SAndroid Build Coastguard Worker  *      value, not the difference is returned.
1724*fd1fabb7SAndroid Build Coastguard Worker  *
1725*fd1fabb7SAndroid Build Coastguard Worker  * Results:
1726*fd1fabb7SAndroid Build Coastguard Worker  *	None.
1727*fd1fabb7SAndroid Build Coastguard Worker  *
1728*fd1fabb7SAndroid Build Coastguard Worker  * Side effects:
1729*fd1fabb7SAndroid Build Coastguard Worker  *	Bitstream is parsed.
1730*fd1fabb7SAndroid Build Coastguard Worker  *
1731*fd1fabb7SAndroid Build Coastguard Worker  *--------------------------------------------------------------
1732*fd1fabb7SAndroid Build Coastguard Worker  */
1733*fd1fabb7SAndroid Build Coastguard Worker 
DecodeFirstRow(MCU * curRowBuf)1734*fd1fabb7SAndroid Build Coastguard Worker void dng_lossless_decoder::DecodeFirstRow (MCU *curRowBuf)
1735*fd1fabb7SAndroid Build Coastguard Worker 	{
1736*fd1fabb7SAndroid Build Coastguard Worker 
1737*fd1fabb7SAndroid Build Coastguard Worker     int32 compsInScan = info.compsInScan;
1738*fd1fabb7SAndroid Build Coastguard Worker 
1739*fd1fabb7SAndroid Build Coastguard Worker     // Process the first column in the row.
1740*fd1fabb7SAndroid Build Coastguard Worker 
1741*fd1fabb7SAndroid Build Coastguard Worker     for (int32 curComp = 0; curComp < compsInScan; curComp++)
1742*fd1fabb7SAndroid Build Coastguard Worker     	{
1743*fd1fabb7SAndroid Build Coastguard Worker 
1744*fd1fabb7SAndroid Build Coastguard Worker         int32 ci = info.MCUmembership [curComp];
1745*fd1fabb7SAndroid Build Coastguard Worker 
1746*fd1fabb7SAndroid Build Coastguard Worker         JpegComponentInfo *compptr = info.curCompInfo [ci];
1747*fd1fabb7SAndroid Build Coastguard Worker 
1748*fd1fabb7SAndroid Build Coastguard Worker         HuffmanTable *dctbl = info.dcHuffTblPtrs [compptr->dcTblNo];
1749*fd1fabb7SAndroid Build Coastguard Worker 
1750*fd1fabb7SAndroid Build Coastguard Worker         // Section F.2.2.1: decode the difference
1751*fd1fabb7SAndroid Build Coastguard Worker 
1752*fd1fabb7SAndroid Build Coastguard Worker   		int32 d = 0;
1753*fd1fabb7SAndroid Build Coastguard Worker 
1754*fd1fabb7SAndroid Build Coastguard Worker         int32 s = HuffDecode (dctbl);
1755*fd1fabb7SAndroid Build Coastguard Worker 
1756*fd1fabb7SAndroid Build Coastguard Worker       	if (s)
1757*fd1fabb7SAndroid Build Coastguard Worker       		{
1758*fd1fabb7SAndroid Build Coastguard Worker 
1759*fd1fabb7SAndroid Build Coastguard Worker       		if (s == 16 && !fBug16)
1760*fd1fabb7SAndroid Build Coastguard Worker       			{
1761*fd1fabb7SAndroid Build Coastguard Worker       			d = -32768;
1762*fd1fabb7SAndroid Build Coastguard Worker       			}
1763*fd1fabb7SAndroid Build Coastguard Worker 
1764*fd1fabb7SAndroid Build Coastguard Worker       		else
1765*fd1fabb7SAndroid Build Coastguard Worker       			{
1766*fd1fabb7SAndroid Build Coastguard Worker 				d = get_bits (s);
1767*fd1fabb7SAndroid Build Coastguard Worker             	HuffExtend (d, s);
1768*fd1fabb7SAndroid Build Coastguard Worker             	}
1769*fd1fabb7SAndroid Build Coastguard Worker 
1770*fd1fabb7SAndroid Build Coastguard Worker             }
1771*fd1fabb7SAndroid Build Coastguard Worker 
1772*fd1fabb7SAndroid Build Coastguard Worker 		// Add the predictor to the difference.
1773*fd1fabb7SAndroid Build Coastguard Worker 
1774*fd1fabb7SAndroid Build Coastguard Worker 	    int32 Pr = info.dataPrecision;
1775*fd1fabb7SAndroid Build Coastguard Worker 	    int32 Pt = info.Pt;
1776*fd1fabb7SAndroid Build Coastguard Worker 
1777*fd1fabb7SAndroid Build Coastguard Worker         curRowBuf [0] [curComp] = (ComponentType) (d + (1 << (Pr-Pt-1)));
1778*fd1fabb7SAndroid Build Coastguard Worker 
1779*fd1fabb7SAndroid Build Coastguard Worker     	}
1780*fd1fabb7SAndroid Build Coastguard Worker 
1781*fd1fabb7SAndroid Build Coastguard Worker     // Process the rest of the row.
1782*fd1fabb7SAndroid Build Coastguard Worker 
1783*fd1fabb7SAndroid Build Coastguard Worker     int32 numCOL = info.imageWidth;
1784*fd1fabb7SAndroid Build Coastguard Worker 
1785*fd1fabb7SAndroid Build Coastguard Worker     for (int32 col = 1; col < numCOL; col++)
1786*fd1fabb7SAndroid Build Coastguard Worker     	{
1787*fd1fabb7SAndroid Build Coastguard Worker 
1788*fd1fabb7SAndroid Build Coastguard Worker         for (int32 curComp = 0; curComp < compsInScan; curComp++)
1789*fd1fabb7SAndroid Build Coastguard Worker         	{
1790*fd1fabb7SAndroid Build Coastguard Worker 
1791*fd1fabb7SAndroid Build Coastguard Worker             int32 ci = info.MCUmembership [curComp];
1792*fd1fabb7SAndroid Build Coastguard Worker 
1793*fd1fabb7SAndroid Build Coastguard Worker             JpegComponentInfo *compptr = info.curCompInfo [ci];
1794*fd1fabb7SAndroid Build Coastguard Worker 
1795*fd1fabb7SAndroid Build Coastguard Worker             HuffmanTable *dctbl = info.dcHuffTblPtrs [compptr->dcTblNo];
1796*fd1fabb7SAndroid Build Coastguard Worker 
1797*fd1fabb7SAndroid Build Coastguard Worker 			// Section F.2.2.1: decode the difference
1798*fd1fabb7SAndroid Build Coastguard Worker 
1799*fd1fabb7SAndroid Build Coastguard Worker 	  		int32 d = 0;
1800*fd1fabb7SAndroid Build Coastguard Worker 
1801*fd1fabb7SAndroid Build Coastguard Worker 	        int32 s = HuffDecode (dctbl);
1802*fd1fabb7SAndroid Build Coastguard Worker 
1803*fd1fabb7SAndroid Build Coastguard Worker 	      	if (s)
1804*fd1fabb7SAndroid Build Coastguard Worker 	      		{
1805*fd1fabb7SAndroid Build Coastguard Worker 
1806*fd1fabb7SAndroid Build Coastguard Worker 	      		if (s == 16 && !fBug16)
1807*fd1fabb7SAndroid Build Coastguard Worker 	      			{
1808*fd1fabb7SAndroid Build Coastguard Worker 	      			d = -32768;
1809*fd1fabb7SAndroid Build Coastguard Worker 	      			}
1810*fd1fabb7SAndroid Build Coastguard Worker 
1811*fd1fabb7SAndroid Build Coastguard Worker 	      		else
1812*fd1fabb7SAndroid Build Coastguard Worker 	      			{
1813*fd1fabb7SAndroid Build Coastguard Worker 					d = get_bits (s);
1814*fd1fabb7SAndroid Build Coastguard Worker 	            	HuffExtend (d, s);
1815*fd1fabb7SAndroid Build Coastguard Worker 	            	}
1816*fd1fabb7SAndroid Build Coastguard Worker 
1817*fd1fabb7SAndroid Build Coastguard Worker 	            }
1818*fd1fabb7SAndroid Build Coastguard Worker 
1819*fd1fabb7SAndroid Build Coastguard Worker 			// Add the predictor to the difference.
1820*fd1fabb7SAndroid Build Coastguard Worker 
1821*fd1fabb7SAndroid Build Coastguard Worker             curRowBuf [col] [curComp] = (ComponentType) (d + curRowBuf [col-1] [curComp]);
1822*fd1fabb7SAndroid Build Coastguard Worker 
1823*fd1fabb7SAndroid Build Coastguard Worker        		}
1824*fd1fabb7SAndroid Build Coastguard Worker 
1825*fd1fabb7SAndroid Build Coastguard Worker     	}
1826*fd1fabb7SAndroid Build Coastguard Worker 
1827*fd1fabb7SAndroid Build Coastguard Worker     // Update the restart counter
1828*fd1fabb7SAndroid Build Coastguard Worker 
1829*fd1fabb7SAndroid Build Coastguard Worker     if (info.restartInRows)
1830*fd1fabb7SAndroid Build Coastguard Worker     	{
1831*fd1fabb7SAndroid Build Coastguard Worker        	info.restartRowsToGo--;
1832*fd1fabb7SAndroid Build Coastguard Worker     	}
1833*fd1fabb7SAndroid Build Coastguard Worker 
1834*fd1fabb7SAndroid Build Coastguard Worker 	}
1835*fd1fabb7SAndroid Build Coastguard Worker 
1836*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
1837*fd1fabb7SAndroid Build Coastguard Worker 
1838*fd1fabb7SAndroid Build Coastguard Worker /*
1839*fd1fabb7SAndroid Build Coastguard Worker  *--------------------------------------------------------------
1840*fd1fabb7SAndroid Build Coastguard Worker  *
1841*fd1fabb7SAndroid Build Coastguard Worker  * DecodeImage --
1842*fd1fabb7SAndroid Build Coastguard Worker  *
1843*fd1fabb7SAndroid Build Coastguard Worker  *      Decode the input stream. This includes modifying
1844*fd1fabb7SAndroid Build Coastguard Worker  *      the component value so the real value, not the
1845*fd1fabb7SAndroid Build Coastguard Worker  *      difference is returned.
1846*fd1fabb7SAndroid Build Coastguard Worker  *
1847*fd1fabb7SAndroid Build Coastguard Worker  * Results:
1848*fd1fabb7SAndroid Build Coastguard Worker  *      None.
1849*fd1fabb7SAndroid Build Coastguard Worker  *
1850*fd1fabb7SAndroid Build Coastguard Worker  * Side effects:
1851*fd1fabb7SAndroid Build Coastguard Worker  *      Bitstream is parsed.
1852*fd1fabb7SAndroid Build Coastguard Worker  *
1853*fd1fabb7SAndroid Build Coastguard Worker  *--------------------------------------------------------------
1854*fd1fabb7SAndroid Build Coastguard Worker  */
1855*fd1fabb7SAndroid Build Coastguard Worker 
DecodeImage()1856*fd1fabb7SAndroid Build Coastguard Worker void dng_lossless_decoder::DecodeImage ()
1857*fd1fabb7SAndroid Build Coastguard Worker 	{
1858*fd1fabb7SAndroid Build Coastguard Worker 
1859*fd1fabb7SAndroid Build Coastguard Worker 	#define swap(type,a,b) {type c; c=(a); (a)=(b); (b)=c;}
1860*fd1fabb7SAndroid Build Coastguard Worker 
1861*fd1fabb7SAndroid Build Coastguard Worker     int32 numCOL      = info.imageWidth;
1862*fd1fabb7SAndroid Build Coastguard Worker     int32 numROW	  = info.imageHeight;
1863*fd1fabb7SAndroid Build Coastguard Worker     int32 compsInScan = info.compsInScan;
1864*fd1fabb7SAndroid Build Coastguard Worker 
1865*fd1fabb7SAndroid Build Coastguard Worker     // Precompute the decoding table for each table.
1866*fd1fabb7SAndroid Build Coastguard Worker 
1867*fd1fabb7SAndroid Build Coastguard Worker     HuffmanTable *ht [4];
1868*fd1fabb7SAndroid Build Coastguard Worker 
1869*fd1fabb7SAndroid Build Coastguard Worker 	for (int32 curComp = 0; curComp < compsInScan; curComp++)
1870*fd1fabb7SAndroid Build Coastguard Worker     	{
1871*fd1fabb7SAndroid Build Coastguard Worker 
1872*fd1fabb7SAndroid Build Coastguard Worker         int32 ci = info.MCUmembership [curComp];
1873*fd1fabb7SAndroid Build Coastguard Worker 
1874*fd1fabb7SAndroid Build Coastguard Worker         JpegComponentInfo *compptr = info.curCompInfo [ci];
1875*fd1fabb7SAndroid Build Coastguard Worker 
1876*fd1fabb7SAndroid Build Coastguard Worker         ht [curComp] = info.dcHuffTblPtrs [compptr->dcTblNo];
1877*fd1fabb7SAndroid Build Coastguard Worker 
1878*fd1fabb7SAndroid Build Coastguard Worker    		}
1879*fd1fabb7SAndroid Build Coastguard Worker 
1880*fd1fabb7SAndroid Build Coastguard Worker 	MCU *prevRowBuf = mcuROW1;
1881*fd1fabb7SAndroid Build Coastguard Worker 	MCU *curRowBuf  = mcuROW2;
1882*fd1fabb7SAndroid Build Coastguard Worker 
1883*fd1fabb7SAndroid Build Coastguard Worker 	#if qSupportCanon_sRAW
1884*fd1fabb7SAndroid Build Coastguard Worker 
1885*fd1fabb7SAndroid Build Coastguard Worker 	// Canon sRAW support
1886*fd1fabb7SAndroid Build Coastguard Worker 
1887*fd1fabb7SAndroid Build Coastguard Worker 	if (info.compInfo [0].hSampFactor == 2 &&
1888*fd1fabb7SAndroid Build Coastguard Worker 		info.compInfo [0].vSampFactor == 1)
1889*fd1fabb7SAndroid Build Coastguard Worker 		{
1890*fd1fabb7SAndroid Build Coastguard Worker 
1891*fd1fabb7SAndroid Build Coastguard Worker 		for (int32 row = 0; row < numROW; row++)
1892*fd1fabb7SAndroid Build Coastguard Worker 			{
1893*fd1fabb7SAndroid Build Coastguard Worker 
1894*fd1fabb7SAndroid Build Coastguard Worker 			// Initialize predictors.
1895*fd1fabb7SAndroid Build Coastguard Worker 
1896*fd1fabb7SAndroid Build Coastguard Worker 			int32 p0;
1897*fd1fabb7SAndroid Build Coastguard Worker 			int32 p1;
1898*fd1fabb7SAndroid Build Coastguard Worker 			int32 p2;
1899*fd1fabb7SAndroid Build Coastguard Worker 
1900*fd1fabb7SAndroid Build Coastguard Worker 			if (row == 0)
1901*fd1fabb7SAndroid Build Coastguard Worker 				{
1902*fd1fabb7SAndroid Build Coastguard Worker 				p0 = 1 << 14;
1903*fd1fabb7SAndroid Build Coastguard Worker 				p1 = 1 << 14;
1904*fd1fabb7SAndroid Build Coastguard Worker 				p2 = 1 << 14;
1905*fd1fabb7SAndroid Build Coastguard Worker 				}
1906*fd1fabb7SAndroid Build Coastguard Worker 
1907*fd1fabb7SAndroid Build Coastguard Worker 			else
1908*fd1fabb7SAndroid Build Coastguard Worker 				{
1909*fd1fabb7SAndroid Build Coastguard Worker 				p0 = prevRowBuf [0] [0];
1910*fd1fabb7SAndroid Build Coastguard Worker 				p1 = prevRowBuf [0] [1];
1911*fd1fabb7SAndroid Build Coastguard Worker 				p2 = prevRowBuf [0] [2];
1912*fd1fabb7SAndroid Build Coastguard Worker 				}
1913*fd1fabb7SAndroid Build Coastguard Worker 
1914*fd1fabb7SAndroid Build Coastguard Worker 			for (int32 col = 0; col < numCOL; col += 2)
1915*fd1fabb7SAndroid Build Coastguard Worker 				{
1916*fd1fabb7SAndroid Build Coastguard Worker 
1917*fd1fabb7SAndroid Build Coastguard Worker 				// Read first luminance component.
1918*fd1fabb7SAndroid Build Coastguard Worker 
1919*fd1fabb7SAndroid Build Coastguard Worker 					{
1920*fd1fabb7SAndroid Build Coastguard Worker 
1921*fd1fabb7SAndroid Build Coastguard Worker 					int32 d = 0;
1922*fd1fabb7SAndroid Build Coastguard Worker 
1923*fd1fabb7SAndroid Build Coastguard Worker 					int32 s = HuffDecode (ht [0]);
1924*fd1fabb7SAndroid Build Coastguard Worker 
1925*fd1fabb7SAndroid Build Coastguard Worker 					if (s)
1926*fd1fabb7SAndroid Build Coastguard Worker 						{
1927*fd1fabb7SAndroid Build Coastguard Worker 
1928*fd1fabb7SAndroid Build Coastguard Worker 						if (s == 16)
1929*fd1fabb7SAndroid Build Coastguard Worker 							{
1930*fd1fabb7SAndroid Build Coastguard Worker 							d = -32768;
1931*fd1fabb7SAndroid Build Coastguard Worker 							}
1932*fd1fabb7SAndroid Build Coastguard Worker 
1933*fd1fabb7SAndroid Build Coastguard Worker 						else
1934*fd1fabb7SAndroid Build Coastguard Worker 							{
1935*fd1fabb7SAndroid Build Coastguard Worker 							d = get_bits (s);
1936*fd1fabb7SAndroid Build Coastguard Worker 							HuffExtend (d, s);
1937*fd1fabb7SAndroid Build Coastguard Worker 							}
1938*fd1fabb7SAndroid Build Coastguard Worker 
1939*fd1fabb7SAndroid Build Coastguard Worker 						}
1940*fd1fabb7SAndroid Build Coastguard Worker 
1941*fd1fabb7SAndroid Build Coastguard Worker 					p0 += d;
1942*fd1fabb7SAndroid Build Coastguard Worker 
1943*fd1fabb7SAndroid Build Coastguard Worker 					curRowBuf [col] [0] = (ComponentType) p0;
1944*fd1fabb7SAndroid Build Coastguard Worker 
1945*fd1fabb7SAndroid Build Coastguard Worker 					}
1946*fd1fabb7SAndroid Build Coastguard Worker 
1947*fd1fabb7SAndroid Build Coastguard Worker 				// Read second luminance component.
1948*fd1fabb7SAndroid Build Coastguard Worker 
1949*fd1fabb7SAndroid Build Coastguard Worker 					{
1950*fd1fabb7SAndroid Build Coastguard Worker 
1951*fd1fabb7SAndroid Build Coastguard Worker 					int32 d = 0;
1952*fd1fabb7SAndroid Build Coastguard Worker 
1953*fd1fabb7SAndroid Build Coastguard Worker 					int32 s = HuffDecode (ht [0]);
1954*fd1fabb7SAndroid Build Coastguard Worker 
1955*fd1fabb7SAndroid Build Coastguard Worker 					if (s)
1956*fd1fabb7SAndroid Build Coastguard Worker 						{
1957*fd1fabb7SAndroid Build Coastguard Worker 
1958*fd1fabb7SAndroid Build Coastguard Worker 						if (s == 16)
1959*fd1fabb7SAndroid Build Coastguard Worker 							{
1960*fd1fabb7SAndroid Build Coastguard Worker 							d = -32768;
1961*fd1fabb7SAndroid Build Coastguard Worker 							}
1962*fd1fabb7SAndroid Build Coastguard Worker 
1963*fd1fabb7SAndroid Build Coastguard Worker 						else
1964*fd1fabb7SAndroid Build Coastguard Worker 							{
1965*fd1fabb7SAndroid Build Coastguard Worker 							d = get_bits (s);
1966*fd1fabb7SAndroid Build Coastguard Worker 							HuffExtend (d, s);
1967*fd1fabb7SAndroid Build Coastguard Worker 							}
1968*fd1fabb7SAndroid Build Coastguard Worker 
1969*fd1fabb7SAndroid Build Coastguard Worker 						}
1970*fd1fabb7SAndroid Build Coastguard Worker 
1971*fd1fabb7SAndroid Build Coastguard Worker 					p0 += d;
1972*fd1fabb7SAndroid Build Coastguard Worker 
1973*fd1fabb7SAndroid Build Coastguard Worker 					curRowBuf [col + 1] [0] = (ComponentType) p0;
1974*fd1fabb7SAndroid Build Coastguard Worker 
1975*fd1fabb7SAndroid Build Coastguard Worker 					}
1976*fd1fabb7SAndroid Build Coastguard Worker 
1977*fd1fabb7SAndroid Build Coastguard Worker 				// Read first chroma component.
1978*fd1fabb7SAndroid Build Coastguard Worker 
1979*fd1fabb7SAndroid Build Coastguard Worker 					{
1980*fd1fabb7SAndroid Build Coastguard Worker 
1981*fd1fabb7SAndroid Build Coastguard Worker 					int32 d = 0;
1982*fd1fabb7SAndroid Build Coastguard Worker 
1983*fd1fabb7SAndroid Build Coastguard Worker 					int32 s = HuffDecode (ht [1]);
1984*fd1fabb7SAndroid Build Coastguard Worker 
1985*fd1fabb7SAndroid Build Coastguard Worker 					if (s)
1986*fd1fabb7SAndroid Build Coastguard Worker 						{
1987*fd1fabb7SAndroid Build Coastguard Worker 
1988*fd1fabb7SAndroid Build Coastguard Worker 						if (s == 16)
1989*fd1fabb7SAndroid Build Coastguard Worker 							{
1990*fd1fabb7SAndroid Build Coastguard Worker 							d = -32768;
1991*fd1fabb7SAndroid Build Coastguard Worker 							}
1992*fd1fabb7SAndroid Build Coastguard Worker 
1993*fd1fabb7SAndroid Build Coastguard Worker 						else
1994*fd1fabb7SAndroid Build Coastguard Worker 							{
1995*fd1fabb7SAndroid Build Coastguard Worker 							d = get_bits (s);
1996*fd1fabb7SAndroid Build Coastguard Worker 							HuffExtend (d, s);
1997*fd1fabb7SAndroid Build Coastguard Worker 							}
1998*fd1fabb7SAndroid Build Coastguard Worker 
1999*fd1fabb7SAndroid Build Coastguard Worker 						}
2000*fd1fabb7SAndroid Build Coastguard Worker 
2001*fd1fabb7SAndroid Build Coastguard Worker 					p1 += d;
2002*fd1fabb7SAndroid Build Coastguard Worker 
2003*fd1fabb7SAndroid Build Coastguard Worker 					curRowBuf [col    ] [1] = (ComponentType) p1;
2004*fd1fabb7SAndroid Build Coastguard Worker 					curRowBuf [col + 1] [1] = (ComponentType) p1;
2005*fd1fabb7SAndroid Build Coastguard Worker 
2006*fd1fabb7SAndroid Build Coastguard Worker 					}
2007*fd1fabb7SAndroid Build Coastguard Worker 
2008*fd1fabb7SAndroid Build Coastguard Worker 				// Read second chroma component.
2009*fd1fabb7SAndroid Build Coastguard Worker 
2010*fd1fabb7SAndroid Build Coastguard Worker 					{
2011*fd1fabb7SAndroid Build Coastguard Worker 
2012*fd1fabb7SAndroid Build Coastguard Worker 					int32 d = 0;
2013*fd1fabb7SAndroid Build Coastguard Worker 
2014*fd1fabb7SAndroid Build Coastguard Worker 					int32 s = HuffDecode (ht [2]);
2015*fd1fabb7SAndroid Build Coastguard Worker 
2016*fd1fabb7SAndroid Build Coastguard Worker 					if (s)
2017*fd1fabb7SAndroid Build Coastguard Worker 						{
2018*fd1fabb7SAndroid Build Coastguard Worker 
2019*fd1fabb7SAndroid Build Coastguard Worker 						if (s == 16)
2020*fd1fabb7SAndroid Build Coastguard Worker 							{
2021*fd1fabb7SAndroid Build Coastguard Worker 							d = -32768;
2022*fd1fabb7SAndroid Build Coastguard Worker 							}
2023*fd1fabb7SAndroid Build Coastguard Worker 
2024*fd1fabb7SAndroid Build Coastguard Worker 						else
2025*fd1fabb7SAndroid Build Coastguard Worker 							{
2026*fd1fabb7SAndroid Build Coastguard Worker 							d = get_bits (s);
2027*fd1fabb7SAndroid Build Coastguard Worker 							HuffExtend (d, s);
2028*fd1fabb7SAndroid Build Coastguard Worker 							}
2029*fd1fabb7SAndroid Build Coastguard Worker 
2030*fd1fabb7SAndroid Build Coastguard Worker 						}
2031*fd1fabb7SAndroid Build Coastguard Worker 
2032*fd1fabb7SAndroid Build Coastguard Worker 					p2 += d;
2033*fd1fabb7SAndroid Build Coastguard Worker 
2034*fd1fabb7SAndroid Build Coastguard Worker 					curRowBuf [col    ] [2] = (ComponentType) p2;
2035*fd1fabb7SAndroid Build Coastguard Worker 					curRowBuf [col + 1] [2] = (ComponentType) p2;
2036*fd1fabb7SAndroid Build Coastguard Worker 
2037*fd1fabb7SAndroid Build Coastguard Worker 					}
2038*fd1fabb7SAndroid Build Coastguard Worker 
2039*fd1fabb7SAndroid Build Coastguard Worker 				}
2040*fd1fabb7SAndroid Build Coastguard Worker 
2041*fd1fabb7SAndroid Build Coastguard Worker 			PmPutRow (curRowBuf, compsInScan, numCOL, row);
2042*fd1fabb7SAndroid Build Coastguard Worker 
2043*fd1fabb7SAndroid Build Coastguard Worker 			swap (MCU *, prevRowBuf, curRowBuf);
2044*fd1fabb7SAndroid Build Coastguard Worker 
2045*fd1fabb7SAndroid Build Coastguard Worker 			}
2046*fd1fabb7SAndroid Build Coastguard Worker 
2047*fd1fabb7SAndroid Build Coastguard Worker 		return;
2048*fd1fabb7SAndroid Build Coastguard Worker 
2049*fd1fabb7SAndroid Build Coastguard Worker 		}
2050*fd1fabb7SAndroid Build Coastguard Worker 
2051*fd1fabb7SAndroid Build Coastguard Worker 	if (info.compInfo [0].hSampFactor == 2 &&
2052*fd1fabb7SAndroid Build Coastguard Worker 		info.compInfo [0].vSampFactor == 2)
2053*fd1fabb7SAndroid Build Coastguard Worker 		{
2054*fd1fabb7SAndroid Build Coastguard Worker 
2055*fd1fabb7SAndroid Build Coastguard Worker 		for (int32 row = 0; row < numROW; row += 2)
2056*fd1fabb7SAndroid Build Coastguard Worker 			{
2057*fd1fabb7SAndroid Build Coastguard Worker 
2058*fd1fabb7SAndroid Build Coastguard Worker 			// Initialize predictors.
2059*fd1fabb7SAndroid Build Coastguard Worker 
2060*fd1fabb7SAndroid Build Coastguard Worker 			int32 p0;
2061*fd1fabb7SAndroid Build Coastguard Worker 			int32 p1;
2062*fd1fabb7SAndroid Build Coastguard Worker 			int32 p2;
2063*fd1fabb7SAndroid Build Coastguard Worker 
2064*fd1fabb7SAndroid Build Coastguard Worker 			if (row == 0)
2065*fd1fabb7SAndroid Build Coastguard Worker 				{
2066*fd1fabb7SAndroid Build Coastguard Worker 				p0 = 1 << 14;
2067*fd1fabb7SAndroid Build Coastguard Worker 				p1 = 1 << 14;
2068*fd1fabb7SAndroid Build Coastguard Worker 				p2 = 1 << 14;
2069*fd1fabb7SAndroid Build Coastguard Worker 				}
2070*fd1fabb7SAndroid Build Coastguard Worker 
2071*fd1fabb7SAndroid Build Coastguard Worker 			else
2072*fd1fabb7SAndroid Build Coastguard Worker 				{
2073*fd1fabb7SAndroid Build Coastguard Worker 				p0 = prevRowBuf [0] [0];
2074*fd1fabb7SAndroid Build Coastguard Worker 				p1 = prevRowBuf [0] [1];
2075*fd1fabb7SAndroid Build Coastguard Worker 				p2 = prevRowBuf [0] [2];
2076*fd1fabb7SAndroid Build Coastguard Worker 				}
2077*fd1fabb7SAndroid Build Coastguard Worker 
2078*fd1fabb7SAndroid Build Coastguard Worker 			for (int32 col = 0; col < numCOL; col += 2)
2079*fd1fabb7SAndroid Build Coastguard Worker 				{
2080*fd1fabb7SAndroid Build Coastguard Worker 
2081*fd1fabb7SAndroid Build Coastguard Worker 				// Read first luminance component.
2082*fd1fabb7SAndroid Build Coastguard Worker 
2083*fd1fabb7SAndroid Build Coastguard Worker 					{
2084*fd1fabb7SAndroid Build Coastguard Worker 
2085*fd1fabb7SAndroid Build Coastguard Worker 					int32 d = 0;
2086*fd1fabb7SAndroid Build Coastguard Worker 
2087*fd1fabb7SAndroid Build Coastguard Worker 					int32 s = HuffDecode (ht [0]);
2088*fd1fabb7SAndroid Build Coastguard Worker 
2089*fd1fabb7SAndroid Build Coastguard Worker 					if (s)
2090*fd1fabb7SAndroid Build Coastguard Worker 						{
2091*fd1fabb7SAndroid Build Coastguard Worker 
2092*fd1fabb7SAndroid Build Coastguard Worker 						if (s == 16)
2093*fd1fabb7SAndroid Build Coastguard Worker 							{
2094*fd1fabb7SAndroid Build Coastguard Worker 							d = -32768;
2095*fd1fabb7SAndroid Build Coastguard Worker 							}
2096*fd1fabb7SAndroid Build Coastguard Worker 
2097*fd1fabb7SAndroid Build Coastguard Worker 						else
2098*fd1fabb7SAndroid Build Coastguard Worker 							{
2099*fd1fabb7SAndroid Build Coastguard Worker 							d = get_bits (s);
2100*fd1fabb7SAndroid Build Coastguard Worker 							HuffExtend (d, s);
2101*fd1fabb7SAndroid Build Coastguard Worker 							}
2102*fd1fabb7SAndroid Build Coastguard Worker 
2103*fd1fabb7SAndroid Build Coastguard Worker 						}
2104*fd1fabb7SAndroid Build Coastguard Worker 
2105*fd1fabb7SAndroid Build Coastguard Worker 					p0 += d;
2106*fd1fabb7SAndroid Build Coastguard Worker 
2107*fd1fabb7SAndroid Build Coastguard Worker 					prevRowBuf [col] [0] = (ComponentType) p0;
2108*fd1fabb7SAndroid Build Coastguard Worker 
2109*fd1fabb7SAndroid Build Coastguard Worker 					}
2110*fd1fabb7SAndroid Build Coastguard Worker 
2111*fd1fabb7SAndroid Build Coastguard Worker 				// Read second luminance component.
2112*fd1fabb7SAndroid Build Coastguard Worker 
2113*fd1fabb7SAndroid Build Coastguard Worker 					{
2114*fd1fabb7SAndroid Build Coastguard Worker 
2115*fd1fabb7SAndroid Build Coastguard Worker 					int32 d = 0;
2116*fd1fabb7SAndroid Build Coastguard Worker 
2117*fd1fabb7SAndroid Build Coastguard Worker 					int32 s = HuffDecode (ht [0]);
2118*fd1fabb7SAndroid Build Coastguard Worker 
2119*fd1fabb7SAndroid Build Coastguard Worker 					if (s)
2120*fd1fabb7SAndroid Build Coastguard Worker 						{
2121*fd1fabb7SAndroid Build Coastguard Worker 
2122*fd1fabb7SAndroid Build Coastguard Worker 						if (s == 16)
2123*fd1fabb7SAndroid Build Coastguard Worker 							{
2124*fd1fabb7SAndroid Build Coastguard Worker 							d = -32768;
2125*fd1fabb7SAndroid Build Coastguard Worker 							}
2126*fd1fabb7SAndroid Build Coastguard Worker 
2127*fd1fabb7SAndroid Build Coastguard Worker 						else
2128*fd1fabb7SAndroid Build Coastguard Worker 							{
2129*fd1fabb7SAndroid Build Coastguard Worker 							d = get_bits (s);
2130*fd1fabb7SAndroid Build Coastguard Worker 							HuffExtend (d, s);
2131*fd1fabb7SAndroid Build Coastguard Worker 							}
2132*fd1fabb7SAndroid Build Coastguard Worker 
2133*fd1fabb7SAndroid Build Coastguard Worker 						}
2134*fd1fabb7SAndroid Build Coastguard Worker 
2135*fd1fabb7SAndroid Build Coastguard Worker 					p0 += d;
2136*fd1fabb7SAndroid Build Coastguard Worker 
2137*fd1fabb7SAndroid Build Coastguard Worker 					prevRowBuf [col + 1] [0] = (ComponentType) p0;
2138*fd1fabb7SAndroid Build Coastguard Worker 
2139*fd1fabb7SAndroid Build Coastguard Worker 					}
2140*fd1fabb7SAndroid Build Coastguard Worker 
2141*fd1fabb7SAndroid Build Coastguard Worker 				// Read third luminance component.
2142*fd1fabb7SAndroid Build Coastguard Worker 
2143*fd1fabb7SAndroid Build Coastguard Worker 					{
2144*fd1fabb7SAndroid Build Coastguard Worker 
2145*fd1fabb7SAndroid Build Coastguard Worker 					int32 d = 0;
2146*fd1fabb7SAndroid Build Coastguard Worker 
2147*fd1fabb7SAndroid Build Coastguard Worker 					int32 s = HuffDecode (ht [0]);
2148*fd1fabb7SAndroid Build Coastguard Worker 
2149*fd1fabb7SAndroid Build Coastguard Worker 					if (s)
2150*fd1fabb7SAndroid Build Coastguard Worker 						{
2151*fd1fabb7SAndroid Build Coastguard Worker 
2152*fd1fabb7SAndroid Build Coastguard Worker 						if (s == 16)
2153*fd1fabb7SAndroid Build Coastguard Worker 							{
2154*fd1fabb7SAndroid Build Coastguard Worker 							d = -32768;
2155*fd1fabb7SAndroid Build Coastguard Worker 							}
2156*fd1fabb7SAndroid Build Coastguard Worker 
2157*fd1fabb7SAndroid Build Coastguard Worker 						else
2158*fd1fabb7SAndroid Build Coastguard Worker 							{
2159*fd1fabb7SAndroid Build Coastguard Worker 							d = get_bits (s);
2160*fd1fabb7SAndroid Build Coastguard Worker 							HuffExtend (d, s);
2161*fd1fabb7SAndroid Build Coastguard Worker 							}
2162*fd1fabb7SAndroid Build Coastguard Worker 
2163*fd1fabb7SAndroid Build Coastguard Worker 						}
2164*fd1fabb7SAndroid Build Coastguard Worker 
2165*fd1fabb7SAndroid Build Coastguard Worker 					p0 += d;
2166*fd1fabb7SAndroid Build Coastguard Worker 
2167*fd1fabb7SAndroid Build Coastguard Worker 					curRowBuf [col] [0] = (ComponentType) p0;
2168*fd1fabb7SAndroid Build Coastguard Worker 
2169*fd1fabb7SAndroid Build Coastguard Worker 					}
2170*fd1fabb7SAndroid Build Coastguard Worker 
2171*fd1fabb7SAndroid Build Coastguard Worker 				// Read fourth luminance component.
2172*fd1fabb7SAndroid Build Coastguard Worker 
2173*fd1fabb7SAndroid Build Coastguard Worker 					{
2174*fd1fabb7SAndroid Build Coastguard Worker 
2175*fd1fabb7SAndroid Build Coastguard Worker 					int32 d = 0;
2176*fd1fabb7SAndroid Build Coastguard Worker 
2177*fd1fabb7SAndroid Build Coastguard Worker 					int32 s = HuffDecode (ht [0]);
2178*fd1fabb7SAndroid Build Coastguard Worker 
2179*fd1fabb7SAndroid Build Coastguard Worker 					if (s)
2180*fd1fabb7SAndroid Build Coastguard Worker 						{
2181*fd1fabb7SAndroid Build Coastguard Worker 
2182*fd1fabb7SAndroid Build Coastguard Worker 						if (s == 16)
2183*fd1fabb7SAndroid Build Coastguard Worker 							{
2184*fd1fabb7SAndroid Build Coastguard Worker 							d = -32768;
2185*fd1fabb7SAndroid Build Coastguard Worker 							}
2186*fd1fabb7SAndroid Build Coastguard Worker 
2187*fd1fabb7SAndroid Build Coastguard Worker 						else
2188*fd1fabb7SAndroid Build Coastguard Worker 							{
2189*fd1fabb7SAndroid Build Coastguard Worker 							d = get_bits (s);
2190*fd1fabb7SAndroid Build Coastguard Worker 							HuffExtend (d, s);
2191*fd1fabb7SAndroid Build Coastguard Worker 							}
2192*fd1fabb7SAndroid Build Coastguard Worker 
2193*fd1fabb7SAndroid Build Coastguard Worker 						}
2194*fd1fabb7SAndroid Build Coastguard Worker 
2195*fd1fabb7SAndroid Build Coastguard Worker 					p0 += d;
2196*fd1fabb7SAndroid Build Coastguard Worker 
2197*fd1fabb7SAndroid Build Coastguard Worker 					curRowBuf [col + 1] [0] = (ComponentType) p0;
2198*fd1fabb7SAndroid Build Coastguard Worker 
2199*fd1fabb7SAndroid Build Coastguard Worker 					}
2200*fd1fabb7SAndroid Build Coastguard Worker 
2201*fd1fabb7SAndroid Build Coastguard Worker 				// Read first chroma component.
2202*fd1fabb7SAndroid Build Coastguard Worker 
2203*fd1fabb7SAndroid Build Coastguard Worker 					{
2204*fd1fabb7SAndroid Build Coastguard Worker 
2205*fd1fabb7SAndroid Build Coastguard Worker 					int32 d = 0;
2206*fd1fabb7SAndroid Build Coastguard Worker 
2207*fd1fabb7SAndroid Build Coastguard Worker 					int32 s = HuffDecode (ht [1]);
2208*fd1fabb7SAndroid Build Coastguard Worker 
2209*fd1fabb7SAndroid Build Coastguard Worker 					if (s)
2210*fd1fabb7SAndroid Build Coastguard Worker 						{
2211*fd1fabb7SAndroid Build Coastguard Worker 
2212*fd1fabb7SAndroid Build Coastguard Worker 						if (s == 16)
2213*fd1fabb7SAndroid Build Coastguard Worker 							{
2214*fd1fabb7SAndroid Build Coastguard Worker 							d = -32768;
2215*fd1fabb7SAndroid Build Coastguard Worker 							}
2216*fd1fabb7SAndroid Build Coastguard Worker 
2217*fd1fabb7SAndroid Build Coastguard Worker 						else
2218*fd1fabb7SAndroid Build Coastguard Worker 							{
2219*fd1fabb7SAndroid Build Coastguard Worker 							d = get_bits (s);
2220*fd1fabb7SAndroid Build Coastguard Worker 							HuffExtend (d, s);
2221*fd1fabb7SAndroid Build Coastguard Worker 							}
2222*fd1fabb7SAndroid Build Coastguard Worker 
2223*fd1fabb7SAndroid Build Coastguard Worker 						}
2224*fd1fabb7SAndroid Build Coastguard Worker 
2225*fd1fabb7SAndroid Build Coastguard Worker 					p1 += d;
2226*fd1fabb7SAndroid Build Coastguard Worker 
2227*fd1fabb7SAndroid Build Coastguard Worker 					prevRowBuf [col    ] [1] = (ComponentType) p1;
2228*fd1fabb7SAndroid Build Coastguard Worker 					prevRowBuf [col + 1] [1] = (ComponentType) p1;
2229*fd1fabb7SAndroid Build Coastguard Worker 
2230*fd1fabb7SAndroid Build Coastguard Worker 					curRowBuf [col    ] [1] = (ComponentType) p1;
2231*fd1fabb7SAndroid Build Coastguard Worker 					curRowBuf [col + 1] [1] = (ComponentType) p1;
2232*fd1fabb7SAndroid Build Coastguard Worker 
2233*fd1fabb7SAndroid Build Coastguard Worker 					}
2234*fd1fabb7SAndroid Build Coastguard Worker 
2235*fd1fabb7SAndroid Build Coastguard Worker 				// Read second chroma component.
2236*fd1fabb7SAndroid Build Coastguard Worker 
2237*fd1fabb7SAndroid Build Coastguard Worker 					{
2238*fd1fabb7SAndroid Build Coastguard Worker 
2239*fd1fabb7SAndroid Build Coastguard Worker 					int32 d = 0;
2240*fd1fabb7SAndroid Build Coastguard Worker 
2241*fd1fabb7SAndroid Build Coastguard Worker 					int32 s = HuffDecode (ht [2]);
2242*fd1fabb7SAndroid Build Coastguard Worker 
2243*fd1fabb7SAndroid Build Coastguard Worker 					if (s)
2244*fd1fabb7SAndroid Build Coastguard Worker 						{
2245*fd1fabb7SAndroid Build Coastguard Worker 
2246*fd1fabb7SAndroid Build Coastguard Worker 						if (s == 16)
2247*fd1fabb7SAndroid Build Coastguard Worker 							{
2248*fd1fabb7SAndroid Build Coastguard Worker 							d = -32768;
2249*fd1fabb7SAndroid Build Coastguard Worker 							}
2250*fd1fabb7SAndroid Build Coastguard Worker 
2251*fd1fabb7SAndroid Build Coastguard Worker 						else
2252*fd1fabb7SAndroid Build Coastguard Worker 							{
2253*fd1fabb7SAndroid Build Coastguard Worker 							d = get_bits (s);
2254*fd1fabb7SAndroid Build Coastguard Worker 							HuffExtend (d, s);
2255*fd1fabb7SAndroid Build Coastguard Worker 							}
2256*fd1fabb7SAndroid Build Coastguard Worker 
2257*fd1fabb7SAndroid Build Coastguard Worker 						}
2258*fd1fabb7SAndroid Build Coastguard Worker 
2259*fd1fabb7SAndroid Build Coastguard Worker 					p2 += d;
2260*fd1fabb7SAndroid Build Coastguard Worker 
2261*fd1fabb7SAndroid Build Coastguard Worker 					prevRowBuf [col    ] [2] = (ComponentType) p2;
2262*fd1fabb7SAndroid Build Coastguard Worker 					prevRowBuf [col + 1] [2] = (ComponentType) p2;
2263*fd1fabb7SAndroid Build Coastguard Worker 
2264*fd1fabb7SAndroid Build Coastguard Worker 					curRowBuf [col    ] [2] = (ComponentType) p2;
2265*fd1fabb7SAndroid Build Coastguard Worker 					curRowBuf [col + 1] [2] = (ComponentType) p2;
2266*fd1fabb7SAndroid Build Coastguard Worker 
2267*fd1fabb7SAndroid Build Coastguard Worker 					}
2268*fd1fabb7SAndroid Build Coastguard Worker 
2269*fd1fabb7SAndroid Build Coastguard Worker 				}
2270*fd1fabb7SAndroid Build Coastguard Worker 
2271*fd1fabb7SAndroid Build Coastguard Worker 			PmPutRow (prevRowBuf, compsInScan, numCOL, row);
2272*fd1fabb7SAndroid Build Coastguard Worker 			PmPutRow (curRowBuf, compsInScan, numCOL, row);
2273*fd1fabb7SAndroid Build Coastguard Worker 
2274*fd1fabb7SAndroid Build Coastguard Worker 			}
2275*fd1fabb7SAndroid Build Coastguard Worker 
2276*fd1fabb7SAndroid Build Coastguard Worker 		return;
2277*fd1fabb7SAndroid Build Coastguard Worker 
2278*fd1fabb7SAndroid Build Coastguard Worker 		}
2279*fd1fabb7SAndroid Build Coastguard Worker 
2280*fd1fabb7SAndroid Build Coastguard Worker 	#endif
2281*fd1fabb7SAndroid Build Coastguard Worker 
2282*fd1fabb7SAndroid Build Coastguard Worker 	#if qSupportHasselblad_3FR
2283*fd1fabb7SAndroid Build Coastguard Worker 
2284*fd1fabb7SAndroid Build Coastguard Worker 	if (info.Ss == 8 && (numCOL & 1) == 0)
2285*fd1fabb7SAndroid Build Coastguard Worker 		{
2286*fd1fabb7SAndroid Build Coastguard Worker 
2287*fd1fabb7SAndroid Build Coastguard Worker 		fHasselblad3FR = true;
2288*fd1fabb7SAndroid Build Coastguard Worker 
2289*fd1fabb7SAndroid Build Coastguard Worker 		for (int32 row = 0; row < numROW; row++)
2290*fd1fabb7SAndroid Build Coastguard Worker 			{
2291*fd1fabb7SAndroid Build Coastguard Worker 
2292*fd1fabb7SAndroid Build Coastguard Worker 			int32 p0 = 32768;
2293*fd1fabb7SAndroid Build Coastguard Worker 			int32 p1 = 32768;
2294*fd1fabb7SAndroid Build Coastguard Worker 
2295*fd1fabb7SAndroid Build Coastguard Worker 			for (int32 col = 0; col < numCOL; col += 2)
2296*fd1fabb7SAndroid Build Coastguard Worker 				{
2297*fd1fabb7SAndroid Build Coastguard Worker 
2298*fd1fabb7SAndroid Build Coastguard Worker 				int32 s0 = HuffDecode (ht [0]);
2299*fd1fabb7SAndroid Build Coastguard Worker 				int32 s1 = HuffDecode (ht [0]);
2300*fd1fabb7SAndroid Build Coastguard Worker 
2301*fd1fabb7SAndroid Build Coastguard Worker 				if (s0)
2302*fd1fabb7SAndroid Build Coastguard Worker 					{
2303*fd1fabb7SAndroid Build Coastguard Worker 					int32 d = get_bits (s0);
2304*fd1fabb7SAndroid Build Coastguard Worker 					if (s0 == 16)
2305*fd1fabb7SAndroid Build Coastguard Worker 						{
2306*fd1fabb7SAndroid Build Coastguard Worker 						d = -32768;
2307*fd1fabb7SAndroid Build Coastguard Worker 						}
2308*fd1fabb7SAndroid Build Coastguard Worker 					else
2309*fd1fabb7SAndroid Build Coastguard Worker 						{
2310*fd1fabb7SAndroid Build Coastguard Worker 						HuffExtend (d, s0);
2311*fd1fabb7SAndroid Build Coastguard Worker 						}
2312*fd1fabb7SAndroid Build Coastguard Worker 					p0 += d;
2313*fd1fabb7SAndroid Build Coastguard Worker 					}
2314*fd1fabb7SAndroid Build Coastguard Worker 
2315*fd1fabb7SAndroid Build Coastguard Worker 				if (s1)
2316*fd1fabb7SAndroid Build Coastguard Worker 					{
2317*fd1fabb7SAndroid Build Coastguard Worker 					int32 d = get_bits (s1);
2318*fd1fabb7SAndroid Build Coastguard Worker 					if (s1 == 16)
2319*fd1fabb7SAndroid Build Coastguard Worker 						{
2320*fd1fabb7SAndroid Build Coastguard Worker 						d = -32768;
2321*fd1fabb7SAndroid Build Coastguard Worker 						}
2322*fd1fabb7SAndroid Build Coastguard Worker 					else
2323*fd1fabb7SAndroid Build Coastguard Worker 						{
2324*fd1fabb7SAndroid Build Coastguard Worker 						HuffExtend (d, s1);
2325*fd1fabb7SAndroid Build Coastguard Worker 						}
2326*fd1fabb7SAndroid Build Coastguard Worker 					p1 += d;
2327*fd1fabb7SAndroid Build Coastguard Worker 					}
2328*fd1fabb7SAndroid Build Coastguard Worker 
2329*fd1fabb7SAndroid Build Coastguard Worker 				curRowBuf [col    ] [0] = (ComponentType) p0;
2330*fd1fabb7SAndroid Build Coastguard Worker 				curRowBuf [col + 1] [0] = (ComponentType) p1;
2331*fd1fabb7SAndroid Build Coastguard Worker 
2332*fd1fabb7SAndroid Build Coastguard Worker 				}
2333*fd1fabb7SAndroid Build Coastguard Worker 
2334*fd1fabb7SAndroid Build Coastguard Worker 			PmPutRow (curRowBuf, compsInScan, numCOL, row);
2335*fd1fabb7SAndroid Build Coastguard Worker 
2336*fd1fabb7SAndroid Build Coastguard Worker 			}
2337*fd1fabb7SAndroid Build Coastguard Worker 
2338*fd1fabb7SAndroid Build Coastguard Worker 		return;
2339*fd1fabb7SAndroid Build Coastguard Worker 
2340*fd1fabb7SAndroid Build Coastguard Worker 		}
2341*fd1fabb7SAndroid Build Coastguard Worker 
2342*fd1fabb7SAndroid Build Coastguard Worker 	#endif
2343*fd1fabb7SAndroid Build Coastguard Worker 
2344*fd1fabb7SAndroid Build Coastguard Worker     // Decode the first row of image. Output the row and
2345*fd1fabb7SAndroid Build Coastguard Worker     // turn this row into a previous row for later predictor
2346*fd1fabb7SAndroid Build Coastguard Worker     // calculation.
2347*fd1fabb7SAndroid Build Coastguard Worker 
2348*fd1fabb7SAndroid Build Coastguard Worker     DecodeFirstRow (mcuROW1);
2349*fd1fabb7SAndroid Build Coastguard Worker 
2350*fd1fabb7SAndroid Build Coastguard Worker     PmPutRow (mcuROW1, compsInScan, numCOL, 0);
2351*fd1fabb7SAndroid Build Coastguard Worker 
2352*fd1fabb7SAndroid Build Coastguard Worker 	// Process each row.
2353*fd1fabb7SAndroid Build Coastguard Worker 
2354*fd1fabb7SAndroid Build Coastguard Worker     for (int32 row = 1; row < numROW; row++)
2355*fd1fabb7SAndroid Build Coastguard Worker     	{
2356*fd1fabb7SAndroid Build Coastguard Worker 
2357*fd1fabb7SAndroid Build Coastguard Worker         // Account for restart interval, process restart marker if needed.
2358*fd1fabb7SAndroid Build Coastguard Worker 
2359*fd1fabb7SAndroid Build Coastguard Worker 		if (info.restartInRows)
2360*fd1fabb7SAndroid Build Coastguard Worker 			{
2361*fd1fabb7SAndroid Build Coastguard Worker 
2362*fd1fabb7SAndroid Build Coastguard Worker 			if (info.restartRowsToGo == 0)
2363*fd1fabb7SAndroid Build Coastguard Worker 				{
2364*fd1fabb7SAndroid Build Coastguard Worker 
2365*fd1fabb7SAndroid Build Coastguard Worker 				ProcessRestart ();
2366*fd1fabb7SAndroid Build Coastguard Worker 
2367*fd1fabb7SAndroid Build Coastguard Worker                 // Reset predictors at restart.
2368*fd1fabb7SAndroid Build Coastguard Worker 
2369*fd1fabb7SAndroid Build Coastguard Worker 				DecodeFirstRow (curRowBuf);
2370*fd1fabb7SAndroid Build Coastguard Worker 
2371*fd1fabb7SAndroid Build Coastguard Worker 				PmPutRow (curRowBuf, compsInScan, numCOL, row);
2372*fd1fabb7SAndroid Build Coastguard Worker 
2373*fd1fabb7SAndroid Build Coastguard Worker 				swap (MCU *, prevRowBuf, curRowBuf);
2374*fd1fabb7SAndroid Build Coastguard Worker 
2375*fd1fabb7SAndroid Build Coastguard Worker 				continue;
2376*fd1fabb7SAndroid Build Coastguard Worker 
2377*fd1fabb7SAndroid Build Coastguard Worker            		}
2378*fd1fabb7SAndroid Build Coastguard Worker 
2379*fd1fabb7SAndroid Build Coastguard Worker 			info.restartRowsToGo--;
2380*fd1fabb7SAndroid Build Coastguard Worker 
2381*fd1fabb7SAndroid Build Coastguard Worker 			}
2382*fd1fabb7SAndroid Build Coastguard Worker 
2383*fd1fabb7SAndroid Build Coastguard Worker 		// The upper neighbors are predictors for the first column.
2384*fd1fabb7SAndroid Build Coastguard Worker 
2385*fd1fabb7SAndroid Build Coastguard Worker         for (int32 curComp = 0; curComp < compsInScan; curComp++)
2386*fd1fabb7SAndroid Build Coastguard Worker         	{
2387*fd1fabb7SAndroid Build Coastguard Worker 
2388*fd1fabb7SAndroid Build Coastguard Worker 	        // Section F.2.2.1: decode the difference
2389*fd1fabb7SAndroid Build Coastguard Worker 
2390*fd1fabb7SAndroid Build Coastguard Worker 	  		int32 d = 0;
2391*fd1fabb7SAndroid Build Coastguard Worker 
2392*fd1fabb7SAndroid Build Coastguard Worker 	        int32 s = HuffDecode (ht [curComp]);
2393*fd1fabb7SAndroid Build Coastguard Worker 
2394*fd1fabb7SAndroid Build Coastguard Worker 	      	if (s)
2395*fd1fabb7SAndroid Build Coastguard Worker 	      		{
2396*fd1fabb7SAndroid Build Coastguard Worker 
2397*fd1fabb7SAndroid Build Coastguard Worker 	      		if (s == 16 && !fBug16)
2398*fd1fabb7SAndroid Build Coastguard Worker 	      			{
2399*fd1fabb7SAndroid Build Coastguard Worker 	      			d = -32768;
2400*fd1fabb7SAndroid Build Coastguard Worker 	      			}
2401*fd1fabb7SAndroid Build Coastguard Worker 
2402*fd1fabb7SAndroid Build Coastguard Worker 	      		else
2403*fd1fabb7SAndroid Build Coastguard Worker 	      			{
2404*fd1fabb7SAndroid Build Coastguard Worker 					d = get_bits (s);
2405*fd1fabb7SAndroid Build Coastguard Worker 	            	HuffExtend (d, s);
2406*fd1fabb7SAndroid Build Coastguard Worker 	            	}
2407*fd1fabb7SAndroid Build Coastguard Worker 
2408*fd1fabb7SAndroid Build Coastguard Worker 	            }
2409*fd1fabb7SAndroid Build Coastguard Worker 
2410*fd1fabb7SAndroid Build Coastguard Worker 	        // First column of row above is predictor for first column.
2411*fd1fabb7SAndroid Build Coastguard Worker 
2412*fd1fabb7SAndroid Build Coastguard Worker             curRowBuf [0] [curComp] = (ComponentType) (d + prevRowBuf [0] [curComp]);
2413*fd1fabb7SAndroid Build Coastguard Worker 
2414*fd1fabb7SAndroid Build Coastguard Worker 			}
2415*fd1fabb7SAndroid Build Coastguard Worker 
2416*fd1fabb7SAndroid Build Coastguard Worker         // For the rest of the column on this row, predictor
2417*fd1fabb7SAndroid Build Coastguard Worker         // calculations are based on PSV.
2418*fd1fabb7SAndroid Build Coastguard Worker 
2419*fd1fabb7SAndroid Build Coastguard Worker      	if (compsInScan == 2 && info.Ss == 1 && numCOL > 1)
2420*fd1fabb7SAndroid Build Coastguard Worker     		{
2421*fd1fabb7SAndroid Build Coastguard Worker 
2422*fd1fabb7SAndroid Build Coastguard Worker     		// This is the combination used by both the Canon and Kodak raw formats.
2423*fd1fabb7SAndroid Build Coastguard Worker     		// Unrolling the general case logic results in a significant speed increase.
2424*fd1fabb7SAndroid Build Coastguard Worker 
2425*fd1fabb7SAndroid Build Coastguard Worker     		uint16 *dPtr = &curRowBuf [1] [0];
2426*fd1fabb7SAndroid Build Coastguard Worker 
2427*fd1fabb7SAndroid Build Coastguard Worker     		int32 prev0 = dPtr [-2];
2428*fd1fabb7SAndroid Build Coastguard Worker     		int32 prev1 = dPtr [-1];
2429*fd1fabb7SAndroid Build Coastguard Worker 
2430*fd1fabb7SAndroid Build Coastguard Worker 			for (int32 col = 1; col < numCOL; col++)
2431*fd1fabb7SAndroid Build Coastguard Worker 	        	{
2432*fd1fabb7SAndroid Build Coastguard Worker 
2433*fd1fabb7SAndroid Build Coastguard Worker 		        int32 s = HuffDecode (ht [0]);
2434*fd1fabb7SAndroid Build Coastguard Worker 
2435*fd1fabb7SAndroid Build Coastguard Worker 		      	if (s)
2436*fd1fabb7SAndroid Build Coastguard Worker 		      		{
2437*fd1fabb7SAndroid Build Coastguard Worker 
2438*fd1fabb7SAndroid Build Coastguard Worker 		      		int32 d;
2439*fd1fabb7SAndroid Build Coastguard Worker 
2440*fd1fabb7SAndroid Build Coastguard Worker 		      		if (s == 16 && !fBug16)
2441*fd1fabb7SAndroid Build Coastguard Worker 		      			{
2442*fd1fabb7SAndroid Build Coastguard Worker 		      			d = -32768;
2443*fd1fabb7SAndroid Build Coastguard Worker 		      			}
2444*fd1fabb7SAndroid Build Coastguard Worker 
2445*fd1fabb7SAndroid Build Coastguard Worker 		      		else
2446*fd1fabb7SAndroid Build Coastguard Worker 		      			{
2447*fd1fabb7SAndroid Build Coastguard Worker 						d = get_bits (s);
2448*fd1fabb7SAndroid Build Coastguard Worker 		            	HuffExtend (d, s);
2449*fd1fabb7SAndroid Build Coastguard Worker 		            	}
2450*fd1fabb7SAndroid Build Coastguard Worker 
2451*fd1fabb7SAndroid Build Coastguard Worker 		        	prev0 += d;
2452*fd1fabb7SAndroid Build Coastguard Worker 
2453*fd1fabb7SAndroid Build Coastguard Worker 		            }
2454*fd1fabb7SAndroid Build Coastguard Worker 
2455*fd1fabb7SAndroid Build Coastguard Worker 		        s = HuffDecode (ht [1]);
2456*fd1fabb7SAndroid Build Coastguard Worker 
2457*fd1fabb7SAndroid Build Coastguard Worker 		      	if (s)
2458*fd1fabb7SAndroid Build Coastguard Worker 		      		{
2459*fd1fabb7SAndroid Build Coastguard Worker 
2460*fd1fabb7SAndroid Build Coastguard Worker 		      		int32 d;
2461*fd1fabb7SAndroid Build Coastguard Worker 
2462*fd1fabb7SAndroid Build Coastguard Worker 		      		if (s == 16 && !fBug16)
2463*fd1fabb7SAndroid Build Coastguard Worker 		      			{
2464*fd1fabb7SAndroid Build Coastguard Worker 		      			d = -32768;
2465*fd1fabb7SAndroid Build Coastguard Worker 		      			}
2466*fd1fabb7SAndroid Build Coastguard Worker 
2467*fd1fabb7SAndroid Build Coastguard Worker 		      		else
2468*fd1fabb7SAndroid Build Coastguard Worker 		      			{
2469*fd1fabb7SAndroid Build Coastguard Worker 						d = get_bits (s);
2470*fd1fabb7SAndroid Build Coastguard Worker 		            	HuffExtend (d, s);
2471*fd1fabb7SAndroid Build Coastguard Worker 		            	}
2472*fd1fabb7SAndroid Build Coastguard Worker 
2473*fd1fabb7SAndroid Build Coastguard Worker 					prev1 += d;
2474*fd1fabb7SAndroid Build Coastguard Worker 
2475*fd1fabb7SAndroid Build Coastguard Worker 		            }
2476*fd1fabb7SAndroid Build Coastguard Worker 
2477*fd1fabb7SAndroid Build Coastguard Worker 				dPtr [0] = (uint16) prev0;
2478*fd1fabb7SAndroid Build Coastguard Worker 				dPtr [1] = (uint16) prev1;
2479*fd1fabb7SAndroid Build Coastguard Worker 
2480*fd1fabb7SAndroid Build Coastguard Worker 				dPtr += 2;
2481*fd1fabb7SAndroid Build Coastguard Worker 
2482*fd1fabb7SAndroid Build Coastguard Worker        			}
2483*fd1fabb7SAndroid Build Coastguard Worker 
2484*fd1fabb7SAndroid Build Coastguard Worker        		}
2485*fd1fabb7SAndroid Build Coastguard Worker 
2486*fd1fabb7SAndroid Build Coastguard Worker        	else
2487*fd1fabb7SAndroid Build Coastguard Worker        		{
2488*fd1fabb7SAndroid Build Coastguard Worker 
2489*fd1fabb7SAndroid Build Coastguard Worker 			for (int32 col = 1; col < numCOL; col++)
2490*fd1fabb7SAndroid Build Coastguard Worker 	        	{
2491*fd1fabb7SAndroid Build Coastguard Worker 
2492*fd1fabb7SAndroid Build Coastguard Worker 	            for (int32 curComp = 0; curComp < compsInScan; curComp++)
2493*fd1fabb7SAndroid Build Coastguard Worker 	            	{
2494*fd1fabb7SAndroid Build Coastguard Worker 
2495*fd1fabb7SAndroid Build Coastguard Worker 		 	        // Section F.2.2.1: decode the difference
2496*fd1fabb7SAndroid Build Coastguard Worker 
2497*fd1fabb7SAndroid Build Coastguard Worker 			  		int32 d = 0;
2498*fd1fabb7SAndroid Build Coastguard Worker 
2499*fd1fabb7SAndroid Build Coastguard Worker 			        int32 s = HuffDecode (ht [curComp]);
2500*fd1fabb7SAndroid Build Coastguard Worker 
2501*fd1fabb7SAndroid Build Coastguard Worker 			      	if (s)
2502*fd1fabb7SAndroid Build Coastguard Worker 			      		{
2503*fd1fabb7SAndroid Build Coastguard Worker 
2504*fd1fabb7SAndroid Build Coastguard Worker 			      		if (s == 16 && !fBug16)
2505*fd1fabb7SAndroid Build Coastguard Worker 			      			{
2506*fd1fabb7SAndroid Build Coastguard Worker 			      			d = -32768;
2507*fd1fabb7SAndroid Build Coastguard Worker 			      			}
2508*fd1fabb7SAndroid Build Coastguard Worker 
2509*fd1fabb7SAndroid Build Coastguard Worker 			      		else
2510*fd1fabb7SAndroid Build Coastguard Worker 			      			{
2511*fd1fabb7SAndroid Build Coastguard Worker 							d = get_bits (s);
2512*fd1fabb7SAndroid Build Coastguard Worker 			            	HuffExtend (d, s);
2513*fd1fabb7SAndroid Build Coastguard Worker 			            	}
2514*fd1fabb7SAndroid Build Coastguard Worker 
2515*fd1fabb7SAndroid Build Coastguard Worker 			            }
2516*fd1fabb7SAndroid Build Coastguard Worker 
2517*fd1fabb7SAndroid Build Coastguard Worker 			        // Predict the pixel value.
2518*fd1fabb7SAndroid Build Coastguard Worker 
2519*fd1fabb7SAndroid Build Coastguard Worker 	                int32 predictor = QuickPredict (col,
2520*fd1fabb7SAndroid Build Coastguard Worker 		                						    curComp,
2521*fd1fabb7SAndroid Build Coastguard Worker 		                						    curRowBuf,
2522*fd1fabb7SAndroid Build Coastguard Worker 		                						    prevRowBuf);
2523*fd1fabb7SAndroid Build Coastguard Worker 
2524*fd1fabb7SAndroid Build Coastguard Worker 	                // Save the difference.
2525*fd1fabb7SAndroid Build Coastguard Worker 
2526*fd1fabb7SAndroid Build Coastguard Worker 	                curRowBuf [col] [curComp] = (ComponentType) (d + predictor);
2527*fd1fabb7SAndroid Build Coastguard Worker 
2528*fd1fabb7SAndroid Build Coastguard Worker 					}
2529*fd1fabb7SAndroid Build Coastguard Worker 
2530*fd1fabb7SAndroid Build Coastguard Worker 				}
2531*fd1fabb7SAndroid Build Coastguard Worker 
2532*fd1fabb7SAndroid Build Coastguard Worker         	}
2533*fd1fabb7SAndroid Build Coastguard Worker 
2534*fd1fabb7SAndroid Build Coastguard Worker 		PmPutRow (curRowBuf, compsInScan, numCOL, row);
2535*fd1fabb7SAndroid Build Coastguard Worker 
2536*fd1fabb7SAndroid Build Coastguard Worker 		swap (MCU *, prevRowBuf, curRowBuf);
2537*fd1fabb7SAndroid Build Coastguard Worker 
2538*fd1fabb7SAndroid Build Coastguard Worker     	}
2539*fd1fabb7SAndroid Build Coastguard Worker 
2540*fd1fabb7SAndroid Build Coastguard Worker     #undef swap
2541*fd1fabb7SAndroid Build Coastguard Worker 
2542*fd1fabb7SAndroid Build Coastguard Worker 	}
2543*fd1fabb7SAndroid Build Coastguard Worker 
2544*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
2545*fd1fabb7SAndroid Build Coastguard Worker 
StartRead(uint32 & imageWidth,uint32 & imageHeight,uint32 & imageChannels)2546*fd1fabb7SAndroid Build Coastguard Worker void dng_lossless_decoder::StartRead (uint32 &imageWidth,
2547*fd1fabb7SAndroid Build Coastguard Worker 								      uint32 &imageHeight,
2548*fd1fabb7SAndroid Build Coastguard Worker 								      uint32 &imageChannels)
2549*fd1fabb7SAndroid Build Coastguard Worker 	{
2550*fd1fabb7SAndroid Build Coastguard Worker 
2551*fd1fabb7SAndroid Build Coastguard Worker 	ReadFileHeader    ();
2552*fd1fabb7SAndroid Build Coastguard Worker 	ReadScanHeader    ();
2553*fd1fabb7SAndroid Build Coastguard Worker 	DecoderStructInit ();
2554*fd1fabb7SAndroid Build Coastguard Worker 	HuffDecoderInit   ();
2555*fd1fabb7SAndroid Build Coastguard Worker 
2556*fd1fabb7SAndroid Build Coastguard Worker 	imageWidth    = info.imageWidth;
2557*fd1fabb7SAndroid Build Coastguard Worker 	imageHeight   = info.imageHeight;
2558*fd1fabb7SAndroid Build Coastguard Worker 	imageChannels = info.compsInScan;
2559*fd1fabb7SAndroid Build Coastguard Worker 
2560*fd1fabb7SAndroid Build Coastguard Worker 	}
2561*fd1fabb7SAndroid Build Coastguard Worker 
2562*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
2563*fd1fabb7SAndroid Build Coastguard Worker 
FinishRead()2564*fd1fabb7SAndroid Build Coastguard Worker void dng_lossless_decoder::FinishRead ()
2565*fd1fabb7SAndroid Build Coastguard Worker 	{
2566*fd1fabb7SAndroid Build Coastguard Worker 
2567*fd1fabb7SAndroid Build Coastguard Worker 	DecodeImage ();
2568*fd1fabb7SAndroid Build Coastguard Worker 
2569*fd1fabb7SAndroid Build Coastguard Worker 	}
2570*fd1fabb7SAndroid Build Coastguard Worker 
2571*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
2572*fd1fabb7SAndroid Build Coastguard Worker 
DecodeLosslessJPEG(dng_stream & stream,dng_spooler & spooler,uint32 minDecodedSize,uint32 maxDecodedSize,bool bug16)2573*fd1fabb7SAndroid Build Coastguard Worker void DecodeLosslessJPEG (dng_stream &stream,
2574*fd1fabb7SAndroid Build Coastguard Worker 					     dng_spooler &spooler,
2575*fd1fabb7SAndroid Build Coastguard Worker 					     uint32 minDecodedSize,
2576*fd1fabb7SAndroid Build Coastguard Worker 					     uint32 maxDecodedSize,
2577*fd1fabb7SAndroid Build Coastguard Worker 						 bool bug16)
2578*fd1fabb7SAndroid Build Coastguard Worker 	{
2579*fd1fabb7SAndroid Build Coastguard Worker 
2580*fd1fabb7SAndroid Build Coastguard Worker 	dng_lossless_decoder decoder (&stream,
2581*fd1fabb7SAndroid Build Coastguard Worker 							      &spooler,
2582*fd1fabb7SAndroid Build Coastguard Worker 							      bug16);
2583*fd1fabb7SAndroid Build Coastguard Worker 
2584*fd1fabb7SAndroid Build Coastguard Worker 	uint32 imageWidth;
2585*fd1fabb7SAndroid Build Coastguard Worker 	uint32 imageHeight;
2586*fd1fabb7SAndroid Build Coastguard Worker 	uint32 imageChannels;
2587*fd1fabb7SAndroid Build Coastguard Worker 
2588*fd1fabb7SAndroid Build Coastguard Worker 	decoder.StartRead (imageWidth,
2589*fd1fabb7SAndroid Build Coastguard Worker 					   imageHeight,
2590*fd1fabb7SAndroid Build Coastguard Worker 					   imageChannels);
2591*fd1fabb7SAndroid Build Coastguard Worker 
2592*fd1fabb7SAndroid Build Coastguard Worker 	uint32 decodedSize = imageWidth    *
2593*fd1fabb7SAndroid Build Coastguard Worker 						 imageHeight   *
2594*fd1fabb7SAndroid Build Coastguard Worker 						 imageChannels *
2595*fd1fabb7SAndroid Build Coastguard Worker 						 (uint32) sizeof (uint16);
2596*fd1fabb7SAndroid Build Coastguard Worker 
2597*fd1fabb7SAndroid Build Coastguard Worker 	if (decodedSize < minDecodedSize ||
2598*fd1fabb7SAndroid Build Coastguard Worker 		decodedSize > maxDecodedSize)
2599*fd1fabb7SAndroid Build Coastguard Worker 		{
2600*fd1fabb7SAndroid Build Coastguard Worker 		ThrowBadFormat ();
2601*fd1fabb7SAndroid Build Coastguard Worker 		}
2602*fd1fabb7SAndroid Build Coastguard Worker 
2603*fd1fabb7SAndroid Build Coastguard Worker 	decoder.FinishRead ();
2604*fd1fabb7SAndroid Build Coastguard Worker 
2605*fd1fabb7SAndroid Build Coastguard Worker 	}
2606*fd1fabb7SAndroid Build Coastguard Worker 
2607*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
2608*fd1fabb7SAndroid Build Coastguard Worker 
2609*fd1fabb7SAndroid Build Coastguard Worker class dng_lossless_encoder
2610*fd1fabb7SAndroid Build Coastguard Worker 	{
2611*fd1fabb7SAndroid Build Coastguard Worker 
2612*fd1fabb7SAndroid Build Coastguard Worker 	private:
2613*fd1fabb7SAndroid Build Coastguard Worker 
2614*fd1fabb7SAndroid Build Coastguard Worker 		const uint16 *fSrcData;
2615*fd1fabb7SAndroid Build Coastguard Worker 
2616*fd1fabb7SAndroid Build Coastguard Worker 		uint32 fSrcRows;
2617*fd1fabb7SAndroid Build Coastguard Worker 		uint32 fSrcCols;
2618*fd1fabb7SAndroid Build Coastguard Worker 		uint32 fSrcChannels;
2619*fd1fabb7SAndroid Build Coastguard Worker 		uint32 fSrcBitDepth;
2620*fd1fabb7SAndroid Build Coastguard Worker 
2621*fd1fabb7SAndroid Build Coastguard Worker 		int32 fSrcRowStep;
2622*fd1fabb7SAndroid Build Coastguard Worker 		int32 fSrcColStep;
2623*fd1fabb7SAndroid Build Coastguard Worker 
2624*fd1fabb7SAndroid Build Coastguard Worker 		dng_stream &fStream;
2625*fd1fabb7SAndroid Build Coastguard Worker 
2626*fd1fabb7SAndroid Build Coastguard Worker 		HuffmanTable huffTable [4];
2627*fd1fabb7SAndroid Build Coastguard Worker 
2628*fd1fabb7SAndroid Build Coastguard Worker 		uint32 freqCount [4] [257];
2629*fd1fabb7SAndroid Build Coastguard Worker 
2630*fd1fabb7SAndroid Build Coastguard Worker 		// Current bit-accumulation buffer
2631*fd1fabb7SAndroid Build Coastguard Worker 
2632*fd1fabb7SAndroid Build Coastguard Worker 		int32 huffPutBuffer;
2633*fd1fabb7SAndroid Build Coastguard Worker 		int32 huffPutBits;
2634*fd1fabb7SAndroid Build Coastguard Worker 
2635*fd1fabb7SAndroid Build Coastguard Worker 		// Lookup table for number of bits in an 8 bit value.
2636*fd1fabb7SAndroid Build Coastguard Worker 
2637*fd1fabb7SAndroid Build Coastguard Worker 		int numBitsTable [256];
2638*fd1fabb7SAndroid Build Coastguard Worker 
2639*fd1fabb7SAndroid Build Coastguard Worker 	public:
2640*fd1fabb7SAndroid Build Coastguard Worker 
2641*fd1fabb7SAndroid Build Coastguard Worker 		dng_lossless_encoder (const uint16 *srcData,
2642*fd1fabb7SAndroid Build Coastguard Worker 					 	      uint32 srcRows,
2643*fd1fabb7SAndroid Build Coastguard Worker 					 	      uint32 srcCols,
2644*fd1fabb7SAndroid Build Coastguard Worker 					 	      uint32 srcChannels,
2645*fd1fabb7SAndroid Build Coastguard Worker 					 	      uint32 srcBitDepth,
2646*fd1fabb7SAndroid Build Coastguard Worker 					 	      int32 srcRowStep,
2647*fd1fabb7SAndroid Build Coastguard Worker 					 	      int32 srcColStep,
2648*fd1fabb7SAndroid Build Coastguard Worker 					 	      dng_stream &stream);
2649*fd1fabb7SAndroid Build Coastguard Worker 
2650*fd1fabb7SAndroid Build Coastguard Worker 		void Encode ();
2651*fd1fabb7SAndroid Build Coastguard Worker 
2652*fd1fabb7SAndroid Build Coastguard Worker 	private:
2653*fd1fabb7SAndroid Build Coastguard Worker 
2654*fd1fabb7SAndroid Build Coastguard Worker 		void EmitByte (uint8 value);
2655*fd1fabb7SAndroid Build Coastguard Worker 
2656*fd1fabb7SAndroid Build Coastguard Worker 		void EmitBits (int code, int size);
2657*fd1fabb7SAndroid Build Coastguard Worker 
2658*fd1fabb7SAndroid Build Coastguard Worker 		void FlushBits ();
2659*fd1fabb7SAndroid Build Coastguard Worker 
2660*fd1fabb7SAndroid Build Coastguard Worker 		void CountOneDiff (int diff, uint32 *countTable);
2661*fd1fabb7SAndroid Build Coastguard Worker 
2662*fd1fabb7SAndroid Build Coastguard Worker 		void EncodeOneDiff (int diff, HuffmanTable *dctbl);
2663*fd1fabb7SAndroid Build Coastguard Worker 
2664*fd1fabb7SAndroid Build Coastguard Worker 		void FreqCountSet ();
2665*fd1fabb7SAndroid Build Coastguard Worker 
2666*fd1fabb7SAndroid Build Coastguard Worker 		void HuffEncode ();
2667*fd1fabb7SAndroid Build Coastguard Worker 
2668*fd1fabb7SAndroid Build Coastguard Worker 		void GenHuffCoding (HuffmanTable *htbl, uint32 *freq);
2669*fd1fabb7SAndroid Build Coastguard Worker 
2670*fd1fabb7SAndroid Build Coastguard Worker 		void HuffOptimize ();
2671*fd1fabb7SAndroid Build Coastguard Worker 
2672*fd1fabb7SAndroid Build Coastguard Worker 		void EmitMarker (JpegMarker mark);
2673*fd1fabb7SAndroid Build Coastguard Worker 
2674*fd1fabb7SAndroid Build Coastguard Worker 		void Emit2bytes (int value);
2675*fd1fabb7SAndroid Build Coastguard Worker 
2676*fd1fabb7SAndroid Build Coastguard Worker 		void EmitDht (int index);
2677*fd1fabb7SAndroid Build Coastguard Worker 
2678*fd1fabb7SAndroid Build Coastguard Worker 		void EmitSof (JpegMarker code);
2679*fd1fabb7SAndroid Build Coastguard Worker 
2680*fd1fabb7SAndroid Build Coastguard Worker 		void EmitSos ();
2681*fd1fabb7SAndroid Build Coastguard Worker 
2682*fd1fabb7SAndroid Build Coastguard Worker 		void WriteFileHeader ();
2683*fd1fabb7SAndroid Build Coastguard Worker 
2684*fd1fabb7SAndroid Build Coastguard Worker 		void WriteScanHeader ();
2685*fd1fabb7SAndroid Build Coastguard Worker 
2686*fd1fabb7SAndroid Build Coastguard Worker 		void WriteFileTrailer ();
2687*fd1fabb7SAndroid Build Coastguard Worker 
2688*fd1fabb7SAndroid Build Coastguard Worker 	};
2689*fd1fabb7SAndroid Build Coastguard Worker 
2690*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
2691*fd1fabb7SAndroid Build Coastguard Worker 
dng_lossless_encoder(const uint16 * srcData,uint32 srcRows,uint32 srcCols,uint32 srcChannels,uint32 srcBitDepth,int32 srcRowStep,int32 srcColStep,dng_stream & stream)2692*fd1fabb7SAndroid Build Coastguard Worker dng_lossless_encoder::dng_lossless_encoder (const uint16 *srcData,
2693*fd1fabb7SAndroid Build Coastguard Worker 											uint32 srcRows,
2694*fd1fabb7SAndroid Build Coastguard Worker 											uint32 srcCols,
2695*fd1fabb7SAndroid Build Coastguard Worker 											uint32 srcChannels,
2696*fd1fabb7SAndroid Build Coastguard Worker 											uint32 srcBitDepth,
2697*fd1fabb7SAndroid Build Coastguard Worker 											int32 srcRowStep,
2698*fd1fabb7SAndroid Build Coastguard Worker 											int32 srcColStep,
2699*fd1fabb7SAndroid Build Coastguard Worker 											dng_stream &stream)
2700*fd1fabb7SAndroid Build Coastguard Worker 
2701*fd1fabb7SAndroid Build Coastguard Worker 	:	fSrcData     (srcData    )
2702*fd1fabb7SAndroid Build Coastguard Worker 	,	fSrcRows     (srcRows    )
2703*fd1fabb7SAndroid Build Coastguard Worker 	,	fSrcCols     (srcCols    )
2704*fd1fabb7SAndroid Build Coastguard Worker 	,	fSrcChannels (srcChannels)
2705*fd1fabb7SAndroid Build Coastguard Worker 	,	fSrcBitDepth (srcBitDepth)
2706*fd1fabb7SAndroid Build Coastguard Worker 	,	fSrcRowStep  (srcRowStep )
2707*fd1fabb7SAndroid Build Coastguard Worker 	,	fSrcColStep  (srcColStep )
2708*fd1fabb7SAndroid Build Coastguard Worker 	,	fStream      (stream     )
2709*fd1fabb7SAndroid Build Coastguard Worker 
2710*fd1fabb7SAndroid Build Coastguard Worker 	,	huffPutBuffer (0)
2711*fd1fabb7SAndroid Build Coastguard Worker 	,	huffPutBits   (0)
2712*fd1fabb7SAndroid Build Coastguard Worker 
2713*fd1fabb7SAndroid Build Coastguard Worker 	{
2714*fd1fabb7SAndroid Build Coastguard Worker 
2715*fd1fabb7SAndroid Build Coastguard Worker     // Initialize number of bits lookup table.
2716*fd1fabb7SAndroid Build Coastguard Worker 
2717*fd1fabb7SAndroid Build Coastguard Worker     numBitsTable [0] = 0;
2718*fd1fabb7SAndroid Build Coastguard Worker 
2719*fd1fabb7SAndroid Build Coastguard Worker     for (int i = 1; i < 256; i++)
2720*fd1fabb7SAndroid Build Coastguard Worker     	{
2721*fd1fabb7SAndroid Build Coastguard Worker 
2722*fd1fabb7SAndroid Build Coastguard Worker 		int temp = i;
2723*fd1fabb7SAndroid Build Coastguard Worker 		int nbits = 1;
2724*fd1fabb7SAndroid Build Coastguard Worker 
2725*fd1fabb7SAndroid Build Coastguard Worker 		while (temp >>= 1)
2726*fd1fabb7SAndroid Build Coastguard Worker 			{
2727*fd1fabb7SAndroid Build Coastguard Worker 	    	nbits++;
2728*fd1fabb7SAndroid Build Coastguard Worker 			}
2729*fd1fabb7SAndroid Build Coastguard Worker 
2730*fd1fabb7SAndroid Build Coastguard Worker 		numBitsTable [i] = nbits;
2731*fd1fabb7SAndroid Build Coastguard Worker 
2732*fd1fabb7SAndroid Build Coastguard Worker     	}
2733*fd1fabb7SAndroid Build Coastguard Worker 
2734*fd1fabb7SAndroid Build Coastguard Worker 	}
2735*fd1fabb7SAndroid Build Coastguard Worker 
2736*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
2737*fd1fabb7SAndroid Build Coastguard Worker 
EmitByte(uint8 value)2738*fd1fabb7SAndroid Build Coastguard Worker inline void dng_lossless_encoder::EmitByte (uint8 value)
2739*fd1fabb7SAndroid Build Coastguard Worker 	{
2740*fd1fabb7SAndroid Build Coastguard Worker 
2741*fd1fabb7SAndroid Build Coastguard Worker 	fStream.Put_uint8 (value);
2742*fd1fabb7SAndroid Build Coastguard Worker 
2743*fd1fabb7SAndroid Build Coastguard Worker 	}
2744*fd1fabb7SAndroid Build Coastguard Worker 
2745*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
2746*fd1fabb7SAndroid Build Coastguard Worker 
2747*fd1fabb7SAndroid Build Coastguard Worker /*
2748*fd1fabb7SAndroid Build Coastguard Worker  *--------------------------------------------------------------
2749*fd1fabb7SAndroid Build Coastguard Worker  *
2750*fd1fabb7SAndroid Build Coastguard Worker  * EmitBits --
2751*fd1fabb7SAndroid Build Coastguard Worker  *
2752*fd1fabb7SAndroid Build Coastguard Worker  *	Code for outputting bits to the file
2753*fd1fabb7SAndroid Build Coastguard Worker  *
2754*fd1fabb7SAndroid Build Coastguard Worker  *	Only the right 24 bits of huffPutBuffer are used; the valid
2755*fd1fabb7SAndroid Build Coastguard Worker  *	bits are left-justified in this part.  At most 16 bits can be
2756*fd1fabb7SAndroid Build Coastguard Worker  *	passed to EmitBits in one call, and we never retain more than 7
2757*fd1fabb7SAndroid Build Coastguard Worker  *	bits in huffPutBuffer between calls, so 24 bits are
2758*fd1fabb7SAndroid Build Coastguard Worker  *	sufficient.
2759*fd1fabb7SAndroid Build Coastguard Worker  *
2760*fd1fabb7SAndroid Build Coastguard Worker  * Results:
2761*fd1fabb7SAndroid Build Coastguard Worker  *	None.
2762*fd1fabb7SAndroid Build Coastguard Worker  *
2763*fd1fabb7SAndroid Build Coastguard Worker  * Side effects:
2764*fd1fabb7SAndroid Build Coastguard Worker  *	huffPutBuffer and huffPutBits are updated.
2765*fd1fabb7SAndroid Build Coastguard Worker  *
2766*fd1fabb7SAndroid Build Coastguard Worker  *--------------------------------------------------------------
2767*fd1fabb7SAndroid Build Coastguard Worker  */
2768*fd1fabb7SAndroid Build Coastguard Worker 
EmitBits(int code,int size)2769*fd1fabb7SAndroid Build Coastguard Worker inline void dng_lossless_encoder::EmitBits (int code, int size)
2770*fd1fabb7SAndroid Build Coastguard Worker 	{
2771*fd1fabb7SAndroid Build Coastguard Worker 
2772*fd1fabb7SAndroid Build Coastguard Worker     DNG_ASSERT (size != 0, "Bad Huffman table entry");
2773*fd1fabb7SAndroid Build Coastguard Worker 
2774*fd1fabb7SAndroid Build Coastguard Worker     int putBits   = size;
2775*fd1fabb7SAndroid Build Coastguard Worker 	int putBuffer = code;
2776*fd1fabb7SAndroid Build Coastguard Worker 
2777*fd1fabb7SAndroid Build Coastguard Worker     putBits += huffPutBits;
2778*fd1fabb7SAndroid Build Coastguard Worker 
2779*fd1fabb7SAndroid Build Coastguard Worker     putBuffer <<= 24 - putBits;
2780*fd1fabb7SAndroid Build Coastguard Worker     putBuffer |= huffPutBuffer;
2781*fd1fabb7SAndroid Build Coastguard Worker 
2782*fd1fabb7SAndroid Build Coastguard Worker     while (putBits >= 8)
2783*fd1fabb7SAndroid Build Coastguard Worker     	{
2784*fd1fabb7SAndroid Build Coastguard Worker 
2785*fd1fabb7SAndroid Build Coastguard Worker 		uint8 c = (uint8) (putBuffer >> 16);
2786*fd1fabb7SAndroid Build Coastguard Worker 
2787*fd1fabb7SAndroid Build Coastguard Worker 		// Output whole bytes we've accumulated with byte stuffing
2788*fd1fabb7SAndroid Build Coastguard Worker 
2789*fd1fabb7SAndroid Build Coastguard Worker 		EmitByte (c);
2790*fd1fabb7SAndroid Build Coastguard Worker 
2791*fd1fabb7SAndroid Build Coastguard Worker 		if (c == 0xFF)
2792*fd1fabb7SAndroid Build Coastguard Worker 			{
2793*fd1fabb7SAndroid Build Coastguard Worker 	   	 	EmitByte (0);
2794*fd1fabb7SAndroid Build Coastguard Worker 			}
2795*fd1fabb7SAndroid Build Coastguard Worker 
2796*fd1fabb7SAndroid Build Coastguard Worker 		putBuffer <<= 8;
2797*fd1fabb7SAndroid Build Coastguard Worker 		putBits -= 8;
2798*fd1fabb7SAndroid Build Coastguard Worker 
2799*fd1fabb7SAndroid Build Coastguard Worker     	}
2800*fd1fabb7SAndroid Build Coastguard Worker 
2801*fd1fabb7SAndroid Build Coastguard Worker     huffPutBuffer = putBuffer;
2802*fd1fabb7SAndroid Build Coastguard Worker     huffPutBits   = putBits;
2803*fd1fabb7SAndroid Build Coastguard Worker 
2804*fd1fabb7SAndroid Build Coastguard Worker 	}
2805*fd1fabb7SAndroid Build Coastguard Worker 
2806*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
2807*fd1fabb7SAndroid Build Coastguard Worker 
2808*fd1fabb7SAndroid Build Coastguard Worker /*
2809*fd1fabb7SAndroid Build Coastguard Worker  *--------------------------------------------------------------
2810*fd1fabb7SAndroid Build Coastguard Worker  *
2811*fd1fabb7SAndroid Build Coastguard Worker  * FlushBits --
2812*fd1fabb7SAndroid Build Coastguard Worker  *
2813*fd1fabb7SAndroid Build Coastguard Worker  *	Flush any remaining bits in the bit buffer. Used before emitting
2814*fd1fabb7SAndroid Build Coastguard Worker  *	a marker.
2815*fd1fabb7SAndroid Build Coastguard Worker  *
2816*fd1fabb7SAndroid Build Coastguard Worker  * Results:
2817*fd1fabb7SAndroid Build Coastguard Worker  *	None.
2818*fd1fabb7SAndroid Build Coastguard Worker  *
2819*fd1fabb7SAndroid Build Coastguard Worker  * Side effects:
2820*fd1fabb7SAndroid Build Coastguard Worker  *	huffPutBuffer and huffPutBits are reset
2821*fd1fabb7SAndroid Build Coastguard Worker  *
2822*fd1fabb7SAndroid Build Coastguard Worker  *--------------------------------------------------------------
2823*fd1fabb7SAndroid Build Coastguard Worker  */
2824*fd1fabb7SAndroid Build Coastguard Worker 
FlushBits()2825*fd1fabb7SAndroid Build Coastguard Worker void dng_lossless_encoder::FlushBits ()
2826*fd1fabb7SAndroid Build Coastguard Worker 	{
2827*fd1fabb7SAndroid Build Coastguard Worker 
2828*fd1fabb7SAndroid Build Coastguard Worker     // The first call forces output of any partial bytes.
2829*fd1fabb7SAndroid Build Coastguard Worker 
2830*fd1fabb7SAndroid Build Coastguard Worker     EmitBits (0x007F, 7);
2831*fd1fabb7SAndroid Build Coastguard Worker 
2832*fd1fabb7SAndroid Build Coastguard Worker     // We can then zero the buffer.
2833*fd1fabb7SAndroid Build Coastguard Worker 
2834*fd1fabb7SAndroid Build Coastguard Worker     huffPutBuffer = 0;
2835*fd1fabb7SAndroid Build Coastguard Worker     huffPutBits   = 0;
2836*fd1fabb7SAndroid Build Coastguard Worker 
2837*fd1fabb7SAndroid Build Coastguard Worker 	}
2838*fd1fabb7SAndroid Build Coastguard Worker 
2839*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
2840*fd1fabb7SAndroid Build Coastguard Worker 
2841*fd1fabb7SAndroid Build Coastguard Worker /*
2842*fd1fabb7SAndroid Build Coastguard Worker  *--------------------------------------------------------------
2843*fd1fabb7SAndroid Build Coastguard Worker  *
2844*fd1fabb7SAndroid Build Coastguard Worker  * CountOneDiff --
2845*fd1fabb7SAndroid Build Coastguard Worker  *
2846*fd1fabb7SAndroid Build Coastguard Worker  *      Count the difference value in countTable.
2847*fd1fabb7SAndroid Build Coastguard Worker  *
2848*fd1fabb7SAndroid Build Coastguard Worker  * Results:
2849*fd1fabb7SAndroid Build Coastguard Worker  *      diff is counted in countTable.
2850*fd1fabb7SAndroid Build Coastguard Worker  *
2851*fd1fabb7SAndroid Build Coastguard Worker  * Side effects:
2852*fd1fabb7SAndroid Build Coastguard Worker  *      None.
2853*fd1fabb7SAndroid Build Coastguard Worker  *
2854*fd1fabb7SAndroid Build Coastguard Worker  *--------------------------------------------------------------
2855*fd1fabb7SAndroid Build Coastguard Worker  */
2856*fd1fabb7SAndroid Build Coastguard Worker 
CountOneDiff(int diff,uint32 * countTable)2857*fd1fabb7SAndroid Build Coastguard Worker inline void dng_lossless_encoder::CountOneDiff (int diff, uint32 *countTable)
2858*fd1fabb7SAndroid Build Coastguard Worker 	{
2859*fd1fabb7SAndroid Build Coastguard Worker 
2860*fd1fabb7SAndroid Build Coastguard Worker     // Encode the DC coefficient difference per section F.1.2.1
2861*fd1fabb7SAndroid Build Coastguard Worker 
2862*fd1fabb7SAndroid Build Coastguard Worker     int temp = diff;
2863*fd1fabb7SAndroid Build Coastguard Worker 
2864*fd1fabb7SAndroid Build Coastguard Worker     if (temp < 0)
2865*fd1fabb7SAndroid Build Coastguard Worker     	{
2866*fd1fabb7SAndroid Build Coastguard Worker 
2867*fd1fabb7SAndroid Build Coastguard Worker  		temp = -temp;
2868*fd1fabb7SAndroid Build Coastguard Worker 
2869*fd1fabb7SAndroid Build Coastguard Worker 	    }
2870*fd1fabb7SAndroid Build Coastguard Worker 
2871*fd1fabb7SAndroid Build Coastguard Worker     // Find the number of bits needed for the magnitude of the coefficient
2872*fd1fabb7SAndroid Build Coastguard Worker 
2873*fd1fabb7SAndroid Build Coastguard Worker     int nbits = temp >= 256 ? numBitsTable [temp >> 8  ] + 8
2874*fd1fabb7SAndroid Build Coastguard Worker     						: numBitsTable [temp & 0xFF];
2875*fd1fabb7SAndroid Build Coastguard Worker 
2876*fd1fabb7SAndroid Build Coastguard Worker     // Update count for this bit length
2877*fd1fabb7SAndroid Build Coastguard Worker 
2878*fd1fabb7SAndroid Build Coastguard Worker     countTable [nbits] ++;
2879*fd1fabb7SAndroid Build Coastguard Worker 
2880*fd1fabb7SAndroid Build Coastguard Worker 	}
2881*fd1fabb7SAndroid Build Coastguard Worker 
2882*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
2883*fd1fabb7SAndroid Build Coastguard Worker 
2884*fd1fabb7SAndroid Build Coastguard Worker /*
2885*fd1fabb7SAndroid Build Coastguard Worker  *--------------------------------------------------------------
2886*fd1fabb7SAndroid Build Coastguard Worker  *
2887*fd1fabb7SAndroid Build Coastguard Worker  * EncodeOneDiff --
2888*fd1fabb7SAndroid Build Coastguard Worker  *
2889*fd1fabb7SAndroid Build Coastguard Worker  *	Encode a single difference value.
2890*fd1fabb7SAndroid Build Coastguard Worker  *
2891*fd1fabb7SAndroid Build Coastguard Worker  * Results:
2892*fd1fabb7SAndroid Build Coastguard Worker  *	None.
2893*fd1fabb7SAndroid Build Coastguard Worker  *
2894*fd1fabb7SAndroid Build Coastguard Worker  * Side effects:
2895*fd1fabb7SAndroid Build Coastguard Worker  *	None.
2896*fd1fabb7SAndroid Build Coastguard Worker  *
2897*fd1fabb7SAndroid Build Coastguard Worker  *--------------------------------------------------------------
2898*fd1fabb7SAndroid Build Coastguard Worker  */
2899*fd1fabb7SAndroid Build Coastguard Worker 
EncodeOneDiff(int diff,HuffmanTable * dctbl)2900*fd1fabb7SAndroid Build Coastguard Worker inline void dng_lossless_encoder::EncodeOneDiff (int diff, HuffmanTable *dctbl)
2901*fd1fabb7SAndroid Build Coastguard Worker 	{
2902*fd1fabb7SAndroid Build Coastguard Worker 
2903*fd1fabb7SAndroid Build Coastguard Worker     // Encode the DC coefficient difference per section F.1.2.1
2904*fd1fabb7SAndroid Build Coastguard Worker 
2905*fd1fabb7SAndroid Build Coastguard Worker     int temp  = diff;
2906*fd1fabb7SAndroid Build Coastguard Worker     int temp2 = diff;
2907*fd1fabb7SAndroid Build Coastguard Worker 
2908*fd1fabb7SAndroid Build Coastguard Worker     if (temp < 0)
2909*fd1fabb7SAndroid Build Coastguard Worker     	{
2910*fd1fabb7SAndroid Build Coastguard Worker 
2911*fd1fabb7SAndroid Build Coastguard Worker 		temp = -temp;
2912*fd1fabb7SAndroid Build Coastguard Worker 
2913*fd1fabb7SAndroid Build Coastguard Worker 		// For a negative input, want temp2 = bitwise complement of
2914*fd1fabb7SAndroid Build Coastguard Worker 		// abs (input).  This code assumes we are on a two's complement
2915*fd1fabb7SAndroid Build Coastguard Worker 		// machine.
2916*fd1fabb7SAndroid Build Coastguard Worker 
2917*fd1fabb7SAndroid Build Coastguard Worker 		temp2--;
2918*fd1fabb7SAndroid Build Coastguard Worker 
2919*fd1fabb7SAndroid Build Coastguard Worker 	    }
2920*fd1fabb7SAndroid Build Coastguard Worker 
2921*fd1fabb7SAndroid Build Coastguard Worker     // Find the number of bits needed for the magnitude of the coefficient
2922*fd1fabb7SAndroid Build Coastguard Worker 
2923*fd1fabb7SAndroid Build Coastguard Worker     int nbits = temp >= 256 ? numBitsTable [temp >> 8  ] + 8
2924*fd1fabb7SAndroid Build Coastguard Worker     						: numBitsTable [temp & 0xFF];
2925*fd1fabb7SAndroid Build Coastguard Worker 
2926*fd1fabb7SAndroid Build Coastguard Worker     // Emit the Huffman-coded symbol for the number of bits
2927*fd1fabb7SAndroid Build Coastguard Worker 
2928*fd1fabb7SAndroid Build Coastguard Worker     EmitBits (dctbl->ehufco [nbits],
2929*fd1fabb7SAndroid Build Coastguard Worker     		  dctbl->ehufsi [nbits]);
2930*fd1fabb7SAndroid Build Coastguard Worker 
2931*fd1fabb7SAndroid Build Coastguard Worker     // Emit that number of bits of the value, if positive,
2932*fd1fabb7SAndroid Build Coastguard Worker     // or the complement of its magnitude, if negative.
2933*fd1fabb7SAndroid Build Coastguard Worker 
2934*fd1fabb7SAndroid Build Coastguard Worker     // If the number of bits is 16, there is only one possible difference
2935*fd1fabb7SAndroid Build Coastguard Worker     // value (-32786), so the lossless JPEG spec says not to output anything
2936*fd1fabb7SAndroid Build Coastguard Worker     // in that case.  So we only need to output the diference value if
2937*fd1fabb7SAndroid Build Coastguard Worker     // the number of bits is between 1 and 15.
2938*fd1fabb7SAndroid Build Coastguard Worker 
2939*fd1fabb7SAndroid Build Coastguard Worker     if (nbits & 15)
2940*fd1fabb7SAndroid Build Coastguard Worker     	{
2941*fd1fabb7SAndroid Build Coastguard Worker 
2942*fd1fabb7SAndroid Build Coastguard Worker 		EmitBits (temp2 & (0x0FFFF >> (16 - nbits)),
2943*fd1fabb7SAndroid Build Coastguard Worker 				  nbits);
2944*fd1fabb7SAndroid Build Coastguard Worker 
2945*fd1fabb7SAndroid Build Coastguard Worker 		}
2946*fd1fabb7SAndroid Build Coastguard Worker 
2947*fd1fabb7SAndroid Build Coastguard Worker 	}
2948*fd1fabb7SAndroid Build Coastguard Worker 
2949*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
2950*fd1fabb7SAndroid Build Coastguard Worker 
2951*fd1fabb7SAndroid Build Coastguard Worker /*
2952*fd1fabb7SAndroid Build Coastguard Worker  *--------------------------------------------------------------
2953*fd1fabb7SAndroid Build Coastguard Worker  *
2954*fd1fabb7SAndroid Build Coastguard Worker  * FreqCountSet --
2955*fd1fabb7SAndroid Build Coastguard Worker  *
2956*fd1fabb7SAndroid Build Coastguard Worker  *      Count the times each category symbol occurs in this image.
2957*fd1fabb7SAndroid Build Coastguard Worker  *
2958*fd1fabb7SAndroid Build Coastguard Worker  * Results:
2959*fd1fabb7SAndroid Build Coastguard Worker  *	None.
2960*fd1fabb7SAndroid Build Coastguard Worker  *
2961*fd1fabb7SAndroid Build Coastguard Worker  * Side effects:
2962*fd1fabb7SAndroid Build Coastguard Worker  *	The freqCount has counted all category
2963*fd1fabb7SAndroid Build Coastguard Worker  *	symbols appeared in the image.
2964*fd1fabb7SAndroid Build Coastguard Worker  *
2965*fd1fabb7SAndroid Build Coastguard Worker  *--------------------------------------------------------------
2966*fd1fabb7SAndroid Build Coastguard Worker  */
2967*fd1fabb7SAndroid Build Coastguard Worker 
FreqCountSet()2968*fd1fabb7SAndroid Build Coastguard Worker void dng_lossless_encoder::FreqCountSet ()
2969*fd1fabb7SAndroid Build Coastguard Worker 	{
2970*fd1fabb7SAndroid Build Coastguard Worker 
2971*fd1fabb7SAndroid Build Coastguard Worker 	memset (freqCount, 0, sizeof (freqCount));
2972*fd1fabb7SAndroid Build Coastguard Worker 
2973*fd1fabb7SAndroid Build Coastguard Worker 	DNG_ASSERT ((int32)fSrcRows >= 0, "dng_lossless_encoder::FreqCountSet: fSrcRpws too large.");
2974*fd1fabb7SAndroid Build Coastguard Worker 
2975*fd1fabb7SAndroid Build Coastguard Worker     for (int32 row = 0; row < (int32)fSrcRows; row++)
2976*fd1fabb7SAndroid Build Coastguard Worker     	{
2977*fd1fabb7SAndroid Build Coastguard Worker 
2978*fd1fabb7SAndroid Build Coastguard Worker 		const uint16 *sPtr = fSrcData + row * fSrcRowStep;
2979*fd1fabb7SAndroid Build Coastguard Worker 
2980*fd1fabb7SAndroid Build Coastguard Worker 		// Initialize predictors for this row.
2981*fd1fabb7SAndroid Build Coastguard Worker 
2982*fd1fabb7SAndroid Build Coastguard Worker 		int32 predictor [4];
2983*fd1fabb7SAndroid Build Coastguard Worker 
2984*fd1fabb7SAndroid Build Coastguard Worker 		for (int32 channel = 0; channel < (int32)fSrcChannels; channel++)
2985*fd1fabb7SAndroid Build Coastguard Worker 			{
2986*fd1fabb7SAndroid Build Coastguard Worker 
2987*fd1fabb7SAndroid Build Coastguard Worker 			if (row == 0)
2988*fd1fabb7SAndroid Build Coastguard Worker 				predictor [channel] = 1 << (fSrcBitDepth - 1);
2989*fd1fabb7SAndroid Build Coastguard Worker 
2990*fd1fabb7SAndroid Build Coastguard Worker 			else
2991*fd1fabb7SAndroid Build Coastguard Worker 				predictor [channel] = sPtr [channel - fSrcRowStep];
2992*fd1fabb7SAndroid Build Coastguard Worker 
2993*fd1fabb7SAndroid Build Coastguard Worker 			}
2994*fd1fabb7SAndroid Build Coastguard Worker 
2995*fd1fabb7SAndroid Build Coastguard Worker 		// Unroll most common case of two channels
2996*fd1fabb7SAndroid Build Coastguard Worker 
2997*fd1fabb7SAndroid Build Coastguard Worker 		if (fSrcChannels == 2)
2998*fd1fabb7SAndroid Build Coastguard Worker 			{
2999*fd1fabb7SAndroid Build Coastguard Worker 
3000*fd1fabb7SAndroid Build Coastguard Worker 			int32 pred0 = predictor [0];
3001*fd1fabb7SAndroid Build Coastguard Worker 			int32 pred1 = predictor [1];
3002*fd1fabb7SAndroid Build Coastguard Worker 
3003*fd1fabb7SAndroid Build Coastguard Worker 			uint32 srcCols    = fSrcCols;
3004*fd1fabb7SAndroid Build Coastguard Worker 			int32  srcColStep = fSrcColStep;
3005*fd1fabb7SAndroid Build Coastguard Worker 
3006*fd1fabb7SAndroid Build Coastguard Worker 	    	for (uint32 col = 0; col < srcCols; col++)
3007*fd1fabb7SAndroid Build Coastguard Worker 	    		{
3008*fd1fabb7SAndroid Build Coastguard Worker 
3009*fd1fabb7SAndroid Build Coastguard Worker     			int32 pixel0 = sPtr [0];
3010*fd1fabb7SAndroid Build Coastguard Worker 				int32 pixel1 = sPtr [1];
3011*fd1fabb7SAndroid Build Coastguard Worker 
3012*fd1fabb7SAndroid Build Coastguard Worker     			int16 diff0 = (int16) (pixel0 - pred0);
3013*fd1fabb7SAndroid Build Coastguard Worker     			int16 diff1 = (int16) (pixel1 - pred1);
3014*fd1fabb7SAndroid Build Coastguard Worker 
3015*fd1fabb7SAndroid Build Coastguard Worker     			CountOneDiff (diff0, freqCount [0]);
3016*fd1fabb7SAndroid Build Coastguard Worker     			CountOneDiff (diff1, freqCount [1]);
3017*fd1fabb7SAndroid Build Coastguard Worker 
3018*fd1fabb7SAndroid Build Coastguard Worker     			pred0 = pixel0;
3019*fd1fabb7SAndroid Build Coastguard Worker    				pred1 = pixel1;
3020*fd1fabb7SAndroid Build Coastguard Worker 
3021*fd1fabb7SAndroid Build Coastguard Worker 	    		sPtr += srcColStep;
3022*fd1fabb7SAndroid Build Coastguard Worker 
3023*fd1fabb7SAndroid Build Coastguard Worker 	    		}
3024*fd1fabb7SAndroid Build Coastguard Worker 
3025*fd1fabb7SAndroid Build Coastguard Worker 			}
3026*fd1fabb7SAndroid Build Coastguard Worker 
3027*fd1fabb7SAndroid Build Coastguard Worker 		// General case.
3028*fd1fabb7SAndroid Build Coastguard Worker 
3029*fd1fabb7SAndroid Build Coastguard Worker 		else
3030*fd1fabb7SAndroid Build Coastguard Worker 			{
3031*fd1fabb7SAndroid Build Coastguard Worker 
3032*fd1fabb7SAndroid Build Coastguard Worker 	    	for (uint32 col = 0; col < fSrcCols; col++)
3033*fd1fabb7SAndroid Build Coastguard Worker 	    		{
3034*fd1fabb7SAndroid Build Coastguard Worker 
3035*fd1fabb7SAndroid Build Coastguard Worker 	    		for (uint32 channel = 0; channel < fSrcChannels; channel++)
3036*fd1fabb7SAndroid Build Coastguard Worker 	    			{
3037*fd1fabb7SAndroid Build Coastguard Worker 
3038*fd1fabb7SAndroid Build Coastguard Worker 	    			int32 pixel = sPtr [channel];
3039*fd1fabb7SAndroid Build Coastguard Worker 
3040*fd1fabb7SAndroid Build Coastguard Worker 	    			int16 diff = (int16) (pixel - predictor [channel]);
3041*fd1fabb7SAndroid Build Coastguard Worker 
3042*fd1fabb7SAndroid Build Coastguard Worker 	    			CountOneDiff (diff, freqCount [channel]);
3043*fd1fabb7SAndroid Build Coastguard Worker 
3044*fd1fabb7SAndroid Build Coastguard Worker 	    			predictor [channel] = pixel;
3045*fd1fabb7SAndroid Build Coastguard Worker 
3046*fd1fabb7SAndroid Build Coastguard Worker 	    			}
3047*fd1fabb7SAndroid Build Coastguard Worker 
3048*fd1fabb7SAndroid Build Coastguard Worker 	    		sPtr += fSrcColStep;
3049*fd1fabb7SAndroid Build Coastguard Worker 
3050*fd1fabb7SAndroid Build Coastguard Worker 	    		}
3051*fd1fabb7SAndroid Build Coastguard Worker 
3052*fd1fabb7SAndroid Build Coastguard Worker 	    	}
3053*fd1fabb7SAndroid Build Coastguard Worker 
3054*fd1fabb7SAndroid Build Coastguard Worker     	}
3055*fd1fabb7SAndroid Build Coastguard Worker 
3056*fd1fabb7SAndroid Build Coastguard Worker 	}
3057*fd1fabb7SAndroid Build Coastguard Worker 
3058*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
3059*fd1fabb7SAndroid Build Coastguard Worker 
3060*fd1fabb7SAndroid Build Coastguard Worker /*
3061*fd1fabb7SAndroid Build Coastguard Worker  *--------------------------------------------------------------
3062*fd1fabb7SAndroid Build Coastguard Worker  *
3063*fd1fabb7SAndroid Build Coastguard Worker  * HuffEncode --
3064*fd1fabb7SAndroid Build Coastguard Worker  *
3065*fd1fabb7SAndroid Build Coastguard Worker  *      Encode and output Huffman-compressed image data.
3066*fd1fabb7SAndroid Build Coastguard Worker  *
3067*fd1fabb7SAndroid Build Coastguard Worker  * Results:
3068*fd1fabb7SAndroid Build Coastguard Worker  *      None.
3069*fd1fabb7SAndroid Build Coastguard Worker  *
3070*fd1fabb7SAndroid Build Coastguard Worker  * Side effects:
3071*fd1fabb7SAndroid Build Coastguard Worker  *      None.
3072*fd1fabb7SAndroid Build Coastguard Worker  *
3073*fd1fabb7SAndroid Build Coastguard Worker  *--------------------------------------------------------------
3074*fd1fabb7SAndroid Build Coastguard Worker  */
3075*fd1fabb7SAndroid Build Coastguard Worker 
HuffEncode()3076*fd1fabb7SAndroid Build Coastguard Worker void dng_lossless_encoder::HuffEncode ()
3077*fd1fabb7SAndroid Build Coastguard Worker 	{
3078*fd1fabb7SAndroid Build Coastguard Worker 
3079*fd1fabb7SAndroid Build Coastguard Worker 	DNG_ASSERT ((int32)fSrcRows >= 0, "dng_lossless_encoder::HuffEncode: fSrcRows too large.");
3080*fd1fabb7SAndroid Build Coastguard Worker 
3081*fd1fabb7SAndroid Build Coastguard Worker 	for (int32 row = 0; row < (int32)fSrcRows; row++)
3082*fd1fabb7SAndroid Build Coastguard Worker     	{
3083*fd1fabb7SAndroid Build Coastguard Worker 
3084*fd1fabb7SAndroid Build Coastguard Worker 		const uint16 *sPtr = fSrcData + row * fSrcRowStep;
3085*fd1fabb7SAndroid Build Coastguard Worker 
3086*fd1fabb7SAndroid Build Coastguard Worker 		// Initialize predictors for this row.
3087*fd1fabb7SAndroid Build Coastguard Worker 
3088*fd1fabb7SAndroid Build Coastguard Worker 		int32 predictor [4];
3089*fd1fabb7SAndroid Build Coastguard Worker 
3090*fd1fabb7SAndroid Build Coastguard Worker 		for (int32 channel = 0; channel < (int32)fSrcChannels; channel++)
3091*fd1fabb7SAndroid Build Coastguard Worker 			{
3092*fd1fabb7SAndroid Build Coastguard Worker 
3093*fd1fabb7SAndroid Build Coastguard Worker 			if (row == 0)
3094*fd1fabb7SAndroid Build Coastguard Worker 				predictor [channel] = 1 << (fSrcBitDepth - 1);
3095*fd1fabb7SAndroid Build Coastguard Worker 
3096*fd1fabb7SAndroid Build Coastguard Worker 			else
3097*fd1fabb7SAndroid Build Coastguard Worker 				predictor [channel] = sPtr [channel - fSrcRowStep];
3098*fd1fabb7SAndroid Build Coastguard Worker 
3099*fd1fabb7SAndroid Build Coastguard Worker 			}
3100*fd1fabb7SAndroid Build Coastguard Worker 
3101*fd1fabb7SAndroid Build Coastguard Worker 		// Unroll most common case of two channels
3102*fd1fabb7SAndroid Build Coastguard Worker 
3103*fd1fabb7SAndroid Build Coastguard Worker 		if (fSrcChannels == 2)
3104*fd1fabb7SAndroid Build Coastguard Worker 			{
3105*fd1fabb7SAndroid Build Coastguard Worker 
3106*fd1fabb7SAndroid Build Coastguard Worker 			int32 pred0 = predictor [0];
3107*fd1fabb7SAndroid Build Coastguard Worker 			int32 pred1 = predictor [1];
3108*fd1fabb7SAndroid Build Coastguard Worker 
3109*fd1fabb7SAndroid Build Coastguard Worker 			uint32 srcCols    = fSrcCols;
3110*fd1fabb7SAndroid Build Coastguard Worker 			int32  srcColStep = fSrcColStep;
3111*fd1fabb7SAndroid Build Coastguard Worker 
3112*fd1fabb7SAndroid Build Coastguard Worker 	    	for (uint32 col = 0; col < srcCols; col++)
3113*fd1fabb7SAndroid Build Coastguard Worker 	    		{
3114*fd1fabb7SAndroid Build Coastguard Worker 
3115*fd1fabb7SAndroid Build Coastguard Worker     			int32 pixel0 = sPtr [0];
3116*fd1fabb7SAndroid Build Coastguard Worker 				int32 pixel1 = sPtr [1];
3117*fd1fabb7SAndroid Build Coastguard Worker 
3118*fd1fabb7SAndroid Build Coastguard Worker     			int16 diff0 = (int16) (pixel0 - pred0);
3119*fd1fabb7SAndroid Build Coastguard Worker     			int16 diff1 = (int16) (pixel1 - pred1);
3120*fd1fabb7SAndroid Build Coastguard Worker 
3121*fd1fabb7SAndroid Build Coastguard Worker     			EncodeOneDiff (diff0, &huffTable [0]);
3122*fd1fabb7SAndroid Build Coastguard Worker    				EncodeOneDiff (diff1, &huffTable [1]);
3123*fd1fabb7SAndroid Build Coastguard Worker 
3124*fd1fabb7SAndroid Build Coastguard Worker     			pred0 = pixel0;
3125*fd1fabb7SAndroid Build Coastguard Worker    				pred1 = pixel1;
3126*fd1fabb7SAndroid Build Coastguard Worker 
3127*fd1fabb7SAndroid Build Coastguard Worker 	    		sPtr += srcColStep;
3128*fd1fabb7SAndroid Build Coastguard Worker 
3129*fd1fabb7SAndroid Build Coastguard Worker 	    		}
3130*fd1fabb7SAndroid Build Coastguard Worker 
3131*fd1fabb7SAndroid Build Coastguard Worker 			}
3132*fd1fabb7SAndroid Build Coastguard Worker 
3133*fd1fabb7SAndroid Build Coastguard Worker 		// General case.
3134*fd1fabb7SAndroid Build Coastguard Worker 
3135*fd1fabb7SAndroid Build Coastguard Worker 		else
3136*fd1fabb7SAndroid Build Coastguard Worker 			{
3137*fd1fabb7SAndroid Build Coastguard Worker 
3138*fd1fabb7SAndroid Build Coastguard Worker 	    	for (uint32 col = 0; col < fSrcCols; col++)
3139*fd1fabb7SAndroid Build Coastguard Worker 	    		{
3140*fd1fabb7SAndroid Build Coastguard Worker 
3141*fd1fabb7SAndroid Build Coastguard Worker 	    		for (uint32 channel = 0; channel < fSrcChannels; channel++)
3142*fd1fabb7SAndroid Build Coastguard Worker 	    			{
3143*fd1fabb7SAndroid Build Coastguard Worker 
3144*fd1fabb7SAndroid Build Coastguard Worker 	    			int32 pixel = sPtr [channel];
3145*fd1fabb7SAndroid Build Coastguard Worker 
3146*fd1fabb7SAndroid Build Coastguard Worker 	    			int16 diff = (int16) (pixel - predictor [channel]);
3147*fd1fabb7SAndroid Build Coastguard Worker 
3148*fd1fabb7SAndroid Build Coastguard Worker     				EncodeOneDiff (diff, &huffTable [channel]);
3149*fd1fabb7SAndroid Build Coastguard Worker 
3150*fd1fabb7SAndroid Build Coastguard Worker 	    			predictor [channel] = pixel;
3151*fd1fabb7SAndroid Build Coastguard Worker 
3152*fd1fabb7SAndroid Build Coastguard Worker 	    			}
3153*fd1fabb7SAndroid Build Coastguard Worker 
3154*fd1fabb7SAndroid Build Coastguard Worker 	    		sPtr += fSrcColStep;
3155*fd1fabb7SAndroid Build Coastguard Worker 
3156*fd1fabb7SAndroid Build Coastguard Worker 	    		}
3157*fd1fabb7SAndroid Build Coastguard Worker 
3158*fd1fabb7SAndroid Build Coastguard Worker 	    	}
3159*fd1fabb7SAndroid Build Coastguard Worker 
3160*fd1fabb7SAndroid Build Coastguard Worker     	}
3161*fd1fabb7SAndroid Build Coastguard Worker 
3162*fd1fabb7SAndroid Build Coastguard Worker     FlushBits ();
3163*fd1fabb7SAndroid Build Coastguard Worker 
3164*fd1fabb7SAndroid Build Coastguard Worker 	}
3165*fd1fabb7SAndroid Build Coastguard Worker 
3166*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
3167*fd1fabb7SAndroid Build Coastguard Worker 
3168*fd1fabb7SAndroid Build Coastguard Worker /*
3169*fd1fabb7SAndroid Build Coastguard Worker  *--------------------------------------------------------------
3170*fd1fabb7SAndroid Build Coastguard Worker  *
3171*fd1fabb7SAndroid Build Coastguard Worker  * GenHuffCoding --
3172*fd1fabb7SAndroid Build Coastguard Worker  *
3173*fd1fabb7SAndroid Build Coastguard Worker  * 	Generate the optimal coding for the given counts.
3174*fd1fabb7SAndroid Build Coastguard Worker  *	This algorithm is explained in section K.2 of the
3175*fd1fabb7SAndroid Build Coastguard Worker  *	JPEG standard.
3176*fd1fabb7SAndroid Build Coastguard Worker  *
3177*fd1fabb7SAndroid Build Coastguard Worker  * Results:
3178*fd1fabb7SAndroid Build Coastguard Worker  *      htbl->bits and htbl->huffval are constructed.
3179*fd1fabb7SAndroid Build Coastguard Worker  *
3180*fd1fabb7SAndroid Build Coastguard Worker  * Side effects:
3181*fd1fabb7SAndroid Build Coastguard Worker  *      None.
3182*fd1fabb7SAndroid Build Coastguard Worker  *
3183*fd1fabb7SAndroid Build Coastguard Worker  *--------------------------------------------------------------
3184*fd1fabb7SAndroid Build Coastguard Worker  */
3185*fd1fabb7SAndroid Build Coastguard Worker 
GenHuffCoding(HuffmanTable * htbl,uint32 * freq)3186*fd1fabb7SAndroid Build Coastguard Worker void dng_lossless_encoder::GenHuffCoding (HuffmanTable *htbl, uint32 *freq)
3187*fd1fabb7SAndroid Build Coastguard Worker 	{
3188*fd1fabb7SAndroid Build Coastguard Worker 
3189*fd1fabb7SAndroid Build Coastguard Worker 	int i;
3190*fd1fabb7SAndroid Build Coastguard Worker 	int j;
3191*fd1fabb7SAndroid Build Coastguard Worker 
3192*fd1fabb7SAndroid Build Coastguard Worker 	const int MAX_CLEN = 32;     	// assumed maximum initial code length
3193*fd1fabb7SAndroid Build Coastguard Worker 
3194*fd1fabb7SAndroid Build Coastguard Worker 	uint8 bits [MAX_CLEN + 1];	// bits [k] = # of symbols with code length k
3195*fd1fabb7SAndroid Build Coastguard Worker 	short codesize [257];			// codesize [k] = code length of symbol k
3196*fd1fabb7SAndroid Build Coastguard Worker 	short others   [257];			// next symbol in current branch of tree
3197*fd1fabb7SAndroid Build Coastguard Worker 
3198*fd1fabb7SAndroid Build Coastguard Worker 	memset (bits    , 0, sizeof (bits    ));
3199*fd1fabb7SAndroid Build Coastguard Worker   	memset (codesize, 0, sizeof (codesize));
3200*fd1fabb7SAndroid Build Coastguard Worker 
3201*fd1fabb7SAndroid Build Coastguard Worker 	for (i = 0; i < 257; i++)
3202*fd1fabb7SAndroid Build Coastguard Worker 		others [i] = -1;			// init links to empty
3203*fd1fabb7SAndroid Build Coastguard Worker 
3204*fd1fabb7SAndroid Build Coastguard Worker 	// Including the pseudo-symbol 256 in the Huffman procedure guarantees
3205*fd1fabb7SAndroid Build Coastguard Worker 	// that no real symbol is given code-value of all ones, because 256
3206*fd1fabb7SAndroid Build Coastguard Worker 	// will be placed in the largest codeword category.
3207*fd1fabb7SAndroid Build Coastguard Worker 
3208*fd1fabb7SAndroid Build Coastguard Worker 	freq [256] = 1;					// make sure there is a nonzero count
3209*fd1fabb7SAndroid Build Coastguard Worker 
3210*fd1fabb7SAndroid Build Coastguard Worker 	// Huffman's basic algorithm to assign optimal code lengths to symbols
3211*fd1fabb7SAndroid Build Coastguard Worker 
3212*fd1fabb7SAndroid Build Coastguard Worker 	while (true)
3213*fd1fabb7SAndroid Build Coastguard Worker 		{
3214*fd1fabb7SAndroid Build Coastguard Worker 
3215*fd1fabb7SAndroid Build Coastguard Worker 		// Find the smallest nonzero frequency, set c1 = its symbol.
3216*fd1fabb7SAndroid Build Coastguard Worker 		// In case of ties, take the larger symbol number.
3217*fd1fabb7SAndroid Build Coastguard Worker 
3218*fd1fabb7SAndroid Build Coastguard Worker 		int c1 = -1;
3219*fd1fabb7SAndroid Build Coastguard Worker 
3220*fd1fabb7SAndroid Build Coastguard Worker 		uint32 v = 0xFFFFFFFF;
3221*fd1fabb7SAndroid Build Coastguard Worker 
3222*fd1fabb7SAndroid Build Coastguard Worker 		for (i = 0; i <= 256; i++)
3223*fd1fabb7SAndroid Build Coastguard Worker 			{
3224*fd1fabb7SAndroid Build Coastguard Worker 
3225*fd1fabb7SAndroid Build Coastguard Worker 			if (freq [i] && freq [i] <= v)
3226*fd1fabb7SAndroid Build Coastguard Worker 				{
3227*fd1fabb7SAndroid Build Coastguard Worker 				v = freq [i];
3228*fd1fabb7SAndroid Build Coastguard Worker 				c1 = i;
3229*fd1fabb7SAndroid Build Coastguard Worker 				}
3230*fd1fabb7SAndroid Build Coastguard Worker 
3231*fd1fabb7SAndroid Build Coastguard Worker 			}
3232*fd1fabb7SAndroid Build Coastguard Worker 
3233*fd1fabb7SAndroid Build Coastguard Worker 		// Find the next smallest nonzero frequency, set c2 = its symbol.
3234*fd1fabb7SAndroid Build Coastguard Worker 		// In case of ties, take the larger symbol number.
3235*fd1fabb7SAndroid Build Coastguard Worker 
3236*fd1fabb7SAndroid Build Coastguard Worker 		int c2 = -1;
3237*fd1fabb7SAndroid Build Coastguard Worker 
3238*fd1fabb7SAndroid Build Coastguard Worker 		v = 0xFFFFFFFF;
3239*fd1fabb7SAndroid Build Coastguard Worker 
3240*fd1fabb7SAndroid Build Coastguard Worker 		for (i = 0; i <= 256; i++)
3241*fd1fabb7SAndroid Build Coastguard Worker 			{
3242*fd1fabb7SAndroid Build Coastguard Worker 
3243*fd1fabb7SAndroid Build Coastguard Worker       		if (freq [i] && freq [i] <= v && i != c1)
3244*fd1fabb7SAndroid Build Coastguard Worker       			{
3245*fd1fabb7SAndroid Build Coastguard Worker 				v = freq [i];
3246*fd1fabb7SAndroid Build Coastguard Worker 				c2 = i;
3247*fd1fabb7SAndroid Build Coastguard Worker 				}
3248*fd1fabb7SAndroid Build Coastguard Worker 
3249*fd1fabb7SAndroid Build Coastguard Worker 			}
3250*fd1fabb7SAndroid Build Coastguard Worker 
3251*fd1fabb7SAndroid Build Coastguard Worker 		// Done if we've merged everything into one frequency.
3252*fd1fabb7SAndroid Build Coastguard Worker 
3253*fd1fabb7SAndroid Build Coastguard Worker 		if (c2 < 0)
3254*fd1fabb7SAndroid Build Coastguard Worker       		break;
3255*fd1fabb7SAndroid Build Coastguard Worker 
3256*fd1fabb7SAndroid Build Coastguard Worker  		// Else merge the two counts/trees.
3257*fd1fabb7SAndroid Build Coastguard Worker 
3258*fd1fabb7SAndroid Build Coastguard Worker 		freq [c1] += freq [c2];
3259*fd1fabb7SAndroid Build Coastguard Worker 		freq [c2] = 0;
3260*fd1fabb7SAndroid Build Coastguard Worker 
3261*fd1fabb7SAndroid Build Coastguard Worker 		// Increment the codesize of everything in c1's tree branch.
3262*fd1fabb7SAndroid Build Coastguard Worker 
3263*fd1fabb7SAndroid Build Coastguard Worker 		codesize [c1] ++;
3264*fd1fabb7SAndroid Build Coastguard Worker 
3265*fd1fabb7SAndroid Build Coastguard Worker 		while (others [c1] >= 0)
3266*fd1fabb7SAndroid Build Coastguard Worker 			{
3267*fd1fabb7SAndroid Build Coastguard Worker 			c1 = others [c1];
3268*fd1fabb7SAndroid Build Coastguard Worker 			codesize [c1] ++;
3269*fd1fabb7SAndroid Build Coastguard Worker     		}
3270*fd1fabb7SAndroid Build Coastguard Worker 
3271*fd1fabb7SAndroid Build Coastguard Worker 		// chain c2 onto c1's tree branch
3272*fd1fabb7SAndroid Build Coastguard Worker 
3273*fd1fabb7SAndroid Build Coastguard Worker 		others [c1] = (short) c2;
3274*fd1fabb7SAndroid Build Coastguard Worker 
3275*fd1fabb7SAndroid Build Coastguard Worker 		// Increment the codesize of everything in c2's tree branch.
3276*fd1fabb7SAndroid Build Coastguard Worker 
3277*fd1fabb7SAndroid Build Coastguard Worker 		codesize [c2] ++;
3278*fd1fabb7SAndroid Build Coastguard Worker 
3279*fd1fabb7SAndroid Build Coastguard Worker 		while (others [c2] >= 0)
3280*fd1fabb7SAndroid Build Coastguard Worker 			{
3281*fd1fabb7SAndroid Build Coastguard Worker 			c2 = others [c2];
3282*fd1fabb7SAndroid Build Coastguard Worker 			codesize [c2] ++;
3283*fd1fabb7SAndroid Build Coastguard Worker 			}
3284*fd1fabb7SAndroid Build Coastguard Worker 
3285*fd1fabb7SAndroid Build Coastguard Worker 		}
3286*fd1fabb7SAndroid Build Coastguard Worker 
3287*fd1fabb7SAndroid Build Coastguard Worker 	// Now count the number of symbols of each code length.
3288*fd1fabb7SAndroid Build Coastguard Worker 
3289*fd1fabb7SAndroid Build Coastguard Worker 	for (i = 0; i <= 256; i++)
3290*fd1fabb7SAndroid Build Coastguard Worker 		{
3291*fd1fabb7SAndroid Build Coastguard Worker 
3292*fd1fabb7SAndroid Build Coastguard Worker 		if (codesize [i])
3293*fd1fabb7SAndroid Build Coastguard Worker 			{
3294*fd1fabb7SAndroid Build Coastguard Worker 
3295*fd1fabb7SAndroid Build Coastguard Worker  			// The JPEG standard seems to think that this can't happen,
3296*fd1fabb7SAndroid Build Coastguard Worker 			// but I'm paranoid...
3297*fd1fabb7SAndroid Build Coastguard Worker 
3298*fd1fabb7SAndroid Build Coastguard Worker 			if (codesize [i] > MAX_CLEN)
3299*fd1fabb7SAndroid Build Coastguard Worker 				{
3300*fd1fabb7SAndroid Build Coastguard Worker 
3301*fd1fabb7SAndroid Build Coastguard Worker        			DNG_REPORT ("Huffman code size table overflow");
3302*fd1fabb7SAndroid Build Coastguard Worker 
3303*fd1fabb7SAndroid Build Coastguard Worker        			ThrowProgramError ();
3304*fd1fabb7SAndroid Build Coastguard Worker 
3305*fd1fabb7SAndroid Build Coastguard Worker        			}
3306*fd1fabb7SAndroid Build Coastguard Worker 
3307*fd1fabb7SAndroid Build Coastguard Worker 			bits [codesize [i]]++;
3308*fd1fabb7SAndroid Build Coastguard Worker 
3309*fd1fabb7SAndroid Build Coastguard Worker 			}
3310*fd1fabb7SAndroid Build Coastguard Worker 
3311*fd1fabb7SAndroid Build Coastguard Worker 		}
3312*fd1fabb7SAndroid Build Coastguard Worker 
3313*fd1fabb7SAndroid Build Coastguard Worker 	// JPEG doesn't allow symbols with code lengths over 16 bits, so if the pure
3314*fd1fabb7SAndroid Build Coastguard Worker 	// Huffman procedure assigned any such lengths, we must adjust the coding.
3315*fd1fabb7SAndroid Build Coastguard Worker 	// Here is what the JPEG spec says about how this next bit works:
3316*fd1fabb7SAndroid Build Coastguard Worker 	// Since symbols are paired for the longest Huffman code, the symbols are
3317*fd1fabb7SAndroid Build Coastguard Worker 	// removed from this length category two at a time.  The prefix for the pair
3318*fd1fabb7SAndroid Build Coastguard Worker 	// (which is one bit shorter) is allocated to one of the pair; then,
3319*fd1fabb7SAndroid Build Coastguard Worker 	// skipping the BITS entry for that prefix length, a code word from the next
3320*fd1fabb7SAndroid Build Coastguard Worker 	// shortest nonzero BITS entry is converted into a prefix for two code words
3321*fd1fabb7SAndroid Build Coastguard Worker 	// one bit longer.
3322*fd1fabb7SAndroid Build Coastguard Worker 
3323*fd1fabb7SAndroid Build Coastguard Worker 	for (i = MAX_CLEN; i > 16; i--)
3324*fd1fabb7SAndroid Build Coastguard Worker 		{
3325*fd1fabb7SAndroid Build Coastguard Worker 
3326*fd1fabb7SAndroid Build Coastguard Worker 		while (bits [i] > 0)
3327*fd1fabb7SAndroid Build Coastguard Worker 			{
3328*fd1fabb7SAndroid Build Coastguard Worker 
3329*fd1fabb7SAndroid Build Coastguard Worker 			// Kludge: I have never been able to test this logic, and there
3330*fd1fabb7SAndroid Build Coastguard Worker 			// are comments on the web that this encoder has bugs with 16-bit
3331*fd1fabb7SAndroid Build Coastguard Worker 			// data, so just throw an error if we get here and revert to a
3332*fd1fabb7SAndroid Build Coastguard Worker 			// default table.	 - tknoll 12/1/03.
3333*fd1fabb7SAndroid Build Coastguard Worker 
3334*fd1fabb7SAndroid Build Coastguard Worker        		DNG_REPORT ("Info: Optimal huffman table bigger than 16 bits");
3335*fd1fabb7SAndroid Build Coastguard Worker 
3336*fd1fabb7SAndroid Build Coastguard Worker  			ThrowProgramError ();
3337*fd1fabb7SAndroid Build Coastguard Worker 
3338*fd1fabb7SAndroid Build Coastguard Worker 			// Original logic:
3339*fd1fabb7SAndroid Build Coastguard Worker 
3340*fd1fabb7SAndroid Build Coastguard Worker 			j = i - 2;		// find length of new prefix to be used
3341*fd1fabb7SAndroid Build Coastguard Worker 
3342*fd1fabb7SAndroid Build Coastguard Worker 			while (bits [j] == 0)
3343*fd1fabb7SAndroid Build Coastguard Worker 				j--;
3344*fd1fabb7SAndroid Build Coastguard Worker 
3345*fd1fabb7SAndroid Build Coastguard Worker 			bits [i    ] -= 2;		// remove two symbols
3346*fd1fabb7SAndroid Build Coastguard Worker 			bits [i - 1] ++;		// one goes in this length
3347*fd1fabb7SAndroid Build Coastguard Worker 			bits [j + 1] += 2;		// two new symbols in this length
3348*fd1fabb7SAndroid Build Coastguard Worker 			bits [j    ] --;		// symbol of this length is now a prefix
3349*fd1fabb7SAndroid Build Coastguard Worker 
3350*fd1fabb7SAndroid Build Coastguard Worker 			}
3351*fd1fabb7SAndroid Build Coastguard Worker 
3352*fd1fabb7SAndroid Build Coastguard Worker 		}
3353*fd1fabb7SAndroid Build Coastguard Worker 
3354*fd1fabb7SAndroid Build Coastguard Worker 	// Remove the count for the pseudo-symbol 256 from
3355*fd1fabb7SAndroid Build Coastguard Worker 	// the largest codelength.
3356*fd1fabb7SAndroid Build Coastguard Worker 
3357*fd1fabb7SAndroid Build Coastguard Worker 	while (bits [i] == 0)		// find largest codelength still in use
3358*fd1fabb7SAndroid Build Coastguard Worker     	i--;
3359*fd1fabb7SAndroid Build Coastguard Worker 
3360*fd1fabb7SAndroid Build Coastguard Worker 	bits [i] --;
3361*fd1fabb7SAndroid Build Coastguard Worker 
3362*fd1fabb7SAndroid Build Coastguard Worker 	// Return final symbol counts (only for lengths 0..16).
3363*fd1fabb7SAndroid Build Coastguard Worker 
3364*fd1fabb7SAndroid Build Coastguard Worker 	memcpy (htbl->bits, bits, sizeof (htbl->bits));
3365*fd1fabb7SAndroid Build Coastguard Worker 
3366*fd1fabb7SAndroid Build Coastguard Worker  	// Return a list of the symbols sorted by code length.
3367*fd1fabb7SAndroid Build Coastguard Worker 	// It's not real clear to me why we don't need to consider the codelength
3368*fd1fabb7SAndroid Build Coastguard Worker 	// changes made above, but the JPEG spec seems to think this works.
3369*fd1fabb7SAndroid Build Coastguard Worker 
3370*fd1fabb7SAndroid Build Coastguard Worker 	int p = 0;
3371*fd1fabb7SAndroid Build Coastguard Worker 
3372*fd1fabb7SAndroid Build Coastguard Worker 	for (i = 1; i <= MAX_CLEN; i++)
3373*fd1fabb7SAndroid Build Coastguard Worker 		{
3374*fd1fabb7SAndroid Build Coastguard Worker 
3375*fd1fabb7SAndroid Build Coastguard Worker 		for (j = 0; j <= 255; j++)
3376*fd1fabb7SAndroid Build Coastguard Worker 			{
3377*fd1fabb7SAndroid Build Coastguard Worker 
3378*fd1fabb7SAndroid Build Coastguard Worker 			if (codesize [j] == i)
3379*fd1fabb7SAndroid Build Coastguard Worker 				{
3380*fd1fabb7SAndroid Build Coastguard Worker 				htbl->huffval [p] = (uint8) j;
3381*fd1fabb7SAndroid Build Coastguard Worker 				p++;
3382*fd1fabb7SAndroid Build Coastguard Worker 				}
3383*fd1fabb7SAndroid Build Coastguard Worker 
3384*fd1fabb7SAndroid Build Coastguard Worker     		}
3385*fd1fabb7SAndroid Build Coastguard Worker 
3386*fd1fabb7SAndroid Build Coastguard Worker   		}
3387*fd1fabb7SAndroid Build Coastguard Worker 
3388*fd1fabb7SAndroid Build Coastguard Worker 	}
3389*fd1fabb7SAndroid Build Coastguard Worker 
3390*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
3391*fd1fabb7SAndroid Build Coastguard Worker 
3392*fd1fabb7SAndroid Build Coastguard Worker /*
3393*fd1fabb7SAndroid Build Coastguard Worker  *--------------------------------------------------------------
3394*fd1fabb7SAndroid Build Coastguard Worker  *
3395*fd1fabb7SAndroid Build Coastguard Worker  * HuffOptimize --
3396*fd1fabb7SAndroid Build Coastguard Worker  *
3397*fd1fabb7SAndroid Build Coastguard Worker  *	Find the best coding parameters for a Huffman-coded scan.
3398*fd1fabb7SAndroid Build Coastguard Worker  *	When called, the scan data has already been converted to
3399*fd1fabb7SAndroid Build Coastguard Worker  *	a sequence of MCU groups of source image samples, which
3400*fd1fabb7SAndroid Build Coastguard Worker  *	are stored in a "big" array, mcuTable.
3401*fd1fabb7SAndroid Build Coastguard Worker  *
3402*fd1fabb7SAndroid Build Coastguard Worker  *	It counts the times each category symbol occurs. Based on
3403*fd1fabb7SAndroid Build Coastguard Worker  *	this counting, optimal Huffman tables are built. Then it
3404*fd1fabb7SAndroid Build Coastguard Worker  *	uses this optimal Huffman table and counting table to find
3405*fd1fabb7SAndroid Build Coastguard Worker  *	the best PSV.
3406*fd1fabb7SAndroid Build Coastguard Worker  *
3407*fd1fabb7SAndroid Build Coastguard Worker  * Results:
3408*fd1fabb7SAndroid Build Coastguard Worker  *	Optimal Huffman tables are retured in cPtr->dcHuffTblPtrs[tbl].
3409*fd1fabb7SAndroid Build Coastguard Worker  *	Best PSV is retured in cPtr->Ss.
3410*fd1fabb7SAndroid Build Coastguard Worker  *
3411*fd1fabb7SAndroid Build Coastguard Worker  * Side effects:
3412*fd1fabb7SAndroid Build Coastguard Worker  *	None.
3413*fd1fabb7SAndroid Build Coastguard Worker  *
3414*fd1fabb7SAndroid Build Coastguard Worker  *--------------------------------------------------------------
3415*fd1fabb7SAndroid Build Coastguard Worker  */
3416*fd1fabb7SAndroid Build Coastguard Worker 
HuffOptimize()3417*fd1fabb7SAndroid Build Coastguard Worker void dng_lossless_encoder::HuffOptimize ()
3418*fd1fabb7SAndroid Build Coastguard Worker 	{
3419*fd1fabb7SAndroid Build Coastguard Worker 
3420*fd1fabb7SAndroid Build Coastguard Worker     // Collect the frequency counts.
3421*fd1fabb7SAndroid Build Coastguard Worker 
3422*fd1fabb7SAndroid Build Coastguard Worker 	FreqCountSet ();
3423*fd1fabb7SAndroid Build Coastguard Worker 
3424*fd1fabb7SAndroid Build Coastguard Worker 	// Generate Huffman encoding tables.
3425*fd1fabb7SAndroid Build Coastguard Worker 
3426*fd1fabb7SAndroid Build Coastguard Worker 	for (uint32 channel = 0; channel < fSrcChannels; channel++)
3427*fd1fabb7SAndroid Build Coastguard Worker 		{
3428*fd1fabb7SAndroid Build Coastguard Worker 
3429*fd1fabb7SAndroid Build Coastguard Worker 		try
3430*fd1fabb7SAndroid Build Coastguard Worker 			{
3431*fd1fabb7SAndroid Build Coastguard Worker 
3432*fd1fabb7SAndroid Build Coastguard Worker         	GenHuffCoding (&huffTable [channel], freqCount [channel]);
3433*fd1fabb7SAndroid Build Coastguard Worker 
3434*fd1fabb7SAndroid Build Coastguard Worker         	}
3435*fd1fabb7SAndroid Build Coastguard Worker 
3436*fd1fabb7SAndroid Build Coastguard Worker         catch (...)
3437*fd1fabb7SAndroid Build Coastguard Worker         	{
3438*fd1fabb7SAndroid Build Coastguard Worker 
3439*fd1fabb7SAndroid Build Coastguard Worker         	DNG_REPORT ("Info: Reverting to default huffman table");
3440*fd1fabb7SAndroid Build Coastguard Worker 
3441*fd1fabb7SAndroid Build Coastguard Worker         	for (uint32 j = 0; j <= 256; j++)
3442*fd1fabb7SAndroid Build Coastguard Worker         		{
3443*fd1fabb7SAndroid Build Coastguard Worker 
3444*fd1fabb7SAndroid Build Coastguard Worker         		freqCount [channel] [j] = (j <= 16 ? 1 : 0);
3445*fd1fabb7SAndroid Build Coastguard Worker 
3446*fd1fabb7SAndroid Build Coastguard Worker         		}
3447*fd1fabb7SAndroid Build Coastguard Worker 
3448*fd1fabb7SAndroid Build Coastguard Worker         	GenHuffCoding (&huffTable [channel], freqCount [channel]);
3449*fd1fabb7SAndroid Build Coastguard Worker 
3450*fd1fabb7SAndroid Build Coastguard Worker         	}
3451*fd1fabb7SAndroid Build Coastguard Worker 
3452*fd1fabb7SAndroid Build Coastguard Worker         FixHuffTbl (&huffTable [channel]);
3453*fd1fabb7SAndroid Build Coastguard Worker 
3454*fd1fabb7SAndroid Build Coastguard Worker 		}
3455*fd1fabb7SAndroid Build Coastguard Worker 
3456*fd1fabb7SAndroid Build Coastguard Worker 	}
3457*fd1fabb7SAndroid Build Coastguard Worker 
3458*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
3459*fd1fabb7SAndroid Build Coastguard Worker 
3460*fd1fabb7SAndroid Build Coastguard Worker /*
3461*fd1fabb7SAndroid Build Coastguard Worker  *--------------------------------------------------------------
3462*fd1fabb7SAndroid Build Coastguard Worker  *
3463*fd1fabb7SAndroid Build Coastguard Worker  * EmitMarker --
3464*fd1fabb7SAndroid Build Coastguard Worker  *
3465*fd1fabb7SAndroid Build Coastguard Worker  *	Emit a marker code into the output stream.
3466*fd1fabb7SAndroid Build Coastguard Worker  *
3467*fd1fabb7SAndroid Build Coastguard Worker  * Results:
3468*fd1fabb7SAndroid Build Coastguard Worker  *	None.
3469*fd1fabb7SAndroid Build Coastguard Worker  *
3470*fd1fabb7SAndroid Build Coastguard Worker  * Side effects:
3471*fd1fabb7SAndroid Build Coastguard Worker  *	None.
3472*fd1fabb7SAndroid Build Coastguard Worker  *
3473*fd1fabb7SAndroid Build Coastguard Worker  *--------------------------------------------------------------
3474*fd1fabb7SAndroid Build Coastguard Worker  */
3475*fd1fabb7SAndroid Build Coastguard Worker 
EmitMarker(JpegMarker mark)3476*fd1fabb7SAndroid Build Coastguard Worker void dng_lossless_encoder::EmitMarker (JpegMarker mark)
3477*fd1fabb7SAndroid Build Coastguard Worker 	{
3478*fd1fabb7SAndroid Build Coastguard Worker 
3479*fd1fabb7SAndroid Build Coastguard Worker     EmitByte (0xFF);
3480*fd1fabb7SAndroid Build Coastguard Worker     EmitByte ((uint8) mark);
3481*fd1fabb7SAndroid Build Coastguard Worker 
3482*fd1fabb7SAndroid Build Coastguard Worker 	}
3483*fd1fabb7SAndroid Build Coastguard Worker 
3484*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
3485*fd1fabb7SAndroid Build Coastguard Worker 
3486*fd1fabb7SAndroid Build Coastguard Worker /*
3487*fd1fabb7SAndroid Build Coastguard Worker  *--------------------------------------------------------------
3488*fd1fabb7SAndroid Build Coastguard Worker  *
3489*fd1fabb7SAndroid Build Coastguard Worker  * Emit2bytes --
3490*fd1fabb7SAndroid Build Coastguard Worker  *
3491*fd1fabb7SAndroid Build Coastguard Worker  *	Emit a 2-byte integer; these are always MSB first in JPEG
3492*fd1fabb7SAndroid Build Coastguard Worker  *	files
3493*fd1fabb7SAndroid Build Coastguard Worker  *
3494*fd1fabb7SAndroid Build Coastguard Worker  * Results:
3495*fd1fabb7SAndroid Build Coastguard Worker  *	None.
3496*fd1fabb7SAndroid Build Coastguard Worker  *
3497*fd1fabb7SAndroid Build Coastguard Worker  * Side effects:
3498*fd1fabb7SAndroid Build Coastguard Worker  *	None.
3499*fd1fabb7SAndroid Build Coastguard Worker  *
3500*fd1fabb7SAndroid Build Coastguard Worker  *--------------------------------------------------------------
3501*fd1fabb7SAndroid Build Coastguard Worker  */
3502*fd1fabb7SAndroid Build Coastguard Worker 
Emit2bytes(int value)3503*fd1fabb7SAndroid Build Coastguard Worker void dng_lossless_encoder::Emit2bytes (int value)
3504*fd1fabb7SAndroid Build Coastguard Worker 	{
3505*fd1fabb7SAndroid Build Coastguard Worker 
3506*fd1fabb7SAndroid Build Coastguard Worker     EmitByte ((value >> 8) & 0xFF);
3507*fd1fabb7SAndroid Build Coastguard Worker     EmitByte (value & 0xFF);
3508*fd1fabb7SAndroid Build Coastguard Worker 
3509*fd1fabb7SAndroid Build Coastguard Worker 	}
3510*fd1fabb7SAndroid Build Coastguard Worker 
3511*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
3512*fd1fabb7SAndroid Build Coastguard Worker 
3513*fd1fabb7SAndroid Build Coastguard Worker /*
3514*fd1fabb7SAndroid Build Coastguard Worker  *--------------------------------------------------------------
3515*fd1fabb7SAndroid Build Coastguard Worker  *
3516*fd1fabb7SAndroid Build Coastguard Worker  * EmitDht --
3517*fd1fabb7SAndroid Build Coastguard Worker  *
3518*fd1fabb7SAndroid Build Coastguard Worker  *	Emit a DHT marker, follwed by the huffman data.
3519*fd1fabb7SAndroid Build Coastguard Worker  *
3520*fd1fabb7SAndroid Build Coastguard Worker  * Results:
3521*fd1fabb7SAndroid Build Coastguard Worker  *	None
3522*fd1fabb7SAndroid Build Coastguard Worker  *
3523*fd1fabb7SAndroid Build Coastguard Worker  * Side effects:
3524*fd1fabb7SAndroid Build Coastguard Worker  *	None
3525*fd1fabb7SAndroid Build Coastguard Worker  *
3526*fd1fabb7SAndroid Build Coastguard Worker  *--------------------------------------------------------------
3527*fd1fabb7SAndroid Build Coastguard Worker  */
3528*fd1fabb7SAndroid Build Coastguard Worker 
EmitDht(int index)3529*fd1fabb7SAndroid Build Coastguard Worker void dng_lossless_encoder::EmitDht (int index)
3530*fd1fabb7SAndroid Build Coastguard Worker 	{
3531*fd1fabb7SAndroid Build Coastguard Worker 
3532*fd1fabb7SAndroid Build Coastguard Worker 	int i;
3533*fd1fabb7SAndroid Build Coastguard Worker 
3534*fd1fabb7SAndroid Build Coastguard Worker     HuffmanTable *htbl = &huffTable [index];
3535*fd1fabb7SAndroid Build Coastguard Worker 
3536*fd1fabb7SAndroid Build Coastguard Worker  	EmitMarker (M_DHT);
3537*fd1fabb7SAndroid Build Coastguard Worker 
3538*fd1fabb7SAndroid Build Coastguard Worker     int length = 0;
3539*fd1fabb7SAndroid Build Coastguard Worker 
3540*fd1fabb7SAndroid Build Coastguard Worker 	for (i = 1; i <= 16; i++)
3541*fd1fabb7SAndroid Build Coastguard Worker 	    length += htbl->bits [i];
3542*fd1fabb7SAndroid Build Coastguard Worker 
3543*fd1fabb7SAndroid Build Coastguard Worker 	Emit2bytes (length + 2 + 1 + 16);
3544*fd1fabb7SAndroid Build Coastguard Worker 
3545*fd1fabb7SAndroid Build Coastguard Worker 	EmitByte ((uint8) index);
3546*fd1fabb7SAndroid Build Coastguard Worker 
3547*fd1fabb7SAndroid Build Coastguard Worker 	for (i = 1; i <= 16; i++)
3548*fd1fabb7SAndroid Build Coastguard Worker 	    EmitByte (htbl->bits [i]);
3549*fd1fabb7SAndroid Build Coastguard Worker 
3550*fd1fabb7SAndroid Build Coastguard Worker 	for (i = 0; i < length; i++)
3551*fd1fabb7SAndroid Build Coastguard Worker 	    EmitByte (htbl->huffval [i]);
3552*fd1fabb7SAndroid Build Coastguard Worker 
3553*fd1fabb7SAndroid Build Coastguard Worker 	}
3554*fd1fabb7SAndroid Build Coastguard Worker 
3555*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
3556*fd1fabb7SAndroid Build Coastguard Worker 
3557*fd1fabb7SAndroid Build Coastguard Worker /*
3558*fd1fabb7SAndroid Build Coastguard Worker  *--------------------------------------------------------------
3559*fd1fabb7SAndroid Build Coastguard Worker  *
3560*fd1fabb7SAndroid Build Coastguard Worker  * EmitSof --
3561*fd1fabb7SAndroid Build Coastguard Worker  *
3562*fd1fabb7SAndroid Build Coastguard Worker  *	Emit a SOF marker plus data.
3563*fd1fabb7SAndroid Build Coastguard Worker  *
3564*fd1fabb7SAndroid Build Coastguard Worker  * Results:
3565*fd1fabb7SAndroid Build Coastguard Worker  *	None.
3566*fd1fabb7SAndroid Build Coastguard Worker  *
3567*fd1fabb7SAndroid Build Coastguard Worker  * Side effects:
3568*fd1fabb7SAndroid Build Coastguard Worker  *	None.
3569*fd1fabb7SAndroid Build Coastguard Worker  *
3570*fd1fabb7SAndroid Build Coastguard Worker  *--------------------------------------------------------------
3571*fd1fabb7SAndroid Build Coastguard Worker  */
3572*fd1fabb7SAndroid Build Coastguard Worker 
EmitSof(JpegMarker code)3573*fd1fabb7SAndroid Build Coastguard Worker void dng_lossless_encoder::EmitSof (JpegMarker code)
3574*fd1fabb7SAndroid Build Coastguard Worker 	{
3575*fd1fabb7SAndroid Build Coastguard Worker 
3576*fd1fabb7SAndroid Build Coastguard Worker     EmitMarker (code);
3577*fd1fabb7SAndroid Build Coastguard Worker 
3578*fd1fabb7SAndroid Build Coastguard Worker     Emit2bytes (3 * fSrcChannels + 2 + 5 + 1);	// length
3579*fd1fabb7SAndroid Build Coastguard Worker 
3580*fd1fabb7SAndroid Build Coastguard Worker     EmitByte ((uint8) fSrcBitDepth);
3581*fd1fabb7SAndroid Build Coastguard Worker 
3582*fd1fabb7SAndroid Build Coastguard Worker     Emit2bytes (fSrcRows);
3583*fd1fabb7SAndroid Build Coastguard Worker     Emit2bytes (fSrcCols);
3584*fd1fabb7SAndroid Build Coastguard Worker 
3585*fd1fabb7SAndroid Build Coastguard Worker     EmitByte ((uint8) fSrcChannels);
3586*fd1fabb7SAndroid Build Coastguard Worker 
3587*fd1fabb7SAndroid Build Coastguard Worker     for (uint32 i = 0; i < fSrcChannels; i++)
3588*fd1fabb7SAndroid Build Coastguard Worker     	{
3589*fd1fabb7SAndroid Build Coastguard Worker 
3590*fd1fabb7SAndroid Build Coastguard Worker 		EmitByte ((uint8) i);
3591*fd1fabb7SAndroid Build Coastguard Worker 
3592*fd1fabb7SAndroid Build Coastguard Worker 		EmitByte ((uint8) ((1 << 4) + 1));		// Not subsampled.
3593*fd1fabb7SAndroid Build Coastguard Worker 
3594*fd1fabb7SAndroid Build Coastguard Worker         EmitByte (0);					// Tq shall be 0 for lossless.
3595*fd1fabb7SAndroid Build Coastguard Worker 
3596*fd1fabb7SAndroid Build Coastguard Worker     	}
3597*fd1fabb7SAndroid Build Coastguard Worker 
3598*fd1fabb7SAndroid Build Coastguard Worker 	}
3599*fd1fabb7SAndroid Build Coastguard Worker 
3600*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
3601*fd1fabb7SAndroid Build Coastguard Worker 
3602*fd1fabb7SAndroid Build Coastguard Worker /*
3603*fd1fabb7SAndroid Build Coastguard Worker  *--------------------------------------------------------------
3604*fd1fabb7SAndroid Build Coastguard Worker  *
3605*fd1fabb7SAndroid Build Coastguard Worker  * EmitSos --
3606*fd1fabb7SAndroid Build Coastguard Worker  *
3607*fd1fabb7SAndroid Build Coastguard Worker  *	Emit a SOS marker plus data.
3608*fd1fabb7SAndroid Build Coastguard Worker  *
3609*fd1fabb7SAndroid Build Coastguard Worker  * Results:
3610*fd1fabb7SAndroid Build Coastguard Worker  *	None.
3611*fd1fabb7SAndroid Build Coastguard Worker  *
3612*fd1fabb7SAndroid Build Coastguard Worker  * Side effects:
3613*fd1fabb7SAndroid Build Coastguard Worker  *	None.
3614*fd1fabb7SAndroid Build Coastguard Worker  *
3615*fd1fabb7SAndroid Build Coastguard Worker  *--------------------------------------------------------------
3616*fd1fabb7SAndroid Build Coastguard Worker  */
3617*fd1fabb7SAndroid Build Coastguard Worker 
EmitSos()3618*fd1fabb7SAndroid Build Coastguard Worker void dng_lossless_encoder::EmitSos ()
3619*fd1fabb7SAndroid Build Coastguard Worker 	{
3620*fd1fabb7SAndroid Build Coastguard Worker 
3621*fd1fabb7SAndroid Build Coastguard Worker     EmitMarker (M_SOS);
3622*fd1fabb7SAndroid Build Coastguard Worker 
3623*fd1fabb7SAndroid Build Coastguard Worker     Emit2bytes (2 * fSrcChannels + 2 + 1 + 3);	// length
3624*fd1fabb7SAndroid Build Coastguard Worker 
3625*fd1fabb7SAndroid Build Coastguard Worker     EmitByte ((uint8) fSrcChannels);			// Ns
3626*fd1fabb7SAndroid Build Coastguard Worker 
3627*fd1fabb7SAndroid Build Coastguard Worker     for (uint32 i = 0; i < fSrcChannels; i++)
3628*fd1fabb7SAndroid Build Coastguard Worker     	{
3629*fd1fabb7SAndroid Build Coastguard Worker 
3630*fd1fabb7SAndroid Build Coastguard Worker     	// Cs,Td,Ta
3631*fd1fabb7SAndroid Build Coastguard Worker 
3632*fd1fabb7SAndroid Build Coastguard Worker 		EmitByte ((uint8) i);
3633*fd1fabb7SAndroid Build Coastguard Worker 		EmitByte ((uint8) (i << 4));
3634*fd1fabb7SAndroid Build Coastguard Worker 
3635*fd1fabb7SAndroid Build Coastguard Worker     	}
3636*fd1fabb7SAndroid Build Coastguard Worker 
3637*fd1fabb7SAndroid Build Coastguard Worker     EmitByte (1);		// PSV - hardcoded - tknoll
3638*fd1fabb7SAndroid Build Coastguard Worker     EmitByte (0);	    // Spectral selection end  - Se
3639*fd1fabb7SAndroid Build Coastguard Worker     EmitByte (0);  		// The point transform parameter
3640*fd1fabb7SAndroid Build Coastguard Worker 
3641*fd1fabb7SAndroid Build Coastguard Worker 	}
3642*fd1fabb7SAndroid Build Coastguard Worker 
3643*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
3644*fd1fabb7SAndroid Build Coastguard Worker 
3645*fd1fabb7SAndroid Build Coastguard Worker /*
3646*fd1fabb7SAndroid Build Coastguard Worker  *--------------------------------------------------------------
3647*fd1fabb7SAndroid Build Coastguard Worker  *
3648*fd1fabb7SAndroid Build Coastguard Worker  * WriteFileHeader --
3649*fd1fabb7SAndroid Build Coastguard Worker  *
3650*fd1fabb7SAndroid Build Coastguard Worker  *	Write the file header.
3651*fd1fabb7SAndroid Build Coastguard Worker  *
3652*fd1fabb7SAndroid Build Coastguard Worker  * Results:
3653*fd1fabb7SAndroid Build Coastguard Worker  *	None.
3654*fd1fabb7SAndroid Build Coastguard Worker  *
3655*fd1fabb7SAndroid Build Coastguard Worker  * Side effects:
3656*fd1fabb7SAndroid Build Coastguard Worker  *	None.
3657*fd1fabb7SAndroid Build Coastguard Worker  *
3658*fd1fabb7SAndroid Build Coastguard Worker  *--------------------------------------------------------------
3659*fd1fabb7SAndroid Build Coastguard Worker  */
3660*fd1fabb7SAndroid Build Coastguard Worker 
WriteFileHeader()3661*fd1fabb7SAndroid Build Coastguard Worker void dng_lossless_encoder::WriteFileHeader ()
3662*fd1fabb7SAndroid Build Coastguard Worker 	{
3663*fd1fabb7SAndroid Build Coastguard Worker 
3664*fd1fabb7SAndroid Build Coastguard Worker     EmitMarker (M_SOI);		// first the SOI
3665*fd1fabb7SAndroid Build Coastguard Worker 
3666*fd1fabb7SAndroid Build Coastguard Worker     EmitSof (M_SOF3);
3667*fd1fabb7SAndroid Build Coastguard Worker 
3668*fd1fabb7SAndroid Build Coastguard Worker 	}
3669*fd1fabb7SAndroid Build Coastguard Worker 
3670*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
3671*fd1fabb7SAndroid Build Coastguard Worker 
3672*fd1fabb7SAndroid Build Coastguard Worker /*
3673*fd1fabb7SAndroid Build Coastguard Worker  *--------------------------------------------------------------
3674*fd1fabb7SAndroid Build Coastguard Worker  *
3675*fd1fabb7SAndroid Build Coastguard Worker  * WriteScanHeader --
3676*fd1fabb7SAndroid Build Coastguard Worker  *
3677*fd1fabb7SAndroid Build Coastguard Worker  *	Write the start of a scan (everything through the SOS marker).
3678*fd1fabb7SAndroid Build Coastguard Worker  *
3679*fd1fabb7SAndroid Build Coastguard Worker  * Results:
3680*fd1fabb7SAndroid Build Coastguard Worker  *	None.
3681*fd1fabb7SAndroid Build Coastguard Worker  *
3682*fd1fabb7SAndroid Build Coastguard Worker  * Side effects:
3683*fd1fabb7SAndroid Build Coastguard Worker  *	None.
3684*fd1fabb7SAndroid Build Coastguard Worker  *
3685*fd1fabb7SAndroid Build Coastguard Worker  *--------------------------------------------------------------
3686*fd1fabb7SAndroid Build Coastguard Worker  */
3687*fd1fabb7SAndroid Build Coastguard Worker 
WriteScanHeader()3688*fd1fabb7SAndroid Build Coastguard Worker void dng_lossless_encoder::WriteScanHeader ()
3689*fd1fabb7SAndroid Build Coastguard Worker 	{
3690*fd1fabb7SAndroid Build Coastguard Worker 
3691*fd1fabb7SAndroid Build Coastguard Worker     // Emit Huffman tables.
3692*fd1fabb7SAndroid Build Coastguard Worker 
3693*fd1fabb7SAndroid Build Coastguard Worker     for (uint32 i = 0; i < fSrcChannels; i++)
3694*fd1fabb7SAndroid Build Coastguard Worker     	{
3695*fd1fabb7SAndroid Build Coastguard Worker 
3696*fd1fabb7SAndroid Build Coastguard Worker 		EmitDht (i);
3697*fd1fabb7SAndroid Build Coastguard Worker 
3698*fd1fabb7SAndroid Build Coastguard Worker     	}
3699*fd1fabb7SAndroid Build Coastguard Worker 
3700*fd1fabb7SAndroid Build Coastguard Worker 	EmitSos ();
3701*fd1fabb7SAndroid Build Coastguard Worker 
3702*fd1fabb7SAndroid Build Coastguard Worker 	}
3703*fd1fabb7SAndroid Build Coastguard Worker 
3704*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
3705*fd1fabb7SAndroid Build Coastguard Worker 
3706*fd1fabb7SAndroid Build Coastguard Worker /*
3707*fd1fabb7SAndroid Build Coastguard Worker  *--------------------------------------------------------------
3708*fd1fabb7SAndroid Build Coastguard Worker  *
3709*fd1fabb7SAndroid Build Coastguard Worker  * WriteFileTrailer --
3710*fd1fabb7SAndroid Build Coastguard Worker  *
3711*fd1fabb7SAndroid Build Coastguard Worker  *	Write the End of image marker at the end of a JPEG file.
3712*fd1fabb7SAndroid Build Coastguard Worker  *
3713*fd1fabb7SAndroid Build Coastguard Worker  * Results:
3714*fd1fabb7SAndroid Build Coastguard Worker  *	None.
3715*fd1fabb7SAndroid Build Coastguard Worker  *
3716*fd1fabb7SAndroid Build Coastguard Worker  * Side effects:
3717*fd1fabb7SAndroid Build Coastguard Worker  *	None.
3718*fd1fabb7SAndroid Build Coastguard Worker  *
3719*fd1fabb7SAndroid Build Coastguard Worker  *--------------------------------------------------------------
3720*fd1fabb7SAndroid Build Coastguard Worker  */
3721*fd1fabb7SAndroid Build Coastguard Worker 
WriteFileTrailer()3722*fd1fabb7SAndroid Build Coastguard Worker void dng_lossless_encoder::WriteFileTrailer ()
3723*fd1fabb7SAndroid Build Coastguard Worker 	{
3724*fd1fabb7SAndroid Build Coastguard Worker 
3725*fd1fabb7SAndroid Build Coastguard Worker     EmitMarker (M_EOI);
3726*fd1fabb7SAndroid Build Coastguard Worker 
3727*fd1fabb7SAndroid Build Coastguard Worker 	}
3728*fd1fabb7SAndroid Build Coastguard Worker 
3729*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
3730*fd1fabb7SAndroid Build Coastguard Worker 
Encode()3731*fd1fabb7SAndroid Build Coastguard Worker void dng_lossless_encoder::Encode ()
3732*fd1fabb7SAndroid Build Coastguard Worker 	{
3733*fd1fabb7SAndroid Build Coastguard Worker 
3734*fd1fabb7SAndroid Build Coastguard Worker 	DNG_ASSERT (fSrcChannels <= 4, "Too many components in scan");
3735*fd1fabb7SAndroid Build Coastguard Worker 
3736*fd1fabb7SAndroid Build Coastguard Worker 	// Count the times each difference category occurs.
3737*fd1fabb7SAndroid Build Coastguard Worker 	// Construct the optimal Huffman table.
3738*fd1fabb7SAndroid Build Coastguard Worker 
3739*fd1fabb7SAndroid Build Coastguard Worker 	HuffOptimize ();
3740*fd1fabb7SAndroid Build Coastguard Worker 
3741*fd1fabb7SAndroid Build Coastguard Worker     // Write the frame and scan headers.
3742*fd1fabb7SAndroid Build Coastguard Worker 
3743*fd1fabb7SAndroid Build Coastguard Worker     WriteFileHeader ();
3744*fd1fabb7SAndroid Build Coastguard Worker 
3745*fd1fabb7SAndroid Build Coastguard Worker     WriteScanHeader ();
3746*fd1fabb7SAndroid Build Coastguard Worker 
3747*fd1fabb7SAndroid Build Coastguard Worker     // Encode the image.
3748*fd1fabb7SAndroid Build Coastguard Worker 
3749*fd1fabb7SAndroid Build Coastguard Worker     HuffEncode ();
3750*fd1fabb7SAndroid Build Coastguard Worker 
3751*fd1fabb7SAndroid Build Coastguard Worker     // Clean up everything.
3752*fd1fabb7SAndroid Build Coastguard Worker 
3753*fd1fabb7SAndroid Build Coastguard Worker 	WriteFileTrailer ();
3754*fd1fabb7SAndroid Build Coastguard Worker 
3755*fd1fabb7SAndroid Build Coastguard Worker 	}
3756*fd1fabb7SAndroid Build Coastguard Worker 
3757*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
3758*fd1fabb7SAndroid Build Coastguard Worker 
EncodeLosslessJPEG(const uint16 * srcData,uint32 srcRows,uint32 srcCols,uint32 srcChannels,uint32 srcBitDepth,int32 srcRowStep,int32 srcColStep,dng_stream & stream)3759*fd1fabb7SAndroid Build Coastguard Worker void EncodeLosslessJPEG (const uint16 *srcData,
3760*fd1fabb7SAndroid Build Coastguard Worker 						 uint32 srcRows,
3761*fd1fabb7SAndroid Build Coastguard Worker 						 uint32 srcCols,
3762*fd1fabb7SAndroid Build Coastguard Worker 						 uint32 srcChannels,
3763*fd1fabb7SAndroid Build Coastguard Worker 						 uint32 srcBitDepth,
3764*fd1fabb7SAndroid Build Coastguard Worker 						 int32 srcRowStep,
3765*fd1fabb7SAndroid Build Coastguard Worker 						 int32 srcColStep,
3766*fd1fabb7SAndroid Build Coastguard Worker 						 dng_stream &stream)
3767*fd1fabb7SAndroid Build Coastguard Worker 	{
3768*fd1fabb7SAndroid Build Coastguard Worker 
3769*fd1fabb7SAndroid Build Coastguard Worker 	dng_lossless_encoder encoder (srcData,
3770*fd1fabb7SAndroid Build Coastguard Worker 							      srcRows,
3771*fd1fabb7SAndroid Build Coastguard Worker 							      srcCols,
3772*fd1fabb7SAndroid Build Coastguard Worker 							      srcChannels,
3773*fd1fabb7SAndroid Build Coastguard Worker 							      srcBitDepth,
3774*fd1fabb7SAndroid Build Coastguard Worker 							      srcRowStep,
3775*fd1fabb7SAndroid Build Coastguard Worker 							      srcColStep,
3776*fd1fabb7SAndroid Build Coastguard Worker 							      stream);
3777*fd1fabb7SAndroid Build Coastguard Worker 
3778*fd1fabb7SAndroid Build Coastguard Worker 	encoder.Encode ();
3779*fd1fabb7SAndroid Build Coastguard Worker 
3780*fd1fabb7SAndroid Build Coastguard Worker     }
3781*fd1fabb7SAndroid Build Coastguard Worker 
3782*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
3783