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