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