xref: /haiku/src/add-ons/translators/raw/RAW.cpp (revision a906d0a031e721e2f2ec9d95274103e74a3a774f)
1 /*
2  * Copyright 2007-2008, Axel Dörfler, axeld@pinc-software.de.
3  * Distributed under the terms of the MIT License.
4  *
5  * Copyright 1997-2007, Dave Coffin, dcoffin a cybercom o net
6  * This code is based on Dave Coffin's dcraw 8.63 - it's basically the same
7  * thing in C++, but follows common sense programming rules a bit more :-)
8  * Except the Fovean functions, dcraw is public domain.
9  */
10 
11 
12 #include "RAW.h"
13 #include "ReadHelper.h"
14 
15 #include <Message.h>
16 #include <TranslationErrors.h>
17 
18 #include <ctype.h>
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <string.h>
22 
23 
24 //#define TRACE(x) printf x
25 #define TRACE(x)
26 //#define TAG(x...) printf(x)
27 #define TAG(x...)
28 
29 #define ABS(x) (((int)(x) ^ ((int)(x) >> 31)) - ((int)(x) >> 31))
30 #define LIM(x,min,max) MAX(min,MIN(x,max))
31 #define ULIM(x,y,z) ((y) < (z) ? LIM(x,y,z) : LIM(x,z,y))
32 #define CLIP(x) LIM(x,0,65535)
33 #define SWAP(a,b) { a ^= b; a ^= (b ^= a); }
34 
35 #define FC(row,col) \
36 	(fFilters >> ((((row) << 1 & 14) + ((col) & 1)) << 1) & 3)
37 
38 
39 static const uint32 kImageBufferCount = 10;
40 static const uint32 kDecodeBufferCount = 2048;
41 
42 const double xyz_rgb[3][3] = {			/* XYZ from RGB */
43   { 0.412453, 0.357580, 0.180423 },
44   { 0.212671, 0.715160, 0.072169 },
45   { 0.019334, 0.119193, 0.950227 } };
46 const float kD65White[3] = { 0.950456, 1, 1.088754 };
47 
48 struct decode {
49 	struct decode *branch[2];
50 	int32	leaf;
51 };
52 
53 struct jhead {
54 	int		bits, high, wide, clrs, restart, vpred[4];
55 	struct decode *huff[4];
56 	uint16*	row;
57 };
58 
59 struct tiff_header {
60 	uint16	order, magic;
61 	int32	image_file_directory;
62 	uint16	pad, ntag;
63 	struct tiff_tag tag[15];
64 	int32	next_image_file_directory;
65 	uint16	pad2, nexif;
66 	struct tiff_tag exif[4];
67 	int16	bps[4];
68 	int32	rat[6];
69 	char make[64], model[64], soft[32], date[20];
70 };
71 
72 
73 template<class T> inline T
74 square(const T& value)
75 {
76 	return value * value;
77 }
78 
79 
80 static inline bool
81 x_flipped(int32 orientation)
82 {
83 	return orientation == 2 || orientation == 3
84 		|| orientation == 7 || orientation == 8;
85 }
86 
87 
88 static inline bool
89 y_flipped(int32 orientation)
90 {
91 	return orientation == 3 || orientation == 4
92 		|| orientation == 6 || orientation == 7;
93 }
94 
95 
96 #if 0
97 void
98 dump_to_disk(void* data, size_t length)
99 {
100 	FILE* file = fopen("/tmp/RAW.out", "wb");
101 	if (file == NULL)
102 		return;
103 
104 	fwrite(data, length, 1, file);
105 	fclose(file);
106 }
107 #endif
108 
109 
110 //	#pragma mark -
111 
112 
113 DCRaw::DCRaw(BPositionIO& stream)
114 	:
115 	fRead(stream),
116 	fNumImages(0),
117 	fRawIndex(-1),
118 	fThumbIndex(-1),
119 	fDNGVersion(0),
120 	fIsTIFF(false),
121 	fImageData(NULL),
122 	fThreshold(0.0f),
123 	fHalfSize(false),
124 	fUseCameraWhiteBalance(true),
125 	fUseAutoWhiteBalance(true),
126 	fRawColor(true),
127 	fUseGamma(true),
128 	fBrightness(1.0f),
129 	fOutputColor(1),
130 	fHighlight(0),
131 	fDocumentMode(0),
132 	fOutputWidth(0),
133 	fOutputHeight(0),
134 	fInputWidth(0),
135 	fInputHeight(0),
136 	fTopMargin(0),
137 	fLeftMargin(0),
138 	fColors(3),
139 	fOutputProfile(NULL),
140 	fOutputBitsPerSample(8),
141 	fDecodeLeaf(0),
142 	fDecodeBitsZeroAfterMax(false),
143 	fFilters(~0),
144 	fEXIFOffset(-1),
145 	fProgressMonitor(NULL)
146 {
147 	fImages = new image_data_info[kImageBufferCount];
148 	fDecodeBuffer = new decode[kDecodeBufferCount];
149 	fCurve = new uint16[0x1000];
150 	for (uint32 i = 0; i < 0x1000; i++) {
151 		fCurve[i] = i;
152 	}
153 
154 	cbrt = new float[0x10000];
155 	fHistogram = (int32 (*)[4])calloc(sizeof(int32) * 0x2000 * 4, 1);
156 
157 	memset(fImages, 0, sizeof(image_data_info) * kImageBufferCount);
158 	memset(&fMeta, 0, sizeof(image_meta_info));
159 	memset(fUserMultipliers, 0, sizeof(fUserMultipliers));
160 	memset(fWhite, 0, sizeof(fWhite));
161 
162 	fMeta.camera_multipliers[0] = -1;
163 	fCR2Slice[0] = 0;
164 }
165 
166 
167 DCRaw::~DCRaw()
168 {
169 	delete[] fImages;
170 	delete[] fDecodeBuffer;
171 	delete[] fCurve;
172 
173 	delete[] cbrt;
174 
175 	free(fHistogram);
176 	free(fImageData);
177 }
178 
179 
180 int32
181 DCRaw::_AllocateImage()
182 {
183 	if (fNumImages + 1 == kImageBufferCount)
184 		throw (status_t)B_ERROR;
185 
186 	return fNumImages++;
187 }
188 
189 
190 image_data_info&
191 DCRaw::_Raw()
192 {
193 	if (fRawIndex < 0)
194 		fRawIndex = _AllocateImage();
195 	if (fRawIndex < 0)
196 		throw (status_t)B_ERROR;
197 
198 	return fImages[fRawIndex];
199 }
200 
201 
202 image_data_info&
203 DCRaw::_Thumb()
204 {
205 	if (fThumbIndex < 0)
206 		fThumbIndex = _AllocateImage();
207 	if (fThumbIndex < 0)
208 		throw (status_t)B_ERROR;
209 
210 	return fImages[fThumbIndex];
211 }
212 
213 
214 //! Make sure that the raw image always comes first
215 void
216 DCRaw::_CorrectIndex(uint32& index) const
217 {
218 	if (fRawIndex > 0) {
219 		if (index == 0)
220 			index = fRawIndex;
221 		else if (index <= (uint32)fRawIndex)
222 			index--;
223 	}
224 }
225 
226 
227 inline uint16&
228 DCRaw::_Bayer(int32 column, int32 row)
229 {
230 	return fImageData[((row) >> fShrink) * fOutputWidth
231 		+ ((column) >> fShrink)][FC(row, column)];
232 }
233 
234 
235 inline int32
236 DCRaw::_FilterCoefficient(int32 x, int32 y)
237 {
238 	static const char filter[16][16] = {
239 		{ 2,1,1,3,2,3,2,0,3,2,3,0,1,2,1,0 },
240 		{ 0,3,0,2,0,1,3,1,0,1,1,2,0,3,3,2 },
241 		{ 2,3,3,2,3,1,1,3,3,1,2,1,2,0,0,3 },
242 		{ 0,1,0,1,0,2,0,2,2,0,3,0,1,3,2,1 },
243 		{ 3,1,1,2,0,1,0,2,1,3,1,3,0,1,3,0 },
244 		{ 2,0,0,3,3,2,3,1,2,0,2,0,3,2,2,1 },
245 		{ 2,3,3,1,2,1,2,1,2,1,1,2,3,0,0,1 },
246 		{ 1,0,0,2,3,0,0,3,0,3,0,3,2,1,2,3 },
247 		{ 2,3,3,1,1,2,1,0,3,2,3,0,2,3,1,3 },
248 		{ 1,0,2,0,3,0,3,2,0,1,1,2,0,1,0,2 },
249 		{ 0,1,1,3,3,2,2,1,1,3,3,0,2,1,3,2 },
250 		{ 2,3,2,0,0,1,3,0,2,0,1,2,3,0,1,0 },
251 		{ 1,3,1,2,3,2,3,2,0,2,0,1,1,0,3,0 },
252 		{ 0,2,0,3,1,0,0,1,1,3,3,2,3,2,2,1 },
253 		{ 2,1,3,2,3,1,2,1,0,3,0,2,0,2,0,2 },
254 		{ 0,3,1,0,0,2,0,3,2,1,3,1,1,3,1,3 }
255 	};
256 
257 	if (fFilters != 1)
258 		return FC(y, x);
259 
260 	return filter[(y + fTopMargin) & 15][(x + fLeftMargin) & 15];
261 }
262 
263 
264 inline int32
265 DCRaw::_FlipIndex(uint32 row, uint32 col, uint32 flip)
266 {
267 	if (flip > 4)
268 		SWAP(row, col);
269 	if (y_flipped(flip))
270 		row = fInputHeight - 1 - row;
271 	if (x_flipped(flip))
272 		col = fInputWidth - 1 - col;
273 
274 	return row * fInputWidth + col;
275 }
276 
277 
278 bool
279 DCRaw::_SupportsCompression(image_data_info& image) const
280 {
281 	switch (image.compression) {
282 		//case COMPRESSION_NONE:
283 		case COMPRESSION_OLD_JPEG:
284 		case COMPRESSION_PACKBITS:
285 			return true;
286 
287 		default:
288 			return false;
289 	}
290 }
291 
292 
293 bool
294 DCRaw::_IsCanon() const
295 {
296 	return !strncasecmp(fMeta.manufacturer, "Canon", 5);
297 }
298 
299 
300 bool
301 DCRaw::_IsKodak() const
302 {
303 	return !strncasecmp(fMeta.manufacturer, "Kodak", 5);
304 }
305 
306 
307 bool
308 DCRaw::_IsNikon() const
309 {
310 	return !strncasecmp(fMeta.manufacturer, "Nikon", 5);
311 }
312 
313 
314 bool
315 DCRaw::_IsOlympus() const
316 {
317 	return !strncasecmp(fMeta.manufacturer, "Olympus", 7);
318 }
319 
320 
321 bool
322 DCRaw::_IsPentax() const
323 {
324 	return !strncasecmp(fMeta.manufacturer, "Pentax", 6);
325 }
326 
327 
328 bool
329 DCRaw::_IsSamsung() const
330 {
331 	return !strncasecmp(fMeta.manufacturer, "Samsung", 7);
332 }
333 
334 
335 void
336 DCRaw::_ParseThumbTag(off_t baseOffset, uint32 offsetTag, uint32 lengthTag)
337 {
338 	uint16 entries;
339 	fRead(entries);
340 
341 	while (entries--) {
342 		off_t nextOffset;
343 		tiff_tag tag;
344 		_ParseTIFFTag(baseOffset, tag, nextOffset);
345 
346 		if (tag.tag == offsetTag)
347 			_Thumb().data_offset = fRead.Next<uint32>();
348 		if (tag.tag == lengthTag)
349 			_Thumb().bytes = fRead.Next<uint32>();
350 
351 		fRead.Seek(nextOffset, SEEK_SET);
352 	}
353 }
354 
355 
356 void
357 DCRaw::_ParseManufacturerTag(off_t baseOffset)
358 {
359 	static const uchar xlat[2][256] = {
360 		{
361 			0xc1,0xbf,0x6d,0x0d,0x59,0xc5,0x13,0x9d,0x83,0x61,0x6b,0x4f,0xc7,0x7f,0x3d,0x3d,
362 			0x53,0x59,0xe3,0xc7,0xe9,0x2f,0x95,0xa7,0x95,0x1f,0xdf,0x7f,0x2b,0x29,0xc7,0x0d,
363 			0xdf,0x07,0xef,0x71,0x89,0x3d,0x13,0x3d,0x3b,0x13,0xfb,0x0d,0x89,0xc1,0x65,0x1f,
364 			0xb3,0x0d,0x6b,0x29,0xe3,0xfb,0xef,0xa3,0x6b,0x47,0x7f,0x95,0x35,0xa7,0x47,0x4f,
365 			0xc7,0xf1,0x59,0x95,0x35,0x11,0x29,0x61,0xf1,0x3d,0xb3,0x2b,0x0d,0x43,0x89,0xc1,
366 			0x9d,0x9d,0x89,0x65,0xf1,0xe9,0xdf,0xbf,0x3d,0x7f,0x53,0x97,0xe5,0xe9,0x95,0x17,
367 			0x1d,0x3d,0x8b,0xfb,0xc7,0xe3,0x67,0xa7,0x07,0xf1,0x71,0xa7,0x53,0xb5,0x29,0x89,
368 			0xe5,0x2b,0xa7,0x17,0x29,0xe9,0x4f,0xc5,0x65,0x6d,0x6b,0xef,0x0d,0x89,0x49,0x2f,
369 			0xb3,0x43,0x53,0x65,0x1d,0x49,0xa3,0x13,0x89,0x59,0xef,0x6b,0xef,0x65,0x1d,0x0b,
370 			0x59,0x13,0xe3,0x4f,0x9d,0xb3,0x29,0x43,0x2b,0x07,0x1d,0x95,0x59,0x59,0x47,0xfb,
371 			0xe5,0xe9,0x61,0x47,0x2f,0x35,0x7f,0x17,0x7f,0xef,0x7f,0x95,0x95,0x71,0xd3,0xa3,
372 			0x0b,0x71,0xa3,0xad,0x0b,0x3b,0xb5,0xfb,0xa3,0xbf,0x4f,0x83,0x1d,0xad,0xe9,0x2f,
373 			0x71,0x65,0xa3,0xe5,0x07,0x35,0x3d,0x0d,0xb5,0xe9,0xe5,0x47,0x3b,0x9d,0xef,0x35,
374 			0xa3,0xbf,0xb3,0xdf,0x53,0xd3,0x97,0x53,0x49,0x71,0x07,0x35,0x61,0x71,0x2f,0x43,
375 			0x2f,0x11,0xdf,0x17,0x97,0xfb,0x95,0x3b,0x7f,0x6b,0xd3,0x25,0xbf,0xad,0xc7,0xc5,
376 			0xc5,0xb5,0x8b,0xef,0x2f,0xd3,0x07,0x6b,0x25,0x49,0x95,0x25,0x49,0x6d,0x71,0xc7
377 		},
378 		{
379 			0xa7,0xbc,0xc9,0xad,0x91,0xdf,0x85,0xe5,0xd4,0x78,0xd5,0x17,0x46,0x7c,0x29,0x4c,
380 			0x4d,0x03,0xe9,0x25,0x68,0x11,0x86,0xb3,0xbd,0xf7,0x6f,0x61,0x22,0xa2,0x26,0x34,
381 			0x2a,0xbe,0x1e,0x46,0x14,0x68,0x9d,0x44,0x18,0xc2,0x40,0xf4,0x7e,0x5f,0x1b,0xad,
382 			0x0b,0x94,0xb6,0x67,0xb4,0x0b,0xe1,0xea,0x95,0x9c,0x66,0xdc,0xe7,0x5d,0x6c,0x05,
383 			0xda,0xd5,0xdf,0x7a,0xef,0xf6,0xdb,0x1f,0x82,0x4c,0xc0,0x68,0x47,0xa1,0xbd,0xee,
384 			0x39,0x50,0x56,0x4a,0xdd,0xdf,0xa5,0xf8,0xc6,0xda,0xca,0x90,0xca,0x01,0x42,0x9d,
385 			0x8b,0x0c,0x73,0x43,0x75,0x05,0x94,0xde,0x24,0xb3,0x80,0x34,0xe5,0x2c,0xdc,0x9b,
386 			0x3f,0xca,0x33,0x45,0xd0,0xdb,0x5f,0xf5,0x52,0xc3,0x21,0xda,0xe2,0x22,0x72,0x6b,
387 			0x3e,0xd0,0x5b,0xa8,0x87,0x8c,0x06,0x5d,0x0f,0xdd,0x09,0x19,0x93,0xd0,0xb9,0xfc,
388 			0x8b,0x0f,0x84,0x60,0x33,0x1c,0x9b,0x45,0xf1,0xf0,0xa3,0x94,0x3a,0x12,0x77,0x33,
389 			0x4d,0x44,0x78,0x28,0x3c,0x9e,0xfd,0x65,0x57,0x16,0x94,0x6b,0xfb,0x59,0xd0,0xc8,
390 			0x22,0x36,0xdb,0xd2,0x63,0x98,0x43,0xa1,0x04,0x87,0x86,0xf7,0xa6,0x26,0xbb,0xd6,
391 			0x59,0x4d,0xbf,0x6a,0x2e,0xaa,0x2b,0xef,0xe6,0x78,0xb6,0x4e,0xe0,0x2f,0xdc,0x7c,
392 			0xbe,0x57,0x19,0x32,0x7e,0x2a,0xd0,0xb8,0xba,0x29,0x00,0x3c,0x52,0x7d,0xa8,0x49,
393 			0x3b,0x2d,0xeb,0x25,0x49,0xfa,0xa3,0xaa,0x39,0xa7,0xc5,0xa7,0x50,0x11,0x36,0xfb,
394 			0xc6,0x67,0x4a,0xf5,0xa5,0x12,0x65,0x7e,0xb0,0xdf,0xaf,0x4e,0xb3,0x61,0x7f,0x2f
395 		}
396 	};
397 
398 	uint32 ver97 = 0, serial = 0;
399 	uchar buf97[324], ci, cj, ck;
400 	bool originalSwap = fRead.IsSwapping();
401 	image_data_info& image = fImages[fNumImages];
402 
403 	// The MakerNote might have its own TIFF header (possibly with
404 	// its own byte-order!), or it might just be a table.
405 
406 	char type[10];
407 	fRead(type, sizeof(type));
408 
409 	if (!strncmp(type, "KDK", 3)
410 		|| !strncmp(type, "VER", 3)
411 		|| !strncmp(type, "IIII", 4)
412 		|| !strncmp(type, "MMMM", 4)) {
413 		// these aren't TIFF tables
414 		return;
415 	}
416 	if (!strncmp(type, "KC", 2)			// Konica KD-400Z, KD-510Z
417 		|| !strncmp(type, "MLY", 3)) {	// Minolta DiMAGE G series
418 		fRead.SetSwap(B_HOST_IS_LENDIAN != 0);
419 			// this chunk is always in big endian
420 
421 		uint32 whiteBalance[4] = {0, 0, 0, 0};
422 
423 		off_t offset;
424 	    while ((offset = fRead.Position()) < image.data_offset
425 	    	&& offset < 16384) {
426 			whiteBalance[0] = whiteBalance[2];
427 			whiteBalance[2] = whiteBalance[1];
428 			whiteBalance[1] = whiteBalance[3];
429 
430 			whiteBalance[3] = fRead.Next<uint16>();
431 			if (whiteBalance[1] == 256 && whiteBalance[3] == 256
432 				&& whiteBalance[0] > 256 && whiteBalance[0] < 640
433 				&& whiteBalance[2] > 256 && whiteBalance[2] < 640) {
434 				for (uint32 i = 0; i < 4; i++) {
435 					fMeta.camera_multipliers[i] = whiteBalance[i];
436 				}
437 			}
438 		}
439 		goto quit;
440 	}
441 	if (!strcmp(type, "Nikon")) {
442 		baseOffset = fRead.Position();
443 
444 		uint16 endian;
445 		fRead(endian);
446 
447 #if B_HOST_IS_LENDIAN
448 		fRead.SetSwap(endian == 'MM');
449 #else
450 		fRead.SetSwap(endian == 'II');
451 #endif
452 
453 		if (fRead.Next<uint16>() != 42)
454 			goto quit;
455 
456 		uint32 offset = fRead.Next<uint32>();
457 		fRead.Seek(offset - 8, SEEK_CUR);
458 	} else if (!strncmp(type, "FUJIFILM", 8)
459 		|| !strncmp(type, "SONY", 4)
460 		|| !strcmp(type, "Panasonic")) {
461 		fRead.SetSwap(B_HOST_IS_BENDIAN != 0);
462 			// this chunk is always in little endian
463 		fRead.Seek(2, SEEK_CUR);
464 	} else if (!strcmp(type, "OLYMP")
465 		|| !strcmp(type, "LEICA")
466 		|| !strcmp(type, "Ricoh")
467 		|| !strcmp(type, "EPSON"))
468 		fRead.Seek(-2, SEEK_CUR);
469 	else if (!strcmp(type, "AOC") || !strcmp(type, "QVC"))
470 		fRead.Seek(-4, SEEK_CUR);
471 	else
472 		fRead.Seek(-10, SEEK_CUR);
473 
474 	uint16 entries;
475 	fRead(entries);
476 	if (entries > 1000)
477 		return;
478 
479 	while (entries--) {
480 		off_t nextOffset;
481 		tiff_tag tag;
482 		_ParseTIFFTag(baseOffset, tag, nextOffset);
483 		TAG("Manufacturer tag %u (type %u, length %lu)\n", tag.tag, tag.type,
484 			tag.length);
485 
486 		if (strstr(fMeta.manufacturer, "PENTAX")) {
487 			if (tag.tag == 0x1b)
488 				tag.tag = 0x1018;
489 			if (tag.tag == 0x1c)
490 				tag.tag = 0x1017;
491 		} else if (tag.tag == 2 && strstr(fMeta.manufacturer, "NIKON")) {
492 			fRead.Next<uint16>();
493 				// ignored
494 			fMeta.iso_speed = fRead.Next<uint16>();
495 		}
496 
497 		if (tag.tag == 4 && tag.length == 27) {
498 			fRead.Next<uint32>();
499 				// ignored
500 			fMeta.iso_speed = 50 * pow(2, fRead.Next<uint16>() / 32.0 - 4);
501 			fRead.Next<uint16>();
502 				// ignored
503 			fMeta.aperture = pow(2, fRead.Next<uint16>() / 64.0);
504 			fMeta.shutter = pow(2, fRead.Next<int16>() / -32.0);
505 		}
506 		if (tag.tag == 8 && tag.type == 4)
507 			fMeta.shot_order = fRead.Next<uint32>();
508 		if (tag.tag == 0xc && tag.length == 4) {
509 			fMeta.camera_multipliers[0] = fRead.NextDouble(TIFF_FRACTION_TYPE);
510 			fMeta.camera_multipliers[2] = fRead.NextDouble(TIFF_FRACTION_TYPE);
511 		}
512 		if (tag.tag == 0x10 && tag.type == 4)
513 			fUniqueID = fRead.Next<uint32>();
514 		if (tag.tag == 0x11) {
515 			if (_ParseTIFFImageFileDirectory(baseOffset, fRead.Next<uint32>())
516 					== B_OK)
517 				fNumImages++;
518 		}
519 		if (tag.tag == 0x14 && tag.length == 2560 && tag.type == 7) {
520 			fRead.Seek(1248, SEEK_CUR);
521 			goto get2_256;
522 		}
523 		if (tag.tag == 0x1d) {
524 			int c;
525 			while ((c = fRead.Next<uint8>()) && c != EOF) {
526 				serial = serial * 10 + (isdigit(c) ? c - '0' : c % 10);
527 			}
528 		}
529 		if (tag.tag == 0x81 && tag.type == 4) {
530 			_Raw().data_offset = fRead.Next<uint32>();
531 			fRead.Seek(_Raw().data_offset + 41, SEEK_SET);
532 			_Raw().height = fRead.Next<uint16>() * 2;
533 			_Raw().width  = fRead.Next<uint16>();
534 			fFilters = 0x61616161;
535 		}
536 		if ((tag.tag == 0x81 && tag.type == 7)
537 			|| (tag.tag == 0x100 && tag.type == 7)
538 			|| (tag.tag == 0x280 && tag.type == 1)) {
539 			_Thumb().data_offset = fRead.Position();
540 			_Thumb().bytes = tag.length;
541 		}
542 		if (tag.tag == 0x88 && tag.type == 4
543 			&& (_Thumb().data_offset = fRead.Next<uint32>())) {
544 			_Thumb().data_offset += baseOffset;
545 		}
546 		if (tag.tag == 0x89 && tag.type == 4)
547 			_Thumb().bytes = fRead.Next<uint32>();
548 		if (tag.tag == 0x8c)
549 			fCurveOffset = fRead.Position() + 2112;
550 		if (tag.tag == 0x96)
551 			fCurveOffset = fRead.Position() + 2;
552 		if (tag.tag == 0x97) {
553 			for (uint32 i = 0; i < 4; i++) {
554 				ver97 = (ver97 << 4) + fRead.Next<uint8>() - '0';
555 			}
556 			switch (ver97) {
557 				case 0x100:
558 					fRead.Seek(68, SEEK_CUR);
559 					for (uint32 i = 0; i < 4; i++) {
560 						fMeta.camera_multipliers[(i >> 1) | ((i & 1) << 1)]
561 							= fRead.Next<uint16>();
562 					}
563 					break;
564 				case 0x102:
565 					fRead.Seek(6, SEEK_CUR);
566 					goto get2_rggb;
567 				case 0x103:
568 					fRead.Seek(16, SEEK_CUR);
569 					for (uint32 i = 0; i < 4; i++) {
570 						fMeta.camera_multipliers[i] = fRead.Next<uint16>();
571 					}
572 					break;
573 			}
574 			if (ver97 >> 8 == 2) {
575 				if (ver97 != 0x205)
576 					fRead.Seek(280, SEEK_CUR);
577 				fRead(buf97, sizeof(buf97));
578 			}
579 		}
580 		if (tag.tag == 0xa7 && ver97 >> 8 == 2) {
581 			ci = xlat[0][serial & 0xff];
582 			cj = xlat[1][fRead.Next<uint8>() ^ fRead.Next<uint8>()
583 				^ fRead.Next<uint8>() ^ fRead.Next<uint8>()];
584 			ck = 0x60;
585 			for (uint32 i = 0; i < 324; i++) {
586 				buf97[i] ^= (cj += ci * ck++);
587 			}
588 			for (uint32 i = 0; i < 4; i++) {
589 				uint16* data = (uint16*)(buf97
590 					+ (ver97 == 0x205 ? 14 : 6) + i * 2);
591 
592 				if (fRead.IsSwapping()) {
593 					fMeta.camera_multipliers[i ^ (i >> 1)]
594 						= __swap_int16(*data);
595 				} else {
596 					fMeta.camera_multipliers[i ^ (i >> 1)] = *data;
597 				}
598 			}
599 		}
600 		if (tag.tag == 0x200 && tag.length == 4) {
601 			fMeta.black = (fRead.Next<uint16>() + fRead.Next<uint16>()
602 				+ fRead.Next<uint16>() + fRead.Next<uint16>()) / 4;
603 		}
604 		if (tag.tag == 0x201 && tag.length == 4)
605 			goto get2_rggb;
606 		if (tag.tag == 0x401 && tag.length == 4) {
607 			fMeta.black = (fRead.Next<uint32>() + fRead.Next<uint32>()
608 				+ fRead.Next<uint32>() + fRead.Next<uint32>()) / 4;
609 		}
610 		if (tag.tag == 0xe01) {
611 			// Nikon Capture Note
612 			bool previousSwap = fRead.IsSwapping();
613 			fRead.SetSwap(B_HOST_IS_BENDIAN != 0);
614 				// this chunk is always in little endian
615 
616 			off_t offset = 22;
617 			fRead.Seek(offset, SEEK_CUR);
618 
619 			int32 i = 0;
620 
621 			for (; offset + 22 < tag.length; offset += 22 + i) {
622 				tag.tag = fRead.Next<uint32>();
623 				fRead.Seek(14, SEEK_CUR);
624 				i = fRead.Next<uint32>() - 4;
625 				if (tag.tag == 0x76a43207)
626 					fMeta.flip = fRead.Next<uint16>();
627 				else
628 					fRead.Seek(i, SEEK_CUR);
629 			}
630 
631 			fRead.SetSwap(previousSwap);
632 		}
633 		if (tag.tag == 0xe80 && tag.length == 256 && tag.type == 7) {
634 			fRead.Seek(48, SEEK_CUR);
635 			fMeta.camera_multipliers[0]
636 				= fRead.Next<uint16>() * 508 * 1.078 / 0x10000;
637 			fMeta.camera_multipliers[2]
638 				= fRead.Next<uint16>() * 382 * 1.173 / 0x10000;
639 		}
640 		if (tag.tag == 0xf00 && tag.type == 7) {
641 			if (tag.length == 614)
642 				fRead.Seek(176, SEEK_CUR);
643 			else if (tag.length == 734 || tag.length == 1502)
644 				fRead.Seek(148, SEEK_CUR);
645 			else
646 				goto next;
647 			goto get2_256;
648 		}
649 		if (tag.tag == 0x1011 && tag.length == 9 && fUseCameraWhiteBalance) {
650 			for (uint32 i = 0; i < 3; i++) {
651 				for (uint32 j = 0; j < 3; j++) {
652 					fMeta.rgb_camera[i][j] = fRead.Next<int16>() / 256.0;
653 				}
654 			}
655 			fRawColor = fMeta.rgb_camera[0][0] < 1;
656 		}
657 		if (tag.tag == 0x1012 && tag.length == 4) {
658 			fMeta.black = 0;
659 			for (uint32 i = 0; i < 4; i++) {
660 				fMeta.black += fRead.Next<uint16>() << 2;
661 			}
662 		}
663 		if (tag.tag == 0x1017)
664 			fMeta.camera_multipliers[0] = fRead.Next<uint16>() / 256.0;
665 		if (tag.tag == 0x1018)
666 			fMeta.camera_multipliers[2] = fRead.Next<uint16>() / 256.0;
667 
668 		if (tag.tag == 0x2011 && tag.length == 2) {
669 get2_256:
670 			bool previousSwap = fRead.IsSwapping();
671 			fRead.SetSwap(B_HOST_IS_LENDIAN != 0);
672 				// this chunk is always in big endian
673 
674 			fMeta.camera_multipliers[0] = fRead.Next<uint16>() / 256.0;
675 			fMeta.camera_multipliers[2] = fRead.Next<uint16>() / 256.0;
676 
677 			fRead.SetSwap(previousSwap);
678 		}
679 
680 		if (tag.tag == 0x2020)
681 			_ParseThumbTag(baseOffset, 257, 258);
682 		if (tag.tag == 0xb028) {
683 			fRead.Seek(fRead.Next<uint32>(), SEEK_SET);
684 			_ParseThumbTag(baseOffset, 136, 137);
685 		}
686 
687 		if (tag.tag == 0x4001) {
688 			{
689 				off_t offset = tag.length == 582 ? 50 : tag.length == 653
690 					? 68 : 126;
691 				fRead.Seek(offset, SEEK_CUR);
692 			}
693 get2_rggb:
694 			for (uint32 i = 0; i < 4; i++) {
695 				fMeta.camera_multipliers[i ^ (i >> 1)] = fRead.Next<uint16>();
696 			}
697 		}
698 
699 next:
700     	fRead.Seek(nextOffset, SEEK_SET);
701 	}
702 
703 quit:
704 	fRead.SetSwap(originalSwap);
705 }
706 
707 
708 void
709 DCRaw::_ParseEXIF(off_t baseOffset)
710 {
711 	bool kodak = !strncmp(fMeta.manufacturer, "EASTMAN", 7);
712 
713 	uint16 entries;
714 	fRead(entries);
715 
716 	while (entries--) {
717 		off_t nextOffset;
718 		tiff_tag tag;
719 		_ParseTIFFTag(baseOffset, tag, nextOffset);
720 		TAG("EXIF tag %u (type %u, length %lu)\n", tag.tag, tag.type,
721 			tag.length);
722 
723 		switch (tag.tag) {
724 #if 0
725 			default:
726 				printf("  unhandled EXIF tag %u\n", tag.tag);
727 				break;
728 #endif
729 			case 33434:
730 				fMeta.shutter = fRead.NextDouble(TIFF_FRACTION_TYPE);
731 				break;
732 			case 33437:
733 				fMeta.aperture = fRead.NextDouble(TIFF_FRACTION_TYPE);
734 				break;
735 			case 34855:
736 				fMeta.iso_speed = fRead.Next<uint16>();
737 				break;
738 			case 36867:
739 			case 36868:
740 				fMeta.timestamp = _ParseTIFFTimestamp(false);
741 				break;
742 			case 37377:
743 			{
744 				double expo;
745 				if ((expo = -fRead.NextDouble(TIFF_FRACTION_TYPE)) < 128)
746 					fMeta.shutter = pow(2, expo);
747 				break;
748 			}
749 			case 37378:
750 				fMeta.aperture
751 					= pow(2, fRead.NextDouble(TIFF_FRACTION_TYPE) / 2);
752 				break;
753 			case 37386:
754 				fMeta.focal_length = fRead.NextDouble(TIFF_FRACTION_TYPE);
755 				break;
756 			case 37500:
757 				_ParseManufacturerTag(baseOffset);
758 				break;
759 			case 40962:
760 				if (kodak)
761 					_Raw().width = fRead.Next<uint32>();
762 				break;
763 			case 40963:
764 				if (kodak)
765 					_Raw().height = fRead.Next<uint32>();
766 				break;
767 			case 41730:
768 				if (fRead.Next<uint32>() == 0x20002) {
769 					fEXIFFilters = 0;
770 					for (uint32 c = 0; c < 8; c += 2) {
771 						fEXIFFilters |= fRead.Next<uint8>() * 0x01010101 << c;
772 					}
773 				}
774 				break;
775 		}
776 
777 		fRead.Seek(nextOffset, SEEK_SET);
778 	}
779 }
780 
781 
782 void
783 DCRaw::_ParseLinearTable(uint32 length)
784 {
785 	if (length > 0x1000)
786 		length = 0x1000;
787 
788 	fRead.NextShorts(fCurve, length);
789 
790 	for (uint32 i = length; i < 0x1000; i++) {
791 		fCurve[i] = fCurve[i - 1];
792 	}
793 
794 	fMeta.maximum = fCurve[0xfff];
795 }
796 
797 
798 /*!	This (lengthy) method contains fixes for the values in the image data to
799 	be able to actually read the image data correctly.
800 */
801 void
802 DCRaw::_FixupValues()
803 {
804 	// PENTAX and SAMSUNG section
805 	// (Samsung sells rebranded Pentax cameras)
806 
807 	if (_IsPentax() || _IsSamsung()) {
808 		if (fInputWidth == 3936 && fInputHeight == 2624) {
809 			// Pentax K10D and Samsumg GX10
810 			fInputWidth = 3896;
811 			fInputHeight = 2616;
812 		}
813 	}
814 
815 	// CANON
816 
817 	if (_IsCanon()) {
818 		bool isCR2 = false;
819 		if (strstr(fMeta.model, "EOS D2000C")) {
820 			fFilters = 0x61616161;
821 			fMeta.black = fCurve[200];
822 		}
823 
824 		switch (_Raw().width) {
825 			case 2144:
826 				fInputHeight = 1550;
827 				fInputWidth = 2088;
828 				fTopMargin = 8;
829 				fLeftMargin = 4;
830 				if (!strcmp(fMeta.model, "PowerShot G1")) {
831 					fColors = 4;
832 					fFilters = 0xb4b4b4b4;
833 				}
834 				break;
835 
836 			case 2224:
837 				fInputHeight = 1448;
838 				fInputWidth = 2176;
839 				fTopMargin = 6;
840 				fLeftMargin = 48;
841 				break;
842 
843 			case 2376:
844 				fInputHeight = 1720;
845 				fInputWidth = 2312;
846 				fTopMargin = 6;
847 				fLeftMargin = 12;
848 				break;
849 
850 			case 2672:
851 				fInputHeight = 1960;
852 				fInputWidth = 2616;
853 				fTopMargin = 6;
854 				fLeftMargin = 12;
855 				break;
856 
857 			case 3152:
858 				fInputHeight = 2056;
859 				fInputWidth = 3088;
860 				fTopMargin = 12;
861 				fLeftMargin = 64;
862 				if (fUniqueID == 0x80000170)
863 					_AdobeCoefficients("Canon", "EOS 300D");
864 				fMeta.maximum = 0xfa0;
865 				break;
866 
867 			case 3160:
868 				fInputHeight = 2328;
869 				fInputWidth = 3112;
870 				fTopMargin = 12;
871 				fLeftMargin = 44;
872 				break;
873 
874 			case 3344:
875 				fInputHeight = 2472;
876 				fInputWidth = 3288;
877 				fTopMargin = 6;
878 				fLeftMargin = 4;
879 				break;
880 
881 			case 3516:
882 				fTopMargin = 14;
883 				fLeftMargin = 42;
884 				if (fUniqueID == 0x80000189)
885 					_AdobeCoefficients("Canon", "EOS 350D");
886 				isCR2 = true;
887 				break;
888 
889 			case 3596:
890 				fTopMargin = 12;
891 				fLeftMargin = 74;
892 				isCR2 = true;
893 				break;
894 
895 			case 3948:
896 				fTopMargin = 18;
897 				fLeftMargin = 42;
898 				fInputHeight -= 2;
899 				if (fUniqueID == 0x80000236)
900 					_AdobeCoefficients("Canon", "EOS 400D");
901 				isCR2 = true;
902 				break;
903 
904 			case 3984:
905 				fTopMargin  = 20;
906 				fLeftMargin = 76;
907 				fInputHeight -= 2;
908 				fMeta.maximum = 0x3bb0;
909 				isCR2 = true;
910 				break;
911 
912 			case 4476:
913 				fTopMargin  = 34;
914 				fLeftMargin = 90;
915 				fMeta.maximum = 0xe6c;
916 				isCR2 = true;
917 				break;
918 
919 			case 5108:
920 				fTopMargin  = 13;
921 				fLeftMargin = 98;
922 				fMeta.maximum = 0xe80;
923 				isCR2 = true;
924 				break;
925 		}
926 
927 		if (isCR2) {
928 			fInputHeight -= fTopMargin;
929 			fInputWidth -= fLeftMargin;
930 		}
931 	}
932 
933 	// Olympus
934 
935 	if (_IsOlympus()) {
936 		if (!strcmp(fMeta.model,"E-300") || !strcmp(fMeta.model,"E-500")) {
937 			fInputWidth -= 20;
938 			fMeta.maximum = 0xfc30;
939 			//if (load_raw == &CLASS unpacked_load_raw) black = 0;
940 		}
941 	}
942 }
943 
944 
945 //	#pragma mark - Image Conversion
946 
947 
948 void
949 DCRaw::_ScaleColors()
950 {
951 	if (fProgressMonitor != NULL)
952 		fProgressMonitor("Scale Colors", 5, fProgressData);
953 
954 	int dblack, c, val, sum[8];
955 	uint32 row, col, x, y;
956 	double dsum[8], dmin, dmax;
957 	float scale_mul[4];
958 
959 	if (fUseCameraWhiteBalance && fMeta.camera_multipliers[0] != -1) {
960 		memset(sum, 0, sizeof(sum));
961 		for (row = 0; row < 8; row++) {
962 			for (col = 0; col < 8; col++) {
963 				c = FC(row, col);
964 				if ((val = fWhite[row][col] - fMeta.black) > 0)
965 					sum[c] += val;
966 				sum[c + 4]++;
967 			}
968 		}
969 
970 		if (sum[0] && sum[1] && sum[2] && sum[3]) {
971 			for (int c = 0; c < 4; c++) {
972 				fMeta.pre_multipliers[c] = (float)sum[c+4] / sum[c];
973 			}
974 		} else if (fMeta.camera_multipliers[0] && fMeta.camera_multipliers[2]) {
975 			memcpy(fMeta.pre_multipliers, fMeta.camera_multipliers,
976 				sizeof(fMeta.pre_multipliers));
977 		} else
978 			fprintf(stderr, "Cannot use camera white balance.\n");
979 	} else if (fUseAutoWhiteBalance) {
980 		memset(dsum, 0, sizeof(dsum));
981 		for (row = 0; row < fOutputHeight - 7; row += 8) {
982 			for (col = 0; col < fOutputWidth - 7; col += 8) {
983 				memset(sum, 0, sizeof(sum));
984 				for (y = row; y < row + 8; y++) {
985 					for (x = col; x < col + 8; x++) {
986 						for (int c = 0; c < 4; c++) {
987 							val = fImageData[y * fOutputWidth + x][c];
988 							if (!val)
989 								continue;
990 							if (val > fMeta.maximum - 25)
991 								goto skip_block;
992 							val -= fMeta.black;
993 							if (val < 0)
994 								val = 0;
995 							sum[c] += val;
996 							sum[c+4]++;
997 						}
998 					}
999 				}
1000 
1001 				for (c=0; c < 8; c++) {
1002 					dsum[c] += sum[c];
1003 				}
1004 
1005 			skip_block:
1006 				continue;
1007 			}
1008 		}
1009 		for (int c = 0; c < 4; c++) {
1010 			if (dsum[c])
1011 				fMeta.pre_multipliers[c] = dsum[c + 4] / dsum[c];
1012 		}
1013 	}
1014 
1015 
1016 	if (fUserMultipliers[0]) {
1017 		memcpy(fMeta.pre_multipliers, fUserMultipliers,
1018 			sizeof(fMeta.pre_multipliers));
1019 	}
1020 	if (fMeta.pre_multipliers[3] == 0)
1021 		fMeta.pre_multipliers[3] = fColors < 4 ? fMeta.pre_multipliers[1] : 1;
1022 
1023 	dblack = fMeta.black;
1024 	if (fThreshold)
1025 		_WaveletDenoise();
1026 
1027 	fMeta.maximum -= fMeta.black;
1028 	for (dmin = DBL_MAX, dmax = c = 0; c < 4; c++) {
1029 		if (dmin > fMeta.pre_multipliers[c])
1030 			dmin = fMeta.pre_multipliers[c];
1031 		if (dmax < fMeta.pre_multipliers[c])
1032 			dmax = fMeta.pre_multipliers[c];
1033 	}
1034 
1035 	if (!fHighlight)
1036 		dmax = dmin;
1037 
1038 	for (int c = 0; c < 4; c++) {
1039 		scale_mul[c] = (fMeta.pre_multipliers[c] /= dmax) * 65535.0
1040 			/ fMeta.maximum;
1041 	}
1042 
1043 #if 0
1044 	if (1/*verbose*/) {
1045 		fprintf(stderr, "Scaling with black %d, multipliers", dblack);
1046 		for (int c = 0; c < 4; c++) {
1047 			fprintf(stderr, " %f", fMeta.pre_multipliers[c]);
1048 		}
1049 		fputc('\n', stderr);
1050 	}
1051 #endif
1052 
1053 	for (row = 0; row < fOutputHeight; row++) {
1054 		for (col = 0; col < fOutputWidth; col++) {
1055 			for (int c = 0; c < 4; c++) {
1056 				val = fImageData[row * fOutputWidth + col][c];
1057 				if (!val)
1058 					continue;
1059 				val -= fMeta.black;
1060 				val = int(val * scale_mul[c]);
1061 				fImageData[row * fOutputWidth + col][c] = CLIP(val);
1062 			}
1063 		}
1064 	}
1065 }
1066 
1067 
1068 void
1069 DCRaw::_WaveletDenoise()
1070 {
1071 	if (fProgressMonitor != NULL)
1072 		fProgressMonitor("Wavelet Denoise", 8, fProgressData);
1073 
1074 	float *fimg, *temp, mul[2], avg, diff;
1075 	int32 scale = 1, sh, c, i, j, k, m, row, col, size, numColors, dim = 0;
1076 	int32 wlast;
1077 	ushort *window[4];
1078 	// Daubechies 9-tap/7-tap filter
1079 	static const float wlet[] =	{ 1.149604398, -1.586134342,
1080 		-0.05298011854, 0.8829110762, 0.4435068522 };
1081 
1082 	while ((fMeta.maximum << scale) < 0x10000) {
1083 		scale++;
1084 	}
1085 	fMeta.maximum <<= fMeta.maximum << --scale;
1086 	fMeta.black <<= scale;
1087 
1088 	while ((1UL << dim) < fOutputWidth || (1UL << dim) < fOutputHeight) {
1089 		dim++;
1090 	}
1091 
1092 	fimg = (float *)calloc((1UL << dim*2) + (1UL << dim) + 2, sizeof *fimg);
1093 	if (fimg == NULL)
1094 		return;
1095 
1096 	temp = fimg + (1 << dim * 2) + 1;
1097 	numColors = fColors;
1098 	if (numColors == 3 && fFilters)
1099 		numColors++;
1100 
1101 	for (c = 0; c < numColors; c++) {
1102 		// denoise R,G1,B,G3 individually
1103 		for (row = 0; row < (int32)fOutputHeight; row++) {
1104 			for (col = 0; col < (int32)fOutputWidth; col++) {
1105 				fimg[(row << dim) + col]
1106 					= fImageData[row * fOutputWidth + col][c] << scale;
1107 			}
1108 		}
1109 		for (size = 1UL << dim; size > 1; size >>= 1) {
1110 			for (sh = 0; sh <= dim; sh += dim) {
1111 				for (i = 0; i < size; i++) {
1112 					for (j = 0; j < size; j++) {
1113 						temp[j] = fimg[(i << (dim - sh)) + (j << sh)];
1114 					}
1115 					for (k = 1; k < 5; k += 2) {
1116 						temp[size] = temp[size - 2];
1117 						for (m = 1; m < size; m += 2) {
1118 							temp[m] += wlet[k] * (temp[m - 1] + temp[m + 1]);
1119 						}
1120 						temp[-1] = temp[1];
1121 						for (m = 0; m < size; m += 2) {
1122 							temp[m] += wlet[k + 1]
1123 								* (temp[m - 1] + temp[m + 1]);
1124 						}
1125 					}
1126 					for (m = 0; m < size; m++) {
1127 						temp[m] *= (m & 1) ? 1 / wlet[0] : wlet[0];
1128 					}
1129 					for (j = k = 0; j < size; j++, k += 2) {
1130 						if (k == size)
1131 							k = 1;
1132 						fimg[(i << (dim - sh)) + (j << sh)] = temp[k];
1133 					}
1134 				}
1135 			}
1136 		}
1137 
1138 		for (i = 0; i < (1 << dim * 2); i++) {
1139 			if (fimg[i] < -fThreshold)
1140 				fimg[i] += fThreshold;
1141 			else if (fimg[i] > fThreshold)
1142 				fimg[i] -= fThreshold;
1143 			else
1144 				fimg[i] = 0;
1145 		}
1146 
1147 		for (size = 2; size <= (1 << dim); size <<= 1) {
1148 			for (sh = dim; sh >= 0; sh -= dim) {
1149 				for (i = 0; i < size; i++) {
1150 					for (j = k = 0; j < size; j++, k += 2) {
1151 						if (k == size)
1152 							k = 1;
1153 						temp[k] = fimg[(i << (dim - sh)) + (j << sh)];
1154 					}
1155 					for (m = 0; m < size; m++) {
1156 						temp[m] *= (m & 1) ? wlet[0] : 1 / wlet[0];
1157 					}
1158 					for (k = 3; k > 0; k -= 2) {
1159 						temp[-1] = temp[1];
1160 						for (m = 0; m < size; m += 2) {
1161 							temp[m] -= wlet[k + 1]
1162 								* (temp[m - 1] + temp[m + 1]);
1163 						}
1164 						temp[size] = temp[size - 2];
1165 						for (m = 1; m < size; m += 2) {
1166 							temp[m] -= wlet[k] * (temp[m - 1] + temp[m + 1]);
1167 						}
1168 					}
1169 					for (j = 0; j < size; j++) {
1170 						fimg[(i << (dim - sh)) + (j << sh)] = temp[j];
1171 					}
1172 				}
1173 			}
1174 		}
1175 
1176 		for (row = 0; row < (int32)fOutputHeight; row++) {
1177 			for (col = 0; col < (int32)fOutputWidth; col++) {
1178 				fImageData[row * fOutputWidth + col][c]
1179 					= (uint16)CLIP(fimg[(row << dim) + col] + 0.5);
1180 			}
1181 		}
1182 	}
1183 
1184 	if (fFilters && fColors == 3) {
1185 		// pull G1 and G3 closer together
1186 		for (row = 0; row < 2; row++) {
1187 			mul[row] = 0.125 * fMeta.pre_multipliers[FC(row + 1, 0) | 1]
1188 				/ fMeta.pre_multipliers[FC(row, 0) | 1];
1189 		}
1190 		for (i = 0; i < 4; i++) {
1191 			window[i] = (ushort *)fimg + fInputWidth * i;
1192 		}
1193 		for (wlast = -1, row = 1; row < (int32)fInputHeight - 1; row++) {
1194 			while (wlast < (int32)row + 1) {
1195 				for (wlast++, i = 0; i < 4; i++) {
1196 					window[(i + 3) & 3] = window[i];
1197 				}
1198 				for (col = FC(wlast, 1) & 1; col < (int32)fInputWidth;
1199 						col += 2) {
1200 					window[2][col] = _Bayer(col, wlast);
1201 				}
1202 			}
1203 
1204 			for (col = (FC(row, 0) & 1) + 1; col < (int32)fInputWidth - 1;
1205 					col += 2) {
1206 				avg = ( window[0][col - 1] + window[0][col + 1]
1207 					+ window[2][col - 1] + window[2][col + 1] - fMeta.black * 4)
1208 					* mul[row & 1] + (window[1][col] - fMeta.black) * 0.5
1209 					+ fMeta.black;
1210 				diff = _Bayer(col, row) - avg;
1211 
1212 				if (diff < -fThreshold / M_SQRT2)
1213 					diff += fThreshold / M_SQRT2;
1214 				else if (diff > fThreshold / M_SQRT2)
1215 					diff -= fThreshold / M_SQRT2;
1216 				else
1217 					diff = 0;
1218 				_Bayer(col, row) = (uint16)CLIP(avg + diff + 0.5);
1219 			}
1220 		}
1221 	}
1222 
1223 	free(fimg);
1224 }
1225 
1226 
1227 void
1228 DCRaw::_PreInterpolate()
1229 {
1230 	if (fProgressMonitor != NULL)
1231 		fProgressMonitor("Pre-Interpolate", 10, fProgressData);
1232 
1233 	uint32 row, col;
1234 
1235 	if (fShrink) {
1236 		if (fHalfSize) {
1237 			fInputHeight = fOutputHeight;
1238 			fInputWidth = fOutputWidth;
1239 			fFilters = 0;
1240 		} else {
1241 			uint16 (*data)[4] = (uint16 (*)[4])calloc(fInputHeight
1242 				* fInputWidth, sizeof(*data));
1243 			if (data == NULL)
1244 				throw (status_t)B_NO_MEMORY;
1245 
1246 			for (row = 0; row < fInputHeight; row++) {
1247 				for (col = 0; col < fInputWidth; col++) {
1248 					data[row * fInputWidth + col][FC(row, col)]
1249 						= _Bayer(col, row);
1250 				}
1251 			}
1252 
1253 			free(fImageData);
1254 			fImageData = data;
1255 			fShrink = 0;
1256 		}
1257 	}
1258 
1259 	if (fFilters && fColors == 3) {
1260 //		if ((mix_green = four_color_rgb))
1261 //			fColors++;
1262 //		else
1263 		{
1264 			for (row = FC(1, 0) >> 1; row < fInputHeight; row += 2) {
1265 				for (col = FC(row, 1) & 1; col < fInputWidth; col += 2) {
1266 					fImageData[row * fInputWidth + col][1]
1267 						= fImageData[row * fInputWidth + col][3];
1268 				}
1269 			}
1270 			fFilters &= ~((fFilters & 0x55555555) << 1);
1271 		}
1272 	}
1273 }
1274 
1275 
1276 void
1277 DCRaw::_CameraToCIELab(ushort cam[4], float lab[3])
1278 {
1279 	if (cam == NULL) {
1280 		for (uint32 i = 0; i < 0x10000; i++) {
1281 			float r = i / 65535.0;
1282 			cbrt[i] = r > 0.008856 ? pow(r, 1 / 3.0) : 7.787 * r + 16 / 116.0;
1283 		}
1284 		for (uint32 i = 0; i < 3; i++) {
1285 			for (uint32 j = 0; j < fColors; j++) {
1286 				xyz_cam[i][j] = 0;
1287 				for (uint32 k = 0; k < 3; k++) {
1288 					xyz_cam[i][j] += xyz_rgb[i][k] * fMeta.rgb_camera[k][j]
1289 						/ kD65White[i];
1290 				}
1291 			}
1292 		}
1293 	} else {
1294 		float xyz[3];
1295 		xyz[0] = xyz[1] = xyz[2] = 0.5;
1296 		for (uint32 c = 0; c < fColors; c++) {
1297 			xyz[0] += xyz_cam[0][c] * cam[c];
1298 			xyz[1] += xyz_cam[1][c] * cam[c];
1299 			xyz[2] += xyz_cam[2][c] * cam[c];
1300 		}
1301 		xyz[0] = cbrt[CLIP((int) xyz[0])];
1302 		xyz[1] = cbrt[CLIP((int) xyz[1])];
1303 		xyz[2] = cbrt[CLIP((int) xyz[2])];
1304 		lab[0] = 116 * xyz[1] - 16;
1305 		lab[1] = 500 * (xyz[0] - xyz[1]);
1306 		lab[2] = 200 * (xyz[1] - xyz[2]);
1307 	}
1308 }
1309 
1310 
1311 void
1312 DCRaw::_CameraXYZCoefficients(double cameraXYZ[4][3])
1313 {
1314 	double cam_rgb[4][3], inverse[4][3], num;
1315 	uint32 i, j, k;
1316 
1317 	// Multiply out XYZ colorspace
1318 	for (i = 0; i < fColors; i++)	{
1319 		for (j = 0; j < 3; j++) {
1320 			for (cam_rgb[i][j] = k = 0; k < 3; k++) {
1321 				cam_rgb[i][j] += cameraXYZ[i][k] * xyz_rgb[k][j];
1322 			}
1323 		}
1324 	}
1325 
1326 	// Normalize cam_rgb so that cam_rgb * (1,1,1) is (1,1,1,1)
1327 	for (i = 0; i < fColors; i++) {
1328 		for (num = j = 0; j < 3; j++) {
1329 			num += cam_rgb[i][j];
1330 		}
1331 		for (j = 0; j < 3; j++) {
1332 			cam_rgb[i][j] /= num;
1333 		}
1334 		fMeta.pre_multipliers[i] = 1 / num;
1335 	}
1336 
1337 	_PseudoInverse(cam_rgb, inverse, fColors);
1338 
1339 	fRawColor = false;
1340 	for (i = 0; i < 3; i++) {
1341 		for (j=0; j < fColors; j++) {
1342 			fMeta.rgb_camera[i][j] = inverse[j][i];
1343 		}
1344 	}
1345 }
1346 
1347 
1348 /*!	Thanks to Adobe for providing these excellent CAM -> XYZ matrices!
1349 */
1350 void
1351 DCRaw::_AdobeCoefficients(const char *make, const char *model)
1352 {
1353 	static const struct {
1354 		const char *prefix;
1355 		short black, trans[12];
1356 	} table[] = {
1357 		{ "Canon EOS D2000", 0,
1358 			{ 24542,-10860,-3401,-1490,11370,-297,2858,-605,3225 }},
1359 		{ "Canon EOS D6000", 0,
1360 			{ 20482,-7172,-3125,-1033,10410,-285,2542,226,3136 }},
1361 		{ "Canon EOS D30", 0,
1362 			{ 9805,-2689,-1312,-5803,13064,3068,-2438,3075,8775 }},
1363 		{ "Canon EOS D60", 0,
1364 			{ 6188,-1341,-890,-7168,14489,2937,-2640,3228,8483 }},
1365 		{ "Canon EOS 5D", 0,
1366 			{ 6347,-479,-972,-8297,15954,2480,-1968,2131,7649 }},
1367 		{ "Canon EOS 20Da", 0,
1368 			{ 14155,-5065,-1382,-6550,14633,2039,-1623,1824,6561 }},
1369 		{ "Canon EOS 20D", 0,
1370 			{ 6599,-537,-891,-8071,15783,2424,-1983,2234,7462 }},
1371 		{ "Canon EOS 30D", 0,
1372 			{ 6257,-303,-1000,-7880,15621,2396,-1714,1904,7046 }},
1373 		{ "Canon EOS 350D", 0,
1374 			{ 6018,-617,-965,-8645,15881,2975,-1530,1719,7642 }},
1375 		{ "Canon EOS 400D", 0,
1376 			{ 7054,-1501,-990,-8156,15544,2812,-1278,1414,7796 }},
1377 		{ "Canon EOS-1Ds Mark II", 0,
1378 			{ 6517,-602,-867,-8180,15926,2378,-1618,1771,7633 }},
1379 		{ "Canon EOS-1D Mark II N", 0,
1380 			{ 6240,-466,-822,-8180,15825,2500,-1801,1938,8042 }},
1381 		{ "Canon EOS-1D Mark II", 0,
1382 			{ 6264,-582,-724,-8312,15948,2504,-1744,1919,8664 }},
1383 		{ "Canon EOS-1DS", 0,
1384 			{ 4374,3631,-1743,-7520,15212,2472,-2892,3632,8161 }},
1385 		{ "Canon EOS-1D", 0,
1386 			{ 6806,-179,-1020,-8097,16415,1687,-3267,4236,7690 }},
1387 		{ "Canon EOS", 0,
1388 			{ 8197,-2000,-1118,-6714,14335,2592,-2536,3178,8266 }},
1389 		{ "Canon PowerShot A50", 0,
1390 			{ -5300,9846,1776,3436,684,3939,-5540,9879,6200,-1404,11175,217 }},
1391 		{ "Canon PowerShot A5", 0,
1392 			{ -4801,9475,1952,2926,1611,4094,-5259,10164,5947,-1554,10883,547 }},
1393 		{ "Canon PowerShot G1", 0,
1394 			{ -4778,9467,2172,4743,-1141,4344,-5146,9908,6077,-1566,11051,557 }},
1395 		{ "Canon PowerShot G2", 0,
1396 			{ 9087,-2693,-1049,-6715,14382,2537,-2291,2819,7790 }},
1397 		{ "Canon PowerShot G3", 0,
1398 			{ 9212,-2781,-1073,-6573,14189,2605,-2300,2844,7664 }},
1399 		{ "Canon PowerShot G5", 0,
1400 			{ 9757,-2872,-933,-5972,13861,2301,-1622,2328,7212 }},
1401 		{ "Canon PowerShot G6", 0,
1402 			{ 9877,-3775,-871,-7613,14807,3072,-1448,1305,7485 }},
1403 		{ "Canon PowerShot Pro1", 0,
1404 			{ 10062,-3522,-999,-7643,15117,2730,-765,817,7323 }},
1405 		{ "Canon PowerShot Pro70", 34,
1406 			{ -4155,9818,1529,3939,-25,4522,-5521,9870,6610,-2238,10873,1342 }},
1407 		{ "Canon PowerShot Pro90", 0,
1408 			{ -4963,9896,2235,4642,-987,4294,-5162,10011,5859,-1770,11230,577 }},
1409 		{ "Canon PowerShot S30", 0,
1410 			{ 10566,-3652,-1129,-6552,14662,2006,-2197,2581,7670 }},
1411 		{ "Canon PowerShot S40", 0,
1412 			{ 8510,-2487,-940,-6869,14231,2900,-2318,2829,9013 }},
1413 		{ "Canon PowerShot S45", 0,
1414 			{ 8163,-2333,-955,-6682,14174,2751,-2077,2597,8041 }},
1415 		{ "Canon PowerShot S50", 0,
1416 			{ 8882,-2571,-863,-6348,14234,2288,-1516,2172,6569 }},
1417 		{ "Canon PowerShot S60", 0,
1418 			{ 8795,-2482,-797,-7804,15403,2573,-1422,1996,7082 }},
1419 		{ "Canon PowerShot S70", 0,
1420 			{ 9976,-3810,-832,-7115,14463,2906,-901,989,7889 }},
1421 		{ "Canon PowerShot A610", 0, /* DJC */
1422 			{ 15591,-6402,-1592,-5365,13198,2168,-1300,1824,5075 }},
1423 		{ "Canon PowerShot A620", 0, /* DJC */
1424 			{ 15265,-6193,-1558,-4125,12116,2010,-888,1639,5220 }},
1425 		{ "Canon PowerShot S3 IS", 0, /* DJC */
1426 			{ 14062,-5199,-1446,-4712,12470,2243,-1286,2028,4836 }},
1427 		{ "Contax N Digital", 0,
1428 			{ 7777,1285,-1053,-9280,16543,2916,-3677,5679,7060 }},
1429 		{ "EPSON R-D1", 0,
1430 			{ 6827,-1878,-732,-8429,16012,2564,-704,592,7145 }},
1431 		{ "FUJIFILM FinePix E550", 0,
1432 			{ 11044,-3888,-1120,-7248,15168,2208,-1531,2277,8069 }},
1433 		{ "FUJIFILM FinePix E900", 0,
1434 			{ 9183,-2526,-1078,-7461,15071,2574,-2022,2440,8639 }},
1435 		{ "FUJIFILM FinePix F8", 0,
1436 			{ 11044,-3888,-1120,-7248,15168,2208,-1531,2277,8069 }},
1437 		{ "FUJIFILM FinePix F7", 0,
1438 			{ 10004,-3219,-1201,-7036,15047,2107,-1863,2565,7736 }},
1439 		{ "FUJIFILM FinePix S20Pro", 0,
1440 			{ 10004,-3219,-1201,-7036,15047,2107,-1863,2565,7736 }},
1441 		{ "FUJIFILM FinePix S2Pro", 128,
1442 			{ 12492,-4690,-1402,-7033,15423,1647,-1507,2111,7697 }},
1443 		{ "FUJIFILM FinePix S3Pro", 0,
1444 			{ 11807,-4612,-1294,-8927,16968,1988,-2120,2741,8006 }},
1445 		{ "FUJIFILM FinePix S5000", 0,
1446 			{ 8754,-2732,-1019,-7204,15069,2276,-1702,2334,6982 }},
1447 		{ "FUJIFILM FinePix S5100", 0,
1448 			{ 11940,-4431,-1255,-6766,14428,2542,-993,1165,7421 }},
1449 		{ "FUJIFILM FinePix S5500", 0,
1450 			{ 11940,-4431,-1255,-6766,14428,2542,-993,1165,7421 }},
1451 		{ "FUJIFILM FinePix S5200", 0,
1452 			{ 9636,-2804,-988,-7442,15040,2589,-1803,2311,8621 }},
1453 		{ "FUJIFILM FinePix S5600", 0,
1454 			{ 9636,-2804,-988,-7442,15040,2589,-1803,2311,8621 }},
1455 		{ "FUJIFILM FinePix S6", 0,
1456 			{ 12628,-4887,-1401,-6861,14996,1962,-2198,2782,7091 }},
1457 		{ "FUJIFILM FinePix S7000", 0,
1458 			{ 10190,-3506,-1312,-7153,15051,2238,-2003,2399,7505 }},
1459 		{ "FUJIFILM FinePix S9000", 0,
1460 			{ 10491,-3423,-1145,-7385,15027,2538,-1809,2275,8692 }},
1461 		{ "FUJIFILM FinePix S9500", 0,
1462 			{ 10491,-3423,-1145,-7385,15027,2538,-1809,2275,8692 }},
1463 		{ "FUJIFILM FinePix S9100", 0,
1464 			{ 12343,-4515,-1285,-7165,14899,2435,-1895,2496,8800 }},
1465 		{ "FUJIFILM FinePix S9600", 0,
1466 			{ 12343,-4515,-1285,-7165,14899,2435,-1895,2496,8800 }},
1467 		{ "Imacon Ixpress", 0,	/* DJC */
1468 			{ 7025,-1415,-704,-5188,13765,1424,-1248,2742,6038 }},
1469 		{ "KODAK NC2000", 0,	/* DJC */
1470 			{ 16475,-6903,-1218,-851,10375,477,2505,-7,1020 }},
1471 		{ "Kodak DCS315C", 8,
1472 			{ 17523,-4827,-2510,756,8546,-137,6113,1649,2250 }},
1473 		{ "Kodak DCS330C", 8,
1474 			{ 20620,-7572,-2801,-103,10073,-396,3551,-233,2220 }},
1475 		{ "KODAK DCS420", 0,
1476 			{ 10868,-1852,-644,-1537,11083,484,2343,628,2216 }},
1477 		{ "KODAK DCS460", 0,
1478 			{ 10592,-2206,-967,-1944,11685,230,2206,670,1273 }},
1479 		{ "KODAK EOSDCS1", 0,
1480 			{ 10592,-2206,-967,-1944,11685,230,2206,670,1273 }},
1481 		{ "KODAK EOSDCS3B", 0,
1482 			{ 9898,-2700,-940,-2478,12219,206,1985,634,1031 }},
1483 		{ "Kodak DCS520C", 180,
1484 			{ 24542,-10860,-3401,-1490,11370,-297,2858,-605,3225 }},
1485 		{ "Kodak DCS560C", 188,
1486 			{ 20482,-7172,-3125,-1033,10410,-285,2542,226,3136 }},
1487 		{ "Kodak DCS620C", 180,
1488 			{ 23617,-10175,-3149,-2054,11749,-272,2586,-489,3453 }},
1489 		{ "Kodak DCS620X", 185,
1490 			{ 13095,-6231,154,12221,-21,-2137,895,4602,2258 }},
1491 		{ "Kodak DCS660C", 214,
1492 			{ 18244,-6351,-2739,-791,11193,-521,3711,-129,2802 }},
1493 		{ "Kodak DCS720X", 0,
1494 			{ 11775,-5884,950,9556,1846,-1286,-1019,6221,2728 }},
1495 		{ "Kodak DCS760C", 0,
1496 			{ 16623,-6309,-1411,-4344,13923,323,2285,274,2926 }},
1497 		{ "Kodak DCS Pro SLR", 0,
1498 			{ 5494,2393,-232,-6427,13850,2846,-1876,3997,5445 }},
1499 		{ "Kodak DCS Pro 14nx", 0,
1500 			{ 5494,2393,-232,-6427,13850,2846,-1876,3997,5445 }},
1501 		{ "Kodak DCS Pro 14", 0,
1502 			{ 7791,3128,-776,-8588,16458,2039,-2455,4006,6198 }},
1503 		{ "Kodak ProBack645", 0,
1504 			{ 16414,-6060,-1470,-3555,13037,473,2545,122,4948 }},
1505 		{ "Kodak ProBack", 0,
1506 			{ 21179,-8316,-2918,-915,11019,-165,3477,-180,4210 }},
1507 		{ "KODAK P712", 0,
1508 			{ 9658,-3314,-823,-5163,12695,2768,-1342,1843,6044 }},
1509 		{ "KODAK P850", 0,
1510 			{ 10511,-3836,-1102,-6946,14587,2558,-1481,1792,6246 }},
1511 		{ "KODAK P880", 0,
1512 			{ 12805,-4662,-1376,-7480,15267,2360,-1626,2194,7904 }},
1513 		{ "Leaf CMost", 0,
1514 			{ 3952,2189,449,-6701,14585,2275,-4536,7349,6536 }},
1515 		{ "Leaf Valeo 6", 0,
1516 			{ 3952,2189,449,-6701,14585,2275,-4536,7349,6536 }},
1517 		{ "Leaf Aptus 65", 0,
1518 			{ 7914,1414,-1190,-8777,16582,2280,-2811,4605,5562 }},
1519 		{ "Leaf Aptus 75", 0,
1520 			{ 7914,1414,-1190,-8777,16582,2280,-2811,4605,5562 }},
1521 		{ "Leaf", 0,
1522 			{ 8236,1746,-1314,-8251,15953,2428,-3673,5786,5771 }},
1523 		{ "Micron 2010", 110,	/* DJC */
1524 			{ 16695,-3761,-2151,155,9682,163,3433,951,4904 }},
1525 		{ "Minolta DiMAGE 5", 0,
1526 			{ 8983,-2942,-963,-6556,14476,2237,-2426,2887,8014 }},
1527 		{ "Minolta DiMAGE 7Hi", 0,
1528 			{ 11368,-3894,-1242,-6521,14358,2339,-2475,3056,7285 }},
1529 		{ "Minolta DiMAGE 7", 0,
1530 			{ 9144,-2777,-998,-6676,14556,2281,-2470,3019,7744 }},
1531 		{ "Minolta DiMAGE A1", 0,
1532 			{ 9274,-2547,-1167,-8220,16323,1943,-2273,2720,8340 }},
1533 		{ "MINOLTA DiMAGE A200", 0,
1534 			{ 8560,-2487,-986,-8112,15535,2771,-1209,1324,7743 }},
1535 		{ "Minolta DiMAGE A2", 0,
1536 			{ 9097,-2726,-1053,-8073,15506,2762,-966,981,7763 }},
1537 		{ "Minolta DiMAGE Z2", 0,	/* DJC */
1538 			{ 11280,-3564,-1370,-4655,12374,2282,-1423,2168,5396 }},
1539 		{ "MINOLTA DYNAX 5", 0,
1540 			{ 10284,-3283,-1086,-7957,15762,2316,-829,882,6644 }},
1541 		{ "MINOLTA DYNAX 7", 0,
1542 			{ 10239,-3104,-1099,-8037,15727,2451,-927,925,6871 }},
1543 		{ "NIKON D100", 0,
1544 			{ 5902,-933,-782,-8983,16719,2354,-1402,1455,6464 }},
1545 		{ "NIKON D1H", 0,
1546 			{ 7577,-2166,-926,-7454,15592,1934,-2377,2808,8606 }},
1547 		{ "NIKON D1X", 0,
1548 			{ 7702,-2245,-975,-9114,17242,1875,-2679,3055,8521 }},
1549 		{ "NIKON D1", 0,	/* multiplied by 2.218750, 1.0, 1.148438 */
1550 			{ 16772,-4726,-2141,-7611,15713,1972,-2846,3494,9521 }},
1551 		{ "NIKON D2H", 0,
1552 			{ 5710,-901,-615,-8594,16617,2024,-2975,4120,6830 }},
1553 		{ "NIKON D2X", 0,
1554 			{ 10231,-2769,-1255,-8301,15900,2552,-797,680,7148 }},
1555 		{ "NIKON D40", 0,
1556 			{ 6992,-1668,-806,-8138,15748,2543,-874,850,7897 }},
1557 		{ "NIKON D50", 0,
1558 			{ 7732,-2422,-789,-8238,15884,2498,-859,783,7330 }},
1559 		{ "NIKON D70", 0,
1560 			{ 7732,-2422,-789,-8238,15884,2498,-859,783,7330 }},
1561 		{ "NIKON D80", 0,
1562 			{ 8629,-2410,-883,-9055,16940,2171,-1490,1363,8520 }},
1563 		{ "NIKON D200", 0,
1564 			{ 8367,-2248,-763,-8758,16447,2422,-1527,1550,8053 }},
1565 		{ "NIKON E950", 0,		/* DJC */
1566 			{ -3746,10611,1665,9621,-1734,2114,-2389,7082,3064,3406,6116,-244 }},
1567 		{ "NIKON E995", 0,	/* copied from E5000 */
1568 			{ -5547,11762,2189,5814,-558,3342,-4924,9840,5949,688,9083,96 }},
1569 		{ "NIKON E2500", 0,
1570 			{ -5547,11762,2189,5814,-558,3342,-4924,9840,5949,688,9083,96 }},
1571 		{ "NIKON E4300", 0, /* copied from Minolta DiMAGE Z2 */
1572 			{ 11280,-3564,-1370,-4655,12374,2282,-1423,2168,5396 }},
1573 		{ "NIKON E4500", 0,
1574 			{ -5547,11762,2189,5814,-558,3342,-4924,9840,5949,688,9083,96 }},
1575 		{ "NIKON E5000", 0,
1576 			{ -5547,11762,2189,5814,-558,3342,-4924,9840,5949,688,9083,96 }},
1577 		{ "NIKON E5400", 0,
1578 			{ 9349,-2987,-1001,-7919,15766,2266,-2098,2680,6839 }},
1579 		{ "NIKON E5700", 0,
1580 			{ -5368,11478,2368,5537,-113,3148,-4969,10021,5782,778,9028,211 }},
1581 		{ "NIKON E8400", 0,
1582 			{ 7842,-2320,-992,-8154,15718,2599,-1098,1342,7560 }},
1583 		{ "NIKON E8700", 0,
1584 			{ 8489,-2583,-1036,-8051,15583,2643,-1307,1407,7354 }},
1585 		{ "NIKON E8800", 0,
1586 			{ 7971,-2314,-913,-8451,15762,2894,-1442,1520,7610 }},
1587 		{ "OLYMPUS C5050", 0,
1588 			{ 10508,-3124,-1273,-6079,14294,1901,-1653,2306,6237 }},
1589 		{ "OLYMPUS C5060", 0,
1590 			{ 10445,-3362,-1307,-7662,15690,2058,-1135,1176,7602 }},
1591 		{ "OLYMPUS C7070", 0,
1592 			{ 10252,-3531,-1095,-7114,14850,2436,-1451,1723,6365 }},
1593 		{ "OLYMPUS C70", 0,
1594 			{ 10793,-3791,-1146,-7498,15177,2488,-1390,1577,7321 }},
1595 		{ "OLYMPUS C80", 0,
1596 			{ 8606,-2509,-1014,-8238,15714,2703,-942,979,7760 }},
1597 		{ "OLYMPUS E-10", 0,
1598 			{ 12745,-4500,-1416,-6062,14542,1580,-1934,2256,6603 }},
1599 		{ "OLYMPUS E-1", 0,
1600 			{ 11846,-4767,-945,-7027,15878,1089,-2699,4122,8311 }},
1601 		{ "OLYMPUS E-20", 0,
1602 			{ 13173,-4732,-1499,-5807,14036,1895,-2045,2452,7142 }},
1603 		{ "OLYMPUS E-300", 0,
1604 			{ 7828,-1761,-348,-5788,14071,1830,-2853,4518,6557 }},
1605 		{ "OLYMPUS E-330", 0,
1606 			{ 8961,-2473,-1084,-7979,15990,2067,-2319,3035,8249 }},
1607 		{ "OLYMPUS E-400", 0,
1608 			{ 6169,-1483,-21,-7107,14761,2536,-2904,3580,8568 }},
1609 		{ "OLYMPUS E-500", 0,
1610 			{ 8136,-1968,-299,-5481,13742,1871,-2556,4205,6630 }},
1611 		{ "OLYMPUS SP350", 0,
1612 			{ 12078,-4836,-1069,-6671,14306,2578,-786,939,7418 }},
1613 		{ "OLYMPUS SP3", 0,
1614 			{ 11766,-4445,-1067,-6901,14421,2707,-1029,1217,7572 }},
1615 		{ "OLYMPUS SP500UZ", 0,
1616 			{ 9493,-3415,-666,-5211,12334,3260,-1548,2262,6482 }},
1617 		{ "OLYMPUS SP510UZ", 0,
1618 			{ 10593,-3607,-1010,-5881,13127,3084,-1200,1805,6721 }},
1619 		{ "PENTAX *ist DL2", 0,
1620 			{ 10504,-2438,-1189,-8603,16207,2531,-1022,863,12242 }},
1621 		{ "PENTAX *ist DL", 0,
1622 			{ 10829,-2838,-1115,-8339,15817,2696,-837,680,11939 }},
1623 		{ "PENTAX *ist DS2", 0,
1624 			{ 10504,-2438,-1189,-8603,16207,2531,-1022,863,12242 }},
1625 		{ "PENTAX *ist DS", 0,
1626 			{ 10371,-2333,-1206,-8688,16231,2602,-1230,1116,11282 }},
1627 		{ "PENTAX *ist D", 0,
1628 			{ 9651,-2059,-1189,-8881,16512,2487,-1460,1345,10687 }},
1629 		{ "PENTAX K10D", 0,
1630 			{ 9566,-2863,-803,-7170,15172,2112,-818,803,9705 }},
1631 		{ "PENTAX K1", 0,
1632 			{ 11095,-3157,-1324,-8377,15834,2720,-1108,947,11688 }},
1633 		{ "Panasonic DMC-FZ30", 0,
1634 			{ 10976,-4029,-1141,-7918,15491,2600,-1670,2071,8246 }},
1635 		{ "Panasonic DMC-FZ50", 0,	/* aka "LEICA V-LUX1" */
1636 			{ 7906,-2709,-594,-6231,13351,3220,-1922,2631,6537 }},
1637 		{ "Panasonic DMC-L1", 0,	/* aka "LEICA DIGILUX 3" */
1638 			{ 8054,-1885,-1025,-8349,16367,2040,-2805,3542,7629 }},
1639 		{ "Panasonic DMC-LC1", 0,	/* aka "LEICA DIGILUX 2" */
1640 			{ 11340,-4069,-1275,-7555,15266,2448,-2960,3426,7685 }},
1641 		{ "Panasonic DMC-LX1", 0,	/* aka "LEICA D-LUX2" */
1642 			{ 10704,-4187,-1230,-8314,15952,2501,-920,945,8927 }},
1643 		{ "Panasonic DMC-LX2", 0,	/* aka "LEICA D-LUX3" */
1644 			{ 8048,-2810,-623,-6450,13519,3272,-1700,2146,7049 }},
1645 		{ "SAMSUNG GX-1", 0,
1646 			{ 10504,-2438,-1189,-8603,16207,2531,-1022,863,12242 }},
1647 		{ "Sinar", 0,		/* DJC */
1648 			{ 16442,-2956,-2422,-2877,12128,750,-1136,6066,4559 }},
1649 		{ "SONY DSC-F828", 491,
1650 			{ 7924,-1910,-777,-8226,15459,2998,-1517,2199,6818,-7242,11401,3481 }},
1651 		{ "SONY DSC-R1", 512,
1652 			{ 8512,-2641,-694,-8042,15670,2526,-1821,2117,7414 }},
1653 		{ "SONY DSC-V3", 0,
1654 			{ 7511,-2571,-692,-7894,15088,3060,-948,1111,8128 }},
1655 		{ "SONY DSLR-A100", 0,
1656 			{ 9437,-2811,-774,-8405,16215,2290,-710,596,7181 }}
1657 	};
1658 	double cameraXYZ[4][3];
1659 
1660 	for (uint32 i = 0; i < sizeof table / sizeof *table; i++) {
1661 		if (!strncasecmp(model, table[i].prefix, strlen(table[i].prefix))) {
1662 			if (table[i].black)
1663 				fMeta.black = table[i].black;
1664 			for (uint32 j = 0; j < 12; j++) {
1665 				cameraXYZ[0][j] = table[i].trans[j] / 10000.0;
1666 			}
1667 			_CameraXYZCoefficients(cameraXYZ);
1668 			break;
1669 		}
1670 	}
1671 }
1672 
1673 
1674 void
1675 DCRaw::_BorderInterpolate(uint32 border)
1676 {
1677 	uint32 row, col, y, x, f, c, sum[8];
1678 
1679 	for (row = 0; row < fInputHeight; row++) {
1680 		for (col = 0; col < fInputWidth; col++) {
1681 			if (col == border && row >= border && row < fInputHeight - border)
1682 				col = fInputWidth - border;
1683 
1684 			memset(sum, 0, sizeof(sum));
1685 
1686 			for (y = row - 1; y != row + 2; y++) {
1687 				for (x = col - 1; x != col + 2; x++) {
1688 					if (y < fInputHeight && x < fInputWidth) {
1689 						f = _FilterCoefficient(x, y);
1690 						sum[f] += fImageData[y * fInputWidth + x][f];
1691 						sum[f + 4]++;
1692 					}
1693 				}
1694 			}
1695 
1696 			f = _FilterCoefficient(col, row);
1697 
1698 			for (c = 0; c < fColors; c++) {
1699 				if (c != f && sum[c + 4]) {
1700 					fImageData[row * fInputWidth + col][c]
1701 						= sum[c] / sum[c + 4];
1702 				}
1703 			}
1704 		}
1705 	}
1706 }
1707 
1708 
1709 /*!	Adaptive Homogeneity-Directed interpolation is based on
1710 	the work of Keigo Hirakawa, Thomas Parks, and Paul Lee.
1711 */
1712 void
1713 DCRaw::_AHDInterpolate()
1714 {
1715 	if (fProgressMonitor != NULL)
1716 		fProgressMonitor("Interpolate", 20, fProgressData);
1717 
1718 #define TS 256		/* Tile Size */
1719 
1720 	int i, j, tr, tc, fc, c, d, val, hm[2];
1721 	uint32 top, left, row, col;
1722 	ushort (*pix)[4], (*rix)[3];
1723 	static const int dir[4] = { -1, 1, -TS, TS };
1724 	unsigned ldiff[2][4], abdiff[2][4], leps, abeps;
1725 	float flab[3];
1726 	ushort (*rgb)[TS][TS][3];
1727 	short (*lab)[TS][TS][3];
1728 	char (*homo)[TS][TS], *buffer;
1729 
1730 	_BorderInterpolate(3);
1731 	buffer = (char *)malloc(26 * TS * TS);		/* 1664 kB */
1732 	if (buffer == NULL)
1733 		throw (status_t)B_NO_MEMORY;
1734 
1735 	rgb = (ushort(*)[TS][TS][3])buffer;
1736 	lab = (short (*)[TS][TS][3])(buffer + 12 * TS * TS);
1737 	homo = (char (*)[TS][TS])(buffer + 24 * TS * TS);
1738 	float percentage = 20;
1739 	float percentageStep = 70.0f / (fInputHeight / (TS - 6));
1740 
1741 	for (top = 0; top < fInputHeight; top += TS - 6) {
1742 		if (fProgressMonitor) {
1743 			fProgressMonitor("Interpolate", percentage, fProgressData);
1744 			percentage += percentageStep;
1745 		}
1746 
1747 		for (left = 0; left < fInputWidth; left += TS - 6) {
1748 			memset(rgb, 0, 12 * TS * TS);
1749 
1750 			/* Interpolate green horizontally and vertically: */
1751 			for (row = top < 2 ? 2 : top; row < top + TS
1752 					&& row < fInputHeight - 2; row++) {
1753 				col = left + (FC(row, left) == 1);
1754 				if (col < 2)
1755 					col += 2;
1756 				for (fc = FC(row, col); col < left + TS
1757 						&& col < fInputWidth - 2; col += 2) {
1758 					pix = fImageData + row * fInputWidth + col;
1759 					val = ((pix[-1][1] + pix[0][fc] + pix[1][1]) * 2
1760 						- pix[-2][fc] - pix[2][fc]) >> 2;
1761 					rgb[0][row - top][col - left][1]
1762 						= ULIM(val, pix[-1][1], pix[1][1]);
1763 					val = ((pix[-fInputWidth][1] + pix[0][fc]
1764 							+ pix[fInputWidth][1]) * 2
1765 						- pix[-2 * fInputWidth][fc] - pix[2 * fInputWidth][fc])
1766 							>> 2;
1767 					rgb[1][row - top][col - left][1] = ULIM(val,
1768 						pix[-fInputWidth][1], pix[fInputWidth][1]);
1769 				}
1770 			}
1771 
1772 			/* Interpolate red and blue, and convert to CIELab: */
1773 			for (d = 0; d < 2; d++) {
1774 				for (row = top + 1; row < top + TS - 1
1775 						&& row < fInputHeight - 1; row++) {
1776 					for (col = left + 1; col < left + TS - 1
1777 							&& col < fInputWidth - 1; col++) {
1778 						pix = fImageData + row * fInputWidth + col;
1779 						rix = &rgb[d][row - top][col - left];
1780 						if ((c = 2 - FC(row, col)) == 1) {
1781 							c = FC(row + 1,col);
1782 							val = pix[0][1] + ((pix[-1][2-c] + pix[1][2 - c]
1783 								- rix[-1][1] - rix[1][1] ) >> 1);
1784 							rix[0][2-c] = CLIP(val);
1785 							val = pix[0][1] + ((pix[-fInputWidth][c]
1786 								+ pix[fInputWidth][c]
1787 								- rix[-TS][1] - rix[TS][1] ) >> 1);
1788 						} else {
1789 							val = rix[0][1] + ((pix[-fInputWidth - 1][c]
1790 								+ pix[-fInputWidth + 1][c]
1791 								+ pix[fInputWidth - 1][c]
1792 								+ pix[fInputWidth + 1][c]
1793 								- rix[-TS - 1][1] - rix[-TS + 1][1]
1794 								- rix[TS - 1][1] - rix[TS + 1][1] + 1) >> 2);
1795 						}
1796 						rix[0][c] = CLIP(val);
1797 						c = FC(row, col);
1798 						rix[0][c] = pix[0][c];
1799 						_CameraToCIELab(rix[0], flab);
1800 						for (c = 0; c < 3; c++) {
1801 							lab[d][row - top][col - left][c]
1802 								= int16(64 * flab[c]);
1803 						}
1804 					}
1805 				}
1806 			}
1807 
1808 			/* Build homogeneity maps from the CIELab images: */
1809 			memset(homo, 0, 2 * TS * TS);
1810 			for (row = top + 2; row < top+TS-2 && row < fInputHeight; row++) {
1811 				tr = row - top;
1812 				for (col = left + 2; col < left + TS - 2
1813 						&& col < fInputWidth; col++) {
1814 					tc = col - left;
1815 					for (d = 0; d < 2; d++) {
1816 						for (i = 0; i < 4; i++) {
1817 							ldiff[d][i] = ABS(lab[d][tr][tc][0]
1818 									- lab[d][tr][tc+dir[i]][0]);
1819 						}
1820 					}
1821 
1822 					leps = MIN(MAX(ldiff[0][0],ldiff[0][1]),
1823 						MAX(ldiff[1][2],ldiff[1][3]));
1824 
1825 					for (d = 0; d < 2; d++) {
1826 						for (i = 0; i < 4; i++) {
1827 							if (i >> 1 == d || ldiff[d][i] <= leps) {
1828 								abdiff[d][i] = square(lab[d][tr][tc][1]
1829 										- lab[d][tr][tc+dir[i]][1])
1830 									+ square(lab[d][tr][tc][2]
1831 										- lab[d][tr][tc+dir[i]][2]);
1832 							}
1833 						}
1834 					}
1835 
1836 					abeps = MIN(MAX(abdiff[0][0],abdiff[0][1]),
1837 						MAX(abdiff[1][2],abdiff[1][3]));
1838 
1839 					for (d=0; d < 2; d++) {
1840 						for (i=0; i < 4; i++) {
1841 							if (ldiff[d][i] <= leps && abdiff[d][i] <= abeps)
1842 								homo[d][tr][tc]++;
1843 						}
1844 					}
1845 				}
1846 			}
1847 
1848 			/* Combine the most homogenous pixels for the final result: */
1849 			for (row = top + 3; row < top + TS - 3 && row < fInputHeight - 3;
1850 					row++) {
1851 				tr = row - top;
1852 				for (col = left + 3; col < left + TS - 3
1853 						&& col < fInputWidth - 3; col++) {
1854 					tc = col - left;
1855 					for (d = 0; d < 2; d++) {
1856 						for (hm[d] = 0, i = tr - 1; i <= tr + 1; i++) {
1857 							for (j = tc - 1; j <= tc + 1; j++) {
1858 								hm[d] += homo[d][i][j];
1859 							}
1860 						}
1861 					}
1862 					if (hm[0] != hm[1]) {
1863 						for (c = 0; c < 3; c++) {
1864 							fImageData[row * fInputWidth + col][c]
1865 								= rgb[hm[1] > hm[0]][tr][tc][c];
1866 						}
1867 					} else {
1868 						for (c = 0; c < 3; c++) {
1869 							fImageData[row * fInputWidth + col][c]
1870 								= (rgb[0][tr][tc][c] + rgb[1][tr][tc][c]) >> 1;
1871 						}
1872 					}
1873 				}
1874 			}
1875 		}
1876 	}
1877 	free(buffer);
1878 #undef TS
1879 }
1880 
1881 
1882 void
1883 DCRaw::_PseudoInverse(double (*in)[3], double (*out)[3], uint32 size)
1884 {
1885 	double work[3][6], num;
1886 	uint32 i, j, k;
1887 
1888 	for (i = 0; i < 3; i++) {
1889 		for (j = 0; j < 6; j++) {
1890 			work[i][j] = j == i + 3;
1891 		}
1892 		for (j = 0; j < 3; j++) {
1893 			for (k = 0; k < size; k++) {
1894 				work[i][j] += in[k][i] * in[k][j];
1895 			}
1896 		}
1897 	}
1898 
1899 	for (i = 0; i < 3; i++) {
1900 		num = work[i][i];
1901 		for (j = 0; j < 6; j++) {
1902 			work[i][j] /= num;
1903 		}
1904 		for (k = 0; k < 3; k++) {
1905 			if (k == i)
1906 				continue;
1907 
1908 			num = work[k][i];
1909 
1910 			for (j = 0; j < 6; j++) {
1911 				work[k][j] -= work[i][j] * num;
1912 			}
1913 		}
1914 	}
1915 
1916 	for (i = 0; i < size; i++) {
1917 		for (j = 0; j < 3; j++) {
1918 			for (out[i][j] = k =0; k < 3; k++) {
1919 				out[i][j] += work[j][k+3] * in[i][k];
1920 			}
1921 		}
1922 	}
1923 }
1924 
1925 
1926 void
1927 DCRaw::_ConvertToRGB()
1928 {
1929 	if (fProgressMonitor != NULL)
1930 		fProgressMonitor("Convert to RGB", 90, fProgressData);
1931 
1932 	uint32 row, col, c, i, j, k;
1933 	float out[3], out_cam[3][4];
1934 	double num, inverse[3][3];
1935 	static const double xyzd50_srgb[3][3] = {
1936 		{ 0.436083, 0.385083, 0.143055 },
1937 		{ 0.222507, 0.716888, 0.060608 },
1938 		{ 0.013930, 0.097097, 0.714022 }};
1939 	static const double rgb_rgb[3][3] = {
1940 		{ 1,0,0 }, { 0,1,0 }, { 0,0,1 }};
1941 	static const double adobe_rgb[3][3] = {
1942 		{ 0.715146, 0.284856, 0.000000 },
1943 		{ 0.000000, 1.000000, 0.000000 },
1944 		{ 0.000000, 0.041166, 0.958839 }};
1945 	static const double wide_rgb[3][3] = {
1946 		{ 0.593087, 0.404710, 0.002206 },
1947 		{ 0.095413, 0.843149, 0.061439 },
1948 		{ 0.011621, 0.069091, 0.919288 }};
1949 	static const double prophoto_rgb[3][3] = {
1950 		{ 0.529317, 0.330092, 0.140588 },
1951 		{ 0.098368, 0.873465, 0.028169 },
1952 		{ 0.016879, 0.117663, 0.865457 }};
1953 	static const double (*out_rgb[])[3]
1954 		= { rgb_rgb, adobe_rgb, wide_rgb, prophoto_rgb, xyz_rgb };
1955 	static const char *name[] = { "sRGB", "Adobe RGB (1998)", "WideGamut D65",
1956 		"ProPhoto D65", "XYZ" };
1957 	static const unsigned phead[] = { 1024, 0, 0x2100000, 0x6d6e7472,
1958 		0x52474220, 0x58595a20, 0, 0, 0, 0x61637370, 0, 0, 0x6e6f6e65,
1959 		0, 0, 0, 0, 0xf6d6, 0x10000, 0xd32d };
1960 	unsigned pbody[] = { 10,
1961 		0x63707274, 0, 36,	/* cprt */
1962 		0x64657363, 0, 40,	/* desc */
1963 		0x77747074, 0, 20,	/* wtpt */
1964 		0x626b7074, 0, 20,	/* bkpt */
1965 		0x72545243, 0, 14,	/* rTRC */
1966 		0x67545243, 0, 14,	/* gTRC */
1967 		0x62545243, 0, 14,	/* bTRC */
1968 		0x7258595a, 0, 20,	/* rXYZ */
1969 		0x6758595a, 0, 20,	/* gXYZ */
1970 		0x6258595a, 0, 20 };	/* bXYZ */
1971 	static const unsigned pwhite[] = { 0xf351, 0x10000, 0x116cc };
1972 	unsigned pcurve[] = { 0x63757276, 0, 1, 0x1000000 };
1973 
1974 	memcpy(out_cam, fMeta.rgb_camera, sizeof(out_cam));
1975 	fRawColor |= fColors == 1 || fDocumentMode
1976 		|| fOutputColor < 1 || fOutputColor > 5;
1977 	if (!fRawColor) {
1978 		fOutputProfile = (uint32 *)calloc(phead[0], 1);
1979 		if (fOutputProfile == NULL)
1980 			throw (status_t)B_NO_MEMORY;
1981 
1982 		memcpy(fOutputProfile, phead, sizeof(phead));
1983 		if (fOutputColor == 5)
1984 			fOutputProfile[4] = fOutputProfile[5];
1985 
1986 		fOutputProfile[0] = 132 + 12 * pbody[0];
1987 		for (i = 0; i < pbody[0]; i++) {
1988 			fOutputProfile[fOutputProfile[0] / 4]
1989 				= i ? (i > 1 ? 0x58595a20 : 0x64657363) : 0x74657874;
1990 			pbody[i*3+2] = fOutputProfile[0];
1991 			fOutputProfile[0] += (pbody[i*3+3] + 3) & -4;
1992 		}
1993 
1994 		memcpy(fOutputProfile + 32, pbody, sizeof(pbody));
1995 		fOutputProfile[pbody[5] / 4 + 2] = strlen(name[fOutputColor - 1]) + 1;
1996 		memcpy((char *)fOutputProfile + pbody[8] + 8, pwhite, sizeof(pwhite));
1997 		if (fOutputBitsPerSample == 8) {
1998 #ifdef SRGB_GAMMA
1999 			pcurve[3] = 0x2330000;
2000 #else
2001 			pcurve[3] = 0x1f00000;
2002 #endif
2003 		}
2004 
2005 		for (i = 4; i < 7; i++) {
2006 			memcpy((char *)fOutputProfile + pbody[i * 3 + 2], pcurve,
2007 				sizeof(pcurve));
2008 		}
2009 
2010 		_PseudoInverse((double (*)[3])out_rgb[fOutputColor - 1], inverse, 3);
2011 
2012 		for (i = 0; i < 3; i++) {
2013 			for (j = 0; j < 3; j++) {
2014 				for (num = k=0; k < 3; k++) {
2015 					num += xyzd50_srgb[i][k] * inverse[j][k];
2016 				}
2017 				fOutputProfile[pbody[j * 3 + 23] / 4 + i + 2]
2018 					= uint32(num * 0x10000 + 0.5);
2019 			}
2020 		}
2021 		for (i = 0; i < phead[0]/4; i++) {
2022 			fOutputProfile[i] = htonl(fOutputProfile[i]);
2023 		}
2024 		strcpy((char *)fOutputProfile + pbody[2] + 8,
2025 			"auto-generated by dcraw");
2026 		strcpy((char *)fOutputProfile + pbody[5] + 12, name[fOutputColor - 1]);
2027 
2028 		for (i = 0; i < 3; i++) {
2029 			for (j = 0; j < fColors; j++) {
2030 				for (out_cam[i][j] = k = 0; k < 3; k++) {
2031 					out_cam[i][j] += out_rgb[fOutputColor-1][i][k]
2032 						* fMeta.rgb_camera[k][j];
2033 				}
2034 			}
2035 		}
2036 	}
2037 
2038 	if (1/*verbose*/) {
2039 		if (fRawColor)
2040 			fprintf(stderr, "Building histograms...\n");
2041 		else {
2042 			fprintf(stderr, "Converting to %s colorspace...\n",
2043 				name[fOutputColor - 1]);
2044 		}
2045 	}
2046 
2047 	ushort* img = fImageData[0];
2048 	memset(fHistogram, 0, sizeof(int32) * 0x2000 * 4);
2049 
2050 	for (row = 0; row < fInputHeight; row++) {
2051 		for (col = 0; col < fInputWidth; col++, img += 4) {
2052 			if (!fRawColor) {
2053 				out[0] = out[1] = out[2] = 0;
2054 				for (c = 0; c < fColors; c++) {
2055 					out[0] += out_cam[0][c] * img[c];
2056 					out[1] += out_cam[1][c] * img[c];
2057 					out[2] += out_cam[2][c] * img[c];
2058 				}
2059 				for (c = 0; c < 3; c++) {
2060 					img[c] = CLIP((int)out[c]);
2061 				}
2062 			} else if (fDocumentMode)
2063 				img[0] = img[FC(row, col)];
2064 
2065 			for (c = 0; c < fColors; c++) {
2066 				fHistogram[img[c] >> 3][c]++;
2067 			}
2068 		}
2069 	}
2070 
2071 	if (fColors == 4 && fOutputColor)
2072 		fColors = 3;
2073 	if (fDocumentMode && fFilters)
2074 		fColors = 1;
2075 }
2076 
2077 
2078 void
2079 DCRaw::_GammaLookUpTable(uchar* lut)
2080 {
2081 	int32 percent, val, total, i;
2082 	float white = 0, r;
2083 
2084 	percent = int32(fInputWidth * fInputHeight * 0.01);
2085 		// 99th percentile white point
2086 
2087 	//  if (fuji_width) perc /= 2;
2088 	if (fHighlight)
2089 		percent = 0;
2090 
2091 	for (uint32 c = 0; c < fColors; c++) {
2092 		for (val = 0x2000, total = 0; --val > 32;) {
2093 			if ((total += fHistogram[val][c]) > percent)
2094 				break;
2095 		}
2096 		if (white < val)
2097 			white = val;
2098 	}
2099 
2100 	white *= 8 / fBrightness;
2101 
2102 	for (i = 0; i < 0x10000; i++) {
2103 		r = i / white;
2104 		val = int32(256 * (!fUseGamma ? r :
2105 #ifdef SRGB_GAMMA
2106 			r <= 0.00304 ? r*12.92 : pow(r,2.5/6)*1.055-0.055));
2107 #else
2108 			r <= 0.018 ? r*4.5 : pow(r,0.45)*1.099-0.099));
2109 #endif
2110 		if (val > 255)
2111 			val = 255;
2112 		lut[i] = val;
2113 	}
2114 }
2115 
2116 
2117 //	#pragma mark - Lossless JPEG
2118 
2119 
2120 void
2121 DCRaw::_InitDecoder()
2122 {
2123 	memset(fDecodeBuffer, 0, sizeof(decode) * kDecodeBufferCount);
2124 	fFreeDecode = fDecodeBuffer;
2125 }
2126 
2127 
2128 /*!	Construct a decode tree according the specification in *source.
2129 	The first 16 bytes specify how many codes should be 1-bit, 2-bit
2130 	3-bit, etc.  Bytes after that are the leaf values.
2131 
2132 	For example, if the source is
2133 
2134 	{ 0,1,4,2,3,1,2,0,0,0,0,0,0,0,0,0,
2135 	  0x04,0x03,0x05,0x06,0x02,0x07,0x01,0x08,0x09,0x00,0x0a,0x0b,0xff  },
2136 
2137 	then the code is
2138 
2139 	00		0x04
2140 	010		0x03
2141 	011		0x05
2142 	100		0x06
2143 	101		0x02
2144 	1100		0x07
2145 	1101		0x01
2146 	11100		0x08
2147 	11101		0x09
2148 	11110		0x00
2149 	111110		0x0a
2150 	1111110		0x0b
2151 	1111111		0xff
2152 */
2153 uchar *
2154 DCRaw::_MakeDecoder(const uchar* source, int level)
2155 {
2156 	if (level == 0)
2157 		fDecodeLeaf = 0;
2158 
2159 	if ((uint8*)fFreeDecode > (uint8*)fDecodeBuffer
2160 			+ sizeof(decode) * kDecodeBufferCount) {
2161 		fprintf(stderr, "decoder table overflow\n");
2162 		throw (status_t)B_ERROR;
2163 	}
2164 
2165 	struct decode* current = fFreeDecode++;
2166 
2167 	int i, next;
2168 	for (i = next = 0; i <= fDecodeLeaf && next < 16; ) {
2169 		i += source[next++];
2170 	}
2171 
2172 	if (i > fDecodeLeaf) {
2173 		if (level < next) {
2174 			current->branch[0] = fFreeDecode;
2175 			_MakeDecoder(source, level + 1);
2176 			current->branch[1] = fFreeDecode;
2177 			_MakeDecoder(source, level + 1);
2178 		} else
2179 			current->leaf = source[16 + fDecodeLeaf++];
2180 	}
2181 
2182 	return (uchar*)source + 16 + fDecodeLeaf;
2183 }
2184 
2185 
2186 /*!	Not a full implementation of Lossless JPEG, just
2187 	enough to decode Canon, Kodak and Adobe DNG images.
2188 */
2189 void
2190 DCRaw::_InitDecodeBits()
2191 {
2192 	fDecodeBits = fDecodeBitsRead = 0;
2193 	fDecodeBitsReset = false;
2194 }
2195 
2196 
2197 /*!	_GetDecodeBits(n) where 0 <= n <= 25 returns an n-bit integer
2198 */
2199 uint32
2200 DCRaw::_GetDecodeBits(uint32 numBits)
2201 {
2202 	if (numBits == 0 || fDecodeBitsReset)
2203 		return 0;
2204 
2205 	while (fDecodeBitsRead < numBits) {
2206 		uint8 c = fRead.Next<uint8>();
2207 		if ((fDecodeBitsReset = fDecodeBitsZeroAfterMax
2208 				&& c == 0xff && fRead.Next<uint8>()))
2209 			return 0;
2210 		fDecodeBits = (fDecodeBits << 8) + c;
2211 		fDecodeBitsRead += 8;
2212 	}
2213 
2214 	fDecodeBitsRead -= numBits;
2215 
2216 	return fDecodeBits << (32 - numBits - fDecodeBitsRead) >> (32 - numBits);
2217 }
2218 
2219 
2220 status_t
2221 DCRaw::_LosslessJPEGInit(struct jhead* jh, bool infoOnly)
2222 {
2223 	int i, tag, len;
2224 
2225 	_InitDecoder();
2226 
2227 	for (i = 0; i < 4; i++) {
2228 		jh->huff[i] = fFreeDecode;
2229 	}
2230 
2231 	jh->restart = INT_MAX;
2232 
2233 	uchar data[0x10000], *dp;
2234 	fRead(data, 2);
2235 	if (data[1] != 0xd8)
2236 		return B_ERROR;
2237 
2238 	do {
2239 		fRead(data, 4);
2240 		tag = data[0] << 8 | data[1];
2241 		len = (data[2] << 8 | data[3]) - 2;
2242 		if (tag <= 0xff00)
2243 			return B_ERROR;
2244 
2245 		fRead(data, len);
2246 		switch (tag) {
2247 			case 0xffc0:
2248 			case 0xffc3:
2249 				jh->bits = data[0];
2250 				jh->high = data[1] << 8 | data[2];
2251 				jh->wide = data[3] << 8 | data[4];
2252 				jh->clrs = data[5];
2253 				break;
2254 			case 0xffc4:
2255 				if (infoOnly)
2256 					break;
2257 
2258 				for (dp = data; dp < data+len && *dp < 4; ) {
2259 					jh->huff[*dp] = fFreeDecode;
2260 					dp = _MakeDecoder(++dp, 0);
2261 				}
2262 				break;
2263 			case 0xffdd:
2264 				jh->restart = data[0] << 8 | data[1];
2265 				break;
2266 		}
2267 	} while (tag != 0xffda);
2268 
2269 	if (infoOnly)
2270 		return B_OK;
2271 
2272 	jh->row = (ushort *)calloc(jh->wide*jh->clrs, 2);
2273 	if (jh->row == NULL)
2274 		throw (status_t)B_NO_MEMORY;
2275 
2276 	fDecodeBitsZeroAfterMax = true;
2277 	return B_OK;
2278 }
2279 
2280 
2281 int
2282 DCRaw::_LosslessJPEGDiff(struct decode *dindex)
2283 {
2284 	while (dindex->branch[0]) {
2285 		dindex = dindex->branch[_GetDecodeBits(1)];
2286 	}
2287 
2288 	int length = dindex->leaf;
2289 	if (length == 16 && (!fDNGVersion || fDNGVersion >= 0x1010000))
2290 		return -32768;
2291 
2292 	int diff = _GetDecodeBits(length);
2293 	if ((diff & (1 << (length - 1))) == 0)
2294 		diff -= (1 << length) - 1;
2295 
2296 	return diff;
2297 }
2298 
2299 
2300 void
2301 DCRaw::_LosslessJPEGRow(struct jhead *jh, int jrow)
2302 {
2303 	if (jrow * jh->wide % jh->restart == 0) {
2304 		for (uint32 i = 0; i < 4; i++) {
2305 			jh->vpred[i] = 1 << (jh->bits - 1);
2306 		}
2307 		if (jrow) {
2308 			uint16 mark = 0;
2309 			int c;
2310 			do {
2311 				mark = (mark << 8) + (c = fRead.Next<uint8>());
2312 			} while (c != EOF && mark >> 4 != 0xffd);
2313 		}
2314 		_InitDecodeBits();
2315 	}
2316 
2317 	uint16* outp = jh->row;
2318 
2319 	for (int32 col = 0; col < jh->wide; col++) {
2320 		for (int32 c = 0; c < jh->clrs; c++) {
2321 			int32 diff = _LosslessJPEGDiff(jh->huff[c]);
2322 			*outp = col ? outp[-jh->clrs]+diff : (jh->vpred[c] += diff);
2323 			outp++;
2324 		}
2325 	}
2326 }
2327 
2328 
2329 //	#pragma mark - RAW loaders
2330 
2331 
2332 void
2333 DCRaw::_LoadRAWUnpacked(const image_data_info& image)
2334 {
2335 	uint32 rawWidth = _Raw().width;
2336 
2337 	uint16* pixel = (uint16*)calloc(rawWidth, sizeof(uint16));
2338 	if (pixel == NULL)
2339 		return;
2340 
2341 	fRead.Seek((fTopMargin * rawWidth + fLeftMargin) * sizeof(uint16),
2342 		SEEK_CUR);
2343 
2344 	for (uint32 row = 0; row < fInputHeight; row++) {
2345 		fRead.NextShorts(pixel, rawWidth);
2346 		for (uint32 column = 0; column < fInputWidth; column++) {
2347 			_Bayer(column, row) = pixel[column];
2348 		}
2349 	}
2350 
2351 	free(pixel);
2352 }
2353 
2354 
2355 /*!	This is, for example, used in PENTAX RAW images
2356 */
2357 void
2358 DCRaw::_LoadRAWPacked12(const image_data_info& image)
2359 {
2360 	uint32 rawWidth = _Raw().width;
2361 
2362 	_InitDecodeBits();
2363 
2364 	for (uint32 row = 0; row < fInputHeight; row++) {
2365 		for (uint32 column = 0; column < fInputWidth; column++) {
2366 			//uint16 bits = _GetDecodeBits(12);
2367 			_Bayer(column, row) = _GetDecodeBits(12);
2368 			//fImageData[((row) >> fShrink)*fOutputWidth + ((column) >> fShrink)][FC(row,column)] = bits;
2369 		}
2370 		for (uint32 column = fInputWidth * 3 / 2; column < rawWidth; column++) {
2371 			_GetDecodeBits(8);
2372 		}
2373 	}
2374 }
2375 
2376 
2377 void
2378 DCRaw::_MakeCanonDecoder(uint32 table)
2379 {
2380 	static const uchar kFirstTree[3][29] = {
2381 		{ 0,1,4,2,3,1,2,0,0,0,0,0,0,0,0,0,
2382 			0x04,0x03,0x05,0x06,0x02,0x07,0x01,0x08,0x09,0x00,0x0a,0x0b,0xff },
2383 		{ 0,2,2,3,1,1,1,1,2,0,0,0,0,0,0,0,
2384 			0x03,0x02,0x04,0x01,0x05,0x00,0x06,0x07,0x09,0x08,0x0a,0x0b,0xff },
2385 		{ 0,0,6,3,1,1,2,0,0,0,0,0,0,0,0,0,
2386 			0x06,0x05,0x07,0x04,0x08,0x03,0x09,0x02,0x00,0x0a,0x01,0x0b,0xff },
2387 	};
2388 	static const uchar kSecondTree[3][180] = {
2389 		{ 0,2,2,2,1,4,2,1,2,5,1,1,0,0,0,139,
2390 			0x03,0x04,0x02,0x05,0x01,0x06,0x07,0x08,
2391 			0x12,0x13,0x11,0x14,0x09,0x15,0x22,0x00,0x21,0x16,0x0a,0xf0,
2392 			0x23,0x17,0x24,0x31,0x32,0x18,0x19,0x33,0x25,0x41,0x34,0x42,
2393 			0x35,0x51,0x36,0x37,0x38,0x29,0x79,0x26,0x1a,0x39,0x56,0x57,
2394 			0x28,0x27,0x52,0x55,0x58,0x43,0x76,0x59,0x77,0x54,0x61,0xf9,
2395 			0x71,0x78,0x75,0x96,0x97,0x49,0xb7,0x53,0xd7,0x74,0xb6,0x98,
2396 			0x47,0x48,0x95,0x69,0x99,0x91,0xfa,0xb8,0x68,0xb5,0xb9,0xd6,
2397 			0xf7,0xd8,0x67,0x46,0x45,0x94,0x89,0xf8,0x81,0xd5,0xf6,0xb4,
2398 			0x88,0xb1,0x2a,0x44,0x72,0xd9,0x87,0x66,0xd4,0xf5,0x3a,0xa7,
2399 			0x73,0xa9,0xa8,0x86,0x62,0xc7,0x65,0xc8,0xc9,0xa1,0xf4,0xd1,
2400 			0xe9,0x5a,0x92,0x85,0xa6,0xe7,0x93,0xe8,0xc1,0xc6,0x7a,0x64,
2401 			0xe1,0x4a,0x6a,0xe6,0xb3,0xf1,0xd3,0xa5,0x8a,0xb2,0x9a,0xba,
2402 			0x84,0xa4,0x63,0xe5,0xc5,0xf3,0xd2,0xc4,0x82,0xaa,0xda,0xe4,
2403 			0xf2,0xca,0x83,0xa3,0xa2,0xc3,0xea,0xc2,0xe2,0xe3,0xff,0xff },
2404 		{ 0,2,2,1,4,1,4,1,3,3,1,0,0,0,0,140,
2405 			0x02,0x03,0x01,0x04,0x05,0x12,0x11,0x06,
2406 			0x13,0x07,0x08,0x14,0x22,0x09,0x21,0x00,0x23,0x15,0x31,0x32,
2407 			0x0a,0x16,0xf0,0x24,0x33,0x41,0x42,0x19,0x17,0x25,0x18,0x51,
2408 			0x34,0x43,0x52,0x29,0x35,0x61,0x39,0x71,0x62,0x36,0x53,0x26,
2409 			0x38,0x1a,0x37,0x81,0x27,0x91,0x79,0x55,0x45,0x28,0x72,0x59,
2410 			0xa1,0xb1,0x44,0x69,0x54,0x58,0xd1,0xfa,0x57,0xe1,0xf1,0xb9,
2411 			0x49,0x47,0x63,0x6a,0xf9,0x56,0x46,0xa8,0x2a,0x4a,0x78,0x99,
2412 			0x3a,0x75,0x74,0x86,0x65,0xc1,0x76,0xb6,0x96,0xd6,0x89,0x85,
2413 			0xc9,0xf5,0x95,0xb4,0xc7,0xf7,0x8a,0x97,0xb8,0x73,0xb7,0xd8,
2414 			0xd9,0x87,0xa7,0x7a,0x48,0x82,0x84,0xea,0xf4,0xa6,0xc5,0x5a,
2415 			0x94,0xa4,0xc6,0x92,0xc3,0x68,0xb5,0xc8,0xe4,0xe5,0xe6,0xe9,
2416 			0xa2,0xa3,0xe3,0xc2,0x66,0x67,0x93,0xaa,0xd4,0xd5,0xe7,0xf8,
2417 			0x88,0x9a,0xd7,0x77,0xc4,0x64,0xe2,0x98,0xa5,0xca,0xda,0xe8,
2418 			0xf3,0xf6,0xa9,0xb2,0xb3,0xf2,0xd2,0x83,0xba,0xd3,0xff,0xff },
2419 		{ 0,0,6,2,1,3,3,2,5,1,2,2,8,10,0,117,
2420 			0x04,0x05,0x03,0x06,0x02,0x07,0x01,0x08,
2421 			0x09,0x12,0x13,0x14,0x11,0x15,0x0a,0x16,0x17,0xf0,0x00,0x22,
2422 			0x21,0x18,0x23,0x19,0x24,0x32,0x31,0x25,0x33,0x38,0x37,0x34,
2423 			0x35,0x36,0x39,0x79,0x57,0x58,0x59,0x28,0x56,0x78,0x27,0x41,
2424 			0x29,0x77,0x26,0x42,0x76,0x99,0x1a,0x55,0x98,0x97,0xf9,0x48,
2425 			0x54,0x96,0x89,0x47,0xb7,0x49,0xfa,0x75,0x68,0xb6,0x67,0x69,
2426 			0xb9,0xb8,0xd8,0x52,0xd7,0x88,0xb5,0x74,0x51,0x46,0xd9,0xf8,
2427 			0x3a,0xd6,0x87,0x45,0x7a,0x95,0xd5,0xf6,0x86,0xb4,0xa9,0x94,
2428 			0x53,0x2a,0xa8,0x43,0xf5,0xf7,0xd4,0x66,0xa7,0x5a,0x44,0x8a,
2429 			0xc9,0xe8,0xc8,0xe7,0x9a,0x6a,0x73,0x4a,0x61,0xc7,0xf4,0xc6,
2430 			0x65,0xe9,0x72,0xe6,0x71,0x91,0x93,0xa6,0xda,0x92,0x85,0x62,
2431 			0xf3,0xc5,0xb2,0xa4,0x84,0xba,0x64,0xa5,0xb3,0xd2,0x81,0xe5,
2432 			0xd3,0xaa,0xc4,0xca,0xf2,0xb1,0xe4,0xd1,0x83,0x63,0xea,0xc3,
2433 			0xe2,0x82,0xf1,0xa3,0xc2,0xa1,0xc1,0xe3,0xa2,0xe1,0xff,0xff }
2434 	};
2435 
2436 	if (table > 2)
2437 		table = 2;
2438 
2439 	_InitDecoder();
2440 
2441 	_MakeDecoder(kFirstTree[table], 0);
2442 	fSecondDecode = fFreeDecode;
2443 	_MakeDecoder(kSecondTree[table], 0);
2444 }
2445 
2446 
2447 /*!	Return 0 if the image starts with compressed data,
2448 	1 if it starts with uncompressed low-order bits.
2449 
2450 	In Canon compressed data, 0xff is always followed by 0x00.
2451 */
2452 bool
2453 DCRaw::_CanonHasLowBits()
2454 {
2455 	bool hasLowBits = true;
2456 	uchar test[0x4000 - 540];
2457 
2458 	fRead.Seek(540, SEEK_SET);
2459 	fRead(test, sizeof(test));
2460 
2461 	for (uint32 i = 0; i < sizeof(test) - 1; i++)
2462 		if (test[i] == 0xff) {
2463 			if (test[i + 1])
2464 				return 1;
2465 			hasLowBits = 0;
2466     }
2467 
2468 	return hasLowBits;
2469 }
2470 
2471 
2472 void
2473 DCRaw::_LoadRAWCanonCompressed(const image_data_info& image)
2474 {
2475 	uint32 rawWidth = _Raw().width;
2476 	int carry = 0, pnum = 0, base[2];
2477 
2478 	_MakeCanonDecoder(image.compression);
2479 
2480 	uint16* pixel = (uint16 *)calloc(rawWidth * 8, sizeof(*pixel));
2481 	if (pixel == NULL)
2482 		throw (status_t)B_NO_MEMORY;
2483 
2484 	bool hasLowBits = _CanonHasLowBits();
2485 	if (!hasLowBits)
2486 		fMeta.maximum = 0x3ff;
2487 
2488 	fRead.Seek(540 + (hasLowBits ? _Raw().height * rawWidth / 4 : 0),
2489 		SEEK_SET);
2490 
2491 	fDecodeBitsZeroAfterMax = true;
2492 	_InitDecodeBits();
2493 
2494 	for (uint32 row = 0; row < _Raw().height; row += 8) {
2495 		for (uint32 block = 0; block < rawWidth >> 3; block++) {
2496 			int diffbuf[64];
2497 			memset(diffbuf, 0, sizeof diffbuf);
2498 			struct decode* decode = fDecodeBuffer;
2499 
2500 			for (uint32 i = 0; i < 64; i++) {
2501 				struct decode* dindex = decode;
2502 				while (dindex->branch[0]) {
2503 					dindex = dindex->branch[_GetDecodeBits(1)];
2504 				}
2505 				int leaf = dindex->leaf;
2506 				decode = fSecondDecode;
2507 				if (leaf == 0 && i)
2508 					break;
2509 				if (leaf == 0xff)
2510 					continue;
2511 				i += leaf >> 4;
2512 
2513 				int len = leaf & 15;
2514 				if (len == 0)
2515 					continue;
2516 				int diff = _GetDecodeBits(len);
2517 				if ((diff & (1 << (len-1))) == 0)
2518 					diff -= (1 << len) - 1;
2519 				if (i < 64)
2520 					diffbuf[i] = diff;
2521 			}
2522 
2523 			diffbuf[0] += carry;
2524 			carry = diffbuf[0];
2525 
2526 			for (uint32 i = 0; i < 64; i++) {
2527 				if (pnum++ % _Raw().width == 0)
2528 					base[0] = base[1] = 512;
2529 				pixel[(block << 6) + i] = (base[i & 1] += diffbuf[i]);
2530 			}
2531 		}
2532 
2533 		if (hasLowBits) {
2534 			off_t savedOffset = fRead.Position();
2535 			fRead.Seek(26 + row * _Raw().width / 4, SEEK_SET);
2536 
2537 			uint16* pixelRow = pixel;
2538 			for (uint32 i = 0; i < rawWidth * 2; i++) {
2539 				uint8 c = fRead.Next<uint8>();
2540 
2541 				for (uint32 r = 0; r < 8; r += 2, pixelRow++) {
2542 					uint32 val = (*pixelRow << 2) + ((c >> r) & 3);
2543 					if (rawWidth == 2672 && val < 512)
2544 						val += 2;
2545 					*pixelRow = val;
2546 				}
2547 			}
2548 
2549 			fRead.Seek(savedOffset, SEEK_SET);
2550 		}
2551 
2552 		for (uint32 r = 0; r < 8; r++) {
2553 			uint32 irow = row - fTopMargin + r;
2554 			if (irow >= fInputHeight)
2555 				continue;
2556 
2557 			for (uint32 col = 0; col < rawWidth; col++) {
2558 				uint32 icol = col - fLeftMargin;
2559 				if (icol < fInputWidth)
2560 					_Bayer(icol, irow) = pixel[r * rawWidth + col];
2561 				else
2562 					fMeta.black += pixel[r * rawWidth + col];
2563 			}
2564 		}
2565 	}
2566 
2567 	free(pixel);
2568 
2569 	if (rawWidth > fInputWidth)
2570 		fMeta.black /= (rawWidth - fInputWidth) * fInputHeight;
2571 }
2572 
2573 
2574 void
2575 DCRaw::_LoadRAWLosslessJPEG(const image_data_info& image)
2576 {
2577 	int jwide, jrow, jcol, val, jidx, i, j, row = 0, col = 0;
2578 	uint32 rawWidth = _Raw().width;
2579 	int min = INT_MAX;
2580 
2581 	struct jhead jh;
2582 	if (_LosslessJPEGInit(&jh, false) != B_OK)
2583 		throw (status_t)B_NO_TRANSLATOR;
2584 
2585 	jwide = jh.wide * jh.clrs;
2586 
2587 	for (jrow = 0; jrow < jh.high; jrow++) {
2588 		_LosslessJPEGRow(&jh, jrow);
2589 
2590 		for (jcol = 0; jcol < jwide; jcol++) {
2591 			val = jh.row[jcol];
2592 			if (jh.bits <= 12)
2593 				val = fCurve[val];
2594 
2595 			if (fCR2Slice[0]) {
2596 				jidx = jrow * jwide + jcol;
2597 				i = jidx / (fCR2Slice[1] * jh.high);
2598 				if ((j = i >= fCR2Slice[0]))
2599 					i  = fCR2Slice[0];
2600 				jidx -= i * (fCR2Slice[1] * jh.high);
2601 				row = jidx / fCR2Slice[1 + j];
2602 				col = jidx % fCR2Slice[1 + j] + i * fCR2Slice[1];
2603 			}
2604 
2605 			if (_Raw().width == 3984 && (col -= 2) < 0) {
2606 				col += rawWidth;
2607 				row--;
2608 			}
2609 
2610 			if (uint32(row - fTopMargin) < fInputHeight) {
2611 				if (uint32(col - fLeftMargin) < fInputWidth) {
2612 					_Bayer(col - fLeftMargin, row - fTopMargin) = val;
2613 					if (min > val)
2614 						min = val;
2615 				} else
2616 					fMeta.black += val;
2617 			}
2618 			if (++col >= (int32)rawWidth) {
2619 				col = 0;
2620 				row++;
2621 			}
2622 		}
2623 	}
2624 
2625 	//dump_to_disk(fImageData, fInputWidth * fColors * 100);
2626 	free(jh.row);
2627 
2628 	if (rawWidth > fInputWidth)
2629 		fMeta.black /= (rawWidth - fInputWidth) * fInputHeight;
2630 	if (_IsKodak())
2631 		fMeta.black = min;
2632 }
2633 
2634 
2635 void
2636 DCRaw::_LoadRAW(const image_data_info& image)
2637 {
2638 #if 0
2639 	if (_IsCanon()) {
2640 		if (fIsTIFF)
2641 		else
2642 			_LoadRAWCanonCompressed(image);
2643 	} else
2644 #endif
2645 	{
2646 		switch (image.compression) {
2647 			case COMPRESSION_NONE:
2648 				_LoadRAWUnpacked(image);
2649 				break;
2650 			case COMPRESSION_OLD_JPEG:
2651 				_LoadRAWLosslessJPEG(image);
2652 				//_LoadRAWCanonCompressed(image);
2653 				break;
2654 			case COMPRESSION_PACKBITS:
2655 				_LoadRAWPacked12(image);
2656 				break;
2657 
2658 			default:
2659 				fprintf(stderr, "DCRaw: unknown compression: %ld\n",
2660 					image.compression);
2661 				throw (status_t)B_NO_TRANSLATOR;
2662 				break;
2663 		}
2664 	}
2665 }
2666 
2667 
2668 //	#pragma mark - Image writers
2669 
2670 
2671 void
2672 DCRaw::_WriteRGB32(image_data_info& image, uint8* outputBuffer)
2673 {
2674 	if (fProgressMonitor != NULL)
2675 		fProgressMonitor("Write RGB", 95, fProgressData);
2676 
2677 	uint8* line, lookUpTable[0x10000];
2678 
2679 	uint32 width = image.flip > 4 ? fOutputHeight : fOutputWidth;
2680 	uint32 height = image.flip > 4 ? fOutputWidth : fOutputHeight;
2681 	uint32 outputRow = (4 * fOutputBitsPerSample / 8) * width;
2682 	uint32 outputOffset = 0;
2683 
2684 	line = (uint8 *)malloc(outputRow);
2685 	if (line == NULL)
2686 		throw (status_t)B_NO_MEMORY;
2687 
2688 	memset(line, 0, outputRow);
2689 
2690 	if (fOutputBitsPerSample == 8)
2691 		_GammaLookUpTable(lookUpTable);
2692 
2693 	int32 sourceOffset = _FlipIndex(0, 0, image.flip);
2694 	int32 colStep = _FlipIndex(0, 1, image.flip) - sourceOffset;
2695 	int32 rowStep = _FlipIndex(1, 0, image.flip)
2696 		- _FlipIndex(0, width, image.flip);
2697 
2698 	TRACE(("flip = %ld, sourceOffset = %ld, colStep = %ld, rowStep = %ld, "
2699 		"input: %lu x %lu, output: %lu x %lu\n", image.flip, sourceOffset,
2700 		colStep, rowStep, fInputWidth, fInputHeight, width,
2701 		height));
2702 
2703 	if (fOutputBitsPerSample == 8) {
2704 		for (uint32 row = 0; row < height; row++, sourceOffset += rowStep) {
2705 			for (uint32 col = 0; col < width; col++, sourceOffset += colStep) {
2706 				line[col * 4 + 2] = lookUpTable[fImageData[sourceOffset][0]];
2707 				line[col * 4 + 1] = lookUpTable[fImageData[sourceOffset][1]];
2708 				line[col * 4 + 0] = lookUpTable[fImageData[sourceOffset][2]];
2709 			}
2710 
2711 			memcpy(&outputBuffer[outputOffset], line, outputRow);
2712 			outputOffset += outputRow;
2713 		}
2714 	} else {
2715 #if 0
2716 		uint16* ppm2 = (uint16*)line;
2717 		for (row = 0; row < fOutputHeight; row++, soff += rstep) {
2718 			for (col = 0; col < fOutputWidth; col++, soff += cstep) {
2719 				FORCC ppm2[col*colors+c] =     image[soff][c];
2720 			}
2721 			if (!output_tiff && htons(0x55aa) != 0x55aa)
2722 				swab (ppm2, ppm2, width*colors*2);
2723 			fwrite (ppm, colors*output_bps/8, width, ofp);
2724 		}
2725 #endif
2726 	}
2727 
2728 	free(line);
2729 }
2730 
2731 
2732 void
2733 DCRaw::_WriteJPEG(image_data_info& image, uint8* outputBuffer)
2734 {
2735 	fRead(outputBuffer, image.bytes);
2736 
2737 	if (outputBuffer[0] != 0xff || outputBuffer[1] != 0xd8)
2738 		throw (status_t)B_NO_TRANSLATOR;
2739 
2740 #if 0
2741 	uint8* thumb = (uint8*)malloc(image.bytes);
2742 	if (thumb == NULL)
2743 		throw (status_t)B_NO_MEMORY;
2744 
2745 	fRead(thumb, image.bytes);
2746 
2747 	uint8* data = (uint8*)fImageData;
2748 	data[0] = 0xff;
2749 	data[1] = 0xd8;
2750 
2751 	if (strcmp((char *)thumb + 6, "Exif")) {
2752 		// TODO: no EXIF data - write them ourselves
2753 	}
2754 
2755 	memcpy(&data[2], thumb + 2, image.bytes - 2);
2756 	free(thumb);
2757 #endif
2758 }
2759 
2760 
2761 //	#pragma mark - TIFF
2762 
2763 
2764 time_t
2765 DCRaw::_ParseTIFFTimestamp(bool reversed)
2766 {
2767 	char str[20];
2768 	str[19] = 0;
2769 
2770 	if (reversed) {
2771 		for (int i = 19; i--; ) {
2772 			str[i] = fRead.Next<uint8>();
2773 		}
2774 	} else
2775 		fRead(str, 19);
2776 
2777 	struct tm t;
2778 	memset(&t, 0, sizeof t);
2779 
2780 	if (sscanf(str, "%d:%d:%d %d:%d:%d", &t.tm_year, &t.tm_mon,
2781 			&t.tm_mday, &t.tm_hour, &t.tm_min, &t.tm_sec) != 6)
2782 		return 0;
2783 
2784 	t.tm_year -= 1900;
2785 	t.tm_mon -= 1;
2786 
2787 	return mktime(&t);
2788 }
2789 
2790 
2791 /*!	Reads a TIFF tag and positions the file stream to its data section
2792 */
2793 void
2794 DCRaw::_ParseTIFFTag(off_t baseOffset, tiff_tag& tag, off_t& offset)
2795 {
2796 	fRead(tag.tag);
2797 	fRead(tag.type);
2798 	fRead(tag.length);
2799 
2800 	offset = fRead.Position() + 4;
2801 
2802 	uint32 length = tag.length;
2803 
2804 	switch (tag.type) {
2805 		case TIFF_UINT16_TYPE:
2806 		case TIFF_INT16_TYPE:
2807 			length *= 2;
2808 			break;
2809 
2810 		case TIFF_UINT32_TYPE:
2811 		case TIFF_INT32_TYPE:
2812 		case TIFF_FLOAT_TYPE:
2813 			length *= 4;
2814 			break;
2815 
2816 		case TIFF_UFRACTION_TYPE:
2817 		case TIFF_FRACTION_TYPE:
2818 		case TIFF_DOUBLE_TYPE:
2819 			length *= 8;
2820 			break;
2821 
2822 		default:
2823 			break;
2824 	}
2825 
2826 	if (length > 4) {
2827 		uint32 position;
2828 		fRead(position);
2829 
2830 		fRead.Seek(baseOffset + position, SEEK_SET);
2831 	}
2832 }
2833 
2834 
2835 status_t
2836 DCRaw::_ParseTIFFImageFileDirectory(off_t baseOffset, uint32 offset)
2837 {
2838 	double analogBalance[] = {1, 1, 1, 1};
2839 	double xyz[] = {1, 1, 1, 1};
2840 	bool useColorMatrix = false;
2841 	double cameraCalibration[4][4], colorMatrix[4][3], cameraXYZ[4][3];
2842 
2843 	for (int32 j = 0; j < 4; j++) {
2844 		for (int32 i = 0; i < 4; i++) {
2845 			cameraCalibration[j][i] = i == j;
2846 		}
2847 	}
2848 
2849 	fRead.Seek(baseOffset + offset, SEEK_SET);
2850 
2851 	uint16 tags;
2852 	fRead(tags);
2853 	if (tags > 512)
2854 		return B_BAD_DATA;
2855 
2856 	image_data_info& image = fImages[fNumImages];
2857 
2858 	while (tags--) {
2859 		off_t nextOffset;
2860 		tiff_tag tag;
2861 		_ParseTIFFTag(baseOffset, tag, nextOffset);
2862 		TAG("TIFF tag: %u\n", tag.tag);
2863 
2864 		switch (tag.tag) {
2865 #if 0
2866 			default:
2867 				printf("tag %u NOT HANDLED!\n", tag.tag);
2868 				break;
2869 #endif
2870 
2871 			case 17:
2872 			case 18:
2873 				if (tag.type == 3 && tag.length == 1) {
2874 					fMeta.camera_multipliers[(tag.tag - 17) * 2]
2875 						= fRead.Next<uint16>() / 256.0;
2876 				}
2877 				break;
2878 
2879 			case 23:	// ISO speed
2880 				fMeta.iso_speed = fRead.Next(tag.type);
2881 				break;
2882 
2883 			case 36:
2884 			case 37:
2885 			case 38:
2886 				fMeta.camera_multipliers[tag.tag - 0x24] = fRead.Next<uint16>();
2887 				break;
2888 
2889 			case 39:
2890 				if (tag.length < 50 || fMeta.camera_multipliers[0])
2891 					break;
2892 
2893 				fRead.Stream().Seek(12, SEEK_CUR);
2894 				for (uint32 i = 0; i < 3; i++) {
2895 					fMeta.camera_multipliers[i] = fRead.Next<uint16>();
2896 				}
2897 				break;
2898 
2899 			case 2:		// image width
2900 			case 256:
2901 				image.width = fRead.Next(tag.type);
2902 				break;
2903 
2904 			case 3:		// image height
2905 			case 257:
2906 				image.height = fRead.Next(tag.type);
2907 				break;
2908 
2909 			case 258:	// bits per sample
2910 				image.samples = tag.length;
2911 				image.bits_per_sample = fRead.Next<uint16>();
2912 				break;
2913 
2914 			case 259:	// compression
2915 				image.compression = fRead.Next<uint16>();
2916 				break;
2917 
2918 			case 262:	// Photometric Interpretation
2919 				image.photometric_interpretation = fRead.Next<uint16>();
2920 				break;
2921 
2922 			case 271:	// manufacturer
2923 				fRead(fMeta.manufacturer, 64);
2924 				break;
2925 
2926 			case 272:	// model
2927 				fRead(fMeta.model, 64);
2928 				break;
2929 
2930 			case 273:	// Strip Offset
2931 			case 513:
2932 				image.data_offset = baseOffset + fRead.Next<uint32>();
2933 				if (!image.bits_per_sample) {
2934 					fRead.Stream().Seek(image.data_offset, SEEK_SET);
2935 					jhead jh;
2936 					if (_LosslessJPEGInit(&jh, true) == B_OK) {
2937 						image.compression = 6;
2938 						image.width = jh.wide << (jh.clrs == 2);
2939 						image.height = jh.high;
2940 						image.bits_per_sample = jh.bits;
2941 						image.samples = jh.clrs;
2942 					}
2943 				}
2944 				break;
2945 
2946 			case 274:	// Orientation
2947 				image.flip = fRead.Next<uint16>();
2948 				break;
2949 
2950 			case 277:	// Samples Per Pixel
2951 				image.samples = fRead.Next(tag.type);
2952 				break;
2953 
2954 			case 279:	// Strip Byte Counts
2955 			case 514:
2956 				image.bytes = fRead.Next<uint32>();
2957 				break;
2958 
2959 			case 305:	// Software
2960 				fRead(fMeta.software, 64);
2961 				if (!strncmp(fMeta.software, "Adobe", 5)
2962 					|| !strncmp(fMeta.software, "dcraw", 5)
2963 					|| !strncmp(fMeta.software, "Bibble", 6)
2964 					|| !strncmp(fMeta.software, "Nikon Scan", 10)
2965 					|| !strcmp(fMeta.software,"Digital Photo Professional"))
2966 					throw (status_t)B_NO_TRANSLATOR;
2967 				break;
2968 
2969 			case 306:	// Date/Time
2970 				fMeta.timestamp = _ParseTIFFTimestamp(false);
2971 				break;
2972 
2973 #if 0
2974 			case 323:	// Tile Length
2975 				tile_length = fRead.Next(type);
2976 				break;
2977 
2978 			case 324:	// Tile Offsets
2979 				image.data_offset = tag.length > 1
2980 					? fRead.Stream().Position() : fRead.Next<uint32>();
2981 				if (tag.length == 4)
2982 					load_raw = &CLASS sinar_4shot_load_raw;
2983 				break;
2984 #endif
2985 
2986 			case 330:	// Sub IFDs
2987 				if (!strcmp(fMeta.model, "DSLR-A100") && image.width == 3872) {
2988 					// TODO: this might no longer work!
2989 					image.data_offset = fRead.Next<uint32>() + baseOffset;
2990 					break;
2991 				}
2992 
2993 				while (tag.length--) {
2994 					off_t nextOffset = fRead.Position() + sizeof(uint32);
2995 
2996 					fRead.Seek(fRead.Next<uint32>() + baseOffset, SEEK_SET);
2997 					if (_ParseTIFFImageFileDirectory(baseOffset) != B_OK)
2998 						break;
2999 
3000 					fNumImages++;
3001 					fRead.Seek(nextOffset, SEEK_SET);
3002 				}
3003 				break;
3004 
3005 #if 0
3006 			case 400:
3007 				strcpy(fMeta.manufacturer, "Sarnoff");
3008 				maximum = 0xfff;
3009 				break;
3010 #endif
3011 
3012 #if 0
3013 			case 29184:
3014 				sony_offset = get4();
3015 				break;
3016 			case 29185:
3017 				sony_length = get4();
3018 				break;
3019 			case 29217:
3020 				sony_key = get4();
3021 				break;
3022 #endif
3023 
3024 			case 29443:
3025 				for (uint32 i = 0; i < 4; i++) {
3026 					fMeta.camera_multipliers[i ^ (i < 2)] = fRead.Next<uint16>();
3027 				}
3028 				break;
3029 
3030 			case 33405:	// Model 2
3031 				fRead(fMeta.model + 64, 64);
3032 				break;
3033 
3034 #if 0
3035 			case 33422:	// CFA Pattern
3036 			case 64777:	// Kodak P-series
3037 			{
3038 				if ((plen=len) > 16) plen = 16;
3039 				fread (cfa_pat, 1, plen, ifp);
3040 				for (colors=cfa=i=0; i < plen; i++) {
3041 				  colors += !(cfa & (1 << cfa_pat[i]));
3042 				  cfa |= 1 << cfa_pat[i];
3043 				}
3044 				if (cfa == 070) memcpy (cfa_pc,"\003\004\005",3);	/* CMY */
3045 				if (cfa == 072) memcpy (cfa_pc,"\005\003\004\001",4);	/* GMCY */
3046 				goto guess_cfa_pc;
3047 				break;
3048 			}
3049 
3050 			case 33424:
3051 				fseek(ifp, get4()+base, SEEK_SET);
3052 				parse_kodak_ifd (base);
3053 				break;
3054 #endif
3055 
3056 			case 33434:	// Exposure Time
3057 				fMeta.shutter = fRead.NextDouble(TIFF_FRACTION_TYPE);
3058 				break;
3059 
3060 			case 33437:	// Aperture
3061 				fMeta.aperture = fRead.NextDouble(TIFF_FRACTION_TYPE);
3062 				break;
3063 
3064 			case 34306:	// Leaf white balance
3065 				for (uint32 i = 0; i < 4; i++) {
3066 					fMeta.camera_multipliers[i ^ 1] = 4096.0 / fRead.Next<uint16>();
3067 				}
3068 				break;
3069 
3070 #if 0
3071 			case 34307:	// Leaf Catch Light color matrix
3072 				fread (software, 1, 7, ifp);
3073 				if (strncmp(software,"MATRIX",6))
3074 					break;
3075 				colors = 4;
3076 				for (fRawColor = i=0; i < 3; i++) {
3077 					FORC4 fscanf (ifp, "%f", &rgb_cam[i][c^1]);
3078 					if (!use_camera_wb)
3079 						continue;
3080 					num = 0;
3081 					FORC4 num += rgb_cam[i][c];
3082 					FORC4 rgb_cam[i][c] /= num;
3083 				}
3084 				break;
3085 			case 34310:	// Leaf metadata
3086 				parse_mos (ftell(ifp));
3087 			case 34303:
3088 				strcpy(image.manufacturer, "Leaf");
3089 				break;
3090 #endif
3091 
3092 			case 34665:	// EXIF tag
3093 				fRead.Seek(fRead.Next<uint32>() + baseOffset, SEEK_SET);
3094 
3095 				fEXIFOffset = fRead.Position();
3096 				fEXIFLength = tag.length;
3097 
3098 				_ParseEXIF(baseOffset);
3099 				break;
3100 
3101 #if 0
3102 			case 34675:	// InterColorProfile
3103 			case 50831:	// AsShotICCProfile
3104 				profile_offset = fRead.Stream().Position();
3105 				profile_length = tag.length;
3106 				break;
3107 
3108 			case 37122:	// Compressed Bits Per Pixel
3109 				kodak_cbpp = fRead.Next<uint32>();
3110 				break;
3111 #endif
3112 
3113 			case 37386:	// Focal Length
3114 				fMeta.focal_length = fRead.NextDouble(TIFF_FRACTION_TYPE);
3115 				break;
3116 
3117 			case 37393:	// Image Number
3118 				fMeta.shot_order = fRead.Next(tag.type);
3119 				break;
3120 
3121 #if 0
3122 			case 37400:	// old Kodak KDC tag
3123 				for (fRawColor = i=0; i < 3; i++) {
3124 					getrat();
3125 					FORC3 rgb_cam[i][c] = getrat();
3126 				}
3127 				break;
3128 
3129 			case 46275:	// Imacon tags
3130 				strcpy (make, "Imacon");
3131 				data_offset = ftell(ifp);
3132 				ima_len = len;
3133 				break;
3134       case 46279:
3135 	fseek (ifp, 78, SEEK_CUR);
3136 	raw_width  = get4();
3137 	raw_height = get4();
3138 	left_margin = get4() & 7;
3139 	width = raw_width - left_margin - (get4() & 7);
3140 	top_margin = get4() & 7;
3141 	height = raw_height - top_margin - (get4() & 7);
3142 	fseek (ifp, 52, SEEK_CUR);
3143 	FORC3 cam_multipliers[c] = getreal(11);
3144 	fseek (ifp, 114, SEEK_CUR);
3145 	flip = (get2() >> 7) * 90;
3146 	if (width * height * 6 == ima_len) {
3147 	  if (flip % 180 == 90) SWAP(width,height);
3148 	  filters = flip = 0;
3149 	}
3150 	break;
3151       case 50454:			/* Sinar tag */
3152       case 50455:
3153 	if (!(cbuf = (char *) malloc(len))) break;
3154 	fread (cbuf, 1, len, ifp);
3155 	for (cp = cbuf-1; cp && cp < cbuf+len; cp = strchr(cp,'\n'))
3156 	  if (!strncmp (++cp,"Neutral ",8))
3157 	    sscanf (cp+8, "%f %f %f", cam_multipliers, cam_multipliers+1, cam_multipliers+2);
3158 	free (cbuf);
3159 	break;
3160 #endif
3161 
3162 			case 50706:	// DNG Version
3163 				for (int32 i = 0; i < 4; i++) {
3164 					fDNGVersion = (fDNGVersion << 8) + fRead.Next<uint8>();
3165 				}
3166 				break;
3167 
3168 #if 0
3169 			case 50710:	// CFAPlaneColor
3170 				if (len > 4)
3171 					len = 4;
3172 				colors = len;
3173 				fread(cfa_pc, 1, colors, ifp);
3174 			guess_cfa_pc:
3175 				FORCC tab[cfa_pc[c]] = c;
3176 				cdesc[c] = 0;
3177 				for (i=16; i--; )
3178 					filters = filters << 2 | tab[cfa_pat[i % plen]];
3179 				break;
3180 			case 50711:	// CFALayout
3181 				if (get2() == 2) {
3182 					fuji_width = 1;
3183 					filters = 0x49494949;
3184 				}
3185 				break;
3186 #endif
3187 
3188 			case 291:	// Linearization Table
3189 			case 50712:
3190 				_ParseLinearTable(tag.length);
3191 				break;
3192 
3193 			case 50714:			/* BlackLevel */
3194 			case 50715:			/* BlackLevelDeltaH */
3195 			case 50716:			/* BlackLevelDeltaV */
3196 			{
3197 				double black = 0.0;
3198 				for (uint32 i = 0; i < tag.length; i++) {
3199 					black += fRead.NextDouble(tag.type);
3200 				}
3201 				fMeta.black += int32(black / tag.length + 0.5);
3202 				break;
3203 			}
3204 
3205 			case 50717:	// White Level
3206 				fMeta.maximum = fRead.Next(tag.type);
3207 				break;
3208 
3209 			case 50718:	// Default Scale
3210 				fMeta.pixel_aspect = fRead.NextDouble(TIFF_FRACTION_TYPE);
3211 				fMeta.pixel_aspect /= fRead.NextDouble(TIFF_FRACTION_TYPE);
3212 				break;
3213 
3214 			case 50721:	// Color Matrix
3215 			case 50722:
3216 				for (uint32 c = 0; c < fColors; c++) {
3217 					for (uint32 j = 0; j < 3; j++) {
3218 						colorMatrix[c][j] = fRead.NextDouble(TIFF_FRACTION_TYPE);
3219 					}
3220 				}
3221 				useColorMatrix = true;
3222 				break;
3223 
3224 			case 50723:	// Camera Calibration
3225 			case 50724:
3226 				for (uint32 i = 0; i < fColors; i++) {
3227 					for (uint32 c = 0; c < fColors; c++) {
3228 						cameraCalibration[i][c] = fRead.NextDouble(
3229 							TIFF_FRACTION_TYPE);
3230 					}
3231 				}
3232 				//break;
3233 			case 50727:	// Analog Balance
3234 				for (uint32 c = 0; c < fColors; c++) {
3235 					analogBalance[c] = fRead.NextDouble(TIFF_FRACTION_TYPE);
3236 					//printf("ab: %g\n", analogBalance[c]);
3237 				}
3238 				break;
3239 #if 0
3240       case 50728:			/* AsShotNeutral */
3241 	FORCC asn[c] = getreal(type);
3242 	break;
3243       case 50729:			/* AsShotWhiteXY */
3244 	xyz[0] = getrat();
3245 	xyz[1] = getrat();
3246 	xyz[2] = 1 - xyz[0] - xyz[1];
3247 	FORC3 xyz[c] /= kD65White[c];
3248 	break;
3249       case 50740:			/* DNGPrivateData */
3250 	if (dng_version) break;
3251 	i = order;
3252 	parse_minolta (j = get4()+base);
3253 	order = i;
3254 	fseek (ifp, j, SEEK_SET);
3255 	parse_tiff_ifd (base);
3256 	break;
3257 #endif
3258 			case 50752:
3259 				fRead.NextShorts(fCR2Slice, 3);
3260 				break;
3261 
3262 			case 50829:	// Active Area
3263 				fTopMargin = fRead.Next(tag.type);
3264 				fLeftMargin = fRead.Next(tag.type);
3265 				fInputHeight = fRead.Next(tag.type) - fTopMargin;
3266 				fInputWidth = fRead.Next(tag.type) - fLeftMargin;
3267 				break;
3268 #if 0
3269       case 64772:			/* Kodak P-series */
3270 	fseek (ifp, 16, SEEK_CUR);
3271 	data_offset = get4();
3272 	fseek (ifp, 28, SEEK_CUR);
3273 	data_offset += get4();
3274 	load_raw = &CLASS packed_12_load_raw;
3275 #endif
3276 		}
3277 		fRead.Seek(nextOffset, SEEK_SET);
3278 	}
3279 
3280 	// handle SONY tags
3281 
3282 #if 0
3283 	if (sony_length && (buf = (unsigned *) malloc(sony_length))) {
3284 		fseek(ifp, sony_offset, SEEK_SET);
3285 		fread(buf, sony_length, 1, ifp);
3286 		sony_decrypt(buf, sony_length / 4, 1, sony_key);
3287 		sfp = ifp;
3288 		if ((ifp = tmpfile())) {
3289 			fwrite(buf, sony_length, 1, ifp);
3290 			fseek(ifp, 0, SEEK_SET);
3291 			parse_tiff_ifd(-sony_offset);
3292 			fclose(ifp);
3293 		}
3294 		ifp = sfp;
3295 		free(buf);
3296 	}
3297 #endif
3298 
3299 	for (uint32 i = 0; i < fColors; i++) {
3300 		for (uint32 c = 0; c < fColors; c++) {
3301 			cameraCalibration[i][c] *= analogBalance[i];
3302 		}
3303 	}
3304 
3305 	if (useColorMatrix) {
3306 		for (uint32 c = 0; c < fColors; c++) {
3307 			for (uint32 i = 0; i < 3; i++) {
3308 				cameraXYZ[c][i] = 0;
3309 				for (uint32 j = 0; j < fColors; j++) {
3310 					cameraXYZ[c][i] += cameraCalibration[c][j]
3311 						* colorMatrix[j][i] * xyz[i];
3312 				}
3313 			}
3314 		}
3315 		_CameraXYZCoefficients(cameraXYZ);
3316 	}
3317 
3318 #if 0
3319 	if (asn[0])
3320     	FORCC pre_multipliers[c] = 1 / asn[c];
3321 #endif
3322 	if (!useColorMatrix) {
3323 		for (uint32 c = 0; c < fColors; c++) {
3324 			fMeta.pre_multipliers[c] /= cameraCalibration[c][c];
3325 		}
3326 	}
3327 
3328 	return B_OK;
3329 }
3330 
3331 
3332 status_t
3333 DCRaw::_ParseTIFFImageFileDirectory(off_t baseOffset)
3334 {
3335 	while (fNumImages < kImageBufferCount) {
3336 		int32 offset;
3337 		fRead(offset);
3338 		if (offset == 0)
3339 			break;
3340 
3341 		status_t status = _ParseTIFFImageFileDirectory(baseOffset, offset);
3342 		if (status < B_OK)
3343 			return status;
3344 
3345 		fNumImages++;
3346 	}
3347 
3348 	return B_OK;
3349 }
3350 
3351 
3352 status_t
3353 DCRaw::_ParseTIFF(off_t baseOffset)
3354 {
3355 	fRead.Stream().Seek(baseOffset, SEEK_SET);
3356 
3357 	uint16 endian;
3358 	fRead(endian);
3359 	if (endian != 'MM' && endian != 'II')
3360 		return B_NO_TRANSLATOR;
3361 
3362 #if B_HOST_IS_LENDIAN
3363 	fRead.SetSwap(endian == 'MM');
3364 #else
3365 	fRead.SetSwap(endian == 'II');
3366 #endif
3367 
3368 	fRead(endian);
3369 		// dummy, not used, should be 42 for actual TIFF images,
3370 		// but may vary for RAW images
3371 
3372 	_ParseTIFFImageFileDirectory(baseOffset);
3373 	fIsTIFF = true;
3374 
3375 	uint32 maxSamples = 0;
3376 
3377 	if (fThumbIndex >= 0 && _Thumb().data_offset) {
3378 		fRead.Seek(_Thumb().data_offset, SEEK_SET);
3379 
3380 		jhead jh;
3381 		if (_LosslessJPEGInit(&jh, true)) {
3382 			_Thumb().bits_per_sample = jh.bits;
3383 			_Thumb().width = jh.wide;
3384 			_Thumb().height = jh.high;
3385 			_Thumb().bits_per_sample = 16;
3386 		}
3387 	}
3388 
3389 	// identify RAW image in list of images retrieved
3390 
3391 	for (uint32 i = 0; i < fNumImages; i++) {
3392 		if (maxSamples < fImages[i].samples)
3393 			maxSamples = fImages[i].samples;
3394 
3395 		if ((fImages[i].compression != COMPRESSION_OLD_JPEG
3396 				|| fImages[i].samples != 3)
3397 			&& _SupportsCompression(fImages[i])) {
3398 			fImages[i].is_raw = true;
3399 
3400 			if (fRawIndex < 0 || fImages[i].width * fImages[i].height
3401 					> _Raw().width * _Raw().height) {
3402 				fRawIndex = i;
3403 				//fuji_secondary = _Raw().samples == 2;
3404 			}
3405 		}
3406 	}
3407 
3408 	if (fRawIndex < 0
3409 		|| (!fDNGVersion && _Raw().samples == 3 && _Raw().bits_per_sample == 8))
3410 		throw (status_t)B_NO_TRANSLATOR;
3411 
3412 	if (fRawIndex >= 0) {
3413 		fMeta.raw_width = _Raw().width;
3414 		fMeta.raw_height = _Raw().height;
3415 	}
3416 
3417 #if 0
3418   fuji_width *= (raw_width+1)/2;
3419   if (tiff_ifd[0].flip) tiff_flip = tiff_ifd[0].flip;
3420   if (raw >= 0 && !load_raw)
3421     switch (tiff_compress) {
3422       case 0:  case 1:
3423 	load_raw = tiff_bps > 8 ?
3424 	  &CLASS unpacked_load_raw : &CLASS eight_bit_load_raw;
3425 	if (tiff_ifd[raw].bytes * 5 == raw_width * raw_height * 8)
3426 	  load_raw = &CLASS olympus_e300_load_raw;
3427 	if (tiff_bps == 12 && tiff_ifd[raw].phint == 2)
3428 	  load_raw = &CLASS olympus_cseries_load_raw;
3429 	break;
3430       case 6:  case 7:  case 99:
3431 	load_raw = &CLASS lossless_jpeg_load_raw;		break;
3432       case 262:
3433 	load_raw = &CLASS kodak_262_load_raw;			break;
3434       case 32773:
3435 	load_raw = &CLASS packed_12_load_raw;			break;
3436       case 65535:
3437 	load_raw = &CLASS pentax_k10_load_raw;			break;
3438       case 65000:
3439 	switch (tiff_ifd[raw].phint) {
3440 	  case 2: load_raw = &CLASS kodak_rgb_load_raw;   fFilters = 0;  break;
3441 	  case 6: load_raw = &CLASS kodak_ycbcr_load_raw; fFilters = 0;  break;
3442 	  case 32803: load_raw = &CLASS kodak_65000_load_raw;
3443 	}
3444     }
3445   if (tiff_samples == 3 && tiff_bps == 8)
3446     if (!dng_version) is_raw = 0;
3447 #endif
3448 
3449 #if 0
3450   if (thm >= 0) {
3451     thumb_misc |= tiff_ifd[thm].samples << 5;
3452     switch (tiff_ifd[thm].comp) {
3453       case 0:
3454 	write_thumb = &CLASS layer_thumb;
3455 	break;
3456       case 1:
3457 	if (tiff_ifd[thm].bps > 8)
3458 	  thumb_load_raw = &CLASS kodak_thumb_load_raw;
3459 	else
3460 	  write_thumb = &CLASS ppm_thumb;
3461 	break;
3462       case 65000:
3463 	thumb_load_raw = tiff_ifd[thm].phint == 6 ?
3464 		&CLASS kodak_ycbcr_load_raw : &CLASS kodak_rgb_load_raw;
3465     }
3466   }
3467 #endif
3468 	return B_OK;
3469 }
3470 
3471 
3472 //	#pragma mark -
3473 
3474 
3475 status_t
3476 DCRaw::Identify()
3477 {
3478 	fRead.Seek(0, SEEK_SET);
3479 
3480 	status_t status = B_NO_TRANSLATOR;
3481 	char header[32];
3482 	fRead(header, sizeof(header));
3483 
3484 	// check for TIFF-like files first
3485 
3486 	uint16 endian = *(uint16*)&header;
3487 	if (endian == 'II' || endian == 'MM')
3488 		status = _ParseTIFF(0);
3489 
3490 	if (status < B_OK)
3491 		return status;
3492 
3493 	// brush up some variables for later use
3494 
3495 	fInputWidth = _Raw().width;
3496 	fInputHeight = _Raw().height;
3497 
3498 	_FixupValues();
3499 
3500 	if ((_Raw().width | _Raw().height) < 0)
3501 		_Raw().width = _Raw().height = 0;
3502 	if (fMeta.maximum == 0)
3503 		fMeta.maximum = (1 << _Raw().bits_per_sample) - 1;
3504 
3505 	if (fFilters == ~0UL)
3506 		fFilters = 0x94949494;
3507 	if (fFilters && fColors == 3) {
3508 		for (int32 i = 0; i < 32; i += 4) {
3509 			if ((fFilters >> i & 15) == 9)
3510 				fFilters |= 2 << i;
3511 			if ((fFilters >> i & 15) == 6)
3512 				fFilters |= 8 << i;
3513 		}
3514 	}
3515 
3516 	if (fRawColor)
3517 		_AdobeCoefficients(fMeta.manufacturer, fMeta.model);
3518 
3519 	// remove invalid images
3520 
3521 	int32 rawCount = 0;
3522 
3523 	for (int32 i = 0; i < (int32)fNumImages; i++) {
3524 		if (fImages[i].width == 0 || fImages[i].height == 0
3525 			|| fImages[i].data_offset == 0) {
3526 			fNumImages--;
3527 			if (i == fRawIndex)
3528 				fRawIndex = -1;
3529 			else if (i < fRawIndex)
3530 				fRawIndex--;
3531 			if (i == fThumbIndex)
3532 				fThumbIndex = -1;
3533 			else if (i < fThumbIndex)
3534 				fThumbIndex--;
3535 
3536 			if (i < (int32)fNumImages) {
3537 				memmove(&fImages[i], &fImages[i + 1],
3538 					sizeof(image_data_info) * (fNumImages - i));
3539 			}
3540 			i--;
3541 		} else if (fImages[i].is_raw)
3542 			rawCount++;
3543 	}
3544 
3545 	// This is to prevent us from identifying TIFF images
3546 	if (rawCount == 0)
3547 		return B_NO_TRANSLATOR;
3548 
3549 	fMeta.flip = _Raw().flip;
3550 	return B_OK;
3551 }
3552 
3553 
3554 status_t
3555 DCRaw::ReadImageAt(uint32 index, uint8*& outputBuffer, size_t& bufferSize)
3556 {
3557 	if (index >= fNumImages)
3558 		return B_BAD_VALUE;
3559 
3560 	_CorrectIndex(index);
3561 
3562 	image_data_info& image = fImages[index];
3563 
3564 	fShrink = (fHalfSize || fThreshold) && fFilters;
3565 	fOutputWidth = (fInputWidth + fShrink) >> fShrink;
3566 	fOutputHeight = (fInputHeight + fShrink) >> fShrink;
3567 
3568 	if (image.flip > 4) {
3569 		// image is rotated
3570 		image.output_width = fOutputHeight;
3571 		image.output_height = fOutputWidth;
3572 	} else {
3573 		image.output_width = fOutputWidth;
3574 		image.output_height = fOutputHeight;
3575 	}
3576 
3577 	if (image.is_raw) {
3578 		bufferSize = fOutputWidth * 4 * fOutputHeight;
3579 
3580 		fImageData = (uint16 (*)[4])calloc(fOutputWidth * fOutputHeight
3581 			* sizeof(*fImageData) + 0, 1); //meta_length, 1);
3582 		if (fImageData == NULL)
3583 			throw (status_t)B_NO_MEMORY;
3584 	} else {
3585 		bufferSize = image.bytes + sizeof(tiff_header) + 10;
3586 			// TIFF header plus EXIF identifier
3587 	}
3588 
3589 	outputBuffer = (uint8*)malloc(bufferSize);
3590 	if (outputBuffer == NULL) {
3591 		free(fImageData);
3592 		fImageData = NULL;
3593 		throw (status_t)B_NO_MEMORY;
3594 	}
3595 
3596 	fRead.Seek(image.data_offset, SEEK_SET);
3597 
3598 	if (image.is_raw) {
3599 		_LoadRAW(image);
3600 
3601 		//bad_pixels();
3602 		//if (dark_frame) subtract (dark_frame);
3603 		//quality = 2 + !fuji_width;
3604 
3605 		if (fDocumentMode < 2)
3606 			_ScaleColors();
3607 		_PreInterpolate();
3608 		_CameraToCIELab(NULL, NULL);
3609 
3610 		if (fFilters && !fDocumentMode) {
3611 #if 0
3612 			if (quality == 0)
3613 				lin_interpolate();
3614 			else if (quality < 3 || colors > 3)
3615 				vng_interpolate();
3616 #endif
3617 			_AHDInterpolate();
3618 		}
3619 
3620 #if 0
3621 		if (fHightlight > 1)
3622 			_RecoverHighlights();
3623 		if (use_fuji_rotate) fuji_rotate();
3624 		if (mix_green && (colors = 3))
3625 			for (i=0; i < height*width; i++)
3626 				image[i][1] = (image[i][1] + image[i][3]) >> 1;
3627 #endif
3628 
3629 		_ConvertToRGB();
3630 		//if (use_fuji_rotate) stretch();
3631 
3632 		_WriteRGB32(image, outputBuffer);
3633 	} else {
3634 		_WriteJPEG(image, outputBuffer);
3635 	}
3636 
3637 	free(fImageData);
3638 	fImageData = NULL;
3639 
3640 	return B_OK;
3641 }
3642 
3643 
3644 void
3645 DCRaw::GetMetaInfo(image_meta_info& metaInfo) const
3646 {
3647 	metaInfo = fMeta;
3648 }
3649 
3650 
3651 uint32
3652 DCRaw::CountImages() const
3653 {
3654 	return fNumImages;
3655 }
3656 
3657 
3658 status_t
3659 DCRaw::ImageAt(uint32 index, image_data_info& info) const
3660 {
3661 	if (index >= fNumImages)
3662 		return B_BAD_VALUE;
3663 
3664 	_CorrectIndex(index);
3665 
3666 	info = fImages[index];
3667 	return B_OK;
3668 }
3669 
3670 
3671 status_t
3672 DCRaw::GetEXIFTag(off_t& offset, size_t& length, bool& bigEndian) const
3673 {
3674 	if (fEXIFOffset < 0)
3675 		return B_ENTRY_NOT_FOUND;
3676 
3677 	offset = fEXIFOffset;
3678 	length = fEXIFLength;
3679 
3680 #if B_HOST_IS_LENDIAN
3681 	bigEndian = fRead.IsSwapping();
3682 #else
3683 	bigEndian = !fRead.IsSwapping();
3684 #endif
3685 	return B_OK;
3686 }
3687 
3688 
3689 void
3690 DCRaw::SetProgressMonitor(monitor_hook hook, void* data)
3691 {
3692 	fProgressMonitor = hook;
3693 	fProgressData = data;
3694 }
3695 
3696 
3697 void
3698 DCRaw::SetHalfSize(bool half)
3699 {
3700 	fHalfSize = half;
3701 }
3702