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