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