00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #define _GNU_SOURCE
00027 #define _USE_MATH_DEFINES
00028 #include <ctype.h>
00029 #include <errno.h>
00030 #include <fcntl.h>
00031 #include <float.h>
00032 #include <limits.h>
00033 #include <math.h>
00034 #include <setjmp.h>
00035 #include <stdio.h>
00036 #include <stdlib.h>
00037 #include <string.h>
00038 #include <time.h>
00039
00040
00041
00042
00043
00044
00045 #define NO_LCMS
00046
00047 #ifndef NO_JPEG
00048 #include <jpeglib.h>
00049 #endif
00050 #ifndef NO_LCMS
00051 #include <lcms.h>
00052 #endif
00053
00054 #ifdef __CYGWIN__
00055 #include <io.h>
00056 #endif
00057 #ifdef WIN32
00058 #include <sys/utime.h>
00059 #include <winsock2.h>
00060 #pragma comment(lib, "ws2_32.lib")
00061 #define strcasecmp stricmp
00062 typedef __int64 INT64;
00063 typedef unsigned __int64 UINT64;
00064 #else
00065 #include <unistd.h>
00066 #include <utime.h>
00067 #include <netinet/in.h>
00068 typedef long long INT64;
00069 typedef unsigned long long UINT64;
00070 #endif
00071
00072 #ifdef LJPEG_DECODE
00073 #error Please compile dcraw.c by itself.
00074 #error Do not link it with ljpeg_decode.
00075 #endif
00076
00077 #ifndef LONG_BIT
00078 #define LONG_BIT (8 * sizeof (long))
00079 #endif
00080
00081 #define ushort UshORt
00082 typedef unsigned char uchar;
00083 typedef unsigned short ushort;
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094 char dcraw_info[1024];
00095 float **dcraw_data;
00096 int dcraw_alpha;
00097 float dcraw_matrix[9];
00098
00099
00100 FILE *ifp;
00101 short order;
00102 char *ifname, make[64], model[72], model2[64], *meta_data, cdesc[5];
00103 float flash_used, canon_ev, iso_speed, shutter, aperture, focal_len;
00104 time_t timestamp;
00105 unsigned shot_order, kodak_cbpp, filters;
00106 int profile_offset, profile_length;
00107 int thumb_offset, thumb_length, thumb_width, thumb_height, thumb_misc;
00108 int data_offset, strip_offset, curve_offset, meta_offset, meta_length;
00109 int tiff_nifds, tiff_flip, tiff_bps, tiff_compress;
00110 int raw_height, raw_width, top_margin, left_margin;
00111 int height, width, fuji_width, colors, tiff_samples;
00112 int black, maximum, clip_max, raw_color, use_gamma;
00113 int iheight, iwidth, shrink, flip, xmag, ymag;
00114 int zero_after_ff, is_raw, dng_version, is_foveon;
00115 ushort (*image)[4], white[8][8], curve[0x1000], cr2_slice[3];
00116 float bright=1, red_scale=1, blue_scale=1, sigma_d=0, sigma_r=0;
00117 int four_color_rgb=0, document_mode=0, clip_color=1;
00118 int verbose=0, use_auto_wb=0, use_camera_wb=0, output_color=1;
00119 int fuji_layout, fuji_secondary, use_secondary=0;
00120 float cam_mul[4], pre_mul[4], rgb_cam[3][4];
00121 const double xyz_rgb[3][3] = {
00122 { 0.412453, 0.357580, 0.180423 },
00123 { 0.212671, 0.715160, 0.072169 },
00124 { 0.019334, 0.119193, 0.950227 } };
00125 const float d65_white[3] = { 0.950456, 1, 1.088754 };
00126 #define camera_red cam_mul[0]
00127 #define camera_blue cam_mul[2]
00128 int histogram[4][0x2000];
00129 void write_ppm(FILE *);
00130 void (*write_thumb)(FILE *), (*write_fun)(FILE *);
00131 void (*load_raw)(), (*thumb_load_raw)();
00132 jmp_buf failure;
00133
00134 struct decode {
00135 struct decode *branch[2];
00136 int leaf;
00137 } first_decode[2048], *second_decode, *free_decode;
00138
00139 struct {
00140 int width, height, bps, comp, phint, offset, flip, samples, bytes;
00141 } tiff_ifd[10];
00142
00143 #define CLASS
00144
00145 #define FORC3 for (c=0; c < 3; c++)
00146 #define FORC4 for (c=0; c < 4; c++)
00147 #define FORCC for (c=0; c < colors; c++)
00148
00149 #define SQR(x) ((x)*(x))
00150 #define ABS(x) (((int)(x) ^ ((int)(x) >> 31)) - ((int)(x) >> 31))
00151 #define MIN(a,b) ((a) < (b) ? (a) : (b))
00152 #define MAX(a,b) ((a) > (b) ? (a) : (b))
00153 #define LIM(x,min,max) MAX(min,MIN(x,max))
00154 #define ULIM(x,y,z) ((y) < (z) ? LIM(x,y,z) : LIM(x,z,y))
00155 #define CLIP(x) LIM(x,0,clip_max)
00156 #define SWAP(a,b) { a ^= b; a ^= (b ^= a); }
00157
00158
00159
00160
00161
00162
00163
00164
00165 #define FC(row,col) \
00166 (filters >> ((((row) << 1 & 14) + ((col) & 1)) << 1) & 3)
00167
00168 #define BAYER(row,col) \
00169 image[((row) >> shrink)*iwidth + ((col) >> shrink)][FC(row,col)]
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201 #ifndef __GLIBC__
00202 char *my_memmem (char *haystack, size_t haystacklen,
00203 char *needle, size_t needlelen)
00204 {
00205 char *c;
00206 for (c = haystack; c <= haystack + haystacklen - needlelen; c++)
00207 if (!memcmp (c, needle, needlelen))
00208 return c;
00209 return NULL;
00210 }
00211 #define memmem my_memmem
00212 #endif
00213
00214 void CLASS merror (void *ptr, char *where)
00215 {
00216 if (ptr) return;
00217 fprintf (stderr, "%s: Out of memory in %s\n", ifname, where);
00218 longjmp (failure, 1);
00219 }
00220
00221 ushort CLASS sget2 (uchar *s)
00222 {
00223 if (order == 0x4949)
00224 return s[0] | s[1] << 8;
00225 else
00226 return s[0] << 8 | s[1];
00227 }
00228
00229 ushort CLASS get2()
00230 {
00231 uchar str[2] = { 0xff,0xff };
00232 fread (str, 1, 2, ifp);
00233 return sget2(str);
00234 }
00235
00236 int CLASS sget4 (uchar *s)
00237 {
00238 if (order == 0x4949)
00239 return s[0] | s[1] << 8 | s[2] << 16 | s[3] << 24;
00240 else
00241 return s[0] << 24 | s[1] << 16 | s[2] << 8 | s[3];
00242 }
00243 #define sget4(s) sget4((uchar *)s)
00244
00245 int CLASS get4()
00246 {
00247 uchar str[4] = { 0xff,0xff,0xff,0xff };
00248 fread (str, 1, 4, ifp);
00249 return sget4(str);
00250 }
00251
00252 int CLASS getint (int type)
00253 {
00254 return type == 3 ? get2() : get4();
00255 }
00256
00257 float CLASS int_to_float (int i)
00258 {
00259 union { int i; float f; } u;
00260 u.i = i;
00261 return u.f;
00262 }
00263
00264 double CLASS getreal (int type)
00265 {
00266 double num;
00267 switch (type) {
00268 case 3: return (unsigned short) get2();
00269 case 4: return (unsigned int) get4();
00270 case 5: num = (unsigned int) get4();
00271 return num / (unsigned int) get4();
00272 case 8: return (signed short) get2();
00273 case 9: return (signed int) get4();
00274 case 10: num = (signed int) get4();
00275 return num / (signed int) get4();
00276 case 11: return int_to_float (get4());
00277 case 12:
00278 fprintf (stderr, "%s: TIFF doubles not supported!\n", ifname);
00279 longjmp (failure, 4);
00280 default: return fgetc(ifp);
00281 }
00282 }
00283 #define getrat() getreal(10)
00284
00285 void CLASS read_shorts (ushort *pixel, int count)
00286 {
00287 fread (pixel, 2, count, ifp);
00288 if ((order == 0x4949) == (ntohs(0x1234) == 0x1234))
00289 swab (pixel, pixel, count*2);
00290 }
00291
00292 void CLASS canon_600_fixed_wb (int temp)
00293 {
00294 static const short mul[4][5] = {
00295 { 667, 358,397,565,452 },
00296 { 731, 390,367,499,517 },
00297 { 1119, 396,348,448,537 },
00298 { 1399, 485,431,508,688 } };
00299 int lo, hi, i;
00300 float frac=0;
00301
00302 for (lo=4; --lo; )
00303 if (*mul[lo] <= temp) break;
00304 for (hi=0; hi < 3; hi++)
00305 if (*mul[hi] >= temp) break;
00306 if (lo != hi)
00307 frac = (float) (temp - *mul[lo]) / (*mul[hi] - *mul[lo]);
00308 for (i=1; i < 5; i++)
00309 pre_mul[i-1] = 1 / (frac * mul[hi][i] + (1-frac) * mul[lo][i]);
00310 }
00311
00312
00313 int CLASS canon_600_color (int ratio[2], int mar)
00314 {
00315 int clipped=0, target, miss;
00316
00317 if (flash_used) {
00318 if (ratio[1] < -104)
00319 { ratio[1] = -104; clipped = 1; }
00320 if (ratio[1] > 12)
00321 { ratio[1] = 12; clipped = 1; }
00322 } else {
00323 if (ratio[1] < -264 || ratio[1] > 461) return 2;
00324 if (ratio[1] < -50)
00325 { ratio[1] = -50; clipped = 1; }
00326 if (ratio[1] > 307)
00327 { ratio[1] = 307; clipped = 1; }
00328 }
00329 target = flash_used || ratio[1] < 197
00330 ? -38 - (398 * ratio[1] >> 10)
00331 : -123 + (48 * ratio[1] >> 10);
00332 if (target - mar <= ratio[0] &&
00333 target + 20 >= ratio[0] && !clipped) return 0;
00334 miss = target - ratio[0];
00335 if (abs(miss) >= mar*4) return 2;
00336 if (miss < -20) miss = -20;
00337 if (miss > mar) miss = mar;
00338 ratio[0] = target - miss;
00339 return 1;
00340 }
00341
00342 void CLASS canon_600_auto_wb()
00343 {
00344 int mar, row, col, i, j, st, count[] = { 0,0 };
00345 int test[8], total[2][8], ratio[2][2], stat[2];
00346
00347 memset (&total, 0, sizeof total);
00348 i = canon_ev + 0.5;
00349 if (i < 10) mar = 150;
00350 else if (i > 12) mar = 20;
00351 else mar = 280 - 20 * i;
00352 if (flash_used) mar = 80;
00353 for (row=14; row < height-14; row+=4)
00354 for (col=10; col < width; col+=2) {
00355 for (i=0; i < 8; i++)
00356 test[(i & 4) + FC(row+(i >> 1),col+(i & 1))] =
00357 BAYER(row+(i >> 1),col+(i & 1));
00358 for (i=0; i < 8; i++)
00359 if (test[i] < 150 || test[i] > 1500) goto next;
00360 for (i=0; i < 4; i++)
00361 if (abs(test[i] - test[i+4]) > 50) goto next;
00362 for (i=0; i < 2; i++) {
00363 for (j=0; j < 4; j+=2)
00364 ratio[i][j >> 1] = ((test[i*4+j+1]-test[i*4+j]) << 10) / test[i*4+j];
00365 stat[i] = canon_600_color (ratio[i], mar);
00366 }
00367 if ((st = stat[0] | stat[1]) > 1) goto next;
00368 for (i=0; i < 2; i++)
00369 if (stat[i])
00370 for (j=0; j < 2; j++)
00371 test[i*4+j*2+1] = test[i*4+j*2] * (0x400 + ratio[i][j]) >> 10;
00372 for (i=0; i < 8; i++)
00373 total[st][i] += test[i];
00374 count[st]++;
00375 next: continue;
00376 }
00377 if (count[0] | count[1]) {
00378 st = count[0]*200 < count[1];
00379 for (i=0; i < 4; i++)
00380 pre_mul[i] = 1.0 / (total[st][i] + total[st][i+4]);
00381 }
00382 }
00383
00384 void CLASS canon_600_coeff()
00385 {
00386 static const short table[6][12] = {
00387 { -190,702,-1878,2390, 1861,-1349,905,-393, -432,944,2617,-2105 },
00388 { -1203,1715,-1136,1648, 1388,-876,267,245, -1641,2153,3921,-3409 },
00389 { -615,1127,-1563,2075, 1437,-925,509,3, -756,1268,2519,-2007 },
00390 { -190,702,-1886,2398, 2153,-1641,763,-251, -452,964,3040,-2528 },
00391 { -190,702,-1878,2390, 1861,-1349,905,-393, -432,944,2617,-2105 },
00392 { -807,1319,-1785,2297, 1388,-876,769,-257, -230,742,2067,-1555 } };
00393 int t=0, i, c;
00394 float mc, yc;
00395
00396 mc = pre_mul[1] / pre_mul[2];
00397 yc = pre_mul[3] / pre_mul[2];
00398 if (mc > 1 && mc <= 1.28 && yc < 0.8789) t=1;
00399 if (mc > 1.28 && mc <= 2) {
00400 if (yc < 0.8789) t=3;
00401 else if (yc <= 2) t=4;
00402 }
00403 if (flash_used) t=5;
00404 for (raw_color = i=0; i < 3; i++)
00405 FORCC rgb_cam[i][c] = table[t][i*4 + c] / 1024.0;
00406 }
00407
00408 void CLASS canon_600_load_raw()
00409 {
00410 uchar data[1120], *dp;
00411 ushort pixel[896], *pix;
00412 int irow, row, col, val;
00413 static const short mul[4][2] =
00414 { { 1141,1145 }, { 1128,1109 }, { 1178,1149 }, { 1128,1109 } };
00415
00416 for (irow=row=0; irow < height; irow++)
00417 {
00418 fread (data, 1120, 1, ifp);
00419 for (dp=data, pix=pixel; dp < data+1120; dp+=10, pix+=8)
00420 {
00421 pix[0] = (dp[0] << 2) + (dp[1] >> 6 );
00422 pix[1] = (dp[2] << 2) + (dp[1] >> 4 & 3);
00423 pix[2] = (dp[3] << 2) + (dp[1] >> 2 & 3);
00424 pix[3] = (dp[4] << 2) + (dp[1] & 3);
00425 pix[4] = (dp[5] << 2) + (dp[9] & 3);
00426 pix[5] = (dp[6] << 2) + (dp[9] >> 2 & 3);
00427 pix[6] = (dp[7] << 2) + (dp[9] >> 4 & 3);
00428 pix[7] = (dp[8] << 2) + (dp[9] >> 6 );
00429 }
00430 for (col=0; col < width; col++)
00431 BAYER(row,col) = pixel[col];
00432 for (col=width; col < 896; col++)
00433 black += pixel[col];
00434 if ((row+=2) > height) row = 1;
00435 }
00436 black = black / ((896 - width) * height) - 4;
00437 for (row=0; row < height; row++)
00438 for (col=0; col < width; col++) {
00439 val = (BAYER(row,col) - black) * mul[row & 3][col & 1] >> 9;
00440 if (val < 0) val = 0;
00441 BAYER(row,col) = val;
00442 }
00443 canon_600_fixed_wb(1311);
00444 canon_600_auto_wb();
00445 canon_600_coeff();
00446 maximum = (0x3ff - black) * 1109 >> 9;
00447 black = 0;
00448 }
00449
00450 void CLASS canon_a5_load_raw()
00451 {
00452 uchar data[1940], *dp;
00453 ushort pixel[1552], *pix;
00454 int row, col;
00455
00456 for (row=0; row < height; row++) {
00457 fread (data, raw_width * 10 / 8, 1, ifp);
00458 for (dp=data, pix=pixel; pix < pixel+raw_width; dp+=10, pix+=8)
00459 {
00460 pix[0] = (dp[1] << 2) + (dp[0] >> 6);
00461 pix[1] = (dp[0] << 4) + (dp[3] >> 4);
00462 pix[2] = (dp[3] << 6) + (dp[2] >> 2);
00463 pix[3] = (dp[2] << 8) + (dp[5] );
00464 pix[4] = (dp[4] << 2) + (dp[7] >> 6);
00465 pix[5] = (dp[7] << 4) + (dp[6] >> 4);
00466 pix[6] = (dp[6] << 6) + (dp[9] >> 2);
00467 pix[7] = (dp[9] << 8) + (dp[8] );
00468 }
00469 for (col=0; col < width; col++)
00470 BAYER(row,col) = (pixel[col] & 0x3ff);
00471 for (col=width; col < raw_width; col++)
00472 black += pixel[col] & 0x3ff;
00473 }
00474 if (raw_width > width)
00475 black /= (raw_width - width) * height;
00476 maximum = 0x3ff;
00477 }
00478
00479
00480
00481
00482
00483 unsigned CLASS getbits (int nbits)
00484 {
00485 static unsigned bitbuf=0;
00486 static int vbits=0, reset=0;
00487 unsigned c;
00488
00489 if (nbits == -1)
00490 return bitbuf = vbits = reset = 0;
00491 if (nbits == 0 || reset) return 0;
00492 while (vbits < nbits) {
00493 c = fgetc(ifp);
00494 if ((reset = zero_after_ff && c == 0xff && fgetc(ifp))) return 0;
00495 bitbuf = (bitbuf << 8) + c;
00496 vbits += 8;
00497 }
00498 vbits -= nbits;
00499 return bitbuf << (32-nbits-vbits) >> (32-nbits);
00500 }
00501
00502 void CLASS init_decoder()
00503 {
00504 memset (first_decode, 0, sizeof first_decode);
00505 free_decode = first_decode;
00506 }
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534 uchar * CLASS make_decoder (const uchar *source, int level)
00535 {
00536 struct decode *cur;
00537 static int leaf;
00538 int i, next;
00539
00540 if (level==0) leaf=0;
00541 cur = free_decode++;
00542 if (free_decode > first_decode+2048) {
00543 fprintf (stderr, "%s: decoder table overflow\n", ifname);
00544 longjmp (failure, 2);
00545 }
00546 for (i=next=0; i <= leaf && next < 16; )
00547 i += source[next++];
00548 if (i > leaf) {
00549 if (level < next) {
00550 cur->branch[0] = free_decode;
00551 make_decoder (source, level+1);
00552 cur->branch[1] = free_decode;
00553 make_decoder (source, level+1);
00554 } else
00555 cur->leaf = source[16 + leaf++];
00556 }
00557 return (uchar *) source + 16 + leaf;
00558 }
00559
00560 void CLASS crw_init_tables (unsigned table)
00561 {
00562 static const uchar first_tree[3][29] = {
00563 { 0,1,4,2,3,1,2,0,0,0,0,0,0,0,0,0,
00564 0x04,0x03,0x05,0x06,0x02,0x07,0x01,0x08,0x09,0x00,0x0a,0x0b,0xff },
00565 { 0,2,2,3,1,1,1,1,2,0,0,0,0,0,0,0,
00566 0x03,0x02,0x04,0x01,0x05,0x00,0x06,0x07,0x09,0x08,0x0a,0x0b,0xff },
00567 { 0,0,6,3,1,1,2,0,0,0,0,0,0,0,0,0,
00568 0x06,0x05,0x07,0x04,0x08,0x03,0x09,0x02,0x00,0x0a,0x01,0x0b,0xff },
00569 };
00570 static const uchar second_tree[3][180] = {
00571 { 0,2,2,2,1,4,2,1,2,5,1,1,0,0,0,139,
00572 0x03,0x04,0x02,0x05,0x01,0x06,0x07,0x08,
00573 0x12,0x13,0x11,0x14,0x09,0x15,0x22,0x00,0x21,0x16,0x0a,0xf0,
00574 0x23,0x17,0x24,0x31,0x32,0x18,0x19,0x33,0x25,0x41,0x34,0x42,
00575 0x35,0x51,0x36,0x37,0x38,0x29,0x79,0x26,0x1a,0x39,0x56,0x57,
00576 0x28,0x27,0x52,0x55,0x58,0x43,0x76,0x59,0x77,0x54,0x61,0xf9,
00577 0x71,0x78,0x75,0x96,0x97,0x49,0xb7,0x53,0xd7,0x74,0xb6,0x98,
00578 0x47,0x48,0x95,0x69,0x99,0x91,0xfa,0xb8,0x68,0xb5,0xb9,0xd6,
00579 0xf7,0xd8,0x67,0x46,0x45,0x94,0x89,0xf8,0x81,0xd5,0xf6,0xb4,
00580 0x88,0xb1,0x2a,0x44,0x72,0xd9,0x87,0x66,0xd4,0xf5,0x3a,0xa7,
00581 0x73,0xa9,0xa8,0x86,0x62,0xc7,0x65,0xc8,0xc9,0xa1,0xf4,0xd1,
00582 0xe9,0x5a,0x92,0x85,0xa6,0xe7,0x93,0xe8,0xc1,0xc6,0x7a,0x64,
00583 0xe1,0x4a,0x6a,0xe6,0xb3,0xf1,0xd3,0xa5,0x8a,0xb2,0x9a,0xba,
00584 0x84,0xa4,0x63,0xe5,0xc5,0xf3,0xd2,0xc4,0x82,0xaa,0xda,0xe4,
00585 0xf2,0xca,0x83,0xa3,0xa2,0xc3,0xea,0xc2,0xe2,0xe3,0xff,0xff },
00586 { 0,2,2,1,4,1,4,1,3,3,1,0,0,0,0,140,
00587 0x02,0x03,0x01,0x04,0x05,0x12,0x11,0x06,
00588 0x13,0x07,0x08,0x14,0x22,0x09,0x21,0x00,0x23,0x15,0x31,0x32,
00589 0x0a,0x16,0xf0,0x24,0x33,0x41,0x42,0x19,0x17,0x25,0x18,0x51,
00590 0x34,0x43,0x52,0x29,0x35,0x61,0x39,0x71,0x62,0x36,0x53,0x26,
00591 0x38,0x1a,0x37,0x81,0x27,0x91,0x79,0x55,0x45,0x28,0x72,0x59,
00592 0xa1,0xb1,0x44,0x69,0x54,0x58,0xd1,0xfa,0x57,0xe1,0xf1,0xb9,
00593 0x49,0x47,0x63,0x6a,0xf9,0x56,0x46,0xa8,0x2a,0x4a,0x78,0x99,
00594 0x3a,0x75,0x74,0x86,0x65,0xc1,0x76,0xb6,0x96,0xd6,0x89,0x85,
00595 0xc9,0xf5,0x95,0xb4,0xc7,0xf7,0x8a,0x97,0xb8,0x73,0xb7,0xd8,
00596 0xd9,0x87,0xa7,0x7a,0x48,0x82,0x84,0xea,0xf4,0xa6,0xc5,0x5a,
00597 0x94,0xa4,0xc6,0x92,0xc3,0x68,0xb5,0xc8,0xe4,0xe5,0xe6,0xe9,
00598 0xa2,0xa3,0xe3,0xc2,0x66,0x67,0x93,0xaa,0xd4,0xd5,0xe7,0xf8,
00599 0x88,0x9a,0xd7,0x77,0xc4,0x64,0xe2,0x98,0xa5,0xca,0xda,0xe8,
00600 0xf3,0xf6,0xa9,0xb2,0xb3,0xf2,0xd2,0x83,0xba,0xd3,0xff,0xff },
00601 { 0,0,6,2,1,3,3,2,5,1,2,2,8,10,0,117,
00602 0x04,0x05,0x03,0x06,0x02,0x07,0x01,0x08,
00603 0x09,0x12,0x13,0x14,0x11,0x15,0x0a,0x16,0x17,0xf0,0x00,0x22,
00604 0x21,0x18,0x23,0x19,0x24,0x32,0x31,0x25,0x33,0x38,0x37,0x34,
00605 0x35,0x36,0x39,0x79,0x57,0x58,0x59,0x28,0x56,0x78,0x27,0x41,
00606 0x29,0x77,0x26,0x42,0x76,0x99,0x1a,0x55,0x98,0x97,0xf9,0x48,
00607 0x54,0x96,0x89,0x47,0xb7,0x49,0xfa,0x75,0x68,0xb6,0x67,0x69,
00608 0xb9,0xb8,0xd8,0x52,0xd7,0x88,0xb5,0x74,0x51,0x46,0xd9,0xf8,
00609 0x3a,0xd6,0x87,0x45,0x7a,0x95,0xd5,0xf6,0x86,0xb4,0xa9,0x94,
00610 0x53,0x2a,0xa8,0x43,0xf5,0xf7,0xd4,0x66,0xa7,0x5a,0x44,0x8a,
00611 0xc9,0xe8,0xc8,0xe7,0x9a,0x6a,0x73,0x4a,0x61,0xc7,0xf4,0xc6,
00612 0x65,0xe9,0x72,0xe6,0x71,0x91,0x93,0xa6,0xda,0x92,0x85,0x62,
00613 0xf3,0xc5,0xb2,0xa4,0x84,0xba,0x64,0xa5,0xb3,0xd2,0x81,0xe5,
00614 0xd3,0xaa,0xc4,0xca,0xf2,0xb1,0xe4,0xd1,0x83,0x63,0xea,0xc3,
00615 0xe2,0x82,0xf1,0xa3,0xc2,0xa1,0xc1,0xe3,0xa2,0xe1,0xff,0xff }
00616 };
00617 if (table > 2) table = 2;
00618 init_decoder();
00619 make_decoder ( first_tree[table], 0);
00620 second_decode = free_decode;
00621 make_decoder (second_tree[table], 0);
00622 }
00623
00624
00625
00626
00627
00628
00629
00630 int CLASS canon_has_lowbits()
00631 {
00632 uchar test[0x4000];
00633 int ret=1, i;
00634
00635 fseek (ifp, 0, SEEK_SET);
00636 fread (test, 1, sizeof test, ifp);
00637 for (i=540; i < sizeof test - 1; i++)
00638 if (test[i] == 0xff) {
00639 if (test[i+1]) return 1;
00640 ret=0;
00641 }
00642 return ret;
00643 }
00644
00645 void CLASS canon_compressed_load_raw()
00646 {
00647 ushort *pixel, *prow;
00648 int lowbits, i, row, r, col, save, val;
00649 unsigned irow, icol;
00650 struct decode *decode, *dindex;
00651 int block, diffbuf[64], leaf, len, diff, carry=0, pnum=0, base[2];
00652 uchar c;
00653
00654 crw_init_tables (tiff_compress);
00655 pixel = calloc (raw_width*8, sizeof *pixel);
00656 merror (pixel, "canon_compressed_load_raw()");
00657 lowbits = canon_has_lowbits();
00658 if (!lowbits) maximum = 0x3ff;
00659 fseek (ifp, 540 + lowbits*raw_height*raw_width/4, SEEK_SET);
00660 zero_after_ff = 1;
00661 getbits(-1);
00662 for (row = 0; row < raw_height; row += 8) {
00663 for (block=0; block < raw_width >> 3; block++) {
00664 memset (diffbuf, 0, sizeof diffbuf);
00665 decode = first_decode;
00666 for (i=0; i < 64; i++ ) {
00667 for (dindex=decode; dindex->branch[0]; )
00668 dindex = dindex->branch[getbits(1)];
00669 leaf = dindex->leaf;
00670 decode = second_decode;
00671 if (leaf == 0 && i) break;
00672 if (leaf == 0xff) continue;
00673 i += leaf >> 4;
00674 len = leaf & 15;
00675 if (len == 0) continue;
00676 diff = getbits(len);
00677 if ((diff & (1 << (len-1))) == 0)
00678 diff -= (1 << len) - 1;
00679 if (i < 64) diffbuf[i] = diff;
00680 }
00681 diffbuf[0] += carry;
00682 carry = diffbuf[0];
00683 for (i=0; i < 64; i++ ) {
00684 if (pnum++ % raw_width == 0)
00685 base[0] = base[1] = 512;
00686 pixel[(block << 6) + i] = ( base[i & 1] += diffbuf[i] );
00687 }
00688 }
00689 if (lowbits) {
00690 save = ftell(ifp);
00691 fseek (ifp, 26 + row*raw_width/4, SEEK_SET);
00692 for (prow=pixel, i=0; i < raw_width*2; i++) {
00693 c = fgetc(ifp);
00694 for (r=0; r < 8; r+=2, prow++) {
00695 val = (*prow << 2) + ((c >> r) & 3);
00696 if (raw_width == 2672 && val < 512) val += 2;
00697 *prow = val;
00698 }
00699 }
00700 fseek (ifp, save, SEEK_SET);
00701 }
00702 for (r=0; r < 8; r++) {
00703 irow = row - top_margin + r;
00704 if (irow >= height) continue;
00705 for (col = 0; col < raw_width; col++) {
00706 icol = col - left_margin;
00707 if (icol < width)
00708 BAYER(irow,icol) = pixel[r*raw_width+col];
00709 else
00710 black += pixel[r*raw_width+col];
00711 }
00712 }
00713 }
00714 free (pixel);
00715 if (raw_width > width)
00716 black /= (raw_width - width) * height;
00717 }
00718
00719
00720
00721
00722
00723 struct jhead {
00724 int bits, high, wide, clrs, restart, vpred[4];
00725 struct decode *huff[4];
00726 ushort *row;
00727 };
00728
00729 int CLASS ljpeg_start (struct jhead *jh, int info_only)
00730 {
00731 int i, tag, len;
00732 uchar data[0x10000], *dp;
00733
00734 init_decoder();
00735 for (i=0; i < 4; i++)
00736 jh->huff[i] = free_decode;
00737 jh->restart = INT_MAX;
00738 fread (data, 2, 1, ifp);
00739 if (data[1] != 0xd8) return 0;
00740 do {
00741 fread (data, 2, 2, ifp);
00742 tag = data[0] << 8 | data[1];
00743 len = (data[2] << 8 | data[3]) - 2;
00744 if (tag <= 0xff00) return 0;
00745 fread (data, 1, len, ifp);
00746 switch (tag) {
00747 case 0xffc0:
00748 case 0xffc3:
00749 jh->bits = data[0];
00750 jh->high = data[1] << 8 | data[2];
00751 jh->wide = data[3] << 8 | data[4];
00752 jh->clrs = data[5];
00753 break;
00754 case 0xffc4:
00755 if (info_only) break;
00756 for (dp = data; dp < data+len && *dp < 4; ) {
00757 jh->huff[*dp] = free_decode;
00758 dp = make_decoder (++dp, 0);
00759 }
00760 break;
00761 case 0xffdd:
00762 jh->restart = data[0] << 8 | data[1];
00763 }
00764 } while (tag != 0xffda);
00765 if (info_only) return 1;
00766 jh->row = calloc (jh->wide*jh->clrs, 2);
00767 merror (jh->row, " jpeg_start()");
00768 return zero_after_ff = 1;
00769 }
00770
00771 int CLASS ljpeg_diff (struct decode *dindex)
00772 {
00773 int len, diff;
00774
00775 while (dindex->branch[0])
00776 dindex = dindex->branch[getbits(1)];
00777 len = dindex->leaf;
00778 if (len == 16 && (!dng_version || dng_version >= 0x1010000))
00779 return -32768;
00780 diff = getbits(len);
00781 if ((diff & (1 << (len-1))) == 0)
00782 diff -= (1 << len) - 1;
00783 return diff;
00784 }
00785
00786 void CLASS ljpeg_row (int jrow, struct jhead *jh)
00787 {
00788 int col, c, diff;
00789 ushort *outp=jh->row;
00790
00791 if (jrow * jh->wide % jh->restart == 0) {
00792 FORC4 jh->vpred[c] = 1 << (jh->bits-1);
00793 if (jrow) get2();
00794 getbits(-1);
00795 }
00796 for (col=0; col < jh->wide; col++)
00797 for (c=0; c < jh->clrs; c++) {
00798 diff = ljpeg_diff (jh->huff[c]);
00799 *outp = col ? outp[-jh->clrs]+diff : (jh->vpred[c] += diff);
00800 outp++;
00801 }
00802 }
00803
00804 void CLASS lossless_jpeg_load_raw()
00805 {
00806 int jwide, jrow, jcol, val, jidx, i, j, row=0, col=0;
00807 struct jhead jh;
00808 int min=INT_MAX;
00809
00810 if (!ljpeg_start (&jh, 0)) return;
00811 jwide = jh.wide * jh.clrs;
00812
00813 for (jrow=0; jrow < jh.high; jrow++) {
00814 ljpeg_row (jrow, &jh);
00815 for (jcol=0; jcol < jwide; jcol++) {
00816 val = jh.row[jcol];
00817 if (jh.bits <= 12)
00818 val = curve[val];
00819 if (cr2_slice[0]) {
00820 jidx = jrow*jwide + jcol;
00821 i = jidx / (cr2_slice[1]*jh.high);
00822 if ((j = i >= cr2_slice[0]))
00823 i = cr2_slice[0];
00824 jidx -= i * (cr2_slice[1]*jh.high);
00825 row = jidx / cr2_slice[1+j];
00826 col = jidx % cr2_slice[1+j] + i*cr2_slice[1];
00827 }
00828 if ((unsigned) (row-top_margin) < height) {
00829 if ((unsigned) (col-left_margin) < width) {
00830 BAYER(row-top_margin,col-left_margin) = val;
00831 if (min > val) min = val;
00832 } else black += val;
00833 }
00834 if (++col >= raw_width)
00835 col = (row++,0);
00836 }
00837 }
00838 free (jh.row);
00839 if (raw_width > width)
00840 black /= (raw_width - width) * height;
00841 if (!strcasecmp(make,"KODAK"))
00842 black = min;
00843 }
00844
00845 void CLASS adobe_copy_pixel (int row, int col, ushort **rp)
00846 {
00847 unsigned r, c;
00848
00849 r = row -= top_margin;
00850 c = col -= left_margin;
00851 if (fuji_secondary && use_secondary) (*rp)++;
00852 if (filters) {
00853 if (fuji_width) {
00854 r = row + fuji_width - 1 - (col >> 1);
00855 c = row + ((col+1) >> 1);
00856 }
00857 if (r < height && c < width)
00858 BAYER(r,c) = **rp < 0x1000 ? curve[**rp] : **rp;
00859 *rp += 1 + fuji_secondary;
00860 } else {
00861 if (r < height && c < width)
00862 for (c=0; c < tiff_samples; c++)
00863 image[row*width+col][c] = (*rp)[c] < 0x1000 ? curve[(*rp)[c]]:(*rp)[c];
00864 *rp += tiff_samples;
00865 }
00866 if (fuji_secondary && use_secondary) (*rp)--;
00867 }
00868
00869 void CLASS adobe_dng_load_raw_lj()
00870 {
00871 int save, twide, trow=0, tcol=0, jrow, jcol;
00872 struct jhead jh;
00873 ushort *rp;
00874
00875 while (1) {
00876 save = ftell(ifp);
00877 fseek (ifp, get4(), SEEK_SET);
00878 if (!ljpeg_start (&jh, 0)) break;
00879 if (trow >= raw_height) break;
00880 if (jh.high > raw_height-trow)
00881 jh.high = raw_height-trow;
00882 twide = jh.wide;
00883 if (filters) twide *= jh.clrs;
00884 else colors = jh.clrs;
00885 if (fuji_secondary) twide /= 2;
00886 if (twide > raw_width-tcol)
00887 twide = raw_width-tcol;
00888
00889 for (jrow=0; jrow < jh.high; jrow++) {
00890 ljpeg_row (jrow, &jh);
00891 for (rp=jh.row, jcol=0; jcol < twide; jcol++)
00892 adobe_copy_pixel (trow+jrow, tcol+jcol, &rp);
00893 }
00894 fseek (ifp, save+4, SEEK_SET);
00895 if ((tcol += twide) >= raw_width) {
00896 tcol = 0;
00897 trow += jh.high;
00898 }
00899 free (jh.row);
00900 }
00901 }
00902
00903 void CLASS adobe_dng_load_raw_nc()
00904 {
00905 ushort *pixel, *rp;
00906 int row, col;
00907
00908 pixel = calloc (raw_width * tiff_samples, sizeof *pixel);
00909 merror (pixel, "adobe_dng_load_raw_nc()");
00910 for (row=0; row < raw_height; row++) {
00911 if (tiff_bps == 16)
00912 read_shorts (pixel, raw_width * tiff_samples);
00913 else {
00914 getbits(-1);
00915 for (col=0; col < raw_width * tiff_samples; col++)
00916 pixel[col] = getbits(tiff_bps);
00917 }
00918 for (rp=pixel, col=0; col < raw_width; col++)
00919 adobe_copy_pixel (row, col, &rp);
00920 }
00921 free (pixel);
00922 }
00923
00924 void CLASS nikon_compressed_load_raw()
00925 {
00926 static const uchar nikon_tree[] = {
00927 0,1,5,1,1,1,1,1,1,2,0,0,0,0,0,0,
00928 5,4,3,6,2,7,1,0,8,9,11,10,12
00929 };
00930 int csize, row, col, i, diff;
00931 ushort vpred[4], hpred[2], *curve;
00932
00933 init_decoder();
00934 make_decoder (nikon_tree, 0);
00935
00936 fseek (ifp, curve_offset, SEEK_SET);
00937 read_shorts (vpred, 4);
00938 csize = get2();
00939 curve = calloc (csize, sizeof *curve);
00940 merror (curve, "nikon_compressed_load_raw()");
00941 read_shorts (curve, csize);
00942
00943 fseek (ifp, data_offset, SEEK_SET);
00944 getbits(-1);
00945
00946 for (row=0; row < height; row++)
00947 for (col=0; col < raw_width; col++)
00948 {
00949 diff = ljpeg_diff (first_decode);
00950 if (col < 2) {
00951 i = 2*(row & 1) + (col & 1);
00952 vpred[i] += diff;
00953 hpred[col] = vpred[i];
00954 } else
00955 hpred[col & 1] += diff;
00956 if ((unsigned) (col-left_margin) >= width) continue;
00957 diff = hpred[col & 1];
00958 if (diff >= csize) diff = csize-1;
00959 BAYER(row,col-left_margin) = curve[diff];
00960 }
00961 free (curve);
00962 }
00963
00964 void CLASS nikon_load_raw()
00965 {
00966 int irow, row, col, i;
00967
00968 getbits(-1);
00969 for (irow=0; irow < height; irow++) {
00970 row = irow;
00971 if (make[0] == 'O' || model[0] == 'E') {
00972 row = irow * 2 % height + irow / (height/2);
00973 if (row == 1 && data_offset == 0) {
00974 fseek (ifp, 0, SEEK_END);
00975 fseek (ifp, ftell(ifp)/2, SEEK_SET);
00976 getbits(-1);
00977 }
00978 }
00979 for (col=0; col < raw_width; col++) {
00980 i = getbits(12);
00981 if ((unsigned) (col-left_margin) < width)
00982 BAYER(row,col-left_margin) = i;
00983 if (tiff_compress == 34713 && (col % 10) == 9)
00984 getbits(8);
00985 }
00986 }
00987 }
00988
00989
00990
00991
00992
00993
00994 int CLASS nikon_is_compressed()
00995 {
00996 uchar test[256];
00997 int i;
00998
00999 if (tiff_compress != 34713)
01000 return 0;
01001 if (strcmp(model,"D100"))
01002 return 1;
01003 fseek (ifp, data_offset, SEEK_SET);
01004 fread (test, 1, 256, ifp);
01005 for (i=15; i < 256; i+=16)
01006 if (test[i]) return 1;
01007 return 0;
01008 }
01009
01010
01011
01012
01013 int CLASS nikon_e995()
01014 {
01015 int i, histo[256];
01016 const uchar often[] = { 0x00, 0x55, 0xaa, 0xff };
01017
01018 memset (histo, 0, sizeof histo);
01019 fseek (ifp, -2000, SEEK_END);
01020 for (i=0; i < 2000; i++)
01021 histo[fgetc(ifp)]++;
01022 for (i=0; i < 4; i++)
01023 if (histo[often[i]] < 200)
01024 return 0;
01025 return 1;
01026 }
01027
01028
01029
01030
01031 int CLASS nikon_e2100()
01032 {
01033 uchar t[12];
01034 int i;
01035
01036 fseek (ifp, 0, SEEK_SET);
01037 for (i=0; i < 1024; i++) {
01038 fread (t, 1, 12, ifp);
01039 if (((t[2] & t[4] & t[7] & t[9]) >> 4
01040 & t[1] & t[6] & t[8] & t[11] & 3) != 3)
01041 return 0;
01042 }
01043 return 1;
01044 }
01045
01046
01047
01048
01049
01050
01051 int CLASS nikon_3700()
01052 {
01053 int i, sum[] = { 0, 0 };
01054 uchar tail[952];
01055
01056 fseek (ifp, -sizeof tail, SEEK_END);
01057 fread (tail, 1, sizeof tail, ifp);
01058 for (i=0; i < sizeof tail; i++)
01059 sum[(i>>2) & 1] += tail[i];
01060 if (sum[1] > 4*sum[0]) return 2;
01061 return sum[0] > 4*sum[1];
01062 }
01063
01064
01065
01066
01067 int CLASS minolta_z2()
01068 {
01069 int i;
01070 char tail[424];
01071
01072 fseek (ifp, -sizeof tail, SEEK_END);
01073 fread (tail, 1, sizeof tail, ifp);
01074 for (i=0; i < sizeof tail; i++)
01075 if (tail[i]) return 1;
01076 return 0;
01077 }
01078
01079
01080 void CLASS nikon_e900_load_raw()
01081 {
01082 int offset=0, irow, row, col;
01083
01084 for (irow=0; irow < height; irow++) {
01085 row = irow * 2 % height;
01086 if (row == 1)
01087 offset = - (-offset & -4096);
01088 fseek (ifp, offset, SEEK_SET);
01089 offset += raw_width;
01090 getbits(-1);
01091 for (col=0; col < width; col++)
01092 BAYER(row,col) = getbits(10);
01093 }
01094 }
01095
01096 void CLASS nikon_e2100_load_raw()
01097 {
01098 uchar data[3456], *dp;
01099 ushort pixel[2304], *pix;
01100 int row, col;
01101
01102 for (row=0; row <= height; row+=2) {
01103 if (row == height) {
01104 fseek (ifp, ((width==1616) << 13) - (-ftell(ifp) & -2048), SEEK_SET);
01105 row = 1;
01106 }
01107 fread (data, 1, width*3/2, ifp);
01108 for (dp=data, pix=pixel; pix < pixel+width; dp+=12, pix+=8) {
01109 pix[0] = (dp[2] >> 4) + (dp[ 3] << 4);
01110 pix[1] = (dp[2] << 8) + dp[ 1];
01111 pix[2] = (dp[7] >> 4) + (dp[ 0] << 4);
01112 pix[3] = (dp[7] << 8) + dp[ 6];
01113 pix[4] = (dp[4] >> 4) + (dp[ 5] << 4);
01114 pix[5] = (dp[4] << 8) + dp[11];
01115 pix[6] = (dp[9] >> 4) + (dp[10] << 4);
01116 pix[7] = (dp[9] << 8) + dp[ 8];
01117 }
01118 for (col=0; col < width; col++)
01119 BAYER(row,col) = (pixel[col] & 0xfff);
01120 }
01121 }
01122
01123
01124
01125
01126 void CLASS fuji_load_raw()
01127 {
01128 ushort *pixel;
01129 int row, col, r, c;
01130
01131 pixel = calloc (raw_width, sizeof *pixel);
01132 merror (pixel, "fuji_load_raw()");
01133 for (row=0; row < raw_height; row++) {
01134 read_shorts (pixel, raw_width);
01135 for (col=0; col < fuji_width << !fuji_layout; col++) {
01136 if (fuji_layout) {
01137 r = fuji_width - 1 - col + (row >> 1);
01138 c = col + ((row+1) >> 1);
01139 } else {
01140 r = fuji_width - 1 + row - (col >> 1);
01141 c = row + ((col+1) >> 1);
01142 }
01143 BAYER(r,c) = pixel[col];
01144 }
01145 }
01146 free (pixel);
01147 }
01148
01149 void CLASS jpeg_thumb (FILE *tfp)
01150 {
01151 char *thumb = malloc (thumb_length);
01152 merror (thumb, "jpeg_thumb()");
01153 fread (thumb, 1, thumb_length, ifp);
01154 thumb[0] = 0xff;
01155 fwrite (thumb, 1, thumb_length, tfp);
01156 free (thumb);
01157 }
01158
01159 void CLASS ppm_thumb (FILE *tfp)
01160 {
01161 char *thumb = malloc (thumb_length);
01162 merror (thumb, "ppm_thumb()");
01163 fprintf (tfp, "P6\n%d %d\n255\n", thumb_width, thumb_height);
01164 fread (thumb, 1, thumb_length, ifp);
01165 fwrite (thumb, 1, thumb_length, tfp);
01166 free (thumb);
01167 }
01168
01169 void CLASS layer_thumb (FILE *tfp)
01170 {
01171 int i, c;
01172 char *thumb;
01173 colors = thumb_misc >> 5;
01174 thumb = malloc (thumb_length*colors);
01175 merror (thumb, "layer_thumb()");
01176 fprintf (tfp, "P%d\n%d %d\n255\n",
01177 5 + (thumb_misc >> 6), thumb_width, thumb_height);
01178 fread (thumb, thumb_length, colors, ifp);
01179 for (i=0; i < thumb_length; i++)
01180 FORCC putc (thumb[i+thumb_length*c], tfp);
01181 free (thumb);
01182 }
01183
01184 void CLASS rollei_thumb (FILE *tfp)
01185 {
01186 int i, size = thumb_width * thumb_height;
01187 ushort *thumb = calloc (size, 2);
01188 merror (thumb, "rollei_thumb()");
01189 fprintf (tfp, "P6\n%d %d\n255\n", thumb_width, thumb_height);
01190 read_shorts (thumb, size);
01191 for (i=0; i < size; i++) {
01192 putc (thumb[i] << 3, tfp);
01193 putc (thumb[i] >> 5 << 2, tfp);
01194 putc (thumb[i] >> 11 << 3, tfp);
01195 }
01196 free (thumb);
01197 }
01198
01199 void CLASS rollei_load_raw()
01200 {
01201 uchar pixel[10];
01202 unsigned iten=0, isix, i, buffer=0, row, col, todo[16];
01203
01204 isix = raw_width * raw_height * 5 / 8;
01205 while (fread (pixel, 1, 10, ifp) == 10) {
01206 for (i=0; i < 10; i+=2) {
01207 todo[i] = iten++;
01208 todo[i+1] = pixel[i] << 8 | pixel[i+1];
01209 buffer = pixel[i] >> 2 | buffer << 6;
01210 }
01211 for ( ; i < 16; i+=2) {
01212 todo[i] = isix++;
01213 todo[i+1] = buffer >> (14-i)*5;
01214 }
01215 for (i=0; i < 16; i+=2) {
01216 row = todo[i] / raw_width - top_margin;
01217 col = todo[i] % raw_width - left_margin;
01218 if (row < height && col < width)
01219 BAYER(row,col) = (todo[i+1] & 0x3ff);
01220 }
01221 }
01222 maximum = 0x3ff;
01223 }
01224
01225 int CLASS bayer (unsigned row, unsigned col)
01226 {
01227 return (row < height && col < width) ? BAYER(row,col) : 0;
01228 }
01229
01230 void CLASS phase_one_correct()
01231 {
01232 unsigned entries, tag, data, save, col, row, type;
01233 int len, i, j, val[4], dev[4], sum, max;
01234 static const signed char dir[12][2] =
01235 { {-1,-1}, {-1,1}, {1,-1}, {1,1}, {-2,0}, {0,-2}, {0,2}, {2,0},
01236 {-2,-2}, {-2,2}, {2,-2}, {2,2} };
01237
01238 if (!meta_length) return;
01239 fseek (ifp, meta_offset, SEEK_SET);
01240 order = get2();
01241 fseek (ifp, 6, SEEK_CUR);
01242 fseek (ifp, meta_offset+get4(), SEEK_SET);
01243 entries = get4(); get4();
01244 while (entries--) {
01245 tag = get4();
01246 len = get4();
01247 data = get4();
01248 save = ftell(ifp);
01249 fseek (ifp, meta_offset+data, SEEK_SET);
01250 if (tag == 0x400)
01251 while ((len -= 8) >= 0) {
01252 col = get2() - left_margin;
01253 row = get2() - top_margin;
01254 type = get2(); get2();
01255 if (col >= width) continue;
01256 if (type == 131)
01257 for (row=0; row < height; row++)
01258 if (FC(row,col) == 1) {
01259 for (sum=i=0; i < 4; i++)
01260 sum += val[i] = bayer (row+dir[i][0], col+dir[i][1]);
01261 for (max=i=0; i < 4; i++) {
01262 dev[i] = abs((val[i] << 2) - sum);
01263 if (dev[max] < dev[i]) max = i;
01264 }
01265 BAYER(row,col) = (sum - val[max])/3.0 + 0.5;
01266 } else {
01267 for (sum=0, i=8; i < 12; i++)
01268 sum += bayer (row+dir[i][0], col+dir[i][1]);
01269 BAYER(row,col) = 0.5 + sum * 0.0732233 +
01270 (bayer(row,col-2) + bayer(row,col+2)) * 0.3535534;
01271 }
01272 else if (type == 129) {
01273 if (row >= height) continue;
01274 j = (FC(row,col) != 1) * 4;
01275 for (sum=0, i=j; i < j+8; i++)
01276 sum += bayer (row+dir[i][0], col+dir[i][1]);
01277 BAYER(row,col) = (sum + 4) >> 3;
01278 }
01279 }
01280 fseek (ifp, save, SEEK_SET);
01281 }
01282 }
01283
01284 void CLASS phase_one_load_raw()
01285 {
01286 int row, col, a, b;
01287 ushort *pixel, akey, bkey, mask;
01288
01289 fseek (ifp, curve_offset, SEEK_SET);
01290 akey = get2();
01291 bkey = get2();
01292 mask = tiff_compress == 1 ? 0x5555:0x1354;
01293 fseek (ifp, data_offset + top_margin*raw_width*2, SEEK_SET);
01294 pixel = calloc (raw_width, sizeof *pixel);
01295 merror (pixel, "phase_one_load_raw()");
01296 for (row=0; row < height; row++) {
01297 read_shorts (pixel, raw_width);
01298 for (col=0; col < raw_width; col+=2) {
01299 a = pixel[col+0] ^ akey;
01300 b = pixel[col+1] ^ bkey;
01301 pixel[col+0] = (a & mask) | (b & ~mask);
01302 pixel[col+1] = (b & mask) | (a & ~mask);
01303 }
01304 for (col=0; col < width; col++)
01305 BAYER(row,col) = pixel[col+left_margin];
01306 }
01307 free (pixel);
01308 maximum = 0xffff;
01309 phase_one_correct();
01310 }
01311
01312 unsigned CLASS ph1_bits (int nbits)
01313 {
01314 static UINT64 bitbuf=0;
01315 static int vbits=0;
01316
01317 if (nbits == 0)
01318 return bitbuf = vbits = 0;
01319 if (vbits < nbits) {
01320 bitbuf = bitbuf << 32 | (unsigned) get4();
01321 vbits += 32;
01322 }
01323 vbits -= nbits;
01324 return bitbuf << (64 - nbits - vbits) >> (64 - nbits);
01325 }
01326
01327 void CLASS phase_one_load_raw_c()
01328 {
01329 static const int length[] = { 8,7,6,9,11,10,5,12,14,13 };
01330 int *offset, len[2], pred[2], row, col, i, j;
01331 ushort *pixel;
01332
01333 pixel = calloc (raw_width + raw_height*2, 2);
01334 merror (pixel, "phase_one_load_raw_c()");
01335 offset = (int *) (pixel + raw_width);
01336 fseek (ifp, strip_offset, SEEK_SET);
01337 for (row=0; row < raw_height; row++)
01338 offset[row] = get4();
01339 for (row=0; row < raw_height; row++) {
01340 fseek (ifp, data_offset + offset[row], SEEK_SET);
01341 ph1_bits(0);
01342 pred[0] = pred[1] = 0;
01343 for (col=0; col < raw_width; col++) {
01344 if (col >= (raw_width & -8))
01345 len[0] = len[1] = 14;
01346 else if ((col & 7) == 0)
01347 for (i=0; i < 2; i++) {
01348 for (j=0; j < 5 && !ph1_bits(1); j++);
01349 if (j--) len[i] = length[j*2 + ph1_bits(1)];
01350 }
01351 if ((i = len[col & 1]) == 14)
01352 pixel[col] = pred[col & 1] = ph1_bits(16);
01353 else
01354 pixel[col] = pred[col & 1] += ph1_bits(i) + 1 - (1 << (i - 1));
01355 }
01356 if ((unsigned) (row-top_margin) < height)
01357 for (col=0; col < width; col++)
01358 BAYER(row-top_margin,col) = pixel[col+left_margin];
01359 }
01360 free (pixel);
01361 maximum = 0x3fff;
01362 phase_one_correct();
01363 }
01364
01365 void CLASS hdr_load_raw()
01366 {
01367 ushort *pixel;
01368 int r, c, row, col;
01369
01370 pixel = calloc (raw_width, sizeof *pixel);
01371 merror (pixel, "hdr_load_raw()");
01372 for (r=0; r < height-32; r+=32)
01373 FORC3 for (row=r; row < r+32; row++) {
01374 read_shorts (pixel, raw_width);
01375 for (col=0; col < width; col++)
01376 image[row*width+col][c] = pixel[col];
01377 }
01378 free (pixel);
01379 }
01380
01381
01382 void CLASS packed_12_load_raw()
01383 {
01384 int row, col;
01385
01386 getbits(-1);
01387 for (row=0; row < height; row++) {
01388 for (col=0; col < width; col++)
01389 BAYER(row,col) = getbits(12);
01390 for (col = width*3/2; col < raw_width; col++)
01391 getbits(8);
01392 }
01393 }
01394
01395 void CLASS unpacked_load_raw()
01396 {
01397 ushort *pixel;
01398 int row, col;
01399
01400 pixel = calloc (raw_width, sizeof *pixel);
01401 merror (pixel, "unpacked_load_raw()");
01402 for (row=0; row < height; row++) {
01403 read_shorts (pixel, raw_width);
01404 for (col=0; col < width; col++)
01405 BAYER(row,col) = pixel[col];
01406 }
01407 free (pixel);
01408 }
01409
01410 void CLASS olympus_e300_load_raw()
01411 {
01412 uchar *data, *dp;
01413 ushort *pixel, *pix;
01414 int dwide, row, col, bls=width, ble=raw_width;
01415
01416 if (raw_width == 3360) bls += 4;
01417 if (raw_width == 3280) ble = bls + 8;
01418 dwide = raw_width * 16 / 10;
01419 data = malloc (dwide + raw_width*2);
01420 merror (data, "olympus_e300_load_raw()");
01421 pixel = (ushort *) (data + dwide);
01422 for (row=0; row < height; row++) {
01423 fread (data, 1, dwide, ifp);
01424 for (dp=data, pix=pixel; pix < pixel+raw_width; dp+=3, pix+=2) {
01425 if (((dp-data) & 15) == 15) dp++;
01426 pix[0] = dp[1] << 8 | dp[0];
01427 pix[1] = dp[2] << 4 | dp[1] >> 4;
01428 }
01429 for (col=0; col < width; col++)
01430 BAYER(row,col) = (pixel[col] & 0xfff);
01431 for (col=bls; col < ble; col++)
01432 black += pixel[col] & 0xfff;
01433 }
01434 if (ble > bls) black /= (ble - bls) * height;
01435 free (data);
01436 }
01437
01438 void CLASS olympus_cseries_load_raw()
01439 {
01440 int irow, row, col;
01441
01442 for (irow=0; irow < height; irow++) {
01443 row = irow * 2 % height + irow / (height/2);
01444 if (row < 2) {
01445 fseek (ifp, data_offset - row*(-width*height*3/4 & -2048), SEEK_SET);
01446 getbits(-1);
01447 }
01448 for (col=0; col < width; col++)
01449 BAYER(row,col) = getbits(12);
01450 }
01451 }
01452
01453 void CLASS minolta_rd175_load_raw()
01454 {
01455 uchar pixel[768];
01456 unsigned irow, box, row, col;
01457
01458 for (irow=0; irow < 1481; irow++) {
01459 fread (pixel, 1, 768, ifp);
01460 box = irow / 82;
01461 row = irow % 82 * 12 + ((box < 12) ? box | 1 : (box-12)*2);
01462 switch (irow) {
01463 case 1477: case 1479: continue;
01464 case 1476: row = 984; break;
01465 case 1480: row = 985; break;
01466 case 1478: row = 985; box = 1;
01467 }
01468 if ((box < 12) && (box & 1)) {
01469 for (col=0; col < 1533; col++, row ^= 1)
01470 if (col != 1) BAYER(row,col) = (col+1) & 2 ?
01471 pixel[col/2-1] + pixel[col/2+1] : pixel[col/2] << 1;
01472 BAYER(row,1) = pixel[1] << 1;
01473 BAYER(row,1533) = pixel[765] << 1;
01474 } else
01475 for (col=row & 1; col < 1534; col+=2)
01476 BAYER(row,col) = pixel[col/2] << 1;
01477 }
01478 maximum = 0xff << 1;
01479 }
01480
01481 void CLASS eight_bit_load_raw()
01482 {
01483 uchar *pixel;
01484 int row, col;
01485
01486 pixel = calloc (raw_width, sizeof *pixel);
01487 merror (pixel, "eight_bit_load_raw()");
01488 for (row=0; row < height; row++) {
01489 fread (pixel, 1, raw_width, ifp);
01490 for (col=0; col < width; col++)
01491 BAYER(row,col) = pixel[col];
01492 }
01493 free (pixel);
01494 maximum = 0xff;
01495 }
01496
01497 void CLASS casio_qv5700_load_raw()
01498 {
01499 uchar data[3232], *dp;
01500 ushort pixel[2576], *pix;
01501 int row, col;
01502
01503 for (row=0; row < height; row++) {
01504 fread (data, 1, 3232, ifp);
01505 for (dp=data, pix=pixel; dp < data+3220; dp+=5, pix+=4) {
01506 pix[0] = (dp[0] << 2) + (dp[1] >> 6);
01507 pix[1] = (dp[1] << 4) + (dp[2] >> 4);
01508 pix[2] = (dp[2] << 6) + (dp[3] >> 2);
01509 pix[3] = (dp[3] << 8) + (dp[4] );
01510 }
01511 for (col=0; col < width; col++)
01512 BAYER(row,col) = (pixel[col] & 0x3ff);
01513 }
01514 maximum = 0x3fc;
01515 }
01516
01517 void CLASS nucore_load_raw()
01518 {
01519 ushort *pixel;
01520 int irow, row, col;
01521
01522 pixel = calloc (width, 2);
01523 merror (pixel, "nucore_load_raw()");
01524 for (irow=0; irow < height; irow++) {
01525 read_shorts (pixel, width);
01526 row = irow/2 + height/2 * (irow & 1);
01527 for (col=0; col < width; col++)
01528 BAYER(row,col) = pixel[col];
01529 }
01530 free (pixel);
01531 }
01532
01533 const int * CLASS make_decoder_int (const int *source, int level)
01534 {
01535 struct decode *cur;
01536
01537 cur = free_decode++;
01538 if (level < source[0]) {
01539 cur->branch[0] = free_decode;
01540 source = make_decoder_int (source, level+1);
01541 cur->branch[1] = free_decode;
01542 source = make_decoder_int (source, level+1);
01543 } else {
01544 cur->leaf = source[1];
01545 source += 2;
01546 }
01547 return source;
01548 }
01549
01550 int CLASS radc_token (int tree)
01551 {
01552 int t;
01553 static struct decode *dstart[18], *dindex;
01554 static const int *s, source[] = {
01555 1,1, 2,3, 3,4, 4,2, 5,7, 6,5, 7,6, 7,8,
01556 1,0, 2,1, 3,3, 4,4, 5,2, 6,7, 7,6, 8,5, 8,8,
01557 2,1, 2,3, 3,0, 3,2, 3,4, 4,6, 5,5, 6,7, 6,8,
01558 2,0, 2,1, 2,3, 3,2, 4,4, 5,6, 6,7, 7,5, 7,8,
01559 2,1, 2,4, 3,0, 3,2, 3,3, 4,7, 5,5, 6,6, 6,8,
01560 2,3, 3,1, 3,2, 3,4, 3,5, 3,6, 4,7, 5,0, 5,8,
01561 2,3, 2,6, 3,0, 3,1, 4,4, 4,5, 4,7, 5,2, 5,8,
01562 2,4, 2,7, 3,3, 3,6, 4,1, 4,2, 4,5, 5,0, 5,8,
01563 2,6, 3,1, 3,3, 3,5, 3,7, 3,8, 4,0, 5,2, 5,4,
01564 2,0, 2,1, 3,2, 3,3, 4,4, 4,5, 5,6, 5,7, 4,8,
01565 1,0, 2,2, 2,-2,
01566 1,-3, 1,3,
01567 2,-17, 2,-5, 2,5, 2,17,
01568 2,-7, 2,2, 2,9, 2,18,
01569 2,-18, 2,-9, 2,-2, 2,7,
01570 2,-28, 2,28, 3,-49, 3,-9, 3,9, 4,49, 5,-79, 5,79,
01571 2,-1, 2,13, 2,26, 3,39, 4,-16, 5,55, 6,-37, 6,76,
01572 2,-26, 2,-13, 2,1, 3,-39, 4,16, 5,-55, 6,-76, 6,37
01573 };
01574
01575 if (free_decode == first_decode)
01576 for (s=source, t=0; t < 18; t++) {
01577 dstart[t] = free_decode;
01578 s = make_decoder_int (s, 0);
01579 }
01580 if (tree == 18) {
01581 if (kodak_cbpp == 243)
01582 return (getbits(6) << 2) + 2;
01583 else
01584 return (getbits(5) << 3) + 4;
01585 }
01586 for (dindex = dstart[tree]; dindex->branch[0]; )
01587 dindex = dindex->branch[getbits(1)];
01588 return dindex->leaf;
01589 }
01590
01591 #define FORYX for (y=1; y < 3; y++) for (x=col+1; x >= col; x--)
01592
01593 #define PREDICTOR (c ? (buf[c][y-1][x] + buf[c][y][x+1]) / 2 \
01594 : (buf[c][y-1][x+1] + 2*buf[c][y-1][x] + buf[c][y][x+1]) / 4)
01595
01596 void CLASS kodak_radc_load_raw()
01597 {
01598 int row, col, tree, nreps, rep, step, i, c, s, r, x, y, val;
01599 short last[3] = { 16,16,16 }, mul[3], buf[3][3][386];
01600
01601 init_decoder();
01602 getbits(-1);
01603 for (i=0; i < sizeof(buf)/sizeof(short); i++)
01604 buf[0][0][i] = 2048;
01605 for (row=0; row < height; row+=4) {
01606 FORC3 mul[c] = getbits(6);
01607 FORC3 {
01608 val = ((0x1000000/last[c] + 0x7ff) >> 12) * mul[c];
01609 s = val > 65564 ? 10:12;
01610 x = ~(-1 << (s-1));
01611 val <<= 12-s;
01612 for (i=0; i < sizeof(buf[0])/sizeof(short); i++)
01613 buf[c][0][i] = (buf[c][0][i] * val + x) >> s;
01614 last[c] = mul[c];
01615 for (r=0; r <= !c; r++) {
01616 buf[c][1][width/2] = buf[c][2][width/2] = mul[c] << 7;
01617 for (tree=1, col=width/2; col > 0; ) {
01618 if ((tree = radc_token(tree))) {
01619 col -= 2;
01620 if (tree == 8)
01621 FORYX buf[c][y][x] = radc_token(tree+10) * mul[c];
01622 else
01623 FORYX buf[c][y][x] = radc_token(tree+10) * 16 + PREDICTOR;
01624 } else
01625 do {
01626 nreps = (col > 2) ? radc_token(9) + 1 : 1;
01627 for (rep=0; rep < 8 && rep < nreps && col > 0; rep++) {
01628 col -= 2;
01629 FORYX buf[c][y][x] = PREDICTOR;
01630 if (rep & 1) {
01631 step = radc_token(10) << 4;
01632 FORYX buf[c][y][x] += step;
01633 }
01634 }
01635 } while (nreps == 9);
01636 }
01637 for (y=0; y < 2; y++)
01638 for (x=0; x < width/2; x++) {
01639 val = (buf[c][y+1][x] << 4) / mul[c];
01640 if (val < 0) val = 0;
01641 if (c)
01642 BAYER(row+y*2+c-1,x*2+2-c) = val;
01643 else
01644 BAYER(row+r*2+y,x*2+y) = val;
01645 }
01646 memcpy (buf[c][0]+!c, buf[c][2], sizeof buf[c][0]-2*!c);
01647 }
01648 }
01649 for (y=row; y < row+4; y++)
01650 for (x=0; x < width; x++)
01651 if ((x+y) & 1) {
01652 val = (BAYER(y,x)-2048)*2 + (BAYER(y,x-1)+BAYER(y,x+1))/2;
01653 if (val < 0) val = 0;
01654 BAYER(y,x) = val;
01655 }
01656 }
01657 maximum = 10000;
01658 }
01659
01660 #undef FORYX
01661 #undef PREDICTOR
01662
01663 #ifdef NO_JPEG
01664 void CLASS kodak_jpeg_load_raw() {}
01665 #else
01666
01667 METHODDEF(boolean)
01668 fill_input_buffer (j_decompress_ptr cinfo)
01669 {
01670 static uchar jpeg_buffer[4096];
01671 size_t nbytes;
01672
01673 nbytes = fread (jpeg_buffer, 1, 4096, ifp);
01674 swab (jpeg_buffer, jpeg_buffer, nbytes);
01675 cinfo->src->next_input_byte = jpeg_buffer;
01676 cinfo->src->bytes_in_buffer = nbytes;
01677 return TRUE;
01678 }
01679
01680 void CLASS kodak_jpeg_load_raw()
01681 {
01682 struct jpeg_decompress_struct cinfo;
01683 struct jpeg_error_mgr jerr;
01684 JSAMPARRAY buf;
01685 JSAMPLE (*pixel)[3];
01686 int row, col;
01687
01688 cinfo.err = jpeg_std_error (&jerr);
01689 jpeg_create_decompress (&cinfo);
01690 jpeg_stdio_src (&cinfo, ifp);
01691 cinfo.src->fill_input_buffer = fill_input_buffer;
01692 jpeg_read_header (&cinfo, TRUE);
01693 jpeg_start_decompress (&cinfo);
01694 if ((cinfo.output_width != width ) ||
01695 (cinfo.output_height*2 != height ) ||
01696 (cinfo.output_components != 3 )) {
01697 fprintf (stderr, "%s: incorrect JPEG dimensions\n", ifname);
01698 jpeg_destroy_decompress (&cinfo);
01699 longjmp (failure, 3);
01700 }
01701 buf = (*cinfo.mem->alloc_sarray)
01702 ((j_common_ptr) &cinfo, JPOOL_IMAGE, width*3, 1);
01703
01704 while (cinfo.output_scanline < cinfo.output_height) {
01705 row = cinfo.output_scanline * 2;
01706 jpeg_read_scanlines (&cinfo, buf, 1);
01707 pixel = (void *) buf[0];
01708 for (col=0; col < width; col+=2) {
01709 BAYER(row+0,col+0) = pixel[col+0][1] << 1;
01710 BAYER(row+1,col+1) = pixel[col+1][1] << 1;
01711 BAYER(row+0,col+1) = pixel[col][0] + pixel[col+1][0];
01712 BAYER(row+1,col+0) = pixel[col][2] + pixel[col+1][2];
01713 }
01714 }
01715 jpeg_finish_decompress (&cinfo);
01716 jpeg_destroy_decompress (&cinfo);
01717 maximum = 0xff << 1;
01718 }
01719 #endif
01720
01721 void CLASS kodak_dc120_load_raw()
01722 {
01723 static const int mul[4] = { 162, 192, 187, 92 };
01724 static const int add[4] = { 0, 636, 424, 212 };
01725 uchar pixel[848];
01726 int row, shift, col;
01727
01728 for (row=0; row < height; row++) {
01729 fread (pixel, 848, 1, ifp);
01730 shift = row * mul[row & 3] + add[row & 3];
01731 for (col=0; col < width; col++)
01732 BAYER(row,col) = (ushort) pixel[(col + shift) % 848];
01733 }
01734 maximum = 0xff;
01735 }
01736
01737 void CLASS kodak_easy_load_raw()
01738 {
01739 uchar *pixel;
01740 unsigned row, col, icol;
01741
01742 if (raw_width > width)
01743 black = 0;
01744 pixel = calloc (raw_width, sizeof *pixel);
01745 merror (pixel, "kodak_easy_load_raw()");
01746 for (row=0; row < height; row++) {
01747 fread (pixel, 1, raw_width, ifp);
01748 for (col=0; col < raw_width; col++) {
01749 icol = col - left_margin;
01750 if (icol < width)
01751 BAYER(row,icol) = (ushort) curve[pixel[col]];
01752 else
01753 black += curve[pixel[col]];
01754 }
01755 }
01756 free (pixel);
01757 if (raw_width > width)
01758 black /= (raw_width - width) * height;
01759 if (!strncmp(model,"DC2",3))
01760 black = 0;
01761 maximum = curve[0xff];
01762 }
01763
01764 int CLASS kodak_65000_decode (short *out, int bsize)
01765 {
01766 uchar c, blen[768];
01767 ushort raw[6];
01768 INT64 bitbuf=0;
01769 int save, bits=0, i, j, len, diff;
01770
01771 save = ftell(ifp);
01772 bsize = (bsize + 3) & -4;
01773 for (i=0; i < bsize; i+=2) {
01774 c = fgetc(ifp);
01775 if ((blen[i ] = c & 15) > 12 ||
01776 (blen[i+1] = c >> 4) > 12 ) {
01777 fseek (ifp, save, SEEK_SET);
01778 for (i=0; i < bsize; i+=8) {
01779 read_shorts (raw, 6);
01780 out[i ] = raw[0] >> 12 << 8 | raw[2] >> 12 << 4 | raw[4] >> 12;
01781 out[i+1] = raw[1] >> 12 << 8 | raw[3] >> 12 << 4 | raw[5] >> 12;
01782 for (j=0; j < 6; j++)
01783 out[i+2+j] = raw[j] & 0xfff;
01784 }
01785 return 1;
01786 }
01787 }
01788 if ((bsize & 7) == 4) {
01789 bitbuf = fgetc(ifp) << 8;
01790 bitbuf += fgetc(ifp);
01791 bits = 16;
01792 }
01793 for (i=0; i < bsize; i++) {
01794 len = blen[i];
01795 if (bits < len) {
01796 for (j=0; j < 32; j+=8)
01797 bitbuf += (INT64) fgetc(ifp) << (bits+(j^8));
01798 bits += 32;
01799 }
01800 diff = bitbuf & (0xffff >> (16-len));
01801 bitbuf >>= len;
01802 bits -= len;
01803 if ((diff & (1 << (len-1))) == 0)
01804 diff -= (1 << len) - 1;
01805 out[i] = diff;
01806 }
01807 return 0;
01808 }
01809
01810 void CLASS kodak_65000_load_raw()
01811 {
01812 short buf[256];
01813 int row, col, len, pred[2], ret, i;
01814
01815 for (row=0; row < height; row++)
01816 for (col=0; col < width; col+=256) {
01817 pred[0] = pred[1] = 0;
01818 len = MIN (256, width-col);
01819 ret = kodak_65000_decode (buf, len);
01820 for (i=0; i < len; i++)
01821 BAYER(row,col+i) = curve[ret ? buf[i] : (pred[i & 1] += buf[i])];
01822 }
01823 }
01824
01825 void CLASS kodak_ycbcr_load_raw()
01826 {
01827 short buf[384], *bp;
01828 int row, col, len, c, i, j, k, y[2][2], cb, cr, rgb[3];
01829 ushort *ip;
01830
01831 for (row=0; row < height; row+=2)
01832 for (col=0; col < width; col+=128) {
01833 len = MIN (128, width-col);
01834 kodak_65000_decode (buf, len*3);
01835 y[0][1] = y[1][1] = cb = cr = 0;
01836 for (bp=buf, i=0; i < len; i+=2, bp+=2) {
01837 cb += bp[4];
01838 cr += bp[5];
01839 rgb[1] = -((cb + cr + 2) >> 2);
01840 rgb[2] = rgb[1] + cb;
01841 rgb[0] = rgb[1] + cr;
01842 for (j=0; j < 2; j++)
01843 for (k=0; k < 2; k++) {
01844 y[j][k] = y[j][k^1] + *bp++;
01845 ip = image[(row+j)*width + col+i+k];
01846 FORC3 ip[c] = curve[LIM(y[j][k]+rgb[c], 0, 0xfff)];
01847 }
01848 }
01849 }
01850 }
01851
01852 void CLASS kodak_rgb_load_raw()
01853 {
01854 short buf[768], *bp;
01855 int row, col, len, c, i, rgb[3];
01856 ushort *ip=image[0];
01857
01858 for (row=0; row < height; row++)
01859 for (col=0; col < width; col+=256) {
01860 len = MIN (256, width-col);
01861 kodak_65000_decode (buf, len*3);
01862 memset (rgb, 0, sizeof rgb);
01863 for (bp=buf, i=0; i < len; i++, ip+=4)
01864 FORC3 ip[c] = (rgb[c] += *bp++) & 0xfff;
01865 }
01866 }
01867
01868 void CLASS kodak_thumb_load_raw()
01869 {
01870 int row, col;
01871 colors = thumb_misc >> 5;
01872 for (row=0; row < height; row++)
01873 for (col=0; col < width; col++)
01874 read_shorts (image[row*width+col], colors);
01875 maximum = (1 << (thumb_misc & 31)) - 1;
01876 }
01877
01878 void CLASS sony_decrypt (unsigned *data, int len, int start, int key)
01879 {
01880 static unsigned pad[128], p;
01881
01882 if (start) {
01883 for (p=0; p < 4; p++)
01884 pad[p] = key = key * 48828125 + 1;
01885 pad[3] = pad[3] << 1 | (pad[0]^pad[2]) >> 31;
01886 for (p=4; p < 127; p++)
01887 pad[p] = (pad[p-4]^pad[p-2]) << 1 | (pad[p-3]^pad[p-1]) >> 31;
01888 for (p=0; p < 127; p++)
01889 pad[p] = htonl(pad[p]);
01890 }
01891 while (len--)
01892 *data++ ^= pad[p++ & 127] = pad[(p+1) & 127] ^ pad[(p+65) & 127];
01893 }
01894
01895 void CLASS sony_load_raw()
01896 {
01897 uchar head[40];
01898 ushort *pixel;
01899 unsigned i, key, row, col;
01900
01901 fseek (ifp, 200896, SEEK_SET);
01902 fseek (ifp, (unsigned) fgetc(ifp)*4 - 1, SEEK_CUR);
01903 order = 0x4d4d;
01904 key = get4();
01905 fseek (ifp, 164600, SEEK_SET);
01906 fread (head, 1, 40, ifp);
01907 sony_decrypt ((void *) head, 10, 1, key);
01908 for (i=26; i-- > 22; )
01909 key = key << 8 | head[i];
01910 fseek (ifp, data_offset, SEEK_SET);
01911 pixel = calloc (raw_width, sizeof *pixel);
01912 merror (pixel, "sony_load_raw()");
01913 for (row=0; row < height; row++) {
01914 fread (pixel, 2, raw_width, ifp);
01915 sony_decrypt ((void *) pixel, raw_width/2, !row, key);
01916 for (col=9; col < left_margin; col++)
01917 black += ntohs(pixel[col]);
01918 for (col=0; col < width; col++)
01919 BAYER(row,col) = ntohs(pixel[col+left_margin]);
01920 }
01921 free (pixel);
01922 if (left_margin > 9)
01923 black /= (left_margin-9) * height;
01924 maximum = 0x3ff0;
01925 }
01926
01927 #define HOLE(row) ((holes >> (((row) - raw_height) & 7)) & 1)
01928
01929
01930 void CLASS smal_decode_segment (unsigned seg[2][2], int holes)
01931 {
01932 uchar hist[3][13] = {
01933 { 7, 7, 0, 0, 63, 55, 47, 39, 31, 23, 15, 7, 0 },
01934 { 7, 7, 0, 0, 63, 55, 47, 39, 31, 23, 15, 7, 0 },
01935 { 3, 3, 0, 0, 63, 47, 31, 15, 0 } };
01936 int low, high=0xff, carry=0, nbits=8;
01937 int s, count, bin, next, i, sym[3];
01938 uchar diff, pred[]={0,0};
01939 ushort data=0, range=0;
01940 unsigned pix, row, col;
01941
01942 fseek (ifp, seg[0][1]+1, SEEK_SET);
01943 getbits(-1);
01944 for (pix=seg[0][0]; pix < seg[1][0]; pix++) {
01945 for (s=0; s < 3; s++) {
01946 data = data << nbits | getbits(nbits);
01947 if (carry < 0)
01948 carry = (nbits += carry+1) < 1 ? nbits-1 : 0;
01949 while (--nbits >= 0)
01950 if ((data >> nbits & 0xff) == 0xff) break;
01951 if (nbits > 0)
01952 data = ((data & ((1 << (nbits-1)) - 1)) << 1) |
01953 ((data + (((data & (1 << (nbits-1)))) << 1)) & (-1 << nbits));
01954 if (nbits >= 0) {
01955 data += getbits(1);
01956 carry = nbits - 8;
01957 }
01958 count = ((((data-range+1) & 0xffff) << 2) - 1) / (high >> 4);
01959 for (bin=0; hist[s][bin+5] > count; bin++);
01960 low = hist[s][bin+5] * (high >> 4) >> 2;
01961 if (bin) high = hist[s][bin+4] * (high >> 4) >> 2;
01962 high -= low;
01963 for (nbits=0; high << nbits < 128; nbits++);
01964 range = (range+low) << nbits;
01965 high <<= nbits;
01966 next = hist[s][1];
01967 if (++hist[s][2] > hist[s][3]) {
01968 next = (next+1) & hist[s][0];
01969 hist[s][3] = (hist[s][next+4] - hist[s][next+5]) >> 2;
01970 hist[s][2] = 1;
01971 }
01972 if (hist[s][hist[s][1]+4] - hist[s][hist[s][1]+5] > 1) {
01973 if (bin < hist[s][1])
01974 for (i=bin; i < hist[s][1]; i++) hist[s][i+5]--;
01975 else if (next <= bin)
01976 for (i=hist[s][1]; i < bin; i++) hist[s][i+5]++;
01977 }
01978 hist[s][1] = next;
01979 sym[s] = bin;
01980 }
01981 diff = sym[2] << 5 | sym[1] << 2 | (sym[0] & 3);
01982 if (sym[0] & 4)
01983 diff = diff ? -diff : 0x80;
01984 if (ftell(ifp) + 12 >= seg[1][1])
01985 diff = 0;
01986 pred[pix & 1] += diff;
01987 row = pix / raw_width - top_margin;
01988 col = pix % raw_width - left_margin;
01989 if (row < height && col < width)
01990 BAYER(row,col) = pred[pix & 1];
01991 if (!(pix & 1) && HOLE(row)) pix += 2;
01992 }
01993 maximum = 0xff;
01994 }
01995
01996 void CLASS smal_v6_load_raw()
01997 {
01998 unsigned seg[2][2];
01999
02000 fseek (ifp, 16, SEEK_SET);
02001 seg[0][0] = 0;
02002 seg[0][1] = get2();
02003 seg[1][0] = raw_width * raw_height;
02004 seg[1][1] = INT_MAX;
02005 smal_decode_segment (seg, 0);
02006 use_gamma = 0;
02007 }
02008
02009 int CLASS median4 (int *p)
02010 {
02011 int min, max, sum, i;
02012
02013 min = max = sum = p[0];
02014 for (i=1; i < 4; i++) {
02015 sum += p[i];
02016 if (min > p[i]) min = p[i];
02017 if (max < p[i]) max = p[i];
02018 }
02019 return (sum - min - max) >> 1;
02020 }
02021
02022 void CLASS fill_holes (int holes)
02023 {
02024 int row, col, val[4];
02025
02026 for (row=2; row < height-2; row++) {
02027 if (!HOLE(row)) continue;
02028 for (col=1; col < width-1; col+=4) {
02029 val[0] = BAYER(row-1,col-1);
02030 val[1] = BAYER(row-1,col+1);
02031 val[2] = BAYER(row+1,col-1);
02032 val[3] = BAYER(row+1,col+1);
02033 BAYER(row,col) = median4(val);
02034 }
02035 for (col=2; col < width-2; col+=4)
02036 if (HOLE(row-2) || HOLE(row+2))
02037 BAYER(row,col) = (BAYER(row,col-2) + BAYER(row,col+2)) >> 1;
02038 else {
02039 val[0] = BAYER(row,col-2);
02040 val[1] = BAYER(row,col+2);
02041 val[2] = BAYER(row-2,col);
02042 val[3] = BAYER(row+2,col);
02043 BAYER(row,col) = median4(val);
02044 }
02045 }
02046 }
02047
02048 void CLASS smal_v9_load_raw()
02049 {
02050 unsigned seg[256][2], offset, nseg, holes, i;
02051
02052 fseek (ifp, 67, SEEK_SET);
02053 offset = get4();
02054 nseg = fgetc(ifp);
02055 fseek (ifp, offset, SEEK_SET);
02056 for (i=0; i < nseg*2; i++)
02057 seg[0][i] = get4() + data_offset*(i & 1);
02058 fseek (ifp, 78, SEEK_SET);
02059 holes = fgetc(ifp);
02060 fseek (ifp, 88, SEEK_SET);
02061 seg[nseg][0] = raw_height * raw_width;
02062 seg[nseg][1] = get4() + data_offset;
02063 for (i=0; i < nseg; i++)
02064 smal_decode_segment (seg+i, holes);
02065 if (holes) fill_holes (holes);
02066 }
02067
02068
02069
02070 void CLASS foveon_decoder (unsigned size, unsigned code)
02071 {
02072 static unsigned huff[1024];
02073 struct decode *cur;
02074 int i, len;
02075
02076 if (!code) {
02077 for (i=0; i < size; i++)
02078 huff[i] = get4();
02079 init_decoder();
02080 }
02081 cur = free_decode++;
02082 if (free_decode > first_decode+2048) {
02083 fprintf (stderr, "%s: decoder table overflow\n", ifname);
02084 longjmp (failure, 2);
02085 }
02086 if (code)
02087 for (i=0; i < size; i++)
02088 if (huff[i] == code) {
02089 cur->leaf = i;
02090 return;
02091 }
02092 if ((len = code >> 27) > 26) return;
02093 code = (len+1) << 27 | (code & 0x3ffffff) << 1;
02094
02095 cur->branch[0] = free_decode;
02096 foveon_decoder (size, code);
02097 cur->branch[1] = free_decode;
02098 foveon_decoder (size, code+1);
02099 }
02100
02101 void CLASS foveon_thumb (FILE *tfp)
02102 {
02103 int bwide, row, col, bit=-1, c, i;
02104 char *buf;
02105 struct decode *dindex;
02106 short pred[3];
02107 unsigned bitbuf=0;
02108
02109 bwide = get4();
02110 fprintf (tfp, "P6\n%d %d\n255\n", thumb_width, thumb_height);
02111 if (bwide > 0) {
02112 buf = malloc (bwide);
02113 merror (buf, "foveon_thumb()");
02114 for (row=0; row < thumb_height; row++) {
02115 fread (buf, 1, bwide, ifp);
02116 fwrite (buf, 3, thumb_width, tfp);
02117 }
02118 free (buf);
02119 return;
02120 }
02121 foveon_decoder (256, 0);
02122
02123 for (row=0; row < thumb_height; row++) {
02124 memset (pred, 0, sizeof pred);
02125 if (!bit) get4();
02126 for (col=bit=0; col < thumb_width; col++)
02127 FORC3 {
02128 for (dindex=first_decode; dindex->branch[0]; ) {
02129 if ((bit = (bit-1) & 31) == 31)
02130 for (i=0; i < 4; i++)
02131 bitbuf = (bitbuf << 8) + fgetc(ifp);
02132 dindex = dindex->branch[bitbuf >> bit & 1];
02133 }
02134 pred[c] += dindex->leaf;
02135 fputc (pred[c], tfp);
02136 }
02137 }
02138 }
02139
02140 void CLASS foveon_load_camf()
02141 {
02142 unsigned key, i, val;
02143
02144 fseek (ifp, meta_offset, SEEK_SET);
02145 key = get4();
02146 fread (meta_data, 1, meta_length, ifp);
02147 for (i=0; i < meta_length; i++) {
02148 key = (key * 1597 + 51749) % 244944;
02149 val = key * (INT64) 301593171 >> 24;
02150 meta_data[i] ^= ((((key << 8) - val) >> 1) + val) >> 17;
02151 }
02152 }
02153
02154 void CLASS foveon_load_raw()
02155 {
02156 struct decode *dindex;
02157 short diff[1024], pred[3];
02158 unsigned bitbuf=0;
02159 int fixed, row, col, bit=-1, c, i;
02160
02161 fixed = get4();
02162 read_shorts ((ushort *) diff, 1024);
02163 if (!fixed) foveon_decoder (1024, 0);
02164
02165 for (row=0; row < height; row++) {
02166 memset (pred, 0, sizeof pred);
02167 if (!bit && !fixed) get4();
02168 for (col=bit=0; col < width; col++) {
02169 if (fixed) {
02170 bitbuf = get4();
02171 FORC3 pred[2-c] += diff[bitbuf >> c*10 & 0x3ff];
02172 }
02173 else FORC3 {
02174 for (dindex=first_decode; dindex->branch[0]; ) {
02175 if ((bit = (bit-1) & 31) == 31)
02176 for (i=0; i < 4; i++)
02177 bitbuf = (bitbuf << 8) + fgetc(ifp);
02178 dindex = dindex->branch[bitbuf >> bit & 1];
02179 }
02180 pred[c] += diff[dindex->leaf];
02181 }
02182 FORC3 image[row*width+col][c] = pred[c];
02183 }
02184 }
02185 if (document_mode)
02186 for (i=0; i < height*width*4; i++)
02187 if ((short) image[0][i] < 0) image[0][i] = 0;
02188 foveon_load_camf();
02189 clip_max = 0xffff;
02190 }
02191
02192 char * CLASS foveon_camf_param (char *block, char *param)
02193 {
02194 unsigned idx, num;
02195 char *pos, *cp, *dp;
02196
02197 for (idx=0; idx < meta_length; idx += sget4(pos+8)) {
02198 pos = meta_data + idx;
02199 if (strncmp (pos, "CMb", 3)) break;
02200 if (pos[3] != 'P') continue;
02201 if (strcmp (block, pos+sget4(pos+12))) continue;
02202 cp = pos + sget4(pos+16);
02203 num = sget4(cp);
02204 dp = pos + sget4(cp+4);
02205 while (num--) {
02206 cp += 8;
02207 if (!strcmp (param, dp+sget4(cp)))
02208 return dp+sget4(cp+4);
02209 }
02210 }
02211 return NULL;
02212 }
02213
02214 void * CLASS foveon_camf_matrix (int dim[3], char *name)
02215 {
02216 unsigned i, idx, type, ndim, size, *mat;
02217 char *pos, *cp, *dp;
02218
02219 for (idx=0; idx < meta_length; idx += sget4(pos+8)) {
02220 pos = meta_data + idx;
02221 if (strncmp (pos, "CMb", 3)) break;
02222 if (pos[3] != 'M') continue;
02223 if (strcmp (name, pos+sget4(pos+12))) continue;
02224 dim[0] = dim[1] = dim[2] = 1;
02225 cp = pos + sget4(pos+16);
02226 type = sget4(cp);
02227 if ((ndim = sget4(cp+4)) > 3) break;
02228 dp = pos + sget4(cp+8);
02229 for (i=ndim; i--; ) {
02230 cp += 12;
02231 dim[i] = sget4(cp);
02232 }
02233 if ((size = dim[0]*dim[1]*dim[2]) > meta_length/4) break;
02234 mat = malloc (size * 4);
02235 merror (mat, "foveon_camf_matrix()");
02236 for (i=0; i < size; i++)
02237 if (type && type != 6)
02238 mat[i] = sget4(dp + i*4);
02239 else
02240 mat[i] = sget4(dp + i*2) & 0xffff;
02241 return mat;
02242 }
02243 fprintf (stderr, "%s: \"%s\" matrix not found!\n", ifname, name);
02244 return NULL;
02245 }
02246
02247 int CLASS foveon_fixed (void *ptr, int size, char *name)
02248 {
02249 void *dp;
02250 int dim[3];
02251
02252 dp = foveon_camf_matrix (dim, name);
02253 if (!dp) return 0;
02254 memcpy (ptr, dp, size*4);
02255 free (dp);
02256 return 1;
02257 }
02258
02259 float CLASS foveon_avg (short *pix, int range[2], float cfilt)
02260 {
02261 int i;
02262 float val, min=FLT_MAX, max=-FLT_MAX, sum=0;
02263
02264 for (i=range[0]; i <= range[1]; i++) {
02265 sum += val = pix[i*4] + (pix[i*4]-pix[(i-1)*4]) * cfilt;
02266 if (min > val) min = val;
02267 if (max < val) max = val;
02268 }
02269 return (sum - min - max) / (range[1] - range[0] - 1);
02270 }
02271
02272 short * CLASS foveon_make_curve (double max, double mul, double filt)
02273 {
02274 short *curve;
02275 int i, size;
02276 double x;
02277
02278 if (!filt) filt = 0.8;
02279 size = 4*M_PI*max / filt;
02280 curve = calloc (size+1, sizeof *curve);
02281 merror (curve, "foveon_make_curve()");
02282 curve[0] = size;
02283 for (i=0; i < size; i++) {
02284 x = i*filt/max/4;
02285 curve[i+1] = (cos(x)+1)/2 * tanh(i*filt/mul) * mul + 0.5;
02286 }
02287 return curve;
02288 }
02289
02290 void CLASS foveon_make_curves
02291 (short **curvep, float dq[3], float div[3], float filt)
02292 {
02293 double mul[3], max=0;
02294 int c;
02295
02296 FORC3 mul[c] = dq[c]/div[c];
02297 FORC3 if (max < mul[c]) max = mul[c];
02298 FORC3 curvep[c] = foveon_make_curve (max, mul[c], filt);
02299 }
02300
02301 int CLASS foveon_apply_curve (short *curve, int i)
02302 {
02303 if (abs(i) >= curve[0]) return 0;
02304 return i < 0 ? -curve[1-i] : curve[1+i];
02305 }
02306
02307 #define image ((short (*)[4]) image)
02308
02309 void CLASS foveon_interpolate()
02310 {
02311 static const short hood[] = { -1,-1, -1,0, -1,1, 0,-1, 0,1, 1,-1, 1,0, 1,1 };
02312 short *pix, prev[3], *curve[8], (*shrink)[3];
02313 float cfilt=0, ddft[3][3][2], ppm[3][3][3];
02314 float cam_xyz[3][3], correct[3][3], last[3][3], trans[3][3];
02315 float chroma_dq[3], color_dq[3], diag[3][3], div[3];
02316 float (*black)[3], (*sgain)[3], (*sgrow)[3];
02317 float fsum[3], val, frow, num;
02318 int row, col, c, i, j, diff, sgx, irow, sum, min, max, limit;
02319 int dim[3], dscr[2][2], dstb[4], (*smrow[7])[3], total[4], ipix[3];
02320 int work[3][3], smlast, smred, smred_p=0, dev[3];
02321 int satlev[3], keep[4], active[4];
02322 unsigned *badpix;
02323 double dsum=0, trsum[3];
02324 char str[128], *cp;
02325
02326 if (verbose)
02327 fprintf (stderr, "Foveon interpolation...\n");
02328
02329 foveon_fixed (dscr, 4, "DarkShieldColRange");
02330 foveon_fixed (ppm[0][0], 27, "PostPolyMatrix");
02331 foveon_fixed (satlev, 3, "SaturationLevel");
02332 foveon_fixed (keep, 4, "KeepImageArea");
02333 foveon_fixed (active, 4, "ActiveImageArea");
02334 foveon_fixed (chroma_dq, 3, "ChromaDQ");
02335 foveon_fixed (color_dq, 3,
02336 foveon_camf_param ("IncludeBlocks", "ColorDQ") ?
02337 "ColorDQ" : "ColorDQCamRGB");
02338 if (foveon_camf_param ("IncludeBlocks", "ColumnFilter"))
02339 foveon_fixed (&cfilt, 1, "ColumnFilter");
02340
02341 memset (ddft, 0, sizeof ddft);
02342 if (!foveon_camf_param ("IncludeBlocks", "DarkDrift")
02343 || !foveon_fixed (ddft[1][0], 12, "DarkDrift"))
02344 for (i=0; i < 2; i++) {
02345 foveon_fixed (dstb, 4, i ? "DarkShieldBottom":"DarkShieldTop");
02346 for (row = dstb[1]; row <= dstb[3]; row++)
02347 for (col = dstb[0]; col <= dstb[2]; col++)
02348 FORC3 ddft[i+1][c][1] += (short) image[row*width+col][c];
02349 FORC3 ddft[i+1][c][1] /= (dstb[3]-dstb[1]+1) * (dstb[2]-dstb[0]+1);
02350 }
02351
02352 if (!(cp = foveon_camf_param ("WhiteBalanceIlluminants", model2)))
02353 { fprintf (stderr, "%s: Invalid white balance \"%s\"\n", ifname, model2);
02354 return; }
02355 foveon_fixed (cam_xyz, 9, cp);
02356 foveon_fixed (correct, 9,
02357 foveon_camf_param ("WhiteBalanceCorrections", model2));
02358 memset (last, 0, sizeof last);
02359 for (i=0; i < 3; i++)
02360 for (j=0; j < 3; j++)
02361 FORC3 last[i][j] += correct[i][c] * cam_xyz[c][j];
02362
02363 sprintf (str, "%sRGBNeutral", model2);
02364 if (foveon_camf_param ("IncludeBlocks", str))
02365 foveon_fixed (div, 3, str);
02366 else {
02367 #define LAST(x,y) last[(i+x)%3][(c+y)%3]
02368 for (i=0; i < 3; i++)
02369 FORC3 diag[c][i] = LAST(1,1)*LAST(2,2) - LAST(1,2)*LAST(2,1);
02370 #undef LAST
02371 FORC3 div[c] = diag[c][0]*0.3127 + diag[c][1]*0.329 + diag[c][2]*0.3583;
02372 }
02373 num = 0;
02374 FORC3 if (num < div[c]) num = div[c];
02375 FORC3 div[c] /= num;
02376
02377 memset (trans, 0, sizeof trans);
02378 for (i=0; i < 3; i++)
02379 for (j=0; j < 3; j++)
02380 FORC3 trans[i][j] += rgb_cam[i][c] * last[c][j] * div[j];
02381 FORC3 trsum[c] = trans[c][0] + trans[c][1] + trans[c][2];
02382 dsum = (6*trsum[0] + 11*trsum[1] + 3*trsum[2]) / 20;
02383 for (i=0; i < 3; i++)
02384 FORC3 last[i][c] = trans[i][c] * dsum / trsum[i];
02385 memset (trans, 0, sizeof trans);
02386 for (i=0; i < 3; i++)
02387 for (j=0; j < 3; j++)
02388 FORC3 trans[i][j] += (i==c ? 32 : -1) * last[c][j] / 30;
02389
02390 foveon_make_curves (curve, color_dq, div, cfilt);
02391 FORC3 chroma_dq[c] /= 3;
02392 foveon_make_curves (curve+3, chroma_dq, div, cfilt);
02393 FORC3 dsum += chroma_dq[c] / div[c];
02394 curve[6] = foveon_make_curve (dsum, dsum, cfilt);
02395 curve[7] = foveon_make_curve (dsum*2, dsum*2, cfilt);
02396
02397 sgain = foveon_camf_matrix (dim, "SpatialGain");
02398 if (!sgain) return;
02399 sgrow = calloc (dim[1], sizeof *sgrow);
02400 sgx = (width + dim[1]-2) / (dim[1]-1);
02401
02402 black = calloc (height, sizeof *black);
02403 for (row=0; row < height; row++) {
02404 for (i=0; i < 6; i++)
02405 ddft[0][0][i] = ddft[1][0][i] +
02406 row / (height-1.0) * (ddft[2][0][i] - ddft[1][0][i]);
02407 FORC3 black[row][c] =
02408 ( foveon_avg (image[row*width]+c, dscr[0], cfilt) +
02409 foveon_avg (image[row*width]+c, dscr[1], cfilt) * 3
02410 - ddft[0][c][0] ) / 4 - ddft[0][c][1];
02411 }
02412 memcpy (black, black+8, sizeof *black*8);
02413 memcpy (black+height-11, black+height-22, 11*sizeof *black);
02414 memcpy (last, black, sizeof last);
02415
02416 for (row=1; row < height-1; row++) {
02417 FORC3 if (last[1][c] > last[0][c]) {
02418 if (last[1][c] > last[2][c])
02419 black[row][c] = (last[0][c] > last[2][c]) ? last[0][c]:last[2][c];
02420 } else
02421 if (last[1][c] < last[2][c])
02422 black[row][c] = (last[0][c] < last[2][c]) ? last[0][c]:last[2][c];
02423 memmove (last, last+1, 2*sizeof last[0]);
02424 memcpy (last[2], black[row+1], sizeof last[2]);
02425 }
02426 FORC3 black[row][c] = (last[0][c] + last[1][c])/2;
02427 FORC3 black[0][c] = (black[1][c] + black[3][c])/2;
02428
02429 val = 1 - exp(-1/24.0);
02430 memcpy (fsum, black, sizeof fsum);
02431 for (row=1; row < height; row++)
02432 FORC3 fsum[c] += black[row][c] =
02433 (black[row][c] - black[row-1][c])*val + black[row-1][c];
02434 memcpy (last[0], black[height-1], sizeof last[0]);
02435 FORC3 fsum[c] /= height;
02436 for (row = height; row--; )
02437 FORC3 last[0][c] = black[row][c] =
02438 (black[row][c] - fsum[c] - last[0][c])*val + last[0][c];
02439
02440 memset (total, 0, sizeof total);
02441 for (row=2; row < height; row+=4)
02442 for (col=2; col < width; col+=4) {
02443 FORC3 total[c] += (short) image[row*width+col][c];
02444 total[3]++;
02445 }
02446 for (row=0; row < height; row++)
02447 FORC3 black[row][c] += fsum[c]/2 + total[c]/(total[3]*100.0);
02448
02449 for (row=0; row < height; row++) {
02450 for (i=0; i < 6; i++)
02451 ddft[0][0][i] = ddft[1][0][i] +
02452 row / (height-1.0) * (ddft[2][0][i] - ddft[1][0][i]);
02453 pix = image[row*width];
02454 memcpy (prev, pix, sizeof prev);
02455 frow = row / (height-1.0) * (dim[2]-1);
02456 if ((irow = frow) == dim[2]-1) irow--;
02457 frow -= irow;
02458 for (i=0; i < dim[1]; i++)
02459 FORC3 sgrow[i][c] = sgain[ irow *dim[1]+i][c] * (1-frow) +
02460 sgain[(irow+1)*dim[1]+i][c] * frow;
02461 for (col=0; col < width; col++) {
02462 FORC3 {
02463 diff = pix[c] - prev[c];
02464 prev[c] = pix[c];
02465 ipix[c] = pix[c] + floor ((diff + (diff*diff >> 14)) * cfilt
02466 - ddft[0][c][1] - ddft[0][c][0] * ((float) col/width - 0.5)
02467 - black[row][c] );
02468 }
02469 FORC3 {
02470 work[0][c] = ipix[c] * ipix[c] >> 14;
02471 work[2][c] = ipix[c] * work[0][c] >> 14;
02472 work[1][2-c] = ipix[(c+1) % 3] * ipix[(c+2) % 3] >> 14;
02473 }
02474 FORC3 {
02475 for (val=i=0; i < 3; i++)
02476 for ( j=0; j < 3; j++)
02477 val += ppm[c][i][j] * work[i][j];
02478 ipix[c] = floor ((ipix[c] + floor(val)) *
02479 ( sgrow[col/sgx ][c] * (sgx - col%sgx) +
02480 sgrow[col/sgx+1][c] * (col%sgx) ) / sgx / div[c]);
02481 if (ipix[c] > 32000) ipix[c] = 32000;
02482 pix[c] = ipix[c];
02483 }
02484 pix += 4;
02485 }
02486 }
02487 free (black);
02488 free (sgrow);
02489 free (sgain);
02490
02491 if ((badpix = foveon_camf_matrix (dim, "BadPixels"))) {
02492 for (i=0; i < dim[0]; i++) {
02493 col = (badpix[i] >> 8 & 0xfff) - keep[0];
02494 row = (badpix[i] >> 20 ) - keep[1];
02495 if ((unsigned)(row-1) > height-3 || (unsigned)(col-1) > width-3)
02496 continue;
02497 memset (fsum, 0, sizeof fsum);
02498 for (sum=j=0; j < 8; j++)
02499 if (badpix[i] & (1 << j)) {
02500 FORC3 fsum[c] += (short)
02501 image[(row+hood[j*2])*width+col+hood[j*2+1]][c];
02502 sum++;
02503 }
02504 if (sum) FORC3 image[row*width+col][c] = fsum[c]/sum;
02505 }
02506 free (badpix);
02507 }
02508
02509
02510 smrow[6] = calloc (width*5, sizeof **smrow);
02511 merror (smrow[6], "foveon_interpolate()");
02512 for (i=0; i < 5; i++)
02513 smrow[i] = smrow[6] + i*width;
02514
02515
02516 for (smlast=-1, row=2; row < height-2; row++) {
02517 while (smlast < row+2) {
02518 for (i=0; i < 6; i++)
02519 smrow[(i+5) % 6] = smrow[i];
02520 pix = image[++smlast*width+2];
02521 for (col=2; col < width-2; col++) {
02522 smrow[4][col][0] =
02523 (pix[0]*6 + (pix[-4]+pix[4])*4 + pix[-8]+pix[8] + 8) >> 4;
02524 pix += 4;
02525 }
02526 }
02527 pix = image[row*width+2];
02528 for (col=2; col < width-2; col++) {
02529 smred = ( 6 * smrow[2][col][0]
02530 + 4 * (smrow[1][col][0] + smrow[3][col][0])
02531 + smrow[0][col][0] + smrow[4][col][0] + 8 ) >> 4;
02532 if (col == 2)
02533 smred_p = smred;
02534 i = pix[0] + ((pix[0] - ((smred*7 + smred_p) >> 3)) >> 3);
02535 if (i > 32000) i = 32000;
02536 pix[0] = i;
02537 smred_p = smred;
02538 pix += 4;
02539 }
02540 }
02541
02542
02543 min = 0xffff;
02544 FORC3 {
02545 i = satlev[c] / div[c];
02546 if (min > i) min = i;
02547 }
02548 limit = min * 9 >> 4;
02549 for (pix=image[0]; pix < image[height*width]; pix+=4) {
02550 if (pix[0] <= limit || pix[1] <= limit || pix[2] <= limit)
02551 continue;
02552 min = max = pix[0];
02553 for (c=1; c < 3; c++) {
02554 if (min > pix[c]) min = pix[c];
02555 if (max < pix[c]) max = pix[c];
02556 }
02557 if (min >= limit*2) {
02558 pix[0] = pix[1] = pix[2] = max;
02559 } else {
02560 i = 0x4000 - ((min - limit) << 14) / limit;
02561 i = 0x4000 - (i*i >> 14);
02562 i = i*i >> 14;
02563 FORC3 pix[c] += (max - pix[c]) * i >> 14;
02564 }
02565 }
02566
02567
02568
02569
02570
02571 for (smlast=-1, row=2; row < height-2; row++) {
02572 while (smlast < row+2) {
02573 for (i=0; i < 6; i++)
02574 smrow[(i+5) % 6] = smrow[i];
02575 pix = image[++smlast*width+2];
02576 for (col=2; col < width-2; col++) {
02577 FORC3 smrow[4][col][c] = (pix[c-4]+2*pix[c]+pix[c+4]+2) >> 2;
02578 pix += 4;
02579 }
02580 }
02581 pix = image[row*width+2];
02582 for (col=2; col < width-2; col++) {
02583 FORC3 dev[c] = -foveon_apply_curve (curve[7], pix[c] -
02584 ((smrow[1][col][c] + 2*smrow[2][col][c] + smrow[3][col][c]) >> 2));
02585 sum = (dev[0] + dev[1] + dev[2]) >> 3;
02586 FORC3 pix[c] += dev[c] - sum;
02587 pix += 4;
02588 }
02589 }
02590 for (smlast=-1, row=2; row < height-2; row++) {
02591 while (smlast < row+2) {
02592 for (i=0; i < 6; i++)
02593 smrow[(i+5) % 6] = smrow[i];
02594 pix = image[++smlast*width+2];
02595 for (col=2; col < width-2; col++) {
02596 FORC3 smrow[4][col][c] =
02597 (pix[c-8]+pix[c-4]+pix[c]+pix[c+4]+pix[c+8]+2) >> 2;
02598 pix += 4;
02599 }
02600 }
02601 pix = image[row*width+2];
02602 for (col=2; col < width-2; col++) {
02603 for (total[3]=375, sum=60, c=0; c < 3; c++) {
02604 for (total[c]=i=0; i < 5; i++)
02605 total[c] += smrow[i][col][c];
02606 total[3] += total[c];
02607 sum += pix[c];
02608 }
02609 if (sum < 0) sum = 0;
02610 j = total[3] > 375 ? (sum << 16) / total[3] : sum * 174;
02611 FORC3 pix[c] += foveon_apply_curve (curve[6],
02612 ((j*total[c] + 0x8000) >> 16) - pix[c]);
02613 pix += 4;
02614 }
02615 }
02616
02617
02618 for (pix=image[0]; pix < image[height*width]; pix+=4) {
02619 FORC3 pix[c] -= foveon_apply_curve (curve[c], pix[c]);
02620 sum = (pix[0]+pix[1]+pix[1]+pix[2]) >> 2;
02621 FORC3 pix[c] -= foveon_apply_curve (curve[c], pix[c]-sum);
02622 FORC3 {
02623 for (dsum=i=0; i < 3; i++)
02624 dsum += trans[c][i] * pix[i];
02625 if (dsum < 0) dsum = 0;
02626 if (dsum > 24000) dsum = 24000;
02627 ipix[c] = dsum + 0.5;
02628 }
02629 FORC3 pix[c] = ipix[c];
02630 }
02631
02632
02633 shrink = calloc ((width/4) * (height/4), sizeof *shrink);
02634 merror (shrink, "foveon_interpolate()");
02635 for (row = height/4; row--; )
02636 for (col=0; col < width/4; col++) {
02637 ipix[0] = ipix[1] = ipix[2] = 0;
02638 for (i=0; i < 4; i++)
02639 for (j=0; j < 4; j++)
02640 FORC3 ipix[c] += image[(row*4+i)*width+col*4+j][c];
02641 FORC3
02642 if (row+2 > height/4)
02643 shrink[row*(width/4)+col][c] = ipix[c] >> 4;
02644 else
02645 shrink[row*(width/4)+col][c] =
02646 (shrink[(row+1)*(width/4)+col][c]*1840 + ipix[c]*141 + 2048) >> 12;
02647 }
02648
02649 for (row=0; row < (height & ~3); row++) {
02650 ipix[0] = ipix[1] = ipix[2] = 0;
02651 if ((row & 3) == 0)
02652 for (col = width & ~3 ; col--; )
02653 FORC3 smrow[0][col][c] = ipix[c] =
02654 (shrink[(row/4)*(width/4)+col/4][c]*1485 + ipix[c]*6707 + 4096) >> 13;
02655
02656
02657 ipix[0] = ipix[1] = ipix[2] = 0;
02658 for (col=0; col < (width & ~3); col++)
02659 FORC3 smrow[1][col][c] = ipix[c] =
02660 (smrow[0][col][c]*1485 + ipix[c]*6707 + 4096) >> 13;
02661
02662
02663 if (row == 0)
02664 memcpy (smrow[2], smrow[1], sizeof **smrow * width);
02665 else
02666 for (col=0; col < (width & ~3); col++)
02667 FORC3 smrow[2][col][c] =
02668 (smrow[2][col][c]*6707 + smrow[1][col][c]*1485 + 4096) >> 13;
02669
02670
02671 for (col=0; col < (width & ~3); col++) {
02672 for (i=j=30, c=0; c < 3; c++) {
02673 i += smrow[2][col][c];
02674 j += image[row*width+col][c];
02675 }
02676 j = (j << 16) / i;
02677 for (sum=c=0; c < 3; c++) {
02678 ipix[c] = foveon_apply_curve (curve[c+3],
02679 ((smrow[2][col][c] * j + 0x8000) >> 16) - image[row*width+col][c]);
02680 sum += ipix[c];
02681 }
02682 sum >>= 3;
02683 FORC3 {
02684 i = image[row*width+col][c] + ipix[c] - sum;
02685 if (i < 0) i = 0;
02686 image[row*width+col][c] = i;
02687 }
02688 }
02689 }
02690 free (shrink);
02691 free (smrow[6]);
02692 for (i=0; i < 8; i++)
02693 free (curve[i]);
02694
02695
02696 active[1] -= keep[1];
02697 active[3] -= 2;
02698 i = active[2] - active[0];
02699 for (row = 0; row < active[3]-active[1]; row++)
02700 memcpy (image[row*i], image[(row+active[1])*width+active[0]],
02701 i * sizeof *image);
02702 width = i;
02703 height = row;
02704 }
02705 #undef image
02706
02707
02708
02709
02710
02711
02712
02713 void CLASS bad_pixels()
02714 {
02715 FILE *fp=NULL;
02716 char *fname, *cp, line[128];
02717 int len, time, row, col, r, c, rad, tot, n, fixed=0;
02718
02719 if (!filters) return;
02720 for (len=32 ; ; len *= 2) {
02721 fname = malloc (len);
02722 if (!fname) return;
02723 if (getcwd (fname, len-16)) break;
02724 free (fname);
02725 if (errno != ERANGE) return;
02726 }
02727 #if defined(WIN32) || defined(DJGPP)
02728 if (fname[1] == ':')
02729 memmove (fname, fname+2, len-2);
02730 for (cp=fname; *cp; cp++)
02731 if (*cp == '\\') *cp = '/';
02732 #endif
02733 cp = fname + strlen(fname);
02734 if (cp[-1] == '/') cp--;
02735 while (*fname == '/') {
02736 strcpy (cp, "/.badpixels");
02737 if ((fp = fopen (fname, "r"))) break;
02738 if (cp == fname) break;
02739 while (*--cp != '/');
02740 }
02741 free (fname);
02742 if (!fp) return;
02743 while (fgets (line, 128, fp)) {
02744 cp = strchr (line, '#');
02745 if (cp) *cp = 0;
02746 if (sscanf (line, "%d %d %d", &col, &row, &time) != 3) continue;
02747 if ((unsigned) col >= width || (unsigned) row >= height) continue;
02748 if (time > timestamp) continue;
02749 for (tot=n=0, rad=1; rad < 3 && n==0; rad++)
02750 for (r = row-rad; r <= row+rad; r++)
02751 for (c = col-rad; c <= col+rad; c++)
02752 if ((unsigned) r < height && (unsigned) c < width &&
02753 (r != row || c != col) && FC(r,c) == FC(row,col)) {
02754 tot += BAYER(r,c);
02755 n++;
02756 }
02757 BAYER(row,col) = tot/n;
02758 if (verbose) {
02759 if (!fixed++)
02760 fprintf (stderr, "Fixed bad pixels at:");
02761 fprintf (stderr, " %d,%d", col, row);
02762 }
02763 }
02764 if (fixed) fputc ('\n', stderr);
02765 fclose (fp);
02766 }
02767
02768 void CLASS pseudoinverse (double (*in)[3], double (*out)[3], int size)
02769 {
02770 double work[3][6], num;
02771 int i, j, k;
02772
02773 for (i=0; i < 3; i++) {
02774 for (j=0; j < 6; j++)
02775 work[i][j] = j == i+3;
02776 for (j=0; j < 3; j++)
02777 for (k=0; k < size; k++)
02778 work[i][j] += in[k][i] * in[k][j];
02779 }
02780 for (i=0; i < 3; i++) {
02781 num = work[i][i];
02782 for (j=0; j < 6; j++)
02783 work[i][j] /= num;
02784 for (k=0; k < 3; k++) {
02785 if (k==i) continue;
02786 num = work[k][i];
02787 for (j=0; j < 6; j++)
02788 work[k][j] -= work[i][j] * num;
02789 }
02790 }
02791 for (i=0; i < size; i++)
02792 for (j=0; j < 3; j++)
02793 for (out[i][j]=k=0; k < 3; k++)
02794 out[i][j] += work[j][k+3] * in[i][k];
02795 }
02796
02797 void CLASS cam_xyz_coeff (double cam_xyz[4][3])
02798 {
02799 double cam_rgb[4][3], inverse[4][3], num;
02800 int i, j, k;
02801
02802 for (i=0; i < colors; i++)
02803 for (j=0; j < 3; j++)
02804 for (cam_rgb[i][j] = k=0; k < 3; k++)
02805 cam_rgb[i][j] += cam_xyz[i][k] * xyz_rgb[k][j];
02806
02807 for (i=0; i < colors; i++) {
02808 for (num=j=0; j < 3; j++)
02809 num += cam_rgb[i][j];
02810 for (j=0; j < 3; j++)
02811 cam_rgb[i][j] /= num;
02812 pre_mul[i] = 1 / num;
02813 }
02814 pseudoinverse (cam_rgb, inverse, colors);
02815 for (raw_color = i=0; i < 3; i++)
02816 for (j=0; j < colors; j++)
02817 rgb_cam[i][j] = inverse[j][i];
02818 }
02819
02820 #ifdef COLORCHECK
02821 void CLASS colorcheck()
02822 {
02823 #define NSQ 24
02824
02825
02826 static const int cut[NSQ][4] = {
02827 { 241, 231, 234, 274 },
02828 { 251, 235, 534, 274 },
02829 { 255, 239, 838, 272 },
02830 { 255, 240, 1146, 274 },
02831 { 251, 237, 1452, 278 },
02832 { 243, 238, 1758, 288 },
02833 { 253, 253, 218, 558 },
02834 { 255, 249, 524, 562 },
02835 { 261, 253, 830, 562 },
02836 { 260, 255, 1144, 564 },
02837 { 261, 255, 1450, 566 },
02838 { 247, 247, 1764, 576 },
02839 { 255, 251, 212, 862 },
02840 { 259, 259, 518, 862 },
02841 { 263, 261, 826, 864 },
02842 { 265, 263, 1138, 866 },
02843 { 265, 257, 1450, 872 },
02844 { 257, 255, 1762, 874 },
02845 { 257, 253, 212, 1164 },
02846 { 262, 251, 516, 1172 },
02847 { 263, 257, 826, 1172 },
02848 { 263, 255, 1136, 1176 },
02849 { 255, 252, 1452, 1182 },
02850 { 257, 253, 1760, 1180 } };
02851
02852 static const double gmb_xyY[NSQ][3] = {
02853 { 0.400, 0.350, 10.1 },
02854 { 0.377, 0.345, 35.8 },
02855 { 0.247, 0.251, 19.3 },
02856 { 0.337, 0.422, 13.3 },
02857 { 0.265, 0.240, 24.3 },
02858 { 0.261, 0.343, 43.1 },
02859 { 0.506, 0.407, 30.1 },
02860 { 0.211, 0.175, 12.0 },
02861 { 0.453, 0.306, 19.8 },
02862 { 0.285, 0.202, 6.6 },
02863 { 0.380, 0.489, 44.3 },
02864 { 0.473, 0.438, 43.1 },
02865 { 0.187, 0.129, 6.1 },
02866 { 0.305, 0.478, 23.4 },
02867 { 0.539, 0.313, 12.0 },
02868 { 0.448, 0.470, 59.1 },
02869 { 0.364, 0.233, 19.8 },
02870 { 0.196, 0.252, 19.8 },
02871 { 0.310, 0.316, 90.0 },
02872 { 0.310, 0.316, 59.1 },
02873 { 0.310, 0.316, 36.2 },
02874 { 0.310, 0.316, 19.8 },
02875 { 0.310, 0.316, 9.0 },
02876 { 0.310, 0.316, 3.1 } };
02877 double gmb_cam[NSQ][4], gmb_xyz[NSQ][3];
02878 double inverse[NSQ][3], cam_xyz[4][3], num;
02879 int c, i, j, k, sq, row, col, count[4];
02880
02881 memset (gmb_cam, 0, sizeof gmb_cam);
02882 for (sq=0; sq < NSQ; sq++) {
02883 FORCC count[c] = 0;
02884 for (row=cut[sq][3]; row < cut[sq][3]+cut[sq][1]; row++)
02885 for (col=cut[sq][2]; col < cut[sq][2]+cut[sq][0]; col++) {
02886 c = FC(row,col);
02887 if (c >= colors) c -= 2;
02888 gmb_cam[sq][c] += BAYER(row,col);
02889 count[c]++;
02890 }
02891 FORCC gmb_cam[sq][c] = gmb_cam[sq][c]/count[c] - black;
02892 gmb_xyz[sq][0] = gmb_xyY[sq][2] * gmb_xyY[sq][0] / gmb_xyY[sq][1];
02893 gmb_xyz[sq][1] = gmb_xyY[sq][2];
02894 gmb_xyz[sq][2] = gmb_xyY[sq][2] *
02895 (1 - gmb_xyY[sq][0] - gmb_xyY[sq][1]) / gmb_xyY[sq][1];
02896 }
02897 pseudoinverse (gmb_xyz, inverse, NSQ);
02898 for (i=0; i < colors; i++)
02899 for (j=0; j < 3; j++)
02900 for (cam_xyz[i][j] = k=0; k < NSQ; k++)
02901 cam_xyz[i][j] += gmb_cam[k][i] * inverse[k][j];
02902 cam_xyz_coeff (cam_xyz);
02903 if (verbose) {
02904 printf (" { \"%s %s\", %d,\n\t{", make, model, black);
02905 num = 10000 / (cam_xyz[1][0] + cam_xyz[1][1] + cam_xyz[1][2]);
02906 FORCC for (j=0; j < 3; j++)
02907 printf ("%c%d", (c | j) ? ',':' ', (int) (cam_xyz[c][j] * num + 0.5));
02908 puts (" } },");
02909 }
02910 #undef NSQ
02911 }
02912 #endif
02913
02914 void CLASS scale_colors()
02915 {
02916 int row, col, x, y, c, val, shift=0;
02917 int min[4], max[4], sum[8];
02918 double dsum[8], dmin;
02919
02920 maximum -= black;
02921 if (use_auto_wb || (use_camera_wb && camera_red == -1)) {
02922 FORC4 min[c] = INT_MAX;
02923 FORC4 max[c] = 0;
02924 memset (dsum, 0, sizeof dsum);
02925 for (row=0; row < height-7; row++)
02926 for (col=0; col < width-7; col++) {
02927 memset (sum, 0, sizeof sum);
02928 for (y=row; y < row+7; y++)
02929 for (x=col; x < col+7; x++)
02930 FORC4 {
02931 val = image[y*width+x][c];
02932 if (!val) continue;
02933 if (min[c] > val) min[c] = val;
02934 if (max[c] < val) max[c] = val;
02935 val -= black;
02936 if (val > maximum-25) goto skip_block;
02937 if (val < 0) val = 0;
02938 sum[c] += val;
02939 sum[c+4]++;
02940 }
02941 for (c=0; c < 8; c++) dsum[c] += sum[c];
02942 skip_block:
02943 continue;
02944 }
02945 FORC4 if (dsum[c]) pre_mul[c] = dsum[c+4] / dsum[c];
02946 }
02947 if (use_camera_wb && camera_red != -1) {
02948 memset (sum, 0, sizeof sum);
02949 for (row=0; row < 8; row++)
02950 for (col=0; col < 8; col++) {
02951 c = FC(row,col);
02952 if ((val = white[row][col] - black) > 0)
02953 sum[c] += val;
02954 sum[c+4]++;
02955 }
02956 if (sum[0] && sum[1] && sum[2] && sum[3])
02957 FORC4 pre_mul[c] = (float) sum[c+4] / sum[c];
02958 else if (camera_red && camera_blue)
02959 memcpy (pre_mul, cam_mul, sizeof pre_mul);
02960 else
02961 fprintf (stderr, "%s: Cannot use camera white balance.\n", ifname);
02962 }
02963 if (raw_color || !output_color) {
02964 pre_mul[0] *= red_scale;
02965 pre_mul[2] *= blue_scale;
02966 }
02967 if (pre_mul[3] == 0) pre_mul[3] = colors < 4 ? pre_mul[1] : 1;
02968 dmin = DBL_MAX;
02969 FORC4 if (dmin > pre_mul[c])
02970 dmin = pre_mul[c];
02971 FORC4 pre_mul[c] /= dmin;
02972
02973 while (maximum << shift < 0x8000) shift++;
02974 FORC4 pre_mul[c] *= 1 << shift;
02975 maximum <<= shift;
02976
02977 if (write_fun != write_ppm || bright < 1) {
02978 maximum *= bright;
02979 if (maximum > 0xffff)
02980 maximum = 0xffff;
02981 FORC4 pre_mul[c] *= bright;
02982 }
02983 if (verbose) {
02984 fprintf (stderr, "Scaling with black=%d, pre_mul[] =", black);
02985 FORC4 fprintf (stderr, " %f", pre_mul[c]);
02986 fputc ('\n', stderr);
02987 }
02988 clip_max = clip_color ? maximum : 0xffff;
02989 for (row=0; row < height; row++)
02990 for (col=0; col < width; col++)
02991 FORC4 {
02992 val = image[row*width+col][c];
02993 if (!val) continue;
02994 val -= black;
02995 val *= pre_mul[c];
02996 image[row*width+col][c] = CLIP(val);
02997 }
02998 if (filters && colors == 3) {
02999 if (four_color_rgb) {
03000 colors++;
03001 FORC3 rgb_cam[c][3] = rgb_cam[c][1] /= 2;
03002 } else {
03003 for (row = FC(1,0) >> 1; row < height; row+=2)
03004 for (col = FC(row,1) & 1; col < width; col+=2)
03005 image[row*width+col][1] = image[row*width+col][3];
03006 filters &= ~((filters & 0x55555555) << 1);
03007 }
03008 }
03009 }
03010
03011 void CLASS border_interpolate (int border)
03012 {
03013 unsigned row, col, y, x, c, sum[8];
03014
03015 for (row=0; row < height; row++)
03016 for (col=0; col < width; col++) {
03017 if (col==border && row >= border && row < height-border)
03018 col = width-border;
03019 memset (sum, 0, sizeof sum);
03020 for (y=row-1; y != row+2; y++)
03021 for (x=col-1; x != col+2; x++)
03022 if (y < height && x < width) {
03023 sum[FC(y,x)] += BAYER(y,x);
03024 sum[FC(y,x)+4]++;
03025 }
03026 FORCC if (c != FC(row,col))
03027 image[row*width+col][c] = sum[c] / sum[c+4];
03028 }
03029 }
03030
03031 void CLASS lin_interpolate()
03032 {
03033 int code[8][2][32], *ip, sum[4];
03034 int c, i, x, y, row, col, shift, color;
03035 ushort *pix;
03036
03037 if (verbose) fprintf (stderr, "Bilinear interpolation...\n");
03038
03039 border_interpolate(1);
03040 for (row=0; row < 8; row++)
03041 {
03042 for (col=0; col < 2; col++)
03043 {
03044 ip = code[row][col];
03045 memset (sum, 0, sizeof sum);
03046 for (y=-1; y <= 1; y++)
03047 {
03048 for (x=-1; x <= 1; x++)
03049 {
03050 shift = (y==0) + (x==0);
03051 if (shift == 2) continue;
03052 color = FC(row+y,col+x);
03053 *ip++ = (width*y + x)*4 + color;
03054 *ip++ = shift;
03055 *ip++ = color;
03056 sum[color] += 1 << shift;
03057 }
03058 }
03059
03060 FORCC
03061 {
03062 if (c != FC(row,col))
03063 {
03064 *ip++ = c;
03065 *ip++ = sum[c];
03066 }
03067 }
03068 }
03069 }
03070
03071 for (row=1; row < height-1; row++)
03072 {
03073 for (col=1; col < width-1; col++)
03074 {
03075 pix = image[row*width+col];
03076 ip = code[row & 7][col & 1];
03077 memset (sum, 0, sizeof sum);
03078 for (i=8; i--; ip+=3)
03079 sum[ip[2]] += pix[ip[0]] << ip[1];
03080 for (i=colors; --i; ip+=2)
03081 pix[ip[0]] = sum[ip[0]] / ip[1];
03082 }
03083 }
03084 }
03085
03086
03087
03088
03089
03090
03091
03092
03093
03094
03095
03096 void CLASS vng_interpolate()
03097 {
03098 static const signed char *cp, terms[] = {
03099 -2,-2,+0,-1,0,0x01, -2,-2,+0,+0,1,0x01, -2,-1,-1,+0,0,0x01,
03100 -2,-1,+0,-1,0,0x02, -2,-1,+0,+0,0,0x03, -2,-1,+0,+1,1,0x01,
03101 -2,+0,+0,-1,0,0x06, -2,+0,+0,+0,1,0x02, -2,+0,+0,+1,0,0x03,
03102 -2,+1,-1,+0,0,0x04, -2,+1,+0,-1,1,0x04, -2,+1,+0,+0,0,0x06,
03103 -2,+1,+0,+1,0,0x02, -2,+2,+0,+0,1,0x04, -2,+2,+0,+1,0,0x04,
03104 -1,-2,-1,+0,0,0x80, -1,-2,+0,-1,0,0x01, -1,-2,+1,-1,0,0x01,
03105 -1,-2,+1,+0,1,0x01, -1,-1,-1,+1,0,0x88, -1,-1,+1,-2,0,0x40,
03106 -1,-1,+1,-1,0,0x22, -1,-1,+1,+0,0,0x33, -1,-1,+1,+1,1,0x11,
03107 -1,+0,-1,+2,0,0x08, -1,+0,+0,-1,0,0x44, -1,+0,+0,+1,0,0x11,
03108 -1,+0,+1,-2,1,0x40, -1,+0,+1,-1,0,0x66, -1,+0,+1,+0,1,0x22,
03109 -1,+0,+1,+1,0,0x33, -1,+0,+1,+2,1,0x10, -1,+1,+1,-1,1,0x44,
03110 -1,+1,+1,+0,0,0x66, -1,+1,+1,+1,0,0x22, -1,+1,+1,+2,0,0x10,
03111 -1,+2,+0,+1,0,0x04, -1,+2,+1,+0,1,0x04, -1,+2,+1,+1,0,0x04,
03112 +0,-2,+0,+0,1,0x80, +0,-1,+0,+1,1,0x88, +0,-1,+1,-2,0,0x40,
03113 +0,-1,+1,+0,0,0x11, +0,-1,+2,-2,0,0x40, +0,-1,+2,-1,0,0x20,
03114 +0,-1,+2,+0,0,0x30, +0,-1,+2,+1,1,0x10, +0,+0,+0,+2,1,0x08,
03115 +0,+0,+2,-2,1,0x40, +0,+0,+2,-1,0,0x60, +0,+0,+2,+0,1,0x20,
03116 +0,+0,+2,+1,0,0x30, +0,+0,+2,+2,1,0x10, +0,+1,+1,+0,0,0x44,
03117 +0,+1,+1,+2,0,0x10, +0,+1,+2,-1,1,0x40, +0,+1,+2,+0,0,0x60,
03118 +0,+1,+2,+1,0,0x20, +0,+1,+2,+2,0,0x10, +1,-2,+1,+0,0,0x80,
03119 +1,-1,+1,+1,0,0x88, +1,+0,+1,+2,0,0x08, +1,+0,+2,-1,0,0x40,
03120 +1,+0,+2,+1,0,0x10
03121 }, chood[] = { -1,-1, -1,0, -1,+1, 0,+1, +1,+1, +1,0, +1,-1, 0,-1 };
03122 ushort (*brow[5])[4], *pix;
03123 int code[8][2][320], *ip, gval[8], gmin, gmax, sum[4];
03124 int row, col, x, y, x1, x2, y1, y2, t, weight, grads, color, diag;
03125 int g, diff, thold, num, c;
03126
03127 lin_interpolate();
03128 if (verbose) fprintf (stderr, "VNG interpolation...\n");
03129
03130 for (row=0; row < 8; row++) {
03131 for (col=0; col < 2; col++) {
03132 ip = code[row][col];
03133 for (cp=terms, t=0; t < 64; t++) {
03134 y1 = *cp++; x1 = *cp++;
03135 y2 = *cp++; x2 = *cp++;
03136 weight = *cp++;
03137 grads = *cp++;
03138 color = FC(row+y1,col+x1);
03139 if (FC(row+y2,col+x2) != color) continue;
03140 diag = (FC(row,col+1) == color && FC(row+1,col) == color) ? 2:1;
03141 if (abs(y1-y2) == diag && abs(x1-x2) == diag) continue;
03142 *ip++ = (y1*width + x1)*4 + color;
03143 *ip++ = (y2*width + x2)*4 + color;
03144 *ip++ = weight;
03145 for (g=0; g < 8; g++)
03146 if (grads & 1<<g) *ip++ = g;
03147 *ip++ = -1;
03148 }
03149 *ip++ = INT_MAX;
03150 for (cp=chood, g=0; g < 8; g++) {
03151 y = *cp++; x = *cp++;
03152 *ip++ = (y*width + x) * 4;
03153 color = FC(row,col);
03154 if (FC(row+y,col+x) != color && FC(row+y*2,col+x*2) == color)
03155 *ip++ = (y*width + x) * 8 + color;
03156 else
03157 *ip++ = 0;
03158 }
03159 }
03160 }
03161 brow[4] = calloc (width*3, sizeof **brow);
03162 merror (brow[4], "vng_interpolate()");
03163 for (row=0; row < 3; row++)
03164 brow[row] = brow[4] + row*width;
03165 for (row=2; row < height-2; row++) {
03166 for (col=2; col < width-2; col++) {
03167 pix = image[row*width+col];
03168 ip = code[row & 7][col & 1];
03169 memset (gval, 0, sizeof gval);
03170 while ((g = ip[0]) != INT_MAX) {
03171 diff = ABS(pix[g] - pix[ip[1]]) << ip[2];
03172 gval[ip[3]] += diff;
03173 ip += 5;
03174 if ((g = ip[-1]) == -1) continue;
03175 gval[g] += diff;
03176 while ((g = *ip++) != -1)
03177 gval[g] += diff;
03178 }
03179 ip++;
03180 gmin = gmax = gval[0];
03181 for (g=1; g < 8; g++) {
03182 if (gmin > gval[g]) gmin = gval[g];
03183 if (gmax < gval[g]) gmax = gval[g];
03184 }
03185 if (gmax == 0) {
03186 memcpy (brow[2][col], pix, sizeof *image);
03187 continue;
03188 }
03189 thold = gmin + (gmax >> 1);
03190 memset (sum, 0, sizeof sum);
03191 color = FC(row,col);
03192 for (num=g=0; g < 8; g++,ip+=2) {
03193 if (gval[g] <= thold) {
03194 FORCC
03195 if (c == color && ip[1])
03196 sum[c] += (pix[c] + pix[ip[1]]) >> 1;
03197 else
03198 sum[c] += pix[ip[0] + c];
03199 num++;
03200 }
03201 }
03202 FORCC {
03203 t = pix[color];
03204 if (c != color)
03205 t += (sum[c] - sum[color]) / num;
03206 brow[2][col][c] = CLIP(t);
03207 }
03208 }
03209 if (row > 3)
03210 memcpy (image[(row-2)*width+2], brow[0]+2, (width-4)*sizeof *image);
03211 for (g=0; g < 4; g++)
03212 brow[(g-1) & 3] = brow[g];
03213 }
03214 memcpy (image[(row-2)*width+2], brow[0]+2, (width-4)*sizeof *image);
03215 memcpy (image[(row-1)*width+2], brow[1]+2, (width-4)*sizeof *image);
03216 free (brow[4]);
03217 }
03218
03219 void CLASS cam_to_cielab (ushort cam[4], float lab[3])
03220 {
03221 int c, i, j, k;
03222 float r, xyz[3];
03223 static float cbrt[0x10000], xyz_cam[3][4];
03224
03225 if (cam == NULL) {
03226 for (i=0; i < 0x10000; i++) {
03227 r = (float) i / maximum;
03228 cbrt[i] = r > 0.008856 ? pow(r,1/3.0) : 7.787*r + 16/116.0;
03229 }
03230 for (i=0; i < 3; i++)
03231 for (j=0; j < colors; j++)
03232 for (xyz_cam[i][j] = k=0; k < 3; k++)
03233 xyz_cam[i][j] += xyz_rgb[i][k] * rgb_cam[k][j] / d65_white[i];
03234 } else {
03235 for (i=0; i < 3; i++) {
03236 for (xyz[i]=0.5, c=0; c < colors; c++)
03237 xyz[i] += xyz_cam[i][c] * cam[c];
03238 xyz[i] = cbrt[CLIP((int) xyz[i])];
03239 }
03240 lab[0] = 116 * xyz[1] - 16;
03241 lab[1] = 500 * (xyz[0] - xyz[1]);
03242 lab[2] = 200 * (xyz[1] - xyz[2]);
03243 }
03244 }
03245
03246
03247
03248
03249
03250 #define TS 256
03251
03252 void CLASS ahd_interpolate()
03253 {
03254 int i, j, top, left, row, col, tr, tc, fc, c, d, val, hm[2];
03255 ushort (*pix)[4], (*rix)[3];
03256 static const int dir[4] = { -1, 1, -TS, TS };
03257 unsigned ldiff[2][4], abdiff[2][4], leps, abeps;
03258 float flab[3];
03259 ushort (*rgb)[TS][TS][3];
03260 short (*lab)[TS][TS][3];
03261 char (*homo)[TS][TS], *buffer;
03262
03263 if (verbose) fprintf (stderr, "AHD interpolation...\n");
03264
03265 border_interpolate(3);
03266 buffer = malloc (26*TS*TS);
03267 merror (buffer, "ahd_interpolate()");
03268 rgb = (void *) buffer;
03269 lab = (void *) (buffer + 12*TS*TS);
03270 homo = (void *) (buffer + 24*TS*TS);
03271
03272 for (top=0; top < height; top += TS-6)
03273 for (left=0; left < width; left += TS-6) {
03274 memset (rgb, 0, 12*TS*TS);
03275
03276
03277 for (row = top < 2 ? 2:top; row < top+TS && row < height-2; row++) {
03278 col = left + (FC(row,left) == 1);
03279 if (col < 2) col += 2;
03280 for (fc = FC(row,col); col < left+TS && col < width-2; col+=2) {
03281 pix = image + row*width+col;
03282 val = ((pix[-1][1] + pix[0][fc] + pix[1][1]) * 2
03283 - pix[-2][fc] - pix[2][fc]) >> 2;
03284 rgb[0][row-top][col-left][1] = ULIM(val,pix[-1][1],pix[1][1]);
03285 val = ((pix[-width][1] + pix[0][fc] + pix[width][1]) * 2
03286 - pix[-2*width][fc] - pix[2*width][fc]) >> 2;
03287 rgb[1][row-top][col-left][1] = ULIM(val,pix[-width][1],pix[width][1]);
03288 }
03289 }
03290
03291 for (d=0; d < 2; d++)
03292 for (row=top+1; row < top+TS-1 && row < height-1; row++)
03293 for (col=left+1; col < left+TS-1 && col < width-1; col++) {
03294 pix = image + row*width+col;
03295 rix = &rgb[d][row-top][col-left];
03296 if ((c = 2 - FC(row,col)) == 1) {
03297 c = FC(row+1,col);
03298 val = pix[0][1] + (( pix[-1][2-c] + pix[1][2-c]
03299 - rix[-1][1] - rix[1][1] ) >> 1);
03300 rix[0][2-c] = CLIP(val);
03301 val = pix[0][1] + (( pix[-width][c] + pix[width][c]
03302 - rix[-TS][1] - rix[TS][1] ) >> 1);
03303 } else
03304 val = rix[0][1] + (( pix[-width-1][c] + pix[-width+1][c]
03305 + pix[+width-1][c] + pix[+width+1][c]
03306 - rix[-TS-1][1] - rix[-TS+1][1]
03307 - rix[+TS-1][1] - rix[+TS+1][1] + 1) >> 2);
03308 rix[0][c] = CLIP(val);
03309 c = FC(row,col);
03310 rix[0][c] = pix[0][c];
03311 cam_to_cielab (rix[0], flab);
03312 FORC3 lab[d][row-top][col-left][c] = 64*flab[c];
03313 }
03314
03315 memset (homo, 0, 2*TS*TS);
03316 for (row=top+2; row < top+TS-2 && row < height; row++) {
03317 tr = row-top;
03318 for (col=left+2; col < left+TS-2 && col < width; col++) {
03319 tc = col-left;
03320 for (d=0; d < 2; d++)
03321 for (i=0; i < 4; i++)
03322 ldiff[d][i] = ABS(lab[d][tr][tc][0]-lab[d][tr][tc+dir[i]][0]);
03323 leps = MIN(MAX(ldiff[0][0],ldiff[0][1]),
03324 MAX(ldiff[1][2],ldiff[1][3]));
03325 for (d=0; d < 2; d++)
03326 for (i=0; i < 4; i++)
03327 if (i >> 1 == d || ldiff[d][i] <= leps)
03328 abdiff[d][i] = SQR(lab[d][tr][tc][1]-lab[d][tr][tc+dir[i]][1])
03329 + SQR(lab[d][tr][tc][2]-lab[d][tr][tc+dir[i]][2]);
03330 abeps = MIN(MAX(abdiff[0][0],abdiff[0][1]),
03331 MAX(abdiff[1][2],abdiff[1][3]));
03332 for (d=0; d < 2; d++)
03333 for (i=0; i < 4; i++)
03334 if (ldiff[d][i] <= leps && abdiff[d][i] <= abeps)
03335 homo[d][tr][tc]++;
03336 }
03337 }
03338
03339 for (row=top+3; row < top+TS-3 && row < height-3; row++) {
03340 tr = row-top;
03341 for (col=left+3; col < left+TS-3 && col < width-3; col++) {
03342 tc = col-left;
03343 for (d=0; d < 2; d++)
03344 for (hm[d]=0, i=tr-1; i <= tr+1; i++)
03345 for (j=tc-1; j <= tc+1; j++)
03346 hm[d] += homo[d][i][j];
03347 if (hm[0] != hm[1])
03348 FORC3 image[row*width+col][c] = rgb[hm[1] > hm[0]][tr][tc][c];
03349 else
03350 FORC3 image[row*width+col][c] =
03351 (rgb[0][tr][tc][c] + rgb[1][tr][tc][c]) >> 1;
03352 }
03353 }
03354 }
03355 free (buffer);
03356 }
03357 #undef TS
03358
03359
03360
03361
03362 void CLASS bilateral_filter()
03363 {
03364 float (**window)[7], *kernel, scale_r, elut[1024], sum[5];
03365 int c, i, wr, ws, wlast, row, col, y, x;
03366 unsigned sep;
03367
03368 if (verbose) fprintf (stderr, "Bilateral filtering...\n");
03369
03370 wr = ceil(sigma_d*2);
03371 ws = 2*wr + 1;
03372 window = calloc ((ws+1)*sizeof *window +
03373 ws*width*sizeof **window + ws*sizeof *kernel, 1);
03374 merror (window, "bilateral_filter()");
03375 for (i=0; i <= ws; i++)
03376 window[i] = (float(*)[7]) (window+ws+1) + i*width;
03377 kernel = (float *) window[ws] + wr;
03378 for (i=-wr; i <= wr; i++)
03379 kernel[i] = 256 / (2*SQR(sigma_d)) * i*i + 0.25;
03380 scale_r = 256 / (2*SQR(sigma_r));
03381 for (i=0; i < 1024; i++)
03382 elut[i] = exp (-i/256.0);
03383
03384 for (wlast=-1, row=0; row < height; row++) {
03385 while (wlast < row+wr) {
03386 wlast++;
03387 for (i=0; i <= ws; i++)
03388 window[(ws+i) % (ws+1)] = window[i];
03389 if (wlast < height)
03390 for (col=0; col < width; col++) {
03391 FORCC window[ws-1][col][c] = image[wlast*width+col][c];
03392 cam_to_cielab (image[wlast*width+col], window[ws-1][col]+4);
03393 }
03394 }
03395 for (col=0; col < width; col++) {
03396 memset (sum, 0, sizeof sum);
03397 for (y=-wr; y <= wr; y++)
03398 if ((unsigned)(row+y) < height)
03399 for (x=-wr; x <= wr; x++)
03400 if ((unsigned)(col+x) < width) {
03401 sep = ( SQR(window[wr+y][col+x][4] - window[wr][col][4])
03402 + SQR(window[wr+y][col+x][5] - window[wr][col][5])
03403 + SQR(window[wr+y][col+x][6] - window[wr][col][6]) )
03404 * scale_r + kernel[y] + kernel[x];
03405 if (sep < 1024) {
03406 FORCC sum[c] += elut[sep] * window[wr+y][col+x][c];
03407 sum[4] += elut[sep];
03408 }
03409 }
03410 FORCC image[row*width+col][c] = sum[c]/sum[4];
03411 }
03412 }
03413 free (window);
03414 }
03415
03416 void CLASS tiff_get (unsigned base,
03417 unsigned *tag, unsigned *type, unsigned *len, unsigned *save)
03418 {
03419 *tag = get2();
03420 *type = get2();
03421 *len = get4();
03422 *save = ftell(ifp) + 4;
03423 if (*len * ("1112481124848"[*type < 13 ? *type:0]-'0') > 4)
03424 fseek (ifp, get4()+base, SEEK_SET);
03425 }
03426
03427 void CLASS parse_olympus_note (int base)
03428 {
03429 unsigned entries, tag, type, len, save;
03430
03431 entries = get2();
03432 while (entries--) {
03433 tiff_get (base, &tag, &type, &len, &save);
03434 if (tag == 257) thumb_offset = get4();
03435 if (tag == 258) thumb_length = get4();
03436 fseek (ifp, save, SEEK_SET);
03437 }
03438 }
03439
03440 void CLASS parse_makernote (int base)
03441 {
03442 static const uchar xlat[2][256] = {
03443 { 0xc1,0xbf,0x6d,0x0d,0x59,0xc5,0x13,0x9d,0x83,0x61,0x6b,0x4f,0xc7,0x7f,0x3d,0x3d,
03444 0x53,0x59,0xe3,0xc7,0xe9,0x2f,0x95,0xa7,0x95,0x1f,0xdf,0x7f,0x2b,0x29,0xc7,0x0d,
03445 0xdf,0x07,0xef,0x71,0x89,0x3d,0x13,0x3d,0x3b,0x13,0xfb,0x0d,0x89,0xc1,0x65,0x1f,
03446 0xb3,0x0d,0x6b,0x29,0xe3,0xfb,0xef,0xa3,0x6b,0x47,0x7f,0x95,0x35,0xa7,0x47,0x4f,
03447 0xc7,0xf1,0x59,0x95,0x35,0x11,0x29,0x61,0xf1,0x3d,0xb3,0x2b,0x0d,0x43,0x89,0xc1,
03448 0x9d,0x9d,0x89,0x65,0xf1,0xe9,0xdf,0xbf,0x3d,0x7f,0x53,0x97,0xe5,0xe9,0x95,0x17,
03449 0x1d,0x3d,0x8b,0xfb,0xc7,0xe3,0x67,0xa7,0x07,0xf1,0x71,0xa7,0x53,0xb5,0x29,0x89,
03450 0xe5,0x2b,0xa7,0x17,0x29,0xe9,0x4f,0xc5,0x65,0x6d,0x6b,0xef,0x0d,0x89,0x49,0x2f,
03451 0xb3,0x43,0x53,0x65,0x1d,0x49,0xa3,0x13,0x89,0x59,0xef,0x6b,0xef,0x65,0x1d,0x0b,
03452 0x59,0x13,0xe3,0x4f,0x9d,0xb3,0x29,0x43,0x2b,0x07,0x1d,0x95,0x59,0x59,0x47,0xfb,
03453 0xe5,0xe9,0x61,0x47,0x2f,0x35,0x7f,0x17,0x7f,0xef,0x7f,0x95,0x95,0x71,0xd3,0xa3,
03454 0x0b,0x71,0xa3,0xad,0x0b,0x3b,0xb5,0xfb,0xa3,0xbf,0x4f,0x83,0x1d,0xad,0xe9,0x2f,
03455 0x71,0x65,0xa3,0xe5,0x07,0x35,0x3d,0x0d,0xb5,0xe9,0xe5,0x47,0x3b,0x9d,0xef,0x35,
03456 0xa3,0xbf,0xb3,0xdf,0x53,0xd3,0x97,0x53,0x49,0x71,0x07,0x35,0x61,0x71,0x2f,0x43,
03457 0x2f,0x11,0xdf,0x17,0x97,0xfb,0x95,0x3b,0x7f,0x6b,0xd3,0x25,0xbf,0xad,0xc7,0xc5,
03458 0xc5,0xb5,0x8b,0xef,0x2f,0xd3,0x07,0x6b,0x25,0x49,0x95,0x25,0x49,0x6d,0x71,0xc7 },
03459 { 0xa7,0xbc,0xc9,0xad,0x91,0xdf,0x85,0xe5,0xd4,0x78,0xd5,0x17,0x46,0x7c,0x29,0x4c,
03460 0x4d,0x03,0xe9,0x25,0x68,0x11,0x86,0xb3,0xbd,0xf7,0x6f,0x61,0x22,0xa2,0x26,0x34,
03461 0x2a,0xbe,0x1e,0x46,0x14,0x68,0x9d,0x44,0x18,0xc2,0x40,0xf4,0x7e,0x5f,0x1b,0xad,
03462 0x0b,0x94,0xb6,0x67,0xb4,0x0b,0xe1,0xea,0x95,0x9c,0x66,0xdc,0xe7,0x5d,0x6c,0x05,
03463 0xda,0xd5,0xdf,0x7a,0xef,0xf6,0xdb,0x1f,0x82,0x4c,0xc0,0x68,0x47,0xa1,0xbd,0xee,
03464 0x39,0x50,0x56,0x4a,0xdd,0xdf,0xa5,0xf8,0xc6,0xda,0xca,0x90,0xca,0x01,0x42,0x9d,
03465 0x8b,0x0c,0x73,0x43,0x75,0x05,0x94,0xde,0x24,0xb3,0x80,0x34,0xe5,0x2c,0xdc,0x9b,
03466 0x3f,0xca,0x33,0x45,0xd0,0xdb,0x5f,0xf5,0x52,0xc3,0x21,0xda,0xe2,0x22,0x72,0x6b,
03467 0x3e,0xd0,0x5b,0xa8,0x87,0x8c,0x06,0x5d,0x0f,0xdd,0x09,0x19,0x93,0xd0,0xb9,0xfc,
03468 0x8b,0x0f,0x84,0x60,0x33,0x1c,0x9b,0x45,0xf1,0xf0,0xa3,0x94,0x3a,0x12,0x77,0x33,
03469 0x4d,0x44,0x78,0x28,0x3c,0x9e,0xfd,0x65,0x57,0x16,0x94,0x6b,0xfb,0x59,0xd0,0xc8,
03470 0x22,0x36,0xdb,0xd2,0x63,0x98,0x43,0xa1,0x04,0x87,0x86,0xf7,0xa6,0x26,0xbb,0xd6,
03471 0x59,0x4d,0xbf,0x6a,0x2e,0xaa,0x2b,0xef,0xe6,0x78,0xb6,0x4e,0xe0,0x2f,0xdc,0x7c,
03472 0xbe,0x57,0x19,0x32,0x7e,0x2a,0xd0,0xb8,0xba,0x29,0x00,0x3c,0x52,0x7d,0xa8,0x49,
03473 0x3b,0x2d,0xeb,0x25,0x49,0xfa,0xa3,0xaa,0x39,0xa7,0xc5,0xa7,0x50,0x11,0x36,0xfb,
03474 0xc6,0x67,0x4a,0xf5,0xa5,0x12,0x65,0x7e,0xb0,0xdf,0xaf,0x4e,0xb3,0x61,0x7f,0x2f } };
03475 unsigned offset=0, entries, tag, type, len, save, c;
03476 unsigned ver97=0, serial=0, i;
03477 uchar buf97[324], ci, cj, ck;
03478 short sorder;
03479 char buf[10];
03480
03481
03482
03483
03484 sorder = order;
03485 fread (buf, 1, 10, ifp);
03486 if (!strncmp (buf,"KC" ,2) ||
03487 !strncmp (buf,"KDK" ,3) ||
03488 !strncmp (buf,"MLY" ,3) ||
03489 !strncmp (buf,"VER" ,3) ||
03490 !strncmp (buf,"IIII",4) ||
03491 !strncmp (buf,"MMMM",4)) return;
03492 if (!strcmp (buf,"Nikon")) {
03493 base = ftell(ifp);
03494 order = get2();
03495 if (get2() != 42) goto quit;
03496 offset = get4();
03497 fseek (ifp, offset-8, SEEK_CUR);
03498 } else if (!strncmp (buf,"FUJIFILM",8) ||
03499 !strncmp (buf,"SONY",4) ||
03500 !strcmp (buf,"Panasonic")) {
03501 order = 0x4949;
03502 fseek (ifp, 2, SEEK_CUR);
03503 } else if (!strcmp (buf,"OLYMP") ||
03504 !strcmp (buf,"LEICA") ||
03505 !strcmp (buf,"Ricoh") ||
03506 !strcmp (buf,"EPSON"))
03507 fseek (ifp, -2, SEEK_CUR);
03508 else if (!strcmp (buf,"AOC") ||
03509 !strcmp (buf,"QVC"))
03510 fseek (ifp, -4, SEEK_CUR);
03511 else fseek (ifp, -10, SEEK_CUR);
03512
03513 entries = get2();
03514 if (entries > 1000) return;
03515 while (entries--) {
03516 tiff_get (base, &tag, &type, &len, &save);
03517 if (tag == 2 && strstr(make,"NIKON"))
03518 iso_speed = (get2(),get2());
03519 if (tag == 4 && len == 27) {
03520 iso_speed = 50 * pow (2, (get4(),get2())/32.0 - 4);
03521 aperture = (get2(), pow (2, get2()/64.0));
03522 shutter = pow (2, ((short) get2())/-32.0);
03523 }
03524 if (tag == 8 && type == 4)
03525 shot_order = get4();
03526 if (tag == 0xc && len == 4) {
03527 camera_red = getrat();
03528 camera_blue = getrat();
03529 }
03530 if (tag == 0x14 && len == 2560 && type == 7) {
03531 fseek (ifp, 1248, SEEK_CUR);
03532 goto get2_256;
03533 }
03534 if (strstr(make,"PENTAX")) {
03535 if (tag == 0x1b) tag = 0x1018;
03536 if (tag == 0x1c) tag = 0x1017;
03537 }
03538 if (tag == 0x1d)
03539 while ((c = fgetc(ifp)))
03540 serial = serial*10 + (isdigit(c) ? c - '0' : c % 10);
03541 if (tag == 0x81 && type == 4) {
03542 data_offset = get4();
03543 fseek (ifp, data_offset + 41, SEEK_SET);
03544 raw_height = get2() * 2;
03545 raw_width = get2();
03546 filters = 0x61616161;
03547 }
03548 if ((tag == 0x81 && type == 7) ||
03549 (tag == 0x100 && type == 7) ||
03550 (tag == 0x280 && type == 1)) {
03551 thumb_offset = ftell(ifp);
03552 thumb_length = len;
03553 }
03554 if (tag == 0x88 && type == 4 && (thumb_offset = get4()))
03555 thumb_offset += base;
03556 if (tag == 0x89 && type == 4)
03557 thumb_length = get4();
03558 if (tag == 0x8c)
03559 curve_offset = ftell(ifp) + 2112;
03560 if (tag == 0x96)
03561 curve_offset = ftell(ifp) + 2;
03562 if (tag == 0x97) {
03563 for (i=0; i < 4; i++)
03564 ver97 = (ver97 << 4) + fgetc(ifp)-'0';
03565 switch (ver97) {
03566 case 0x100:
03567 fseek (ifp, 68, SEEK_CUR);
03568 FORC4 cam_mul[(c >> 1) | ((c & 1) << 1)] = get2();
03569 break;
03570 case 0x102:
03571 fseek (ifp, 6, SEEK_CUR);
03572 goto get2_rggb;
03573 case 0x103:
03574 fseek (ifp, 16, SEEK_CUR);
03575 FORC4 cam_mul[c] = get2();
03576 }
03577 if (ver97 >> 8 == 2) {
03578 if (ver97 != 0x205) fseek (ifp, 280, SEEK_CUR);
03579 fread (buf97, 324, 1, ifp);
03580 }
03581 }
03582 if (tag == 0xa7 && ver97 >> 8 == 2) {
03583 ci = xlat[0][serial & 0xff];
03584 cj = xlat[1][fgetc(ifp)^fgetc(ifp)^fgetc(ifp)^fgetc(ifp)];
03585 ck = 0x60;
03586 for (i=0; i < 324; i++)
03587 buf97[i] ^= (cj += ci * ck++);
03588 FORC4 cam_mul[c ^ (c >> 1)] =
03589 sget2 (buf97 + (ver97 == 0x205 ? 14:6) + c*2);
03590 }
03591 if (tag == 0x200 && len == 4)
03592 black = (get2()+get2()+get2()+get2())/4;
03593 if (tag == 0x201 && len == 4)
03594 goto get2_rggb;
03595 if (tag == 0x401 && len == 4) {
03596 black = (get4()+get4()+get4()+get4())/4;
03597 }
03598 if (tag == 0xe01) {
03599 type = order;
03600 order = 0x4949;
03601 fseek (ifp, 22, SEEK_CUR);
03602 for (offset=22; offset+22 < len; offset += 22+i) {
03603 tag = get4();
03604 fseek (ifp, 14, SEEK_CUR);
03605 i = get4()-4;
03606 if (tag == 0x76a43207) flip = get2();
03607 else fseek (ifp, i, SEEK_CUR);
03608 }
03609 order = type;
03610 }
03611 if (tag == 0xe80 && len == 256 && type == 7) {
03612 fseek (ifp, 48, SEEK_CUR);
03613 camera_red = get2() * 508 * 1.078 / 0x10000;
03614 camera_blue = get2() * 382 * 1.173 / 0x10000;
03615 }
03616 if (tag == 0xf00 && len == 614 && type == 7) {
03617 fseek (ifp, 176, SEEK_CUR);
03618 goto get2_256;
03619 }
03620 if (tag == 0x1011 && len == 9 && use_camera_wb) {
03621 for (i=0; i < 3; i++)
03622 FORC3 rgb_cam[i][c] = ((short) get2()) / 256.0;
03623 raw_color = rgb_cam[0][0] < 1;
03624 }
03625 if (tag == 0x1017)
03626 camera_red = get2() / 256.0;
03627 if (tag == 0x1018)
03628 camera_blue = get2() / 256.0;
03629 if (tag == 0x2011 && len == 2) {
03630 get2_256:
03631 order = 0x4d4d;
03632 camera_red = get2() / 256.0;
03633 camera_blue = get2() / 256.0;
03634 }
03635 if (tag == 0x2020)
03636 parse_olympus_note (base);
03637 if (tag == 0x4001) {
03638 i = len == 582 ? 50 : len == 653 ? 68 : len == 796 ? 126 : 0;
03639 fseek (ifp, i ,SEEK_CUR);
03640 get2_rggb:
03641 FORC4 cam_mul[c ^ (c >> 1)] = get2();
03642 }
03643 fseek (ifp, save, SEEK_SET);
03644 }
03645 quit:
03646 order = sorder;
03647 }
03648
03649
03650
03651
03652
03653 void CLASS get_timestamp (int reversed)
03654 {
03655 struct tm t;
03656 char str[20];
03657 int i;
03658
03659 if (timestamp) return;
03660 str[19] = 0;
03661 if (reversed)
03662 for (i=19; i--; ) str[i] = fgetc(ifp);
03663 else
03664 fread (str, 19, 1, ifp);
03665 if (sscanf (str, "%d:%d:%d %d:%d:%d", &t.tm_year, &t.tm_mon,
03666 &t.tm_mday, &t.tm_hour, &t.tm_min, &t.tm_sec) != 6)
03667 return;
03668 t.tm_year -= 1900;
03669 t.tm_mon -= 1;
03670 if (mktime(&t) > 0)
03671 timestamp = mktime(&t);
03672 }
03673
03674 void CLASS parse_exif (int base)
03675 {
03676 unsigned kodak, entries, tag, type, len, save;
03677 double expo;
03678
03679 kodak = !strncmp(make,"EASTMAN",7);
03680 entries = get2();
03681 while (entries--) {
03682 tiff_get (base, &tag, &type, &len, &save);
03683 switch (tag) {
03684 case 33434: shutter = getrat(); break;
03685 case 33437: aperture = getrat(); break;
03686 case 34855: iso_speed = get2(); break;
03687 case 36867:
03688 case 36868: get_timestamp(0); break;
03689 case 37377: if ((expo = -getrat()) < 128)
03690 shutter = pow (2, expo); break;
03691 case 37378: aperture = pow (2, getrat()/2); break;
03692 case 37386: focal_len = getrat(); break;
03693 case 37500: parse_makernote (base); break;
03694 case 40962: if (kodak) raw_width = get4(); break;
03695 case 40963: if (kodak) raw_height = get4(); break;
03696 }
03697 fseek (ifp, save, SEEK_SET);
03698 }
03699 }
03700
03701 void CLASS parse_mos (int offset)
03702 {
03703 char data[40];
03704 int skip, from, i, c, neut[4], planes=0, frot=0;
03705 static const char *mod[] = { "Aptus","Valeo","Volare" };
03706 static const unsigned bayer[] =
03707 { 0x94949494, 0x61616161, 0x16161616, 0x49494949 };
03708
03709 fseek (ifp, offset, SEEK_SET);
03710 while (1) {
03711 fread (data, 1, 8, ifp);
03712 if (strcmp(data,"PKTS")) break;
03713 if (!make[0]) strcpy(make,"Leaf");
03714 fread (data, 1, 40, ifp);
03715 skip = get4();
03716 from = ftell(ifp);
03717 if (!strcmp(data,"JPEG_preview_data")) {
03718 thumb_offset = from;
03719 thumb_length = skip;
03720 }
03721 if (!strcmp(data,"icc_camera_profile")) {
03722 profile_offset = from;
03723 profile_length = skip;
03724 }
03725 if (!strcmp(data,"CaptProf_serial_number")) {
03726 fread (data, 1, 40, ifp);
03727 for (i=0; i < sizeof mod / sizeof *mod; i++)
03728 if (data[0] == mod[i][0] && data[1] == toupper(mod[i][1]))
03729 sprintf (model, "%s %d", mod[i], atoi(data+2));
03730 }
03731 if (!strcmp(data,"CaptProf_number_of_planes"))
03732 fscanf (ifp, "%d", &planes);
03733 if (!strcmp(data,"CaptProf_raw_data_rotation"))
03734 fscanf (ifp, "%d", &flip);
03735 if (!strcmp(data,"CaptProf_mosaic_pattern"))
03736 FORC4 {
03737 fscanf (ifp, "%d", &i);
03738 if (i == 1) frot = c ^ (c >> 1);
03739 }
03740 if (!strcmp(data,"ImgProf_rotation_angle")) {
03741 fscanf (ifp, "%d", &i);
03742 flip = i - flip;
03743 }
03744 if (!strcmp(data,"NeutObj_neutrals")) {
03745 FORC4 fscanf (ifp, "%d", neut+c);
03746 FORC3 cam_mul[c] = (float) neut[0] / neut[c+1];
03747 }
03748 parse_mos (from);
03749 fseek (ifp, skip+from, SEEK_SET);
03750 }
03751 if (planes)
03752 filters = (planes == 1) * bayer[(flip/90 + frot) & 3];
03753 }
03754
03755 int CLASS parse_tiff_ifd (int base, int level)
03756 {
03757 unsigned entries, tag, type, len, plen=16, save;
03758 int ifd, use_cm=0, cfa, i, j, c;
03759 char software[64], *cbuf, *cp;
03760 uchar cfa_pat[16], cfa_pc[] = { 0,1,2,3 }, tab[256];
03761 double dblack, cc[4][4], cm[4][3], cam_xyz[4][3];
03762 double ab[]={ 1,1,1,1 }, asn[] = { 0,0,0,0 }, xyz[] = { 1,1,1 };
03763 unsigned *buf, sony_offset=0, sony_length=0, sony_key=0;
03764 struct jhead jh;
03765 FILE *sfp;
03766
03767 if (tiff_nifds >= sizeof tiff_ifd / sizeof tiff_ifd[0])
03768 return 1;
03769 ifd = tiff_nifds++;
03770 for (j=0; j < 4; j++)
03771 for (i=0; i < 4; i++)
03772 cc[j][i] = i == j;
03773 entries = get2();
03774 if (entries > 512) return 1;
03775 while (entries--) {
03776 tiff_get (base, &tag, &type, &len, &save);
03777 switch (tag) {
03778 case 17: case 18:
03779 if (type == 3 && len == 1)
03780 cam_mul[(tag-17)*2] = get2() / 256.0;
03781 break;
03782 case 36: case 37: case 38:
03783 cam_mul[tag-0x24] = get2();
03784 break;
03785 case 39:
03786 if (len < 50 || cam_mul[0]) break;
03787 fseek (ifp, 12, SEEK_CUR);
03788 FORC3 cam_mul[c] = get2();
03789 break;
03790 case 2: case 256:
03791 tiff_ifd[ifd].width = getint(type);
03792 break;
03793 case 3: case 257:
03794 tiff_ifd[ifd].height = getint(type);
03795 break;
03796 case 258:
03797 tiff_ifd[ifd].samples = len;
03798 tiff_ifd[ifd].bps = get2();
03799 break;
03800 case 259:
03801 tiff_ifd[ifd].comp = get2();
03802 break;
03803 case 262:
03804 tiff_ifd[ifd].phint = get2();
03805 break;
03806 case 271:
03807 fgets (make, 64, ifp);
03808 break;
03809 case 272:
03810 fgets (model, 64, ifp);
03811 break;
03812 case 273:
03813 case 513:
03814 tiff_ifd[ifd].offset = get4()+base;
03815 if (!tiff_ifd[ifd].width) {
03816 fseek (ifp, tiff_ifd[ifd].offset, SEEK_SET);
03817 if (ljpeg_start (&jh, 1)) {
03818 tiff_ifd[ifd].comp = 6;
03819 tiff_ifd[ifd].width = jh.wide << (jh.clrs == 2);
03820 tiff_ifd[ifd].height = jh.high;
03821 tiff_ifd[ifd].bps = jh.bits;
03822 tiff_ifd[ifd].samples = jh.clrs;
03823 }
03824 }
03825 break;
03826 case 274:
03827 tiff_ifd[ifd].flip = "50132467"[get2() & 7]-'0';
03828 break;
03829 case 277:
03830 tiff_ifd[ifd].samples = getint(type);
03831 break;
03832 case 279:
03833 case 514:
03834 tiff_ifd[ifd].bytes = get4();
03835 break;
03836 case 305:
03837 fgets (software, 64, ifp);
03838 if (!strncmp(software,"Adobe",5) ||
03839 !strncmp(software,"Bibble",6) ||
03840 !strcmp (software,"Digital Photo Professional"))
03841 is_raw = 0;
03842 break;
03843 case 306:
03844 get_timestamp(0);
03845 break;
03846 case 324:
03847 tiff_ifd[ifd].offset = level ? ftell(ifp) : get4();
03848 break;
03849 case 330:
03850 while (len--) {
03851 i = ftell(ifp);
03852 fseek (ifp, get4()+base, SEEK_SET);
03853 if (parse_tiff_ifd (base, level+1)) break;
03854 fseek (ifp, i+4, SEEK_SET);
03855 }
03856 break;
03857 case 400:
03858 strcpy (make, "Sarnoff");
03859 maximum = 0xfff;
03860 break;
03861 case 29184: sony_offset = get4(); break;
03862 case 29185: sony_length = get4(); break;
03863 case 29217: sony_key = get4(); break;
03864 case 29443:
03865 FORC4 cam_mul[c ^ (c < 2)] = get2();
03866 break;
03867 case 33405:
03868 fgets (model2, 64, ifp);
03869 break;
03870 case 33422:
03871 case 64777:
03872 if ((plen=len) > 16) plen = 16;
03873 fread (cfa_pat, 1, plen, ifp);
03874 for (colors=cfa=i=0; i < plen; i++) {
03875 colors += !(cfa & (1 << cfa_pat[i]));
03876 cfa |= 1 << cfa_pat[i];
03877 }
03878 if (cfa == 070) memcpy (cfa_pc,"\003\004\005",3);
03879 if (cfa == 072) memcpy (cfa_pc,"\005\003\004\001",4);
03880 goto guess_cfa_pc;
03881 case 33434:
03882 shutter = getrat();
03883 break;
03884 case 33437:
03885 aperture = getrat();
03886 break;
03887 case 34310:
03888 parse_mos (ftell(ifp));
03889 break;
03890 case 34665:
03891 fseek (ifp, get4()+base, SEEK_SET);
03892 parse_exif (base);
03893 break;
03894 case 34675:
03895 case 50831:
03896 profile_offset = ftell(ifp);
03897 profile_length = len;
03898 break;
03899 case 37122:
03900 kodak_cbpp = get4();
03901 break;
03902 case 37386:
03903 focal_len = getrat();
03904 break;
03905 case 37393:
03906 shot_order = getint(type);
03907 break;
03908 case 37400:
03909 for (raw_color = i=0; i < 3; i++) {
03910 getrat();
03911 FORC3 rgb_cam[i][c] = getrat();
03912 }
03913 break;
03914 case 46275:
03915 strcpy (make, "Imacon");
03916 data_offset = ftell(ifp);
03917 break;
03918 case 46279:
03919 fseek (ifp, 78, SEEK_CUR);
03920 raw_width = get4();
03921 raw_height = get4();
03922 break;
03923 case 50454:
03924 case 50455:
03925 if (!(cbuf = malloc(len))) break;
03926 fread (cbuf, 1, len, ifp);
03927 for (cp = cbuf-1; cp && cp < cbuf+len; cp = strchr(cp,'\n'))
03928 if (!strncmp (++cp,"Neutral ",8))
03929 sscanf (cp+8, "%f %f %f", cam_mul, cam_mul+1, cam_mul+2);
03930 free (cbuf);
03931 break;
03932 case 50706:
03933 FORC4 dng_version = (dng_version << 8) + fgetc(ifp);
03934 break;
03935 case 50710:
03936 if (len > 4) len = 4;
03937 colors = len;
03938 fread (cfa_pc, 1, colors, ifp);
03939 guess_cfa_pc:
03940 FORCC tab[cfa_pc[c]] = c;
03941 cdesc[c] = 0;
03942 for (i=16; i--; )
03943 filters = filters << 2 | tab[cfa_pat[i % plen]];
03944 break;
03945 case 50711:
03946 if (get2() == 2) {
03947 fuji_width = 1;
03948 filters = 0x49494949;
03949 }
03950 break;
03951 case 291:
03952 case 2317:
03953 case 50712:
03954 if (len > 0x1000)
03955 len = 0x1000;
03956 read_shorts (curve, len);
03957 for (i=len; i < 0x1000; i++)
03958 curve[i] = curve[i-1];
03959 maximum = curve[0xfff];
03960 break;
03961 case 50714:
03962 case 50715:
03963 case 50716:
03964 for (dblack=i=0; i < len; i++)
03965 dblack += getreal(type);
03966 black += dblack/len + 0.5;
03967 break;
03968 case 50717:
03969 maximum = getint(type);
03970 break;
03971 case 50718:
03972 i = get4();
03973 j = get4() * get4();
03974 i *= get4();
03975 if (i > j) xmag = i / j;
03976 else ymag = j / i;
03977 break;
03978 case 50721:
03979 case 50722:
03980 FORCC for (j=0; j < 3; j++)
03981 cm[c][j] = getrat();
03982 use_cm = 1;
03983 break;
03984 case 50723:
03985 case 50724:
03986 for (i=0; i < colors; i++)
03987 FORCC cc[i][c] = getrat();
03988 case 50727:
03989 FORCC ab[c] = getrat();
03990 break;
03991 case 50728:
03992 FORCC asn[c] = getreal(type);
03993 break;
03994 case 50729:
03995 xyz[0] = getrat();
03996 xyz[1] = getrat();
03997 xyz[2] = 1 - xyz[0] - xyz[1];
03998 FORC3 xyz[c] /= d65_white[c];
03999 break;
04000 case 50740:
04001 if (dng_version) break;
04002 fseek (ifp, get4()+base, SEEK_SET);
04003 parse_tiff_ifd (base, level+1);
04004 break;
04005 case 50752:
04006 read_shorts (cr2_slice, 3);
04007 break;
04008 case 50829:
04009 top_margin = getint(type);
04010 left_margin = getint(type);
04011 height = getint(type) - top_margin;
04012 width = getint(type) - left_margin;
04013 break;
04014 case 64772:
04015 fseek (ifp, 16, SEEK_CUR);
04016 data_offset = get4();
04017 fseek (ifp, 28, SEEK_CUR);
04018 data_offset += get4();
04019 load_raw = packed_12_load_raw;
04020 }
04021 fseek (ifp, save, SEEK_SET);
04022 }
04023 if (sony_length && (buf = malloc(sony_length))) {
04024 fseek (ifp, sony_offset, SEEK_SET);
04025 fread (buf, sony_length, 1, ifp);
04026 sony_decrypt (buf, sony_length/4, 1, sony_key);
04027 sfp = ifp;
04028 if ((ifp = tmpfile())) {
04029 fwrite (buf, sony_length, 1, ifp);
04030 fseek (ifp, 0, SEEK_SET);
04031 parse_tiff_ifd (-sony_offset, level);
04032 fclose (ifp);
04033 }
04034 ifp = sfp;
04035 free (buf);
04036 }
04037 for (i=0; i < colors; i++)
04038 FORCC cc[i][c] *= ab[i];
04039 if (use_cm) {
04040 FORCC for (i=0; i < 3; i++)
04041 for (cam_xyz[c][i]=j=0; j < colors; j++)
04042 cam_xyz[c][i] += cc[c][j] * cm[j][i] * xyz[i];
04043 cam_xyz_coeff (cam_xyz);
04044 }
04045 if (asn[0])
04046 FORCC pre_mul[c] = 1 / asn[c];
04047 if (!use_cm)
04048 FORCC pre_mul[c] /= cc[c][c];
04049 return 0;
04050 }
04051
04052 void CLASS parse_tiff (int base)
04053 {
04054 int doff, max_samp=0, raw=-1, thm=-1, i;
04055 struct jhead jh;
04056
04057 fseek (ifp, base, SEEK_SET);
04058 order = get2();
04059 if (order != 0x4949 && order != 0x4d4d) return;
04060 get2();
04061 memset (tiff_ifd, 0, sizeof tiff_ifd);
04062 tiff_nifds = 0;
04063 while ((doff = get4())) {
04064 fseek (ifp, doff+base, SEEK_SET);
04065 if (parse_tiff_ifd (base, 0)) break;
04066 }
04067 if (!dng_version && !strncmp(make,"Kodak",5)) {
04068 fseek (ifp, 12+base, SEEK_SET);
04069 parse_tiff_ifd (base, 2);
04070 }
04071 thumb_misc = 16;
04072 if (thumb_offset) {
04073 fseek (ifp, thumb_offset, SEEK_SET);
04074 if (ljpeg_start (&jh, 1)) {
04075 thumb_misc = jh.bits;
04076 thumb_width = jh.wide;
04077 thumb_height = jh.high;
04078 }
04079 }
04080 for (i=0; i < tiff_nifds; i++) {
04081 if (max_samp < tiff_ifd[i].samples)
04082 max_samp = tiff_ifd[i].samples;
04083 if ((tiff_ifd[i].comp != 6 || tiff_ifd[i].samples != 3) &&
04084 tiff_ifd[i].width*tiff_ifd[i].height > raw_width*raw_height) {
04085 raw_width = tiff_ifd[i].width;
04086 raw_height = tiff_ifd[i].height;
04087 tiff_bps = tiff_ifd[i].bps;
04088 tiff_compress = tiff_ifd[i].comp;
04089 data_offset = tiff_ifd[i].offset;
04090 tiff_flip = tiff_ifd[i].flip;
04091 tiff_samples = tiff_ifd[i].samples;
04092 fuji_secondary = tiff_samples == 2;
04093 raw = i;
04094 }
04095 }
04096 fuji_width *= (raw_width+1)/2;
04097 if (tiff_ifd[0].flip) tiff_flip = tiff_ifd[0].flip;
04098 if (raw >= 0) {
04099 if (tiff_compress < 2)
04100 load_raw = tiff_bps > 8 ? unpacked_load_raw : eight_bit_load_raw;
04101 if (tiff_compress/2 == 3)
04102 load_raw = lossless_jpeg_load_raw;
04103 if (tiff_compress == 32773)
04104 load_raw = packed_12_load_raw;
04105 if (tiff_compress == 65000)
04106 switch (tiff_ifd[raw].phint) {
04107 case 2: load_raw = kodak_rgb_load_raw; filters = 0; break;
04108 case 6: load_raw = kodak_ycbcr_load_raw; filters = 0; break;
04109 case 32803: load_raw = kodak_65000_load_raw;
04110 }
04111 }
04112 if (tiff_samples == 3 && tiff_bps == 8)
04113 if (!dng_version) is_raw = 0;
04114 for (i=0; i < tiff_nifds; i++)
04115 if (i != raw && tiff_ifd[i].samples == max_samp &&
04116 tiff_ifd[i].width * tiff_ifd[i].height / SQR(tiff_ifd[i].bps+1) >
04117 thumb_width * thumb_height / SQR(thumb_misc+1)) {
04118 thumb_width = tiff_ifd[i].width;
04119 thumb_height = tiff_ifd[i].height;
04120 thumb_offset = tiff_ifd[i].offset;
04121 thumb_length = tiff_ifd[i].bytes;
04122 thumb_misc = tiff_ifd[i].bps;
04123 thm = i;
04124 }
04125 if (thm >= 0) {
04126 thumb_misc |= tiff_ifd[thm].samples << 5;
04127 switch (tiff_ifd[thm].comp) {
04128 case 0:
04129 write_thumb = layer_thumb;
04130 break;
04131 case 1:
04132 if (tiff_ifd[thm].bps > 8)
04133 thumb_load_raw = kodak_thumb_load_raw;
04134 else
04135 write_thumb = ppm_thumb;
04136 break;
04137 case 65000:
04138 thumb_load_raw = tiff_ifd[thm].phint == 6 ?
04139 kodak_ycbcr_load_raw : kodak_rgb_load_raw;
04140 }
04141 }
04142 }
04143
04144 void CLASS parse_minolta()
04145 {
04146 int save, tag, len, offset, high=0, wide=0, i, c;
04147
04148 fseek (ifp, 4, SEEK_SET);
04149 offset = get4() + 8;
04150 while ((save=ftell(ifp)) < offset) {
04151 tag = get4();
04152 len = get4();
04153 switch (tag) {
04154 case 0x505244:
04155 fseek (ifp, 8, SEEK_CUR);
04156 high = get2();
04157 wide = get2();
04158 break;
04159 case 0x574247:
04160 get4();
04161 i = strstr(model,"A200") ? 3:0;
04162 FORC4 cam_mul[c ^ (c >> 1) ^ i] = get2();
04163 break;
04164 case 0x545457:
04165 parse_tiff (ftell(ifp));
04166 }
04167 fseek (ifp, save+len+8, SEEK_SET);
04168 }
04169 raw_height = high;
04170 raw_width = wide;
04171 data_offset = offset;
04172 }
04173
04174
04175
04176
04177
04178
04179 void CLASS parse_external_jpeg()
04180 {
04181 char *file, *ext, *jname, *jfile, *jext;
04182 FILE *save=ifp;
04183
04184 ext = strrchr (ifname, '.');
04185 file = strrchr (ifname, '/');
04186 if (!file) file = strrchr (ifname, '\\');
04187 if (!file) file = ifname-1;
04188 file++;
04189 if (!ext || strlen(ext) != 4 || ext-file != 8) return;
04190 jname = malloc (strlen(ifname) + 1);
04191 merror (jname, "parse_external()");
04192 strcpy (jname, ifname);
04193 jfile = file - ifname + jname;
04194 jext = ext - ifname + jname;
04195 if (strcasecmp (ext, ".jpg")) {
04196 strcpy (jext, isupper(ext[1]) ? ".JPG":".jpg");
04197 memcpy (jfile, file+4, 4);
04198 memcpy (jfile+4, file, 4);
04199 } else
04200 while (isdigit(*--jext)) {
04201 if (*jext != '9') {
04202 (*jext)++;
04203 break;
04204 }
04205 *jext = '0';
04206 }
04207 if (strcmp (jname, ifname)) {
04208 if ((ifp = fopen (jname, "rb"))) {
04209 if (verbose)
04210 fprintf (stderr, "Reading metadata from %s...\n", jname);
04211 parse_tiff (12);
04212 thumb_offset = 0;
04213 is_raw = 1;
04214 fclose (ifp);
04215 }
04216 }
04217 if (!timestamp)
04218 fprintf (stderr, "Failed to read metadata from %s\n", jname);
04219 free (jname);
04220 ifp = save;
04221 }
04222
04223
04224
04225
04226
04227 void CLASS ciff_block_1030()
04228 {
04229 static const ushort key[] = { 0x410, 0x45f3 };
04230 int i, bpp, row, col, vbits=0;
04231 unsigned long bitbuf=0;
04232
04233 if ((get2(),get4()) != 0x80008 || !get4()) return;
04234 bpp = get2();
04235 if (bpp != 10 && bpp != 12) return;
04236 for (i=row=0; row < 8; row++)
04237 for (col=0; col < 8; col++) {
04238 if (vbits < bpp) {
04239 bitbuf = bitbuf << 16 | (get2() ^ key[i++ & 1]);
04240 vbits += 16;
04241 }
04242 white[row][col] =
04243 bitbuf << (LONG_BIT - vbits) >> (LONG_BIT - bpp);
04244 vbits -= bpp;
04245 }
04246 }
04247
04248
04249
04250
04251 void CLASS parse_ciff (int offset, int length)
04252 {
04253 int tboff, nrecs, i, c, type, len, roff, aoff, save, wbi=-1;
04254 ushort key[] = { 0x410, 0x45f3 };
04255
04256 if (strcmp(model,"Canon PowerShot G6") &&
04257 strcmp(model,"Canon PowerShot S60") &&
04258 strcmp(model,"Canon PowerShot S70") &&
04259 strcmp(model,"Canon PowerShot Pro1"))
04260 key[0] = key[1] = 0;
04261 fseek (ifp, offset+length-4, SEEK_SET);
04262 tboff = get4() + offset;
04263 fseek (ifp, tboff, SEEK_SET);
04264 nrecs = get2();
04265 if (nrecs > 100) return;
04266 for (i = 0; i < nrecs; i++) {
04267 type = get2();
04268 len = get4();
04269 roff = get4();
04270 aoff = offset + roff;
04271 save = ftell(ifp);
04272 if (type == 0x080a) {
04273 fseek (ifp, aoff, SEEK_SET);
04274 fread (make, 64, 1, ifp);
04275 fseek (ifp, aoff+strlen(make)+1, SEEK_SET);
04276 fread (model, 64, 1, ifp);
04277 }
04278 if (type == 0x102a) {
04279 fseek (ifp, aoff+4, SEEK_SET);
04280 iso_speed = 50 * pow (2, get2()/32.0 - 4);
04281 aperture = (get2(), pow (2, get2()/64.0));
04282 shutter = pow (2, ((short) get2())/-32.0);
04283 wbi = (get2(),get2());
04284 if (wbi > 17) wbi = 0;
04285 if (((!strcmp(model,"Canon EOS DIGITAL REBEL") ||
04286 !strcmp(model,"Canon EOS 300D DIGITAL"))) && wbi == 6)
04287 wbi++;
04288 }
04289 if (type == 0x102c) {
04290 if (!strcmp(model,"Canon PowerShot G1") ||
04291 !strcmp(model,"Canon PowerShot Pro90 IS")) {
04292 fseek (ifp, aoff+120, SEEK_SET);
04293 FORC4 cam_mul[c ^ 2] = get2();
04294 } else {
04295 fseek (ifp, aoff+100, SEEK_SET);
04296 goto common;
04297 }
04298 }
04299 if (type == 0x0032) {
04300 if (!strcmp(model,"Canon EOS D30")) {
04301 fseek (ifp, aoff+72, SEEK_SET);
04302 common:
04303 camera_red = get2() ^ key[0];
04304 camera_red =(get2() ^ key[1]) / camera_red;
04305 camera_blue = get2() ^ key[0];
04306 camera_blue /= get2() ^ key[1];
04307 if (!wbi) camera_red = -1;
04308 } else if (key[0]) {
04309 fseek (ifp, aoff+96 + 8*("01345:000000006008"[wbi]-'0'), SEEK_SET);
04310 goto common;
04311 } else {
04312 fseek (ifp, aoff+80 + (wbi < 6 ? 8*("123451"[wbi]-'0') : 0), SEEK_SET);
04313 if (!camera_red)
04314 goto common;
04315 }
04316 }
04317 if (type == 0x10a9) {
04318 if (!strcmp(model,"Canon EOS 10D"))
04319 wbi = "0134560028"[wbi]-'0';
04320 fseek (ifp, aoff+2 + wbi*8, SEEK_SET);
04321 camera_red = get2();
04322 camera_red /= get2();
04323 camera_blue = get2();
04324 camera_blue = get2() / camera_blue;
04325 }
04326 if (type == 0x1030 && (wbi == 6 || wbi == 15)) {
04327 fseek (ifp, aoff, SEEK_SET);
04328 ciff_block_1030();
04329 }
04330 if (type == 0x1031) {
04331 fseek (ifp, aoff+2, SEEK_SET);
04332 raw_width = get2();
04333 raw_height = get2();
04334 }
04335 if (type == 0x180e) {
04336 fseek (ifp, aoff, SEEK_SET);
04337 timestamp = get4();
04338 }
04339 if (type == 0x580e)
04340 timestamp = len;
04341 #ifdef LOCALTIME
04342 if ((type | 0x4000) == 0x580e)
04343 timestamp = mktime (gmtime (×tamp));
04344 #endif
04345 if (type == 0x5813)
04346 flash_used = int_to_float(len);
04347 if (type == 0x5814)
04348 canon_ev = int_to_float(len);
04349 if (type == 0x5817)
04350 shot_order = len;
04351 if (type == 0x1810) {
04352 fseek (ifp, aoff+12, SEEK_SET);
04353 flip = get4();
04354 }
04355 if (type == 0x1818) {
04356 fseek (ifp, aoff+4, SEEK_SET);
04357 shutter = pow (2, -int_to_float(get4()));
04358 aperture = pow (2, int_to_float(get4())/2);
04359 }
04360 if (type == 0x1835) {
04361 fseek (ifp, aoff, SEEK_SET);
04362 tiff_compress = get4();
04363 }
04364 if (type == 0x2007) {
04365 thumb_offset = aoff;
04366 thumb_length = len;
04367 }
04368 if (type >> 8 == 0x28 || type >> 8 == 0x30)
04369 parse_ciff(aoff, len);
04370 fseek (ifp, save, SEEK_SET);
04371 }
04372 }
04373
04374 void CLASS parse_rollei()
04375 {
04376 char line[128], *val;
04377 struct tm t;
04378
04379 fseek (ifp, 0, SEEK_SET);
04380 do {
04381 fgets (line, 128, ifp);
04382 if ((val = strchr(line,'=')))
04383 *val++ = 0;
04384 else
04385 val = line + strlen(line);
04386 if (!strcmp(line,"DAT"))
04387 sscanf (val, "%d.%d.%d", &t.tm_mday, &t.tm_mon, &t.tm_year);
04388 if (!strcmp(line,"TIM"))
04389 sscanf (val, "%d:%d:%d", &t.tm_hour, &t.tm_min, &t.tm_sec);
04390 if (!strcmp(line,"HDR"))
04391 thumb_offset = atoi(val);
04392 if (!strcmp(line,"X "))
04393 raw_width = atoi(val);
04394 if (!strcmp(line,"Y "))
04395 raw_height = atoi(val);
04396 if (!strcmp(line,"TX "))
04397 thumb_width = atoi(val);
04398 if (!strcmp(line,"TY "))
04399 thumb_height = atoi(val);
04400 } while (strncmp(line,"EOHD",4));
04401 data_offset = thumb_offset + thumb_width * thumb_height * 2;
04402 t.tm_year -= 1900;
04403 t.tm_mon -= 1;
04404 if (mktime(&t) > 0)
04405 timestamp = mktime(&t);
04406 strcpy (make, "Rollei");
04407 strcpy (model,"d530flex");
04408 write_thumb = rollei_thumb;
04409 }
04410
04411 void CLASS parse_phase_one (int base)
04412 {
04413 unsigned entries, tag, type, len, data, save, i, c;
04414 char *cp;
04415
04416 fseek (ifp, base, SEEK_SET);
04417 order = get4() & 0xffff;
04418 if (get4() >> 8 != 0x526177) return;
04419 fseek (ifp, base+get4(), SEEK_SET);
04420 entries = get4();
04421 get4();
04422 while (entries--) {
04423 tag = get4();
04424 type = get4();
04425 len = get4();
04426 data = get4();
04427 save = ftell(ifp);
04428 fseek (ifp, base+data, SEEK_SET);
04429 switch (tag) {
04430 case 0x100: flip = "0653"[data & 3]-'0'; break;
04431 case 0x106:
04432 for (raw_color = i=0; i < 3; i++)
04433 FORC3 rgb_cam[i][c] = int_to_float(get4());
04434 break;
04435 case 0x107:
04436 FORC3 cam_mul[c] = pre_mul[c] = int_to_float(get4());
04437 break;
04438 case 0x108: raw_width = data; break;
04439 case 0x109: raw_height = data; break;
04440 case 0x10a: left_margin = data; break;
04441 case 0x10b: top_margin = data; break;
04442 case 0x10c: width = data; break;
04443 case 0x10d: height = data; break;
04444 case 0x10e: tiff_compress = data; break;
04445 case 0x10f: data_offset = data+base; break;
04446 case 0x110: meta_offset = data+base;
04447 meta_length = len; break;
04448 case 0x112: curve_offset = save - 4; break;
04449 case 0x21c: strip_offset = data+base; break;
04450 case 0x301:
04451 model[63] = 0;
04452 fread (model, 1, 63, ifp);
04453 if ((cp = strstr(model," camera"))) *cp = 0;
04454 }
04455 fseek (ifp, save, SEEK_SET);
04456 }
04457 load_raw = tiff_compress < 3 ?
04458 phase_one_load_raw : phase_one_load_raw_c;
04459 strcpy (make, "Phase One");
04460 if (model[0]) return;
04461 switch (raw_height) {
04462 case 2060: strcpy (model,"LightPhase"); break;
04463 case 2682: strcpy (model,"H 10"); break;
04464 case 4128: strcpy (model,"H 20"); break;
04465 case 5488: strcpy (model,"H 25"); break;
04466 }
04467 }
04468
04469 void CLASS parse_fuji (int offset)
04470 {
04471 unsigned entries, tag, len, save, c;
04472
04473 fseek (ifp, offset, SEEK_SET);
04474 entries = get4();
04475 if (entries > 255) return;
04476 while (entries--) {
04477 tag = get2();
04478 len = get2();
04479 save = ftell(ifp);
04480 if (tag == 0x100) {
04481 raw_height = get2();
04482 raw_width = get2();
04483 } else if (tag == 0x121) {
04484 height = get2();
04485 if ((width = get2()) == 4284) width += 3;
04486 } else if (tag == 0x130)
04487 fuji_layout = fgetc(ifp) >> 7;
04488 if (tag == 0x2ff0)
04489 FORC4 cam_mul[c ^ 1] = get2();
04490 fseek (ifp, save+len, SEEK_SET);
04491 }
04492 if (fuji_layout) {
04493 height *= 2;
04494 width /= 2;
04495 }
04496 }
04497
04498 int CLASS parse_jpeg (int offset)
04499 {
04500 int len, save, hlen, mark;
04501
04502 fseek (ifp, offset, SEEK_SET);
04503 if (fgetc(ifp) != 0xff || fgetc(ifp) != 0xd8) return 0;
04504
04505 while (fgetc(ifp) == 0xff && (mark = fgetc(ifp)) != 0xda) {
04506 order = 0x4d4d;
04507 len = get2() - 2;
04508 save = ftell(ifp);
04509 if (mark == 0xc0 || mark == 0xc3) {
04510 fgetc(ifp);
04511 raw_height = get2();
04512 raw_width = get2();
04513 }
04514 order = get2();
04515 hlen = get4();
04516 if (get4() == 0x48454150)
04517 parse_ciff (save+hlen, len-hlen);
04518 parse_tiff (save+6);
04519 fseek (ifp, save+len, SEEK_SET);
04520 }
04521 return 1;
04522 }
04523
04524 void CLASS parse_riff()
04525 {
04526 unsigned i, size, end;
04527 char tag[4], date[64], month[64];
04528 static const char mon[12][4] =
04529 { "Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec" };
04530 struct tm t;
04531
04532 order = 0x4949;
04533 fread (tag, 4, 1, ifp);
04534 size = get4();
04535 if (!memcmp(tag,"RIFF",4) || !memcmp(tag,"LIST",4)) {
04536 end = ftell(ifp) + size;
04537 get4();
04538 while (ftell(ifp) < end)
04539 parse_riff();
04540 } else if (!memcmp(tag,"IDIT",4) && size < 64) {
04541 fread (date, 64, 1, ifp);
04542 date[size] = 0;
04543 if (sscanf (date, "%*s %s %d %d:%d:%d %d", month, &t.tm_mday,
04544 &t.tm_hour, &t.tm_min, &t.tm_sec, &t.tm_year) == 6) {
04545 for (i=0; i < 12 && strcmp(mon[i],month); i++);
04546 t.tm_mon = i;
04547 t.tm_year -= 1900;
04548 if (mktime(&t) > 0)
04549 timestamp = mktime(&t);
04550 }
04551 } else
04552 fseek (ifp, size, SEEK_CUR);
04553 }
04554
04555 void CLASS parse_smal (int offset, int fsize)
04556 {
04557 int ver;
04558
04559 fseek (ifp, offset+2, SEEK_SET);
04560 order = 0x4949;
04561 ver = fgetc(ifp);
04562 if (ver == 6)
04563 fseek (ifp, 5, SEEK_CUR);
04564 if (get4() != fsize) return;
04565 if (ver > 6) data_offset = get4();
04566 raw_height = height = get2();
04567 raw_width = width = get2();
04568 strcpy (make, "SMaL");
04569 sprintf (model, "v%d %dx%d", ver, width, height);
04570 if (ver == 6) load_raw = smal_v6_load_raw;
04571 if (ver == 9) load_raw = smal_v9_load_raw;
04572 }
04573
04574 char * CLASS foveon_gets (int offset, char *str, int len)
04575 {
04576 int i;
04577 fseek (ifp, offset, SEEK_SET);
04578 for (i=0; i < len-1; i++)
04579 if ((str[i] = get2()) == 0) break;
04580 str[i] = 0;
04581 return str;
04582 }
04583
04584 void CLASS parse_foveon()
04585 {
04586 int entries, img=0, off, len, tag, save, i, wide, high, pent, poff[256][2];
04587 char name[64], value[64];
04588
04589 order = 0x4949;
04590 fseek (ifp, 36, SEEK_SET);
04591 flip = get4();
04592 fseek (ifp, -4, SEEK_END);
04593 fseek (ifp, get4(), SEEK_SET);
04594 if (get4() != 0x64434553) return;
04595 entries = (get4(),get4());
04596 while (entries--) {
04597 off = get4();
04598 len = get4();
04599 tag = get4();
04600 save = ftell(ifp);
04601 fseek (ifp, off, SEEK_SET);
04602 if (get4() != (0x20434553 | (tag << 24))) return;
04603 switch (tag) {
04604 case 0x47414d49:
04605 case 0x32414d49:
04606 fseek (ifp, 12, SEEK_CUR);
04607 wide = get4();
04608 high = get4();
04609 if (wide > raw_width && high > raw_height) {
04610 raw_width = wide;
04611 raw_height = high;
04612 data_offset = off+24;
04613 }
04614 fseek (ifp, off+28, SEEK_SET);
04615 if (fgetc(ifp) == 0xff && fgetc(ifp) == 0xd8) {
04616 thumb_offset = off+28;
04617 thumb_length = len-28;
04618 }
04619 if (++img == 2 && !thumb_length) {
04620 thumb_offset = off+24;
04621 thumb_width = wide;
04622 thumb_height = high;
04623 write_thumb = foveon_thumb;
04624 }
04625 break;
04626 case 0x464d4143:
04627 meta_offset = off+24;
04628 meta_length = len-28;
04629 if (meta_length > 0x20000)
04630 meta_length = 0x20000;
04631 break;
04632 case 0x504f5250:
04633 pent = (get4(),get4());
04634 fseek (ifp, 12, SEEK_CUR);
04635 off += pent*8 + 24;
04636 if (pent > 256) pent=256;
04637 for (i=0; i < pent*2; i++)
04638 poff[0][i] = off + get4()*2;
04639 for (i=0; i < pent; i++) {
04640 foveon_gets (poff[i][0], name, 64);
04641 foveon_gets (poff[i][1], value, 64);
04642 if (!strcmp (name, "ISO"))
04643 iso_speed = atoi(value);
04644 if (!strcmp (name, "CAMMANUF"))
04645 strcpy (make, value);
04646 if (!strcmp (name, "CAMMODEL"))
04647 strcpy (model, value);
04648 if (!strcmp (name, "WB_DESC"))
04649 strcpy (model2, value);
04650 if (!strcmp (name, "TIME"))
04651 timestamp = atoi(value);
04652 if (!strcmp (name, "EXPTIME"))
04653 shutter = atoi(value) / 1000000.0;
04654 if (!strcmp (name, "APERTURE"))
04655 aperture = atof(value);
04656 if (!strcmp (name, "FLENGTH"))
04657 focal_len = atof(value);
04658 }
04659 #ifdef LOCALTIME
04660 timestamp = mktime (gmtime (×tamp));
04661 #endif
04662 }
04663 fseek (ifp, save, SEEK_SET);
04664 }
04665 is_foveon = 1;
04666 }
04667
04668
04669
04670
04671 void CLASS adobe_coeff (char *make, char *model)
04672 {
04673 static const struct {
04674 const char *prefix;
04675 short black, trans[12];
04676 } table[] = {
04677 { "Canon EOS D2000", 0,
04678 { 24542,-10860,-3401,-1490,11370,-297,2858,-605,3225 } },
04679 { "Canon EOS D6000", 0,
04680 { 20482,-7172,-3125,-1033,10410,-285,2542,226,3136 } },
04681 { "Canon EOS D30", 0,
04682 { 9805,-2689,-1312,-5803,13064,3068,-2438,3075,8775 } },
04683 { "Canon EOS D60", 0,
04684 { 6188,-1341,-890,-7168,14489,2937,-2640,3228,8483 } },
04685 { "Canon EOS 5D", 0,
04686 { 6347,-479,-972,-8297,15954,2480,-1968,2131,7649 } },
04687 { "Canon EOS 20Da", 0,
04688 { 14155,-5065,-1382,-6550,14633,2039,-1623,1824,6561 } },
04689 { "Canon EOS 20D", 0,
04690 { 6599,-537,-891,-8071,15783,2424,-1983,2234,7462 } },
04691 { "Canon EOS 350D", 0,
04692 { 6018,-617,-965,-8645,15881,2975,-1530,1719,7642 } },
04693 { "Canon EOS DIGITAL REBEL XT", 0,
04694 { 6018,-617,-965,-8645,15881,2975,-1530,1719,7642 } },
04695 { "Canon EOS-1Ds Mark II", 0,
04696 { 6517,-602,-867,-8180,15926,2378,-1618,1771,7633 } },
04697 { "Canon EOS-1D Mark II N", 0,
04698 { 6240,-466,-822,-8180,15825,2500,-1801,1938,8042 } },
04699 { "Canon EOS-1D Mark II", 0,
04700 { 6264,-582,-724,-8312,15948,2504,-1744,1919,8664 } },
04701 { "Canon EOS-1DS", 0,
04702 { 4374,3631,-1743,-7520,15212,2472,-2892,3632,8161 } },
04703 { "Canon EOS-1D", 0,
04704 { 6806,-179,-1020,-8097,16415,1687,-3267,4236,7690 } },
04705 { "Canon EOS", 0,
04706 { 8197,-2000,-1118,-6714,14335,2592,-2536,3178,8266 } },
04707 { "Canon PowerShot A50", 0,
04708 { -5300,9846,1776,3436,684,3939,-5540,9879,6200,-1404,11175,217 } },
04709 { "Canon PowerShot A5", 0,
04710 { -4801,9475,1952,2926,1611,4094,-5259,10164,5947,-1554,10883,547 } },
04711 { "Canon PowerShot G1", 0,
04712 { -4778,9467,2172,4743,-1141,4344,-5146,9908,6077,-1566,11051,557 } },
04713 { "Canon PowerShot G2", 0,
04714 { 9087,-2693,-1049,-6715,14382,2537,-2291,2819,7790 } },
04715 { "Canon PowerShot G3", 0,
04716 { 9212,-2781,-1073,-6573,14189,2605,-2300,2844,7664 } },
04717 { "Canon PowerShot G5", 0,
04718 { 9757,-2872,-933,-5972,13861,2301,-1622,2328,7212 } },
04719 { "Canon PowerShot G6", 0,
04720 { 9877,-3775,-871,-7613,14807,3072,-1448,1305,7485 } },
04721 { "Canon PowerShot Pro1", 0,
04722 { 10062,-3522,-999,-7643,15117,2730,-765,817,7323 } },
04723 { "Canon PowerShot Pro70", 34,
04724 { -4155,9818,1529,3939,-25,4522,-5521,9870,6610,-2238,10873,1342 } },
04725 { "Canon PowerShot Pro90", 0,
04726 { -4963,9896,2235,4642,-987,4294,-5162,10011,5859,-1770,11230,577 } },
04727 { "Canon PowerShot S30", 0,
04728 { 10566,-3652,-1129,-6552,14662,2006,-2197,2581,7670 } },
04729 { "Canon PowerShot S40", 0,
04730 { 8510,-2487,-940,-6869,14231,2900,-2318,2829,9013 } },
04731 { "Canon PowerShot S45", 0,
04732 { 8163,-2333,-955,-6682,14174,2751,-2077,2597,8041 } },
04733 { "Canon PowerShot S50", 0,
04734 { 8882,-2571,-863,-6348,14234,2288,-1516,2172,6569 } },
04735 { "Canon PowerShot S60", 0,
04736 { 8795,-2482,-797,-7804,15403,2573,-1422,1996,7082 } },
04737 { "Canon PowerShot S70", 0,
04738 { 9976,-3810,-832,-7115,14463,2906,-901,989,7889 } },
04739 { "Contax N Digital", 0,
04740 { 7777,1285,-1053,-9280,16543,2916,-3677,5679,7060 } },
04741 { "EPSON R-D1", 0,
04742 { 6827,-1878,-732,-8429,16012,2564,-704,592,7145 } },
04743 { "FUJIFILM FinePix E550", 0,
04744 { 11044,-3888,-1120,-7248,15168,2208,-1531,2277,8069 } },
04745 { "FUJIFILM FinePix E900", 0,
04746 { 9183,-2526,-1078,-7461,15071,2574,-2022,2440,8639 } },
04747 { "FUJIFILM FinePix F8", 0,
04748 { 11044,-3888,-1120,-7248,15168,2208,-1531,2277,8069 } },
04749 { "FUJIFILM FinePix F7", 0,
04750 { 10004,-3219,-1201,-7036,15047,2107,-1863,2565,7736 } },
04751 { "FUJIFILM FinePix S20Pro", 0,
04752 { 10004,-3219,-1201,-7036,15047,2107,-1863,2565,7736 } },
04753 { "FUJIFILM FinePix S2Pro", 128,
04754 { 12492,-4690,-1402,-7033,15423,1647,-1507,2111,7697 } },
04755 { "FUJIFILM FinePix S3Pro", 0,
04756 { 11807,-4612,-1294,-8927,16968,1988,-2120,2741,8006 } },
04757 { "FUJIFILM FinePix S5000", 0,
04758 { 8754,-2732,-1019,-7204,15069,2276,-1702,2334,6982 } },
04759 { "FUJIFILM FinePix S5100", 0,
04760 { 11940,-4431,-1255,-6766,14428,2542,-993,1165,7421 } },
04761 { "FUJIFILM FinePix S5500", 0,
04762 { 11940,-4431,-1255,-6766,14428,2542,-993,1165,7421 } },
04763 { "FUJIFILM FinePix S5200", 0,
04764 { 9636,-2804,-988,-7442,15040,2589,-1803,2311,8621 } },
04765 { "FUJIFILM FinePix S5600", 0,
04766 { 9636,-2804,-988,-7442,15040,2589,-1803,2311,8621 } },
04767 { "FUJIFILM FinePix S7000", 0,
04768 { 10190,-3506,-1312,-7153,15051,2238,-2003,2399,7505 } },
04769 { "FUJIFILM FinePix S9", 0,
04770 { 10491,-3423,-1145,-7385,15027,2538,-1809,2275,8692 } },
04771 { "KODAK NC2000F", 0,
04772 { 16475,-6903,-1218,-851,10375,477,2505,-7,1020 } },
04773 { "Kodak DCS315C", 8,
04774 { 17523,-4827,-2510,756,8546,-137,6113,1649,2250 } },
04775 { "Kodak DCS330C", 8,
04776 { 20620,-7572,-2801,-103,10073,-396,3551,-233,2220 } },
04777 { "KODAK DCS420", 0,
04778 { 10868,-1852,-644,-1537,11083,484,2343,628,2216 } },
04779 { "KODAK DCS460", 0,
04780 { 10592,-2206,-967,-1944,11685,230,2206,670,1273 } },
04781 { "KODAK EOSDCS1", 0,
04782 { 10592,-2206,-967,-1944,11685,230,2206,670,1273 } },
04783 { "KODAK EOSDCS3B", 0,
04784 { 9898,-2700,-940,-2478,12219,206,1985,634,1031 } },
04785 { "Kodak DCS520C", 180,
04786 { 24542,-10860,-3401,-1490,11370,-297,2858,-605,3225 } },
04787 { "Kodak DCS560C", 188,
04788 { 20482,-7172,-3125,-1033,10410,-285,2542,226,3136 } },
04789 { "Kodak DCS620C", 180,
04790 { 23617,-10175,-3149,-2054,11749,-272,2586,-489,3453 } },
04791 { "Kodak DCS620X", 185,
04792 { 13095,-6231,154,12221,-21,-2137,895,4602,2258 } },
04793 { "Kodak DCS660C", 214,
04794 { 18244,-6351,-2739,-791,11193,-521,3711,-129,2802 } },
04795 { "Kodak DCS720X", 0,
04796 { 11775,-5884,950,9556,1846,-1286,-1019,6221,2728 } },
04797 { "Kodak DCS760C", 0,
04798 { 16623,-6309,-1411,-4344,13923,323,2285,274,2926 } },
04799 { "Kodak DCS Pro SLR", 0,
04800 { 5494,2393,-232,-6427,13850,2846,-1876,3997,5445 } },
04801 { "Kodak DCS Pro 14nx", 0,
04802 { 5494,2393,-232,-6427,13850,2846,-1876,3997,5445 } },
04803 { "Kodak DCS Pro 14", 0,
04804 { 7791,3128,-776,-8588,16458,2039,-2455,4006,6198 } },
04805 { "Kodak ProBack645", 0,
04806 { 16414,-6060,-1470,-3555,13037,473,2545,122,4948 } },
04807 { "Kodak ProBack", 0,
04808 { 21179,-8316,-2918,-915,11019,-165,3477,-180,4210 } },
04809 { "KODAK P850", 0,
04810 { 10511,-3836,-1102,-6946,14587,2558,-1481,1792,6246 } },
04811 { "KODAK P880", 0,
04812 { 12805,-4662,-1376,-7480,15267,2360,-1626,2194,7904 } },
04813 { "LEICA DIGILUX 2", 0,
04814 { 11340,-4069,-1275,-7555,15266,2448,-2960,3426,7685 } },
04815 { "Leaf", 0,
04816 { 8236,1746,-1314,-8251,15953,2428,-3673,5786,5771 } },
04817 { "Minolta DiMAGE 5", 0,
04818 { 8983,-2942,-963,-6556,14476,2237,-2426,2887,8014 } },
04819 { "Minolta DiMAGE 7Hi", 0,
04820 { 11368,-3894,-1242,-6521,14358,2339,-2475,3056,7285 } },
04821 { "Minolta DiMAGE 7", 0,
04822 { 9144,-2777,-998,-6676,14556,2281,-2470,3019,7744 } },
04823 { "Minolta DiMAGE A1", 0,
04824 { 9274,-2547,-1167,-8220,16323,1943,-2273,2720,8340 } },
04825 { "MINOLTA DiMAGE A200", 0,
04826 { 8560,-2487,-986,-8112,15535,2771,-1209,1324,7743 } },
04827 { "Minolta DiMAGE A2", 0,
04828 { 9097,-2726,-1053,-8073,15506,2762,-966,981,7763 } },
04829 { "Minolta DiMAGE Z2", 0,
04830 { 11280,-3564,-1370,-4655,12374,2282,-1423,2168,5396 } },
04831 { "MINOLTA DYNAX 5", 0,
04832 { 10284,-3283,-1086,-7957,15762,2316,-829,882,6644 } },
04833 { "MINOLTA DYNAX 7", 0,
04834 { 10239,-3104,-1099,-8037,15727,2451,-927,925,6871 } },
04835 { "NIKON D100", 0,
04836 { 5902,-933,-782,-8983,16719,2354,-1402,1455,6464 } },
04837 { "NIKON D1H", 0,
04838 { 7577,-2166,-926,-7454,15592,1934,-2377,2808,8606 } },
04839 { "NIKON D1X", 0,
04840 { 7702,-2245,-975,-9114,17242,1875,-2679,3055,8521 } },
04841 { "NIKON D1", 0,
04842 { 16772,-4726,-2141,-7611,15713,1972,-2846,3494,9521 } },
04843 { "NIKON D2H", 0,
04844 { 5710,-901,-615,-8594,16617,2024,-2975,4120,6830 } },
04845 { "NIKON D2X", 0,
04846 { 10231,-2769,-1255,-8301,15900,2552,-797,680,7148 } },
04847 { "NIKON D50", 0,
04848 { 7732,-2422,-789,-8238,15884,2498,-859,783,7330 } },
04849 { "NIKON D70", 0,
04850 { 7732,-2422,-789,-8238,15884,2498,-859,783,7330 } },
04851 { "NIKON D200", 0,
04852 { 8367,-2248,-763,-8758,16447,2422,-1527,1550,8053 } },
04853 { "NIKON E950", 0,
04854 { -3746,10611,1665,9621,-1734,2114,-2389,7082,3064,3406,6116,-244 } },
04855 { "NIKON E995", 0,
04856 { -5547,11762,2189,5814,-558,3342,-4924,9840,5949,688,9083,96 } },
04857 { "NIKON E2500", 0,
04858 { -5547,11762,2189,5814,-558,3342,-4924,9840,5949,688,9083,96 } },
04859 { "NIKON E4300", 0,
04860 { 11280,-3564,-1370,-4655,12374,2282,-1423,2168,5396 } },
04861 { "NIKON E4500", 0,
04862 { -5547,11762,2189,5814,-558,3342,-4924,9840,5949,688,9083,96 } },
04863 { "NIKON E5000", 0,
04864 { -5547,11762,2189,5814,-558,3342,-4924,9840,5949,688,9083,96 } },
04865 { "NIKON E5400", 0,
04866 { 9349,-2987,-1001,-7919,15766,2266,-2098,2680,6839 } },
04867 { "NIKON E5700", 0,
04868 { -5368,11478,2368,5537,-113,3148,-4969,10021,5782,778,9028,211 } },
04869 { "NIKON E8400", 0,
04870 { 7842,-2320,-992,-8154,15718,2599,-1098,1342,7560 } },
04871 { "NIKON E8700", 0,
04872 { 8489,-2583,-1036,-8051,15583,2643,-1307,1407,7354 } },
04873 { "NIKON E8800", 0,
04874 { 7971,-2314,-913,-8451,15762,2894,-1442,1520,7610 } },
04875 { "OLYMPUS C5050", 0,
04876 { 10508,-3124,-1273,-6079,14294,1901,-1653,2306,6237 } },
04877 { "OLYMPUS C5060", 0,
04878 { 10445,-3362,-1307,-7662,15690,2058,-1135,1176,7602 } },
04879 { "OLYMPUS C7070", 0,
04880 { 10252,-3531,-1095,-7114,14850,2436,-1451,1723,6365 } },
04881 { "OLYMPUS C70", 0,
04882 { 10793,-3791,-1146,-7498,15177,2488,-1390,1577,7321 } },
04883 { "OLYMPUS C80", 0,
04884 { 8606,-2509,-1014,-8238,15714,2703,-942,979,7760 } },
04885 { "OLYMPUS E-10", 0,
04886 { 12745,-4500,-1416,-6062,14542,1580,-1934,2256,6603 } },
04887 { "OLYMPUS E-1", 0,
04888 { 11846,-4767,-945,-7027,15878,1089,-2699,4122,8311 } },
04889 { "OLYMPUS E-20", 0,
04890 { 13173,-4732,-1499,-5807,14036,1895,-2045,2452,7142 } },
04891 { "OLYMPUS E-300", 0,
04892 { 7828,-1761,-348,-5788,14071,1830,-2853,4518,6557 } },
04893 { "OLYMPUS E-500", 0,
04894 { 8136,-1968,-299,-5481,13742,1871,-2556,4205,6630 } },
04895 { "OLYMPUS SP500UZ", 0,
04896 { 9493,-3415,-666,-5211,12334,3260,-1548,2262,6482 } },
04897 { "PENTAX *ist DL", 0,
04898 { 10829,-2838,-1115,-8339,15817,2696,-837,680,11939 } },
04899 { "PENTAX *ist DS2", 0,
04900 { 10504,-2438,-1189,-8603,16207,2531,-1022,863,12242 } },
04901 { "PENTAX *ist DS", 0,
04902 { 10371,-2333,-1206,-8688,16231,2602,-1230,1116,11282 } },
04903 { "PENTAX *ist D", 0,
04904 { 9651,-2059,-1189,-8881,16512,2487,-1460,1345,10687 } },
04905 { "Panasonic DMC-FZ30", 0,
04906 { 10976,-4029,-1141,-7918,15491,2600,-1670,2071,8246 } },
04907 { "Panasonic DMC-LC1", 0,
04908 { 11340,-4069,-1275,-7555,15266,2448,-2960,3426,7685 } },
04909 { "Panasonic DMC-LX1", 0,
04910 { 10704,-4187,-1230,-8314,15952,2501,-920,945,8927 } },
04911 { "SONY DSC-F828", 491,
04912 { 7924,-1910,-777,-8226,15459,2998,-1517,2199,6818,-7242,11401,3481 } },
04913 { "SONY DSC-R1", 512,
04914 { 8512,-2641,-694,-8042,15670,2526,-1821,2117,7414 } },
04915 { "SONY DSC-V3", 0,
04916 { 7511,-2571,-692,-7894,15088,3060,-948,1111,8128 } }
04917 };
04918 double cam_xyz[4][3];
04919 char name[130];
04920 int i, j;
04921
04922 sprintf (name, "%s %s", make, model);
04923 for (i=0; i < sizeof table / sizeof *table; i++)
04924 if (!strncmp (name, table[i].prefix, strlen(table[i].prefix))) {
04925 if (table[i].black)
04926 black = table[i].black;
04927 for (j=0; j < 12; j++)
04928 cam_xyz[0][j] = table[i].trans[j] / 10000.0;
04929 cam_xyz_coeff (cam_xyz);
04930 break;
04931 }
04932 }
04933
04934 void CLASS simple_coeff (int index)
04935 {
04936 static const float table[][12] = {
04937
04938 { 1.4032,-0.2231,-0.1016,-0.5263,1.4816,0.017,-0.0112,0.0183,0.9113 },
04939
04940 { 2.25,0.75,-1.75,-0.25,-0.25,0.75,0.75,-0.25,-0.25,-1.75,0.75,2.25 },
04941
04942 { 1.893,-0.418,-0.476,-0.495,1.773,-0.278,-1.017,-0.655,2.672 },
04943
04944 { -1.936280, 1.800443, -1.448486, 2.584324,
04945 1.405365, -0.524955, -0.289090, 0.408680,
04946 -1.204965, 1.082304, 2.941367, -1.818705 }
04947 };
04948 int i, c;
04949
04950 for (raw_color = i=0; i < 3; i++)
04951 FORCC rgb_cam[i][c] = table[index][i*colors+c];
04952 }
04953
04954 short CLASS guess_byte_order (int words)
04955 {
04956 uchar test[4][2];
04957 int t=2, msb;
04958 double diff, sum[2] = {0,0};
04959
04960 fread (test[0], 2, 2, ifp);
04961 for (words-=2; words--; ) {
04962 fread (test[t], 2, 1, ifp);
04963 for (msb=0; msb < 2; msb++) {
04964 diff = (test[t^2][msb] << 8 | test[t^2][!msb])
04965 - (test[t ][msb] << 8 | test[t ][!msb]);
04966 sum[msb] += diff*diff;
04967 }
04968 t = (t+1) & 3;
04969 }
04970 return sum[0] < sum[1] ? 0x4d4d : 0x4949;
04971 }
04972
04973
04974
04975
04976
04977 void CLASS identify()
04978 {
04979 char head[32], *cp;
04980 unsigned hlen, fsize, i, c, is_canon;
04981 struct jhead jh;
04982 static const struct {
04983 int fsize;
04984 char make[12], model[15], withjpeg;
04985 } table[] = {
04986 { 62464, "Kodak", "DC20" ,0 },
04987 { 124928, "Kodak", "DC20" ,0 },
04988 { 311696, "ST Micro", "STV680 VGA" ,0 },
04989 { 614400, "Kodak", "KAI-0340" ,0 },
04990 { 787456, "Creative", "PC-CAM 600" ,0 },
04991 { 1138688, "Minolta", "RD175" ,0 },
04992 { 3840000, "Foculus", "531C" ,0 },
04993 { 1447680, "AVT", "F-145C" ,0 },
04994 { 1920000, "AVT", "F-201C" ,0 },
04995 { 5067304, "AVT", "F-510C" ,0 },
04996 { 10134608, "AVT", "F-510C" ,0 },
04997 { 16157136, "AVT", "F-810C" ,0 },
04998 { 6624000, "Pixelink", "A782" ,0 },
04999 { 13248000, "Pixelink", "A782" ,0 },
05000 { 6291456, "RoverShot","3320AF" ,0 },
05001 { 5939200, "OLYMPUS", "C770UZ" ,0 },
05002 { 1581060, "NIKON", "E900" ,1 },
05003 { 2465792, "NIKON", "E950" ,1 },
05004 { 2940928, "NIKON", "E2100" ,1 },
05005 { 4771840, "NIKON", "E990" ,1 },
05006 { 4775936, "NIKON", "E3700" ,1 },
05007 { 5869568, "NIKON", "E4300" ,1 },
05008 { 5865472, "NIKON", "E4500" ,1 },
05009 { 7438336, "NIKON", "E5000" ,1 },
05010 { 1976352, "CASIO", "QV-2000UX" ,1 },
05011 { 3217760, "CASIO", "QV-3*00EX" ,1 },
05012 { 6218368, "CASIO", "QV-5700" ,1 },
05013 { 7530816, "CASIO", "QV-R51" ,1 },
05014 { 7684000, "CASIO", "QV-4000" ,1 },
05015 { 4948608, "CASIO", "EX-S100" ,1 },
05016 { 7542528, "CASIO", "EX-Z50" ,1 },
05017 { 7753344, "CASIO", "EX-Z55" ,1 },
05018 { 7426656, "CASIO", "EX-P505" ,1 },
05019 { 9313536, "CASIO", "EX-P600" ,1 },
05020 { 10979200, "CASIO", "EX-P700" ,1 },
05021 { 3178560, "PENTAX", "Optio S" ,1 },
05022 { 4841984, "PENTAX", "Optio S" ,1 },
05023 { 6114240, "PENTAX", "Optio S4" ,1 },
05024 { 12582980, "Sinar", "" ,0 } };
05025 static const char *corp[] =
05026 { "Canon", "NIKON", "EPSON", "KODAK", "Kodak", "OLYMPUS", "PENTAX",
05027 "MINOLTA", "Minolta", "Konica", "CASIO", "Sinar", "Phase One" };
05028
05029 tiff_flip = flip = filters = -1;
05030 raw_height = raw_width = fuji_width = cr2_slice[0] = 0;
05031 maximum = height = width = top_margin = left_margin = 0;
05032 make[0] = model[0] = model2[0] = cdesc[0] = 0;
05033 iso_speed = shutter = aperture = focal_len = 0;
05034 memset (white, 0, sizeof white);
05035 thumb_offset = thumb_length = thumb_width = thumb_height = 0;
05036 load_raw = thumb_load_raw = NULL;
05037 write_thumb = jpeg_thumb;
05038 data_offset = meta_length = tiff_bps = tiff_compress = 0;
05039 kodak_cbpp = zero_after_ff = dng_version = fuji_secondary = 0;
05040 timestamp = shot_order = tiff_samples = black = is_foveon = 0;
05041 is_raw = raw_color = use_gamma = xmag = ymag = 1;
05042 for (i=0; i < 4; i++) {
05043 cam_mul[i] = i == 1;
05044 pre_mul[i] = i < 3;
05045 FORC3 rgb_cam[c][i] = c == i;
05046 }
05047 colors = 3;
05048 tiff_bps = 12;
05049 for (i=0; i < 0x1000; i++) curve[i] = i;
05050 profile_length = 0;
05051
05052 order = get2();
05053 hlen = get4();
05054 fseek (ifp, 0, SEEK_SET);
05055 fread (head, 1, 32, ifp);
05056 fseek (ifp, 0, SEEK_END);
05057 fsize = ftell(ifp);
05058 if ((cp = (char *) memmem (head, 32, "MMMM", 4)) ||
05059 (cp = (char *) memmem (head, 32, "IIII", 4))) {
05060 parse_phase_one (cp-head);
05061 if (cp-head) parse_tiff(0);
05062 } else if (order == 0x4949 || order == 0x4d4d) {
05063 if (!memcmp (head+6,"HEAPCCDR",8)) {
05064 data_offset = hlen;
05065 parse_ciff (hlen, fsize - hlen);
05066 } else {
05067 parse_tiff(0);
05068 }
05069 } else if (!memcmp (head,"\xff\xd8\xff\xe1",4) &&
05070 !memcmp (head+6,"Exif",4)) {
05071 fseek (ifp, 4, SEEK_SET);
05072 fseek (ifp, 4 + get2(), SEEK_SET);
05073 if (fgetc(ifp) != 0xff)
05074 parse_tiff(12);
05075 thumb_offset = 0;
05076 } else if (!memcmp (head,"BM",2) &&
05077 head[26] == 1 && head[28] == 16 && head[30] == 0) {
05078 data_offset = 0x1000;
05079 order = 0x4949;
05080 fseek (ifp, 38, SEEK_SET);
05081 if (get4() == 2834 && get4() == 2834 && get4() == 0 && get4() == 4096) {
05082 strcpy (model, "BMQ");
05083 flip = 3;
05084 goto nucore;
05085 }
05086 } else if (!memcmp (head,"BR",2)) {
05087 strcpy (model, "RAW");
05088 nucore:
05089 strcpy (make, "Nucore");
05090 order = 0x4949;
05091 fseek (ifp, 10, SEEK_SET);
05092 data_offset += get4();
05093 raw_width = (get4(),get4());
05094 raw_height = get4();
05095 if (model[0] == 'B' && raw_width == 2597) {
05096 raw_width++;
05097 data_offset -= 0x1000;
05098 }
05099 } else if (!memcmp (head+25,"ARECOYK",7)) {
05100 strcpy (make, "Contax");
05101 strcpy (model,"N Digital");
05102 fseek (ifp, 33, SEEK_SET);
05103 get_timestamp(1);
05104 fseek (ifp, 60, SEEK_SET);
05105 FORC4 cam_mul[c ^ (c >> 1)] = get4();
05106 } else if (!strcmp (head, "PXN")) {
05107 strcpy (make, "Logitech");
05108 strcpy (model,"Fotoman Pixtura");
05109 } else if (!memcmp (head,"FUJIFILM",8)) {
05110 fseek (ifp, 84, SEEK_SET);
05111 thumb_offset = get4();
05112 thumb_length = get4();
05113 fseek (ifp, 92, SEEK_SET);
05114 parse_fuji (get4());
05115 if (thumb_offset > 120) {
05116 fseek (ifp, 120, SEEK_SET);
05117 fuji_secondary = (i = get4()) && 1;
05118 if (fuji_secondary && use_secondary)
05119 parse_fuji (i);
05120 }
05121 fseek (ifp, 100, SEEK_SET);
05122 data_offset = get4();
05123 parse_tiff (thumb_offset+12);
05124 } else if (!memcmp (head,"RIFF",4)) {
05125 fseek (ifp, 0, SEEK_SET);
05126 parse_riff();
05127 } else if (!memcmp (head,"DSC-Image",9))
05128 parse_rollei();
05129 else if (!memcmp (head,"\0MRM",4))
05130 parse_minolta();
05131 else if (!memcmp (head,"FOVb",4))
05132 parse_foveon();
05133 else
05134 for (i=0; i < sizeof table / sizeof *table; i++)
05135 if (fsize == table[i].fsize) {
05136 strcpy (make, table[i].make );
05137 strcpy (model, table[i].model);
05138 if (table[i].withjpeg)
05139 parse_external_jpeg();
05140 }
05141 parse_mos(8);
05142 parse_mos(3472);
05143 if (make[0] == 0) parse_smal (0, fsize);
05144 if (make[0] == 0) parse_jpeg (is_raw = 0);
05145
05146 for (i=0; i < sizeof corp / sizeof *corp; i++)
05147 if (strstr (make, corp[i]))
05148 strcpy (make, corp[i]);
05149 if (!strncmp (make,"KODAK",5))
05150 make[16] = model[16] = 0;
05151 cp = make + strlen(make);
05152 while (*--cp == ' ') *cp = 0;
05153 cp = model + strlen(model);
05154 while (*--cp == ' ') *cp = 0;
05155 i = strlen(make);
05156 if (!strncmp (model, make, i) && model[i++] == ' ')
05157 memmove (model, model+i, 64-i);
05158 make[63] = model[63] = model2[63] = 0;
05159 if (!is_raw) return;
05160
05161 if ((raw_height | raw_width) < 0)
05162 raw_height = raw_width = 0;
05163 if (!maximum) maximum = (1 << tiff_bps) - 1;
05164 if (!height) height = raw_height;
05165 if (!width) width = raw_width;
05166 if (fuji_width) {
05167 width = height + fuji_width;
05168 height = width - 1;
05169 xmag = ymag = 1;
05170 }
05171 if (dng_version) {
05172 strcat (model," DNG");
05173 if (filters == UINT_MAX) filters = 0;
05174 if (!filters)
05175 colors = tiff_samples;
05176 if (tiff_compress == 1)
05177 load_raw = adobe_dng_load_raw_nc;
05178 if (tiff_compress == 7)
05179 load_raw = adobe_dng_load_raw_lj;
05180 FORC4 cam_mul[c] = pre_mul[c];
05181 goto dng_skip;
05182 }
05183
05184
05185
05186 if ((is_canon = !strcmp(make,"Canon"))) {
05187 load_raw = memcmp (head+6,"HEAPCCDR",8) ?
05188 lossless_jpeg_load_raw : canon_compressed_load_raw;
05189 maximum = 0xfff;
05190 }
05191 if (!strcmp(make,"NIKON"))
05192 load_raw = nikon_is_compressed() ?
05193 nikon_compressed_load_raw : nikon_load_raw;
05194 if (!strncmp (make,"OLYMPUS",7))
05195 height += height & 1;
05196
05197
05198
05199 if (is_foveon) {
05200 if (height*2 < width) ymag = 2;
05201 if (height > width) xmag = 2;
05202 filters = 0;
05203 load_raw = foveon_load_raw;
05204 simple_coeff(0);
05205 } else if (!strcmp(model,"PowerShot 600")) {
05206 height = 613;
05207 width = 854;
05208 colors = 4;
05209 filters = 0xe1e4e1e4;
05210 load_raw = canon_600_load_raw;
05211 } else if (!strcmp(model,"PowerShot A5") ||
05212 !strcmp(model,"PowerShot A5 Zoom")) {
05213 height = 773;
05214 width = 960;
05215 raw_width = 992;
05216 colors = 4;
05217 filters = 0x1e4e1e4e;
05218 load_raw = canon_a5_load_raw;
05219 } else if (!strcmp(model,"PowerShot A50")) {
05220 height = 968;
05221 width = 1290;
05222 raw_width = 1320;
05223 colors = 4;
05224 filters = 0x1b4e4b1e;
05225 load_raw = canon_a5_load_raw;
05226 } else if (!strcmp(model,"PowerShot Pro70")) {
05227 height = 1024;
05228 width = 1552;
05229 colors = 4;
05230 filters = 0x1e4b4e1b;
05231 load_raw = canon_a5_load_raw;
05232 } else if (!strcmp(model,"PowerShot Pro90 IS")) {
05233 width = 1896;
05234 colors = 4;
05235 filters = 0xb4b4b4b4;
05236 } else if (is_canon && raw_width == 2144) {
05237 height = 1550;
05238 width = 2088;
05239 top_margin = 8;
05240 left_margin = 4;
05241 if (!strcmp(model,"PowerShot G1")) {
05242 colors = 4;
05243 filters = 0xb4b4b4b4;
05244 }
05245 } else if (is_canon && raw_width == 2224) {
05246 height = 1448;
05247 width = 2176;
05248 top_margin = 6;
05249 left_margin = 48;
05250 } else if (is_canon && raw_width == 2376) {
05251 height = 1720;
05252 width = 2312;
05253 top_margin = 6;
05254 left_margin = 12;
05255 } else if (is_canon && raw_width == 2672) {
05256 height = 1960;
05257 width = 2616;
05258 top_margin = 6;
05259 left_margin = 12;
05260 } else if (is_canon && raw_width == 3152) {
05261 height = 2056;
05262 width = 3088;
05263 top_margin = 12;
05264 left_margin = 64;
05265 maximum = 0xfa0;
05266 } else if (is_canon && raw_width == 3160) {
05267 height = 2328;
05268 width = 3112;
05269 top_margin = 12;
05270 left_margin = 44;
05271 } else if (is_canon && raw_width == 3344) {
05272 height = 2472;
05273 width = 3288;
05274 top_margin = 6;
05275 left_margin = 4;
05276 } else if (!strcmp(model,"EOS D2000C")) {
05277 filters = 0x61616161;
05278 black = curve[200];
05279 } else if (is_canon && raw_width == 3516) {
05280 top_margin = 14;
05281 left_margin = 42;
05282 goto canon_cr2;
05283 } else if (is_canon && raw_width == 3596) {
05284 top_margin = 12;
05285 left_margin = 74;
05286 goto canon_cr2;
05287 } else if (is_canon && raw_width == 4476) {
05288 top_margin = 34;
05289 left_margin = 90;
05290 goto canon_cr2;
05291 } else if (is_canon && raw_width == 5108) {
05292 top_margin = 13;
05293 left_margin = 98;
05294 maximum = 0xe80;
05295 canon_cr2:
05296 height = raw_height - top_margin;
05297 width = raw_width - left_margin;
05298 } else if (!strcmp(model,"D1")) {
05299 camera_red *= 256/527.0;
05300 camera_blue *= 256/317.0;
05301 } else if (!strcmp(model,"D1X")) {
05302 width -= 4;
05303 ymag = 2;
05304 } else if (!strncmp(model,"D50",3) || !strncmp(model,"D70",3)) {
05305 width--;
05306 maximum = 0xf53;
05307 } else if (!strcmp(model,"D100")) {
05308 if (tiff_compress == 34713 && load_raw == nikon_load_raw)
05309 raw_width = (width += 3) + 3;
05310 maximum = 0xf44;
05311 } else if (!strncmp(model,"D2H",3)) {
05312 left_margin = 6;
05313 width -= 14;
05314 } else if (!strcmp(model,"D2X")) {
05315 width -= 8;
05316 } else if (fsize == 1581060) {
05317 height = 963;
05318 width = 1287;
05319 raw_width = 1632;
05320 load_raw = nikon_e900_load_raw;
05321 maximum = 0x3f4;
05322 colors = 4;
05323 filters = 0x1e1e1e1e;
05324 simple_coeff(3);
05325 pre_mul[0] = 1.2085;
05326 pre_mul[1] = 1.0943;
05327 pre_mul[3] = 1.1103;
05328 } else if (fsize == 2465792) {
05329 height = 1203;
05330 width = 1616;
05331 raw_width = 2048;
05332 load_raw = nikon_e900_load_raw;
05333 maximum = 0x3dd;
05334 colors = 4;
05335 filters = 0x4b4b4b4b;
05336 adobe_coeff ("NIKON","E950");
05337 } else if (fsize == 4771840) {
05338 height = 1540;
05339 width = 2064;
05340 colors = 4;
05341 filters = 0xe1e1e1e1;
05342 load_raw = nikon_load_raw;
05343 if (!timestamp && nikon_e995())
05344 strcpy (model, "E995");
05345 if (strcmp(model,"E995")) {
05346 filters = 0xb4b4b4b4;
05347 simple_coeff(3);
05348 pre_mul[0] = 1.196;
05349 pre_mul[1] = 1.246;
05350 pre_mul[2] = 1.018;
05351 }
05352 } else if (!strcmp(model,"E2100")) {
05353 if (!timestamp && !nikon_e2100()) goto cp_e2500;
05354 height = 1206;
05355 width = 1616;
05356 load_raw = nikon_e2100_load_raw;
05357 pre_mul[0] = 1.945;
05358 pre_mul[2] = 1.040;
05359 } else if (!strcmp(model,"E2500")) {
05360 cp_e2500:
05361 strcpy (model, "E2500");
05362 height = 1204;
05363 width = 1616;
05364 colors = 4;
05365 filters = 0x4b4b4b4b;
05366 } else if (fsize == 4775936) {
05367 height = 1542;
05368 width = 2064;
05369 load_raw = nikon_e2100_load_raw;
05370 pre_mul[0] = 1.818;
05371 pre_mul[2] = 1.618;
05372 if ((i = nikon_3700()) == 2) {
05373 strcpy (make, "OLYMPUS");
05374 strcpy (model, "C740UZ");
05375 } else if (i == 0) {
05376 strcpy (make, "PENTAX");
05377 strcpy (model,"Optio 33WR");
05378 flip = 1;
05379 filters = 0x16161616;
05380 pre_mul[0] = 1.331;
05381 pre_mul[2] = 1.820;
05382 }
05383 } else if (fsize == 5869568) {
05384 height = 1710;
05385 width = 2288;
05386 filters = 0x16161616;
05387 if (!timestamp && minolta_z2()) {
05388 strcpy (make, "Minolta");
05389 strcpy (model,"DiMAGE Z2");
05390 }
05391 if (make[0] == 'M')
05392 load_raw = nikon_e2100_load_raw;
05393 } else if (!strcmp(model,"E4500")) {
05394 height = 1708;
05395 width = 2288;
05396 colors = 4;
05397 filters = 0xb4b4b4b4;
05398 } else if (fsize == 7438336) {
05399 height = 1924;
05400 width = 2576;
05401 colors = 4;
05402 filters = 0xb4b4b4b4;
05403 } else if (!strcmp(model,"R-D1")) {
05404 tiff_compress = 34713;
05405 load_raw = nikon_load_raw;
05406 } else if (!strcmp(model,"FinePix S5100") ||
05407 !strcmp(model,"FinePix S5500")) {
05408 load_raw = unpacked_load_raw;
05409 maximum = 0x3e00;
05410 } else if (!strncmp(model,"FinePix",7)) {
05411 if (!strcmp(model+7,"S2Pro")) {
05412 strcpy (model+7," S2Pro");
05413 height = 2144;
05414 width = 2880;
05415 flip = 6;
05416 } else
05417 maximum = 0x3e00;
05418 top_margin = (raw_height - height)/2;
05419 left_margin = (raw_width - width )/2;
05420 data_offset += (top_margin*raw_width + left_margin) * 2;
05421 if (fuji_secondary)
05422 data_offset += use_secondary * ( strcmp(model+7," S3Pro")
05423 ? (raw_width *= 2) : raw_height*raw_width*2 );
05424 fuji_width = width >> !fuji_layout;
05425 width = (height >> fuji_layout) + fuji_width;
05426 raw_height = height;
05427 height = width - 1;
05428 load_raw = fuji_load_raw;
05429 if (!(fuji_width & 1)) filters = 0x49494949;
05430 } else if (!strcmp(model,"RD175")) {
05431 height = 986;
05432 width = 1534;
05433 data_offset = 513;
05434 filters = 0x61616161;
05435 load_raw = minolta_rd175_load_raw;
05436 } else if (!strcmp(model,"Digital Camera KD-400Z")) {
05437 height = 1712;
05438 width = 2312;
05439 raw_width = 2336;
05440 data_offset = 4034;
05441 fseek (ifp, 2032, SEEK_SET);
05442 goto konica_400z;
05443 } else if (!strcmp(model,"Digital Camera KD-510Z")) {
05444 data_offset = 4032;
05445 pre_mul[0] = 1.297;
05446 pre_mul[2] = 1.438;
05447 fseek (ifp, 2032, SEEK_SET);
05448 goto konica_510z;
05449 } else if (!strcasecmp(make,"MINOLTA")) {
05450 load_raw = unpacked_load_raw;
05451 maximum = 0xf7d;
05452 if (!strncmp(model,"DiMAGE A",8)) {
05453 if (!strcmp(model,"DiMAGE A200"))
05454 filters = 0x49494949;
05455 load_raw = packed_12_load_raw;
05456 maximum = model[8] == '1' ? 0xf8b : 0xfff;
05457 } else if (!strncmp(model,"ALPHA",5) ||
05458 !strncmp(model,"DYNAX",5) ||
05459 !strncmp(model,"MAXXUM",6)) {
05460 sprintf (model, "DYNAX %s", model+6 + (model[0]=='M'));
05461 load_raw = packed_12_load_raw;
05462 maximum = 0xffb;
05463 } else if (!strncmp(model,"DiMAGE G",8)) {
05464 if (model[8] == '4') {
05465 data_offset = 5056;
05466 pre_mul[0] = 1.602;
05467 pre_mul[2] = 1.441;
05468 fseek (ifp, 2078, SEEK_SET);
05469 height = 1716;
05470 width = 2304;
05471 } else if (model[8] == '5') {
05472 data_offset = 4016;
05473 fseek (ifp, 1936, SEEK_SET);
05474 konica_510z:
05475 height = 1956;
05476 width = 2607;
05477 raw_width = 2624;
05478 } else if (model[8] == '6') {
05479 data_offset = 4032;
05480 fseek (ifp, 2030, SEEK_SET);
05481 height = 2136;
05482 width = 2848;
05483 }
05484 filters = 0x61616161;
05485 konica_400z:
05486 load_raw = unpacked_load_raw;
05487 maximum = 0x3df;
05488 order = 0x4d4d;
05489 FORC4 cam_mul[(c >> 1) | ((c & 1) << 1)] = get2();
05490 }
05491 if (pre_mul[0] == 1 && pre_mul[2] == 1) {
05492 pre_mul[0] = 1.42;
05493 pre_mul[2] = 1.25;
05494 }
05495 } else if (!strcmp(model,"*ist DS")) {
05496 height -= 2;
05497 } else if (!strcmp(model,"Optio S")) {
05498 if (fsize == 3178560) {
05499 height = 1540;
05500 width = 2064;
05501 load_raw = eight_bit_load_raw;
05502 camera_red *= 4;
05503 camera_blue *= 4;
05504 pre_mul[0] = 1.391;
05505 pre_mul[2] = 1.188;
05506 } else {
05507 height = 1544;
05508 width = 2068;
05509 raw_width = 3136;
05510 load_raw = packed_12_load_raw;
05511 maximum = 0xf7c;
05512 pre_mul[0] = 1.137;
05513 pre_mul[2] = 1.453;
05514 }
05515 } else if (!strncmp(model,"Optio S4",8)) {
05516 height = 1737;
05517 width = 2324;
05518 raw_width = 3520;
05519 load_raw = packed_12_load_raw;
05520 maximum = 0xf7a;
05521 pre_mul[0] = 1.980;
05522 pre_mul[2] = 1.570;
05523 } else if (!strcmp(model,"STV680 VGA")) {
05524 height = 484;
05525 width = 644;
05526 load_raw = eight_bit_load_raw;
05527 flip = 2;
05528 filters = 0x16161616;
05529 black = 16;
05530 pre_mul[0] = 1.097;
05531 pre_mul[2] = 1.128;
05532 } else if (!strcmp(model,"KAI-0340")) {
05533 height = 477;
05534 width = 640;
05535 order = 0x4949;
05536 data_offset = 3840;
05537 load_raw = unpacked_load_raw;
05538 pre_mul[0] = 1.561;
05539 pre_mul[2] = 2.454;
05540 } else if (!strcmp(model,"531C")) {
05541 height = 1200;
05542 width = 1600;
05543 load_raw = unpacked_load_raw;
05544 filters = 0x49494949;
05545 pre_mul[1] = 1.218;
05546 } else if (!strcmp(model,"F-145C")) {
05547 height = 1040;
05548 width = 1392;
05549 load_raw = eight_bit_load_raw;
05550 } else if (!strcmp(model,"F-201C")) {
05551 height = 1200;
05552 width = 1600;
05553 load_raw = eight_bit_load_raw;
05554 } else if (!strcmp(model,"F-510C")) {
05555 height = 1958;
05556 width = 2588;
05557 load_raw = (fsize < 7500000) ? eight_bit_load_raw : unpacked_load_raw;
05558 maximum = 0xfff0;
05559 } else if (!strcmp(model,"F-810C")) {
05560 height = 2469;
05561 width = 3272;
05562 load_raw = unpacked_load_raw;
05563 maximum = 0xfff0;
05564 } else if (!strcmp(model,"A782")) {
05565 height = 3000;
05566 width = 2208;
05567 filters = 0x61616161;
05568 load_raw = (fsize < 10000000) ? eight_bit_load_raw : unpacked_load_raw;
05569 maximum = 0xffc0;
05570 } else if (!strcmp(model,"3320AF")) {
05571 height = 1536;
05572 raw_width = width = 2048;
05573 filters = 0x61616161;
05574 load_raw = unpacked_load_raw;
05575 maximum = 0x3ff;
05576 pre_mul[0] = 1.717;
05577 pre_mul[2] = 1.138;
05578 fseek (ifp, 0x300000, SEEK_SET);
05579 if ((order = guess_byte_order(0x10000)) == 0x4d4d) {
05580 data_offset = (2048 * 16 + 28) * 2;
05581 height -= 16;
05582 width -= 28;
05583 maximum = 0xf5c0;
05584 strcpy (make, "ISG");
05585 model[0] = 0;
05586 }
05587 } else if (!strcmp(make,"Imacon")) {
05588 sprintf (model, "Ixpress %d-Mp", height*width/1000000);
05589 if (raw_width < 4096) {
05590 data_offset += 6 + raw_width*12;
05591 height = raw_height - 6;
05592 width = raw_width - 10;
05593 filters = 0x61616161;
05594 flip = height > width+10 ? 5:3;
05595 }
05596 load_raw = unpacked_load_raw;
05597 maximum = 0xffff;
05598 pre_mul[0] = 1.963;
05599 pre_mul[2] = 1.430;
05600 } else if (!strcmp(make,"Sinar")) {
05601 if (!memcmp(head,"8BPS",4)) {
05602 fseek (ifp, 14, SEEK_SET);
05603 height = get4();
05604 width = get4();
05605 filters = 0x61616161;
05606 data_offset = 68;
05607 }
05608 load_raw = unpacked_load_raw;
05609 maximum = 0x3fff;
05610 } else if (!strcmp(make,"Leaf")) {
05611 if (tiff_compress == 99)
05612 load_raw = lossless_jpeg_load_raw;
05613 maximum = 0x3fff;
05614 if (filters == 0) {
05615 strcpy (model, "Volare");
05616 load_raw = hdr_load_raw;
05617 maximum = 0xffff;
05618 raw_color = 0;
05619 }
05620 } else if (!strcmp(make,"LEICA") || !strcmp(make,"Panasonic")) {
05621 if (width == 3880) {
05622 data_offset += 12;
05623 maximum = 0xf7f0;
05624 width -= 22;
05625 } else if (width == 3304) {
05626 maximum = 0xf94c;
05627 width -= 16;
05628 } else maximum = 0xfff0;
05629 load_raw = unpacked_load_raw;
05630 } else if (!strcmp(model,"P 30") || !strcmp(model,"P 45")) {
05631 black = 256;
05632 } else if (!strcmp(model,"E-1")) {
05633 filters = 0x61616161;
05634 maximum = 0xfff0;
05635 black = 1024;
05636 } else if (!strcmp(model,"E-10")) {
05637 maximum = 0xfff0;
05638 black = 2048;
05639 } else if (!strncmp(model,"E-20",4)) {
05640 maximum = 0xffc0;
05641 black = 2560;
05642 } else if (!strcmp(model,"E-300") ||
05643 !strcmp(model,"E-500")) {
05644 width -= 20;
05645 maximum = 0xfc30;
05646 if (fsize <= 15728640) {
05647 maximum = 0xfff;
05648 load_raw = olympus_e300_load_raw;
05649 }
05650 } else if (!strcmp(model,"E-330")) {
05651 width -= 30;
05652 load_raw = olympus_e300_load_raw;
05653 } else if (!strcmp(model,"C770UZ")) {
05654 height = 1718;
05655 width = 2304;
05656 filters = 0x16161616;
05657 load_raw = nikon_e2100_load_raw;
05658 } else if (!strcmp(make,"OLYMPUS")) {
05659 load_raw = olympus_cseries_load_raw;
05660 if (!strcmp(model,"C5050Z") ||
05661 !strcmp(model,"C8080WZ"))
05662 filters = 0x16161616;
05663 if (!strcmp(model,"SP500UZ"))
05664 filters = 0x49494949;
05665 } else if (!strcmp(model,"N Digital")) {
05666 height = 2047;
05667 width = 3072;
05668 filters = 0x61616161;
05669 data_offset = 0x1a00;
05670 load_raw = packed_12_load_raw;
05671 maximum = 0xf1e;
05672 } else if (!strcmp(model,"DSC-F828")) {
05673 width = 3288;
05674 left_margin = 5;
05675 data_offset = 862144;
05676 load_raw = sony_load_raw;
05677 filters = 0x9c9c9c9c;
05678 colors = 4;
05679 strcpy (cdesc, "RGBE");
05680 } else if (!strcmp(model,"DSC-V3")) {
05681 width = 3109;
05682 left_margin = 59;
05683 data_offset = 787392;
05684 load_raw = sony_load_raw;
05685 } else if (!strcmp(model,"DSC-R1")) {
05686 width = 3925;
05687 order = 0x4d4d;
05688 } else if (!strncmp(model,"P850",4)) {
05689 maximum = 0xf7c;
05690 } else if (!strcasecmp(make,"KODAK")) {
05691 if (filters == UINT_MAX) filters = 0x61616161;
05692 if (!strcmp(model,"NC2000F")) {
05693 width -= 4;
05694 left_margin = 2;
05695 } else if (!strcmp(model,"EOSDCS3B")) {
05696 width -= 4;
05697 left_margin = 2;
05698 } else if (!strcmp(model,"EOSDCS1")) {
05699 width -= 4;
05700 left_margin = 2;
05701 } else if (!strcmp(model,"DCS420")) {
05702 width -= 4;
05703 left_margin = 2;
05704 } else if (!strcmp(model,"DCS460")) {
05705 width -= 4;
05706 left_margin = 2;
05707 } else if (!strcmp(model,"DCS460A")) {
05708 width -= 4;
05709 left_margin = 2;
05710 colors = 1;
05711 filters = 0;
05712 } else if (!strcmp(model,"DCS660M")) {
05713 black = 214;
05714 colors = 1;
05715 filters = 0;
05716 } else if (!strcmp(model,"DCS760M")) {
05717 colors = 1;
05718 filters = 0;
05719 }
05720 if (load_raw == eight_bit_load_raw)
05721 load_raw = kodak_easy_load_raw;
05722 if (strstr(model,"DC25")) {
05723 strcpy (model, "DC25");
05724 data_offset = 15424;
05725 }
05726 if (!strncmp(model,"DC2",3)) {
05727 height = 242;
05728 if (fsize < 100000) {
05729 raw_width = 256; width = 249;
05730 } else {
05731 raw_width = 512; width = 501;
05732 }
05733 data_offset += raw_width + 1;
05734 colors = 4;
05735 filters = 0x8d8d8d8d;
05736 simple_coeff(1);
05737 pre_mul[1] = 1.179;
05738 pre_mul[2] = 1.209;
05739 pre_mul[3] = 1.036;
05740 load_raw = kodak_easy_load_raw;
05741 } else if (!strcmp(model,"Digital Camera 40")) {
05742 strcpy (model, "DC40");
05743 height = 512;
05744 width = 768;
05745 data_offset = 1152;
05746 load_raw = kodak_radc_load_raw;
05747 } else if (strstr(model,"DC50")) {
05748 strcpy (model, "DC50");
05749 height = 512;
05750 width = 768;
05751 data_offset = 19712;
05752 load_raw = kodak_radc_load_raw;
05753 } else if (strstr(model,"DC120")) {
05754 strcpy (model, "DC120");
05755 height = 976;
05756 width = 848;
05757 load_raw = (tiff_compress == 7)
05758 ? kodak_jpeg_load_raw : kodak_dc120_load_raw;
05759 }
05760 } else if (!strcmp(model,"Fotoman Pixtura")) {
05761 height = 512;
05762 width = 768;
05763 data_offset = 3632;
05764 load_raw = kodak_radc_load_raw;
05765 filters = 0x61616161;
05766 simple_coeff(2);
05767 } else if (!strcmp(make,"Rollei")) {
05768 switch (raw_width) {
05769 case 1316:
05770 height = 1030;
05771 width = 1300;
05772 top_margin = 1;
05773 left_margin = 6;
05774 break;
05775 case 2568:
05776 height = 1960;
05777 width = 2560;
05778 top_margin = 2;
05779 left_margin = 8;
05780 }
05781 filters = 0x16161616;
05782 load_raw = rollei_load_raw;
05783 pre_mul[0] = 1.8;
05784 pre_mul[2] = 1.3;
05785 } else if (!strcmp(model,"PC-CAM 600")) {
05786 height = 768;
05787 data_offset = width = 1024;
05788 filters = 0x49494949;
05789 load_raw = eight_bit_load_raw;
05790 pre_mul[0] = 1.14;
05791 pre_mul[2] = 2.73;
05792 } else if (!strcmp(model,"QV-2000UX")) {
05793 height = 1208;
05794 width = 1632;
05795 data_offset = width * 2;
05796 load_raw = eight_bit_load_raw;
05797 } else if (fsize == 3217760) {
05798 height = 1546;
05799 width = 2070;
05800 raw_width = 2080;
05801 load_raw = eight_bit_load_raw;
05802 } else if (!strcmp(model,"QV-4000")) {
05803 height = 1700;
05804 width = 2260;
05805 load_raw = unpacked_load_raw;
05806 maximum = 0xffff;
05807 } else if (!strcmp(model,"QV-5700")) {
05808 height = 1924;
05809 width = 2576;
05810 load_raw = casio_qv5700_load_raw;
05811 } else if (!strcmp(model,"QV-R51")) {
05812 height = 1926;
05813 width = 2576;
05814 raw_width = 3904;
05815 load_raw = packed_12_load_raw;
05816 pre_mul[0] = 1.340;
05817 pre_mul[2] = 1.672;
05818 } else if (!strcmp(model,"EX-S100")) {
05819 height = 1544;
05820 width = 2058;
05821 raw_width = 3136;
05822 load_raw = packed_12_load_raw;
05823 pre_mul[0] = 1.631;
05824 pre_mul[2] = 1.106;
05825 } else if (!strcmp(model,"EX-Z50")) {
05826 height = 1931;
05827 width = 2570;
05828 raw_width = 3904;
05829 load_raw = packed_12_load_raw;
05830 pre_mul[0] = 2.529;
05831 pre_mul[2] = 1.185;
05832 } else if (!strcmp(model,"EX-Z55")) {
05833 height = 1960;
05834 width = 2570;
05835 raw_width = 3904;
05836 load_raw = packed_12_load_raw;
05837 pre_mul[0] = 1.520;
05838 pre_mul[2] = 1.316;
05839 } else if (!strcmp(model,"EX-P505")) {
05840 height = 1928;
05841 width = 2568;
05842 raw_width = 3852;
05843 load_raw = packed_12_load_raw;
05844 pre_mul[0] = 2.07;
05845 pre_mul[2] = 1.88;
05846 } else if (fsize == 9313536) {
05847 height = 2142;
05848 width = 2844;
05849 raw_width = 4288;
05850 load_raw = packed_12_load_raw;
05851 pre_mul[0] = 1.797;
05852 pre_mul[2] = 1.219;
05853 } else if (!strcmp(model,"EX-P700")) {
05854 height = 2318;
05855 width = 3082;
05856 raw_width = 4672;
05857 load_raw = packed_12_load_raw;
05858 pre_mul[0] = 1.758;
05859 pre_mul[2] = 1.504;
05860 } else if (!strcmp(make,"Nucore")) {
05861 filters = 0x61616161;
05862 load_raw = unpacked_load_raw;
05863 if (width == 2598) {
05864 filters = 0x16161616;
05865 load_raw = nucore_load_raw;
05866 flip = 2;
05867 }
05868 }
05869 if (!model[0])
05870 sprintf (model, "%dx%d", width, height);
05871 if (filters == UINT_MAX) filters = 0x94949494;
05872 if (raw_color) adobe_coeff (make, model);
05873 if (thumb_offset && !thumb_height) {
05874 fseek (ifp, thumb_offset, SEEK_SET);
05875 if (ljpeg_start (&jh, 1)) {
05876 thumb_width = jh.wide;
05877 thumb_height = jh.high;
05878 }
05879 }
05880 dng_skip:
05881 if (!load_raw || !height) is_raw = 0;
05882 #ifdef NO_JPEG
05883 if (load_raw == kodak_jpeg_load_raw) {
05884 fprintf (stderr, "%s: You must link dcraw.c with libjpeg!!\n", ifname);
05885 is_raw = 0;
05886 }
05887 #endif
05888 if (flip == -1) flip = tiff_flip;
05889 if (flip == -1) flip = 0;
05890 if (!cdesc[0])
05891 strcpy (cdesc, colors == 3 ? "RGB":"GMCY");
05892 if (!raw_height) raw_height = height;
05893 if (!raw_width ) raw_width = width;
05894 if (filters && colors == 3)
05895 for (i=0; i < 32; i+=4) {
05896 if ((filters >> i & 15) == 9)
05897 filters |= 2 << i;
05898 if ((filters >> i & 15) == 6)
05899 filters |= 8 << i;
05900 }
05901
05902
05903
05904 if (flip & 4)
05905 sprintf(dcraw_info, "%d %d", height, width);
05906 else
05907 sprintf(dcraw_info, "%d %d", width, height);
05908
05909
05910 }
05911
05912 #ifndef NO_LCMS
05913 void CLASS apply_profile (char *input, char *output)
05914 {
05915 char *prof;
05916 cmsHPROFILE hInProfile=NULL, hOutProfile;
05917 cmsHTRANSFORM hTransform;
05918
05919 cmsErrorAction (LCMS_ERROR_SHOW);
05920 if (strcmp (input, "embed"))
05921 hInProfile = cmsOpenProfileFromFile (input, "r");
05922 else if (profile_length) {
05923 prof = malloc (profile_length);
05924 merror (prof, "apply_profile()");
05925 fseek (ifp, profile_offset, SEEK_SET);
05926 fread (prof, 1, profile_length, ifp);
05927 hInProfile = cmsOpenProfileFromMem (prof, profile_length);
05928 free (prof);
05929 } else
05930 fprintf (stderr, "%s has no embedded profile.\n", ifname);
05931 if (!hInProfile) return;
05932 hOutProfile = output ? cmsOpenProfileFromFile (output, "r")
05933 : cmsCreate_sRGBProfile();
05934 if (!hOutProfile) goto quit;
05935 if (verbose)
05936 fprintf (stderr, "Applying color profile...\n");
05937 hTransform = cmsCreateTransform (hInProfile, TYPE_RGBA_16,
05938 hOutProfile, TYPE_RGBA_16, INTENT_PERCEPTUAL, 0);
05939 cmsDoTransform (hTransform, image, image, width*height);
05940 maximum = 0xffff;
05941 raw_color = 1;
05942 cmsDeleteTransform (hTransform);
05943 cmsCloseProfile (hOutProfile);
05944 quit:
05945 cmsCloseProfile (hInProfile);
05946 }
05947 #endif
05948
05949 void CLASS convert_to_rgb()
05950 {
05951 int mix_green, row, col, c, i, j, k;
05952 ushort *img;
05953 float out[3], out_cam[3][4];
05954 static const double adobe_rgb[3][3] =
05955 { { 0.715146, 0.284856, 0.000000 },
05956 { 0.000000, 1.000000, 0.000000 },
05957 { 0.000000, 0.041166, 0.958839 } };
05958 static const double wgd65_rgb[3][3] =
05959 { { 0.593087, 0.404710, 0.002206 },
05960 { 0.095413, 0.843149, 0.061439 },
05961 { 0.011621, 0.069091, 0.919288 } };
05962 static const double prophoto_rgb[3][3] =
05963 { { 0.529317, 0.330092, 0.140588 },
05964 { 0.098368, 0.873465, 0.028169 },
05965 { 0.016879, 0.117663, 0.865457 } };
05966 static const double (*out_rgb[])[3] =
05967 { adobe_rgb, wgd65_rgb, prophoto_rgb, xyz_rgb };
05968 static const char *name[] =
05969 { "sRGB", "Adobe 1998 RGB", "Wide Gamut D65", "ProPhoto D65", "XYZ" };
05970
05971 memcpy (out_cam, rgb_cam, sizeof out_cam);
05972 raw_color |= colors == 1 || output_color < 1 || output_color > 5;
05973 if (!raw_color) {
05974 if (output_color > 1)
05975 for (i=0; i < 3; i++)
05976 for (j=0; j < colors; j++)
05977 for (out_cam[i][j] = k=0; k < 3; k++)
05978 out_cam[i][j] += out_rgb[output_color-2][i][k] * rgb_cam[k][j];
05979 FORCC {
05980 out_cam[0][c] *= red_scale;
05981 out_cam[2][c] *= blue_scale;
05982 }
05983 }
05984 if (verbose)
05985 fprintf (stderr, raw_color ? "Building histograms...\n" :
05986 "Converting to %s colorspace...\n", name[output_color-1]);
05987
05988
05989
05990
05991
05992 k = 0;
05993 for(i = 0; i < 3; i++)
05994 {
05995 for(j = 0; j < 3; j++)
05996 dcraw_matrix[k++] = rgb_cam[i][j];
05997 }
05998
05999
06000 mix_green = raw_color && rgb_cam[1][1] == rgb_cam[1][3];
06001 memset (histogram, 0, sizeof histogram);
06002 for (row = 0; row < height; row++)
06003 for (col = 0; col < width; col++) {
06004 img = image[row*width+col];
06005 if (document_mode && filters)
06006 img[0] = img[FC(row,col)];
06007 else if (mix_green)
06008 img[1] = (img[1] + img[3]) >> 1;
06009 else if (!raw_color) {
06010 FORC3 for (out[c]=i=0; i < colors; i++)
06011 out[c] += img[i] * out_cam[c][i];
06012 FORC3 img[c] = CLIP((int) out[c]);
06013 }
06014 FORCC histogram[c][img[c] >> 3]++;
06015 }
06016 if (colors == 4 && (output_color || mix_green)) colors = 3;
06017 if (document_mode && filters) colors = 1;
06018 }
06019
06020 void CLASS fuji_rotate()
06021 {
06022 int i, wide, high, row, col;
06023 double step;
06024 float r, c, fr, fc;
06025 unsigned ur, uc;
06026 ushort (*img)[4], (*pix)[4];
06027
06028 if (!fuji_width) return;
06029 if (verbose)
06030 fprintf (stderr, "Rotating image 45 degrees...\n");
06031 fuji_width = (fuji_width - 1 + shrink) >> shrink;
06032 step = sqrt(0.5);
06033 wide = fuji_width / step;
06034 high = (height - fuji_width) / step;
06035 img = calloc (wide*high, sizeof *img);
06036 merror (img, "fuji_rotate()");
06037
06038 for (row=0; row < high; row++)
06039 for (col=0; col < wide; col++) {
06040 ur = r = fuji_width + (row-col)*step;
06041 uc = c = (row+col)*step;
06042 if (ur > height-2 || uc > width-2) continue;
06043 fr = r - ur;
06044 fc = c - uc;
06045 pix = image + ur*width + uc;
06046 for (i=0; i < colors; i++)
06047 img[row*wide+col][i] =
06048 (pix[ 0][i]*(1-fc) + pix[ 1][i]*fc) * (1-fr) +
06049 (pix[width][i]*(1-fc) + pix[width+1][i]*fc) * fr;
06050 }
06051 free (image);
06052 width = wide;
06053 height = high;
06054 image = img;
06055 fuji_width = 0;
06056 }
06057
06058 int CLASS flip_index (int row, int col)
06059 {
06060 if (flip & 1) col = width - 1 - col;
06061 if (flip & 2) row = height - 1 - row;
06062 return (flip & 4) ? col * height + row
06063 : row * width + col;
06064 }
06065
06066 void CLASS flip_image()
06067 {
06068 int row, col, soff=0, doff, rstep, cstep;
06069 INT64 *src, *dest;
06070
06071 if (verbose)
06072 fprintf (stderr, "Flipping image %c:%c:%c...\n",
06073 flip & 1 ? 'H':'0', flip & 2 ? 'V':'0', flip & 4 ? 'T':'0');
06074 src = (INT64 *) image;
06075 dest = calloc (height * width, sizeof *dest);
06076 merror (dest, "flip_image()");
06077 doff = flip_index (0, 0);
06078 cstep = flip_index (0, 1) - doff;
06079 rstep = flip_index (1, 0) - flip_index (0, width);
06080 for (row=0; row < height; row++, doff += rstep)
06081 for (col=0; col < width; col++, doff += cstep)
06082 dest[doff] = src[soff++];
06083 image = (ushort (*)[4]) dest;
06084 free (src);
06085 if (flip & 4) {
06086 SWAP (height, width);
06087 SWAP (ymag, xmag);
06088 }
06089 }
06090
06091 void CLASS write_ppm (FILE *ofp)
06092 {
06093 uchar *ppm, lut[0x10000];
06094 int perc, c, val, total, i, row, col;
06095 float white=0, r;
06096
06097 ppm = calloc (width, colors*xmag);
06098 merror (ppm, "write_ppm()");
06099
06100 if (colors > 3)
06101 fprintf (ofp,
06102 "P7\nWIDTH %d\nHEIGHT %d\nDEPTH %d\nMAXVAL 255\nTUPLTYPE %s\nENDHDR\n",
06103 xmag*width, ymag*height, colors, cdesc);
06104 else
06105 fprintf (ofp, "P%d\n%d %d\n255\n", colors/2+5, xmag*width, ymag*height);
06106
06107 perc = width * height * 0.01;
06108 if (fuji_width) perc /= 2;
06109 FORCC {
06110 for (val=0x2000, total=0; --val > 32; )
06111 if ((total += histogram[c][val]) > perc) break;
06112 if (white < val) white = val;
06113 }
06114 white *= 8 / bright;
06115 for (i=0; i < 0x10000; i++) {
06116 r = i / white;
06117 val = 256 * ( !use_gamma ? r :
06118 #ifdef SRGB_GAMMA
06119 r <= 0.00304 ? r*12.92 : pow(r,2.5/6)*1.055-0.055 );
06120 #else
06121 r <= 0.018 ? r*4.5 : pow(r,0.45)*1.099-0.099 );
06122 #endif
06123 if (val > 255) val = 255;
06124 lut[i] = val;
06125 }
06126 for (row=0; row < height; row++) {
06127 for (col=0; col < width; col++)
06128 FORCC for (i=0; i < xmag; i++)
06129 ppm[(col*xmag+i)*colors+c] = lut[image[row*width+col][c]];
06130 for (i=0; i < ymag; i++)
06131 fwrite (ppm, colors*xmag, width, ofp);
06132 }
06133 free (ppm);
06134 }
06135
06136 void CLASS write_ppm16 (FILE *ofp)
06137 {
06138 int row, col, c;
06139 ushort *ppm;
06140
06141 ppm = calloc (width, 2*colors);
06142 merror (ppm, "write_ppm16()");
06143 if (maximum < 256) maximum = 256;
06144 if (colors > 3)
06145 fprintf (ofp,
06146 "P7\nWIDTH %d\nHEIGHT %d\nDEPTH %d\nMAXVAL %d\nTUPLTYPE %s\nENDHDR\n",
06147 width, height, colors, maximum, cdesc);
06148 else
06149 fprintf (ofp, "P%d\n%d %d\n%d\n",
06150 colors/2+5, width, height, maximum);
06151
06152 for (row = 0; row < height; row++) {
06153 for (col = 0; col < width; col++)
06154 FORCC ppm[col*colors+c] = htons(image[row*width+col][c]);
06155 fwrite (ppm, 2*colors, width, ofp);
06156 }
06157 free (ppm);
06158 }
06159
06160
06161
06162
06163
06164
06165 void CLASS write_cinelerra (FILE *ofp)
06166 {
06167 int row, col, c, val;
06168 float *output;
06169
06170 for (row = 0; row < height; row++)
06171 {
06172 output = dcraw_data[row];
06173
06174 if(document_mode)
06175 {
06176 for (col = 0; col < width; col++)
06177 {
06178 ushort *pixel = image[row * width + col];
06179
06180 *output++ = (float)pixel[0] * red_scale / 0xffff;
06181 *output++ = (float)pixel[1] / 0xffff;
06182 *output++ = (float)pixel[2] * blue_scale / 0xffff;
06183
06184 if(dcraw_alpha) *output++ = 1.0;
06185 }
06186 }
06187 else
06188 {
06189 for (col = 0; col < width; col++)
06190 {
06191 ushort *pixel = image[row * width + col];
06192
06193 *output++ = (float)pixel[0] / 0xffff;
06194 *output++ = (float)pixel[1] / 0xffff;
06195 *output++ = (float)pixel[2] / 0xffff;
06196
06197 if(dcraw_alpha) *output++ = 1.0;
06198 }
06199 }
06200 }
06201 }
06202
06203
06204
06205
06206
06207 void CLASS write_psd (FILE *ofp)
06208 {
06209 char head[] = {
06210 '8','B','P','S',
06211 0,1,0,0,0,0,0,0,
06212 0,3,
06213 0,0,0,0,
06214 0,0,0,0,
06215 0,16,
06216 0,3,
06217 0,0,0,0,
06218 0,0,0,0,
06219 0,0,0,0,
06220 0,0
06221 };
06222 int hw[2], psize, row, col, c;
06223 ushort *buffer, *pred;
06224
06225 hw[0] = htonl(height);
06226 hw[1] = htonl(width);
06227 memcpy (head+14, hw, sizeof hw);
06228 head[13] = head[25] = colors;
06229 fwrite (head, 40, 1, ofp);
06230
06231 psize = height*width;
06232 buffer = calloc (colors, psize*2);
06233 merror (buffer, "write_psd()");
06234 pred = buffer;
06235
06236 for (row = 0; row < height; row++)
06237 for (col = 0; col < width; col++) {
06238 FORCC pred[c*psize] = htons(image[row*width+col][c]);
06239 pred++;
06240 }
06241 fwrite(buffer, psize*2, colors, ofp);
06242 free (buffer);
06243 }
06244
06245
06246 int CLASS dcraw_main (int argc, char **argv)
06247 {
06248
06249
06250 document_mode = 0;
06251 use_camera_wb = 0;
06252
06253 int arg, status=0, user_flip=-1, user_black=-1, user_qual=-1;
06254 int timestamp_only=0, thumbnail_only=0, identify_only=0, write_to_stdout=0;
06255 int half_size=0, use_fuji_rotate=1, quality, i, c;
06256 char opt, *write_ext, *ofname, *cp;
06257 struct utimbuf ut;
06258 FILE *ofp = stdout;
06259 void (*write_image)(FILE *) = write_ppm;
06260 #ifndef NO_LCMS
06261 char *cam_profile = NULL, *out_profile = NULL;
06262 #endif
06263
06264 #ifndef LOCALTIME
06265 putenv ("TZ=UTC");
06266 #endif
06267 if (argc == 1)
06268 {
06269 fprintf (stderr,
06270 "\nRaw Photo Decoder \"dcraw\" v8.11"
06271 "\nby Dave Coffin, dcoffin a cybercom o net"
06272 "\n\nUsage: %s [options] file1 file2 ...\n"
06273 "\nValid options:"
06274 "\n-v Print verbose messages"
06275 "\n-c Write image data to standard output"
06276 "\n-e Extract embedded thumbnail image"
06277 "\n-i Identify files without decoding them"
06278 "\n-z Change file dates to camera timestamp"
06279 "\n-a Use automatic white balance"
06280 "\n-w Use camera white balance, if possible"
06281 "\n-r <num> Set red multiplier (default = 1.0)"
06282 "\n-l <num> Set blue multiplier (default = 1.0)"
06283 "\n-b <num> Set brightness (default = 1.0)"
06284 "\n-k <num> Set black point"
06285 "\n-n Don't clip colors"
06286 "\n-o [0-5] Output colorspace (raw,sRGB,Adobe,Wide,ProPhoto,XYZ)"
06287 #ifndef NO_LCMS
06288 "\n-o <file> Apply output ICC profile from file"
06289 "\n-p <file> Apply camera ICC profile from file or \"embed\""
06290 #endif
06291 "\n-d Document Mode (no color, no interpolation)"
06292 "\n-D Document Mode without scaling (totally raw)"
06293 "\n-q [0-3] Set the interpolation quality"
06294 "\n-h Half-size color image (twice as fast as \"-q 0\")"
06295 "\n-f Interpolate RGGB as four colors"
06296 "\n-B <domain> <range> Apply bilateral filter to reduce noise"
06297 "\n-j Show Fuji Super CCD images tilted 45 degrees"
06298 "\n-s Use secondary pixels (Fuji Super CCD SR only)"
06299 "\n-t [0-7] Flip image (0 = none, 3 = 180, 5 = 90CCW, 6 = 90CW)"
06300 "\n-2 Write 8-bit non-linear PPM (default)"
06301 "\n-4 Write 16-bit linear PPM"
06302 "\n-3 Write 16-bit linear PSD (Adobe Photoshop)"
06303 "\n\n", argv[0]);
06304 return 1;
06305 }
06306
06307 argv[argc] = "";
06308 for (arg=1; argv[arg][0] == '-'; ) {
06309 opt = argv[arg++][1];
06310 if ((strchr("Bbrlktq", opt) && !isdigit(argv[arg][0])) ||
06311 (opt == 'B' && !isdigit(argv[arg+1][0]))) {
06312 fprintf (stderr, "Non-numeric argument to \"-%c\"\n", opt);
06313 return 1;
06314 }
06315 switch (opt)
06316 {
06317 case 'B': sigma_d = atof(argv[arg++]);
06318 sigma_r = atof(argv[arg++]); break;
06319 case 'b': bright = atof(argv[arg++]); break;
06320 case 'r': red_scale = atof(argv[arg++]); break;
06321 case 'l': blue_scale = atof(argv[arg++]); break;
06322 case 'k': user_black = atoi(argv[arg++]); break;
06323 case 't': user_flip = atoi(argv[arg++]); break;
06324 case 'q': user_qual = atoi(argv[arg++]); break;
06325 case 'o':
06326 if (isdigit(argv[arg][0]) && !argv[arg][1])
06327 output_color = atoi(argv[arg++]);
06328 #ifndef NO_LCMS
06329 else out_profile = argv[arg++];
06330 break;
06331 case 'p': cam_profile = argv[arg++];
06332 #endif
06333 break;
06334 case 'z': timestamp_only = 1; break;
06335 case 'e': thumbnail_only = 1; break;
06336 case 'i': identify_only = 1; break;
06337 case 'c': write_to_stdout = 1; break;
06338 case 'v': verbose = 1; break;
06339 case 'h': half_size = 1;
06340 case 'f': four_color_rgb = 1; break;
06341 case 'd': document_mode = 1; break;
06342 case 'D': document_mode = 2; break;
06343 case 'a': use_auto_wb = 1; break;
06344 case 'w': use_camera_wb = 1; break;
06345 case 'j': use_fuji_rotate = 0; break;
06346 case 's': use_secondary = 1; break;
06347 case 'n': clip_color = 0; break;
06348 case 'm': output_color = 0; break;
06349
06350 case '2': write_image = write_ppm; break;
06351 case '4': write_image = write_ppm16; break;
06352 case '3': write_image = write_psd; break;
06353
06354 default:
06355 fprintf (stderr, "Unknown option \"-%c\".\n", opt);
06356 return 1;
06357 }
06358 }
06359
06360
06361
06362 if (arg == argc) {
06363 fprintf (stderr, "No files to process.\n");
06364 return 1;
06365 }
06366
06367
06368 if (write_to_stdout) {
06369
06370 if (0 ) {
06371 fprintf (stderr, "Will not write an image to the terminal!\n");
06372 return 1;
06373 }
06374 #if defined(WIN32) || defined(DJGPP) || defined(__CYGWIN__)
06375 if (setmode(1,O_BINARY) < 0) {
06376 perror("setmode()");
06377 return 1;
06378 }
06379 #endif
06380 }
06381
06382
06383 for ( ; arg < argc; arg++) {
06384 status = 1;
06385 image = NULL;
06386 if (setjmp (failure)) {
06387 if (fileno(ifp) > 2) fclose(ifp);
06388 if (fileno(ofp) > 2) fclose(ofp);
06389 if (image) free (image);
06390 status = 1;
06391 continue;
06392 }
06393 ifname = argv[arg];
06394 if (!(ifp = fopen (ifname, "rb"))) {
06395 perror (ifname);
06396 continue;
06397 }
06398 status = (identify(),!is_raw);
06399 if (timestamp_only) {
06400 if ((status = !timestamp))
06401 fprintf (stderr, "%s has no timestamp.\n", ifname);
06402 else if (identify_only)
06403 printf ("%10ld%10d %s\n", (long) timestamp, shot_order, ifname);
06404 else {
06405 if (verbose)
06406 fprintf (stderr, "%s time set to %d.\n", ifname, (int) timestamp);
06407 ut.actime = ut.modtime = timestamp;
06408 utime (ifname, &ut);
06409 }
06410 goto next;
06411 }
06412
06413 write_fun = write_image;
06414
06415
06416 write_fun = write_cinelerra;
06417
06418
06419 if (thumbnail_only) {
06420 if ((status = !thumb_offset)) {
06421 fprintf (stderr, "%s has no thumbnail.\n", ifname);
06422 goto next;
06423 } else if (thumb_load_raw) {
06424 load_raw = thumb_load_raw;
06425 data_offset = thumb_offset;
06426 height = thumb_height;
06427 width = thumb_width;
06428 filters = 0;
06429 } else {
06430 fseek (ifp, thumb_offset, SEEK_SET);
06431 write_fun = write_thumb;
06432 goto thumbnail;
06433 }
06434 }
06435 if (load_raw == kodak_ycbcr_load_raw) {
06436 height += height & 1;
06437 width += width & 1;
06438 }
06439 if (identify_only && verbose && make[0]) {
06440 printf ("\nFilename: %s\n", ifname);
06441 printf ("Timestamp: %s", ctime(×tamp));
06442 printf ("Camera: %s %s\n", make, model);
06443 printf ("ISO speed: %d\n", (int) iso_speed);
06444 printf ("Shutter: ");
06445 if (shutter > 0 && shutter < 1)
06446 shutter = (printf ("1/"), 1 / shutter);
06447 printf ("%0.1f sec\n", shutter);
06448 printf ("Aperture: f/%0.1f\n", aperture);
06449 printf ("Focal Length: %d mm\n", (int) focal_len);
06450 printf ("Embedded ICC profile: %s\n", profile_length ? "yes":"no");
06451 printf ("Decodable with dcraw: %s\n", is_raw ? "yes":"no");
06452 if (thumb_offset)
06453 printf ("Thumb size: %4d x %d\n", thumb_width, thumb_height);
06454 printf ("Full size: %4d x %d\n", raw_width, raw_height);
06455 }
06456
06457
06458
06459
06460 if (!is_raw) goto next;
06461 if (user_flip >= 0)
06462 flip = user_flip;
06463 switch ((flip+3600) % 360) {
06464 case 270: flip = 5; break;
06465 case 180: flip = 3; break;
06466 case 90: flip = 6;
06467 }
06468 shrink = half_size && filters;
06469 iheight = (height + shrink) >> shrink;
06470 iwidth = (width + shrink) >> shrink;
06471 if (identify_only) {
06472 if (verbose) {
06473 if (fuji_width && use_fuji_rotate) {
06474 fuji_width = (fuji_width - 1 + shrink) >> shrink;
06475 iwidth = fuji_width / sqrt(0.5);
06476 iheight = (iheight - fuji_width) / sqrt(0.5);
06477 }
06478 if (write_fun == write_ppm) {
06479 iheight *= ymag;
06480 iwidth *= xmag;
06481 }
06482 if (flip & 4)
06483 SWAP (iheight, iwidth);
06484 printf ("Image size: %4d x %d\n", width, height);
06485 printf ("Output size: %4d x %d\n", iwidth, iheight);
06486 printf ("Raw colors: %d", colors);
06487 if (filters) {
06488 printf ("\nFilter pattern: ");
06489 if (!cdesc[3]) cdesc[3] = 'G';
06490 for (i=0; i < 32; i+=2)
06491 putchar (cdesc[filters >> i & 3]);
06492 }
06493 printf ("\nDaylight multipliers:");
06494 FORCC printf (" %f", pre_mul[c]);
06495 if (cam_mul[0] > 0) {
06496 printf ("\nCamera multipliers:");
06497 FORCC printf (" %f", cam_mul[c]);
06498 }
06499 putchar ('\n');
06500 } else
06501
06502
06503 next:
06504 fclose(ifp);
06505 continue;
06506 }
06507 image = calloc (iheight*iwidth*sizeof *image + meta_length, 1);
06508 merror (image, "main()");
06509 meta_data = (char *) (image + iheight*iwidth);
06510 if (verbose)
06511 fprintf (stderr,
06512 "Loading %s %s image from %s...\n", make, model, ifname);
06513 fseek (ifp, data_offset, SEEK_SET);
06514 (*load_raw)();
06515 bad_pixels();
06516 height = iheight;
06517 width = iwidth;
06518 quality = 2 + !fuji_width;
06519 if (user_qual >= 0) quality = user_qual;
06520 if (user_black >= 0) black = user_black;
06521 #ifdef COLORCHECK
06522 colorcheck();
06523 #endif
06524 if (is_foveon && !document_mode) foveon_interpolate();
06525 if (!is_foveon && document_mode < 2) scale_colors();
06526 if (shrink) filters = 0;
06527 cam_to_cielab (NULL,NULL);
06528
06529
06530
06531
06532
06533
06534
06535
06536
06537
06538
06539
06540 if (filters && !document_mode)
06541 {
06542 if (quality == 0)
06543 lin_interpolate();
06544 else
06545 if (quality < 3 || colors > 3)
06546 vng_interpolate();
06547 else
06548 ahd_interpolate();
06549 }
06550
06551 if (sigma_d > 0 && sigma_r > 0) bilateral_filter();
06552 if (use_fuji_rotate) fuji_rotate();
06553 #ifndef NO_LCMS
06554 if (cam_profile) apply_profile (cam_profile, out_profile);
06555 #endif
06556 convert_to_rgb();
06557 if (flip) flip_image();
06558 thumbnail:
06559 if (write_fun == jpeg_thumb)
06560 write_ext = ".jpg";
06561 else if (write_fun == write_psd)
06562 write_ext = ".psd";
06563 else
06564 write_ext = ".pgm\0.ppm\0.ppm\0.pam" + colors*5-5;
06565 ofname = malloc (strlen(ifname) + 16);
06566 merror (ofname, "main()");
06567 if (write_to_stdout)
06568 strcpy (ofname, "standard output");
06569 else {
06570 strcpy (ofname, ifname);
06571 if ((cp = strrchr (ofname, '.'))) *cp = 0;
06572 if (thumbnail_only)
06573 strcat (ofname, ".thumb");
06574 strcat (ofname, write_ext);
06575 ofp = fopen (ofname, "wb");
06576 if (!ofp) {
06577 status = 1;
06578 perror(ofname);
06579 goto cleanup;
06580 }
06581 }
06582 if (verbose)
06583 fprintf (stderr, "Writing data to %s ...\n", ofname);
06584 (*write_fun)(ofp);
06585 fclose(ifp);
06586 if (ofp != stdout) fclose(ofp);
06587 cleanup:
06588 free (ofname);
06589 free (image);
06590 }
06591 return status;
06592 }