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