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