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