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