00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #define _GNU_SOURCE
00019 #include <ctype.h>
00020 #include <errno.h>
00021 #include <fcntl.h>
00022 #include <float.h>
00023 #include <limits.h>
00024 #include <math.h>
00025 #include <setjmp.h>
00026 #include <stdio.h>
00027 #include <stdlib.h>
00028 #include <string.h>
00029 #include <time.h>
00030
00031
00032
00033
00034 #ifndef NO_JPEG
00035 #include <jpeglib.h>
00036 #endif
00037
00038 #ifdef WIN32
00039 #include <winsock2.h>
00040 #pragma comment(lib, "ws2_32.lib")
00041 #define strcasecmp stricmp
00042 typedef __int64 INT64;
00043 #else
00044 #include <unistd.h>
00045 #include <netinet/in.h>
00046 typedef long long INT64;
00047 #endif
00048
00049 #ifdef LJPEG_DECODE
00050 #error Please compile dcraw.c by itself.
00051 #error Do not link it with ljpeg_decode.
00052 #endif
00053
00054 #ifndef LONG_BIT
00055 #define LONG_BIT (8 * sizeof (long))
00056 #endif
00057
00058 #define ushort UshORt
00059 typedef unsigned char uchar;
00060 typedef unsigned short ushort;
00061
00062 #define ABS_MAX ((ushort) -1)
00063 #define RGB_MAX ((ushort) -1)
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074 char dcraw_info[1024];
00075 float **dcraw_data;
00076 int dcraw_alpha;
00077
00078
00079 FILE *ifp;
00080 short order;
00081 char *ifname, make[64], model[64], model2[64];
00082 time_t timestamp;
00083 int data_offset, curve_offset, curve_length;
00084 int tiff_data_compression, kodak_data_compression;
00085 int raw_height, raw_width, top_margin, left_margin;
00086 int height, width, colors, black, rgb_max;
00087 int iheight, iwidth, shrink;
00088 int is_canon, is_cmy, is_foveon, use_coeff, trim, flip, xmag, ymag;
00089 int zero_after_ff;
00090 unsigned filters;
00091 ushort (*image)[4], white[8][8];
00092 void (*load_raw)();
00093 float gamma_val=0.6, bright=1.0, red_scale=1.0, blue_scale=1.0;
00094 int four_color_rgb=0, document_mode=0, quick_interpolate=0;
00095 int verbose=0, use_auto_wb=0, use_camera_wb=0, use_secondary=0;
00096 float camera_red, camera_blue;
00097 float pre_mul[4], coeff[3][4];
00098 float k1=1.5, k2=0.5, juice=0.0;
00099 int histogram[0x2000];
00100 void write_ppm(FILE *);
00101
00102
00103 void (*write_fun)(FILE *) = write_ppm;
00104
00105
00106 jmp_buf failure;
00107
00108 float green_scale=1.0;
00109 float saturation = 1.0;
00110 float contrast = 1.0;
00111 int autoexposure=0, use_pivot=0, use_neutral_wb=0;
00112 int alternate_scale = 0;
00113 int center_weight = 0;
00114 int use_camera_black = 1;
00115 int user_black = -1;
00116 float pivot_value = 0.75, exposure_compensation=0.0;
00117 unsigned pivot_point[4], pivot_base[4];
00118 float white_point_fraction = 0.99;
00119
00120 struct decode {
00121 struct decode *branch[2];
00122 int leaf;
00123 } first_decode[2048], *second_decode, *free_decode;
00124
00125 #define CLASS
00126
00127
00128
00129
00130
00131
00132
00133
00134 #define FC(row,col) \
00135 (filters >> ((((row) << 1 & 14) + ((col) & 1)) << 1) & 3)
00136
00137 #define BAYER(row,col) \
00138 image[((row) >> shrink)*iwidth + ((col) >> shrink)][FC(row,col)]
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
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 #ifndef __GLIBC__
00200 char *memmem (char *haystack, size_t haystacklen,
00201 char *needle, size_t needlelen)
00202 {
00203 char *c;
00204 for (c = haystack; c <= haystack + haystacklen - needlelen; c++)
00205 if (!memcmp (c, needle, needlelen))
00206 return c;
00207 return NULL;
00208 }
00209 #endif
00210
00211 void CLASS merror (void *ptr, char *where)
00212 {
00213 if (ptr) return;
00214 fprintf (stderr, "%s: Out of memory in %s\n", ifname, where);
00215 longjmp (failure, 1);
00216 }
00217
00218
00219
00220
00221
00222 ushort CLASS fget2 (FILE *f)
00223 {
00224 uchar a, b;
00225
00226 a = fgetc(f);
00227 b = fgetc(f);
00228 if (order == 0x4949)
00229 return a + (b << 8);
00230 else
00231 return (a << 8) + b;
00232 }
00233
00234
00235
00236
00237 int CLASS fget4 (FILE *f)
00238 {
00239 uchar a, b, c, d;
00240
00241 a = fgetc(f);
00242 b = fgetc(f);
00243 c = fgetc(f);
00244 d = fgetc(f);
00245 if (order == 0x4949)
00246 return a + (b << 8) + (c << 16) + (d << 24);
00247 else
00248 return (a << 24) + (b << 16) + (c << 8) + d;
00249 }
00250
00251 void CLASS canon_600_load_raw()
00252 {
00253 uchar data[1120], *dp;
00254 ushort pixel[896], *pix;
00255 int irow, orow, col;
00256
00257 for (irow=orow=0; irow < height; irow++)
00258 {
00259 fread (data, 1120, 1, ifp);
00260 for (dp=data, pix=pixel; dp < data+1120; dp+=10, pix+=8)
00261 {
00262 pix[0] = (dp[0] << 2) + (dp[1] >> 6 );
00263 pix[1] = (dp[2] << 2) + (dp[1] >> 4 & 3);
00264 pix[2] = (dp[3] << 2) + (dp[1] >> 2 & 3);
00265 pix[3] = (dp[4] << 2) + (dp[1] & 3);
00266 pix[4] = (dp[5] << 2) + (dp[9] & 3);
00267 pix[5] = (dp[6] << 2) + (dp[9] >> 2 & 3);
00268 pix[6] = (dp[7] << 2) + (dp[9] >> 4 & 3);
00269 pix[7] = (dp[8] << 2) + (dp[9] >> 6 );
00270 }
00271 for (col=0; col < width; col++)
00272 BAYER(orow,col) = pixel[col] << 4;
00273 for (col=width; col < 896; col++)
00274 black += pixel[col];
00275 if ((orow+=2) > height)
00276 orow = 1;
00277 }
00278 black = ((INT64) black << 4) / ((896 - width) * height);
00279 }
00280
00281 void CLASS canon_a5_load_raw()
00282 {
00283 uchar data[1940], *dp;
00284 ushort pixel[1552], *pix;
00285 int row, col;
00286
00287 for (row=0; row < height; row++) {
00288 fread (data, raw_width * 10 / 8, 1, ifp);
00289 for (dp=data, pix=pixel; pix < pixel+raw_width; dp+=10, pix+=8)
00290 {
00291 pix[0] = (dp[1] << 2) + (dp[0] >> 6);
00292 pix[1] = (dp[0] << 4) + (dp[3] >> 4);
00293 pix[2] = (dp[3] << 6) + (dp[2] >> 2);
00294 pix[3] = (dp[2] << 8) + (dp[5] );
00295 pix[4] = (dp[4] << 2) + (dp[7] >> 6);
00296 pix[5] = (dp[7] << 4) + (dp[6] >> 4);
00297 pix[6] = (dp[6] << 6) + (dp[9] >> 2);
00298 pix[7] = (dp[9] << 8) + (dp[8] );
00299 }
00300 for (col=0; col < width; col++)
00301 BAYER(row,col) = (pixel[col] & 0x3ff) << 4;
00302 for (col=width; col < raw_width; col++)
00303 black += pixel[col] & 0x3ff;
00304 }
00305 if (raw_width > width)
00306 black = ((INT64) black << 4) / ((raw_width - width) * height);
00307 }
00308
00309
00310
00311
00312
00313 unsigned CLASS getbits (int nbits)
00314 {
00315 static unsigned long bitbuf=0;
00316 static int vbits=0;
00317 unsigned c, ret;
00318
00319 if (nbits == 0) return 0;
00320 if (nbits == -1)
00321 ret = bitbuf = vbits = 0;
00322 else {
00323 ret = bitbuf << (LONG_BIT - vbits) >> (LONG_BIT - nbits);
00324 vbits -= nbits;
00325 }
00326 while (vbits < LONG_BIT - 7) {
00327 c = fgetc(ifp);
00328 bitbuf = (bitbuf << 8) + c;
00329 if (c == 0xff && zero_after_ff)
00330 fgetc(ifp);
00331 vbits += 8;
00332 }
00333 return ret;
00334 }
00335
00336 void CLASS init_decoder ()
00337 {
00338 memset (first_decode, 0, sizeof first_decode);
00339 free_decode = first_decode;
00340 }
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368 uchar * CLASS make_decoder (const uchar *source, int level)
00369 {
00370 struct decode *cur;
00371 static int leaf;
00372 int i, next;
00373
00374 if (level==0) leaf=0;
00375 cur = free_decode++;
00376 if (free_decode > first_decode+2048) {
00377 fprintf (stderr, "%s: decoder table overflow\n", ifname);
00378 longjmp (failure, 2);
00379 }
00380 for (i=next=0; i <= leaf && next < 16; )
00381 i += source[next++];
00382 if (i > leaf) {
00383 if (level < next) {
00384 cur->branch[0] = free_decode;
00385 make_decoder (source, level+1);
00386 cur->branch[1] = free_decode;
00387 make_decoder (source, level+1);
00388 } else
00389 cur->leaf = source[16 + leaf++];
00390 }
00391 return (uchar *) source + 16 + leaf;
00392 }
00393
00394 void CLASS crw_init_tables (unsigned table)
00395 {
00396 static const uchar first_tree[3][29] = {
00397 { 0,1,4,2,3,1,2,0,0,0,0,0,0,0,0,0,
00398 0x04,0x03,0x05,0x06,0x02,0x07,0x01,0x08,0x09,0x00,0x0a,0x0b,0xff },
00399
00400 { 0,2,2,3,1,1,1,1,2,0,0,0,0,0,0,0,
00401 0x03,0x02,0x04,0x01,0x05,0x00,0x06,0x07,0x09,0x08,0x0a,0x0b,0xff },
00402
00403 { 0,0,6,3,1,1,2,0,0,0,0,0,0,0,0,0,
00404 0x06,0x05,0x07,0x04,0x08,0x03,0x09,0x02,0x00,0x0a,0x01,0x0b,0xff },
00405 };
00406
00407 static const uchar second_tree[3][180] = {
00408 { 0,2,2,2,1,4,2,1,2,5,1,1,0,0,0,139,
00409 0x03,0x04,0x02,0x05,0x01,0x06,0x07,0x08,
00410 0x12,0x13,0x11,0x14,0x09,0x15,0x22,0x00,0x21,0x16,0x0a,0xf0,
00411 0x23,0x17,0x24,0x31,0x32,0x18,0x19,0x33,0x25,0x41,0x34,0x42,
00412 0x35,0x51,0x36,0x37,0x38,0x29,0x79,0x26,0x1a,0x39,0x56,0x57,
00413 0x28,0x27,0x52,0x55,0x58,0x43,0x76,0x59,0x77,0x54,0x61,0xf9,
00414 0x71,0x78,0x75,0x96,0x97,0x49,0xb7,0x53,0xd7,0x74,0xb6,0x98,
00415 0x47,0x48,0x95,0x69,0x99,0x91,0xfa,0xb8,0x68,0xb5,0xb9,0xd6,
00416 0xf7,0xd8,0x67,0x46,0x45,0x94,0x89,0xf8,0x81,0xd5,0xf6,0xb4,
00417 0x88,0xb1,0x2a,0x44,0x72,0xd9,0x87,0x66,0xd4,0xf5,0x3a,0xa7,
00418 0x73,0xa9,0xa8,0x86,0x62,0xc7,0x65,0xc8,0xc9,0xa1,0xf4,0xd1,
00419 0xe9,0x5a,0x92,0x85,0xa6,0xe7,0x93,0xe8,0xc1,0xc6,0x7a,0x64,
00420 0xe1,0x4a,0x6a,0xe6,0xb3,0xf1,0xd3,0xa5,0x8a,0xb2,0x9a,0xba,
00421 0x84,0xa4,0x63,0xe5,0xc5,0xf3,0xd2,0xc4,0x82,0xaa,0xda,0xe4,
00422 0xf2,0xca,0x83,0xa3,0xa2,0xc3,0xea,0xc2,0xe2,0xe3,0xff,0xff },
00423
00424 { 0,2,2,1,4,1,4,1,3,3,1,0,0,0,0,140,
00425 0x02,0x03,0x01,0x04,0x05,0x12,0x11,0x06,
00426 0x13,0x07,0x08,0x14,0x22,0x09,0x21,0x00,0x23,0x15,0x31,0x32,
00427 0x0a,0x16,0xf0,0x24,0x33,0x41,0x42,0x19,0x17,0x25,0x18,0x51,
00428 0x34,0x43,0x52,0x29,0x35,0x61,0x39,0x71,0x62,0x36,0x53,0x26,
00429 0x38,0x1a,0x37,0x81,0x27,0x91,0x79,0x55,0x45,0x28,0x72,0x59,
00430 0xa1,0xb1,0x44,0x69,0x54,0x58,0xd1,0xfa,0x57,0xe1,0xf1,0xb9,
00431 0x49,0x47,0x63,0x6a,0xf9,0x56,0x46,0xa8,0x2a,0x4a,0x78,0x99,
00432 0x3a,0x75,0x74,0x86,0x65,0xc1,0x76,0xb6,0x96,0xd6,0x89,0x85,
00433 0xc9,0xf5,0x95,0xb4,0xc7,0xf7,0x8a,0x97,0xb8,0x73,0xb7,0xd8,
00434 0xd9,0x87,0xa7,0x7a,0x48,0x82,0x84,0xea,0xf4,0xa6,0xc5,0x5a,
00435 0x94,0xa4,0xc6,0x92,0xc3,0x68,0xb5,0xc8,0xe4,0xe5,0xe6,0xe9,
00436 0xa2,0xa3,0xe3,0xc2,0x66,0x67,0x93,0xaa,0xd4,0xd5,0xe7,0xf8,
00437 0x88,0x9a,0xd7,0x77,0xc4,0x64,0xe2,0x98,0xa5,0xca,0xda,0xe8,
00438 0xf3,0xf6,0xa9,0xb2,0xb3,0xf2,0xd2,0x83,0xba,0xd3,0xff,0xff },
00439
00440 { 0,0,6,2,1,3,3,2,5,1,2,2,8,10,0,117,
00441 0x04,0x05,0x03,0x06,0x02,0x07,0x01,0x08,
00442 0x09,0x12,0x13,0x14,0x11,0x15,0x0a,0x16,0x17,0xf0,0x00,0x22,
00443 0x21,0x18,0x23,0x19,0x24,0x32,0x31,0x25,0x33,0x38,0x37,0x34,
00444 0x35,0x36,0x39,0x79,0x57,0x58,0x59,0x28,0x56,0x78,0x27,0x41,
00445 0x29,0x77,0x26,0x42,0x76,0x99,0x1a,0x55,0x98,0x97,0xf9,0x48,
00446 0x54,0x96,0x89,0x47,0xb7,0x49,0xfa,0x75,0x68,0xb6,0x67,0x69,
00447 0xb9,0xb8,0xd8,0x52,0xd7,0x88,0xb5,0x74,0x51,0x46,0xd9,0xf8,
00448 0x3a,0xd6,0x87,0x45,0x7a,0x95,0xd5,0xf6,0x86,0xb4,0xa9,0x94,
00449 0x53,0x2a,0xa8,0x43,0xf5,0xf7,0xd4,0x66,0xa7,0x5a,0x44,0x8a,
00450 0xc9,0xe8,0xc8,0xe7,0x9a,0x6a,0x73,0x4a,0x61,0xc7,0xf4,0xc6,
00451 0x65,0xe9,0x72,0xe6,0x71,0x91,0x93,0xa6,0xda,0x92,0x85,0x62,
00452 0xf3,0xc5,0xb2,0xa4,0x84,0xba,0x64,0xa5,0xb3,0xd2,0x81,0xe5,
00453 0xd3,0xaa,0xc4,0xca,0xf2,0xb1,0xe4,0xd1,0x83,0x63,0xea,0xc3,
00454 0xe2,0x82,0xf1,0xa3,0xc2,0xa1,0xc1,0xe3,0xa2,0xe1,0xff,0xff }
00455 };
00456
00457 if (table > 2) table = 2;
00458 init_decoder();
00459 make_decoder ( first_tree[table], 0);
00460 second_decode = free_decode;
00461 make_decoder (second_tree[table], 0);
00462 }
00463
00464
00465
00466
00467
00468
00469
00470 int CLASS canon_has_lowbits()
00471 {
00472 uchar test[0x4000];
00473 int ret=1, i;
00474
00475 fseek (ifp, 0, SEEK_SET);
00476 fread (test, 1, sizeof test, ifp);
00477 for (i=540; i < sizeof test - 1; i++)
00478 if (test[i] == 0xff) {
00479 if (test[i+1]) return 1;
00480 ret=0;
00481 }
00482 return ret;
00483 }
00484
00485 void CLASS canon_compressed_load_raw()
00486 {
00487 ushort *pixel, *prow;
00488 int lowbits, shift, i, row, r, col, save, val;
00489 unsigned irow, icol;
00490 struct decode *decode, *dindex;
00491 int block, diffbuf[64], leaf, len, diff, carry=0, pnum=0, base[2];
00492 uchar c;
00493 INT64 bblack=0;
00494
00495 pixel = calloc (raw_width*8, sizeof *pixel);
00496 merror (pixel, "canon_compressed_load_raw()");
00497 lowbits = canon_has_lowbits();
00498 shift = 4 - lowbits*2;
00499 fseek (ifp, 540 + lowbits*raw_height*raw_width/4, SEEK_SET);
00500 zero_after_ff = 1;
00501 getbits(-1);
00502
00503 for (row = 0; row < raw_height; row += 8) {
00504 for (block=0; block < raw_width >> 3; block++) {
00505 memset (diffbuf, 0, sizeof diffbuf);
00506 decode = first_decode;
00507 for (i=0; i < 64; i++ ) {
00508 for (dindex=decode; dindex->branch[0]; )
00509 dindex = dindex->branch[getbits(1)];
00510 leaf = dindex->leaf;
00511 decode = second_decode;
00512 if (leaf == 0 && i) break;
00513 if (leaf == 0xff) continue;
00514 i += leaf >> 4;
00515 len = leaf & 15;
00516 if (len == 0) continue;
00517 diff = getbits(len);
00518 if ((diff & (1 << (len-1))) == 0)
00519 diff -= (1 << len) - 1;
00520 if (i < 64) diffbuf[i] = diff;
00521 }
00522 diffbuf[0] += carry;
00523 carry = diffbuf[0];
00524 for (i=0; i < 64; i++ ) {
00525 if (pnum++ % raw_width == 0)
00526 base[0] = base[1] = 512;
00527 pixel[(block << 6) + i] = ( base[i & 1] += diffbuf[i] );
00528 }
00529 }
00530 if (lowbits) {
00531 save = ftell(ifp);
00532 fseek (ifp, 26 + row*raw_width/4, SEEK_SET);
00533 for (prow=pixel, i=0; i < raw_width*2; i++) {
00534 c = fgetc(ifp);
00535 for (r=0; r < 8; r+=2, prow++) {
00536 val = (*prow << 2) + ((c >> r) & 3);
00537 if (raw_width == 2672 && val < 512) val += 2;
00538 *prow = val;
00539 }
00540 }
00541 fseek (ifp, save, SEEK_SET);
00542 }
00543 for (r=0; r < 8; r++) {
00544 irow = row - top_margin + r;
00545 if (irow >= height) continue;
00546 for (col = 0; col < raw_width; col++) {
00547 icol = col - left_margin;
00548 if (icol < width)
00549 BAYER(irow,icol) = pixel[r*raw_width+col] << shift;
00550 else
00551 bblack += pixel[r*raw_width+col];
00552 }
00553 }
00554 }
00555 free(pixel);
00556 if (raw_width > width)
00557 black = (bblack << shift) / ((raw_width - width) * height);
00558 }
00559
00560 void CLASS kodak_curve (ushort *curve)
00561 {
00562 int i, entries, tag, type, len, val;
00563
00564 for (i=0; i < 0x1000; i++)
00565 curve[i] = i;
00566 if (strcasecmp(make,"KODAK")) return;
00567 if (!curve_offset) {
00568 fseek (ifp, 12, SEEK_SET);
00569 entries = fget2(ifp);
00570 while (entries--) {
00571 tag = fget2(ifp);
00572 type = fget2(ifp);
00573 len = fget4(ifp);
00574 val = fget4(ifp);
00575 if (tag == 0x90d) {
00576 curve_offset = val;
00577 curve_length = len;
00578 }
00579 }
00580 }
00581 if (curve_offset) {
00582 fseek (ifp, curve_offset, SEEK_SET);
00583 for (i=0; i < curve_length; i++)
00584 curve[i] = fget2(ifp);
00585 for ( ; i < 0x1000; i++)
00586 curve[i] = curve[i-1];
00587 rgb_max = curve[i-1] << 2;
00588 }
00589 fseek (ifp, data_offset, SEEK_SET);
00590 }
00591
00592
00593
00594
00595
00596 void CLASS lossless_jpeg_load_raw()
00597 {
00598 int tag, len, jhigh=0, jwide=0, jrow, jcol, jidx, diff, i, row, col;
00599 uchar data[256], *dp;
00600 int vpred[2] = { 0x800, 0x800 }, hpred[2];
00601 struct decode *dstart[2], *dindex;
00602 ushort curve[0x10000];
00603 INT64 bblack=0;
00604 int min=INT_MAX;
00605
00606 kodak_curve(curve);
00607 order = 0x4d4d;
00608 if (fget2(ifp) != 0xffd8) return;
00609
00610 do {
00611 tag = fget2(ifp);
00612 len = fget2(ifp) - 2;
00613 if (tag <= 0xff00 || len > 255) return;
00614 fread (data, 1, len, ifp);
00615 switch (tag) {
00616 case 0xffc3:
00617 jhigh = (data[1] << 8) + data[2];
00618 jwide =((data[3] << 8) + data[4])*2;
00619 break;
00620 case 0xffc4:
00621 init_decoder();
00622 dstart[0] = dstart[1] = free_decode;
00623 for (dp = data; dp < data+len && *dp < 2; ) {
00624 dstart[*dp] = free_decode;
00625 dp = make_decoder (++dp, 0);
00626 }
00627 }
00628 } while (tag != 0xffda);
00629
00630 zero_after_ff = 1;
00631 getbits(-1);
00632 for (jrow=0; jrow < jhigh; jrow++)
00633 {
00634
00635
00636
00637
00638 for (jcol=0; jcol < jwide; jcol++)
00639 {
00640 for (dindex = dstart[jcol & 1]; dindex->branch[0]; )
00641 dindex = dindex->branch[getbits(1)];
00642 len = dindex->leaf;
00643 diff = getbits(len);
00644 if ((diff & (1 << (len-1))) == 0)
00645 diff -= (1 << len) - 1;
00646 if (jcol < 2) {
00647 vpred[jcol] += diff;
00648 hpred[jcol] = vpred[jcol];
00649 } else
00650 hpred[jcol & 1] += diff;
00651 diff = hpred[jcol & 1];
00652 if (diff < 0) diff = 0;
00653 jidx = jrow*jwide + jcol;
00654 if (raw_width == 5108) {
00655 i = jidx / (1680*jhigh);
00656 if (i < 2) {
00657 row = jidx / 1680 % jhigh;
00658 col = jidx % 1680 + i*1680;
00659 } else {
00660 jidx -= 2*1680*jhigh;
00661 row = jidx / 1748;
00662 col = jidx % 1748 + 2*1680;
00663 }
00664 } else {
00665 row = jidx / raw_width;
00666 col = jidx % raw_width;
00667 }
00668 if ((unsigned) (row-top_margin) >= height)
00669 continue;
00670 if ((unsigned) (col-left_margin) < width) {
00671 BAYER(row-top_margin,col-left_margin) = curve[diff] << 2;
00672 if (min > curve[diff])
00673 min = curve[diff];
00674 } else
00675 bblack += curve[diff];
00676 }
00677 }
00678
00679
00680
00681
00682
00683
00684
00685
00686
00687
00688
00689 if (raw_width > width)
00690 black = (bblack << 2) / ((raw_width - width) * height);
00691 if (!strcasecmp(make,"KODAK"))
00692 black = min << 2;
00693 }
00694
00695 void CLASS nikon_compressed_load_raw()
00696 {
00697 static const uchar nikon_tree[] = {
00698 0,1,5,1,1,1,1,1,1,2,0,0,0,0,0,0,
00699 5,4,3,6,2,7,1,0,8,9,11,10,12
00700 };
00701 int vpred[4], hpred[2], csize, row, col, i, len, diff;
00702 ushort *curve;
00703 struct decode *dindex;
00704
00705 init_decoder();
00706 make_decoder (nikon_tree, 0);
00707
00708 fseek (ifp, curve_offset, SEEK_SET);
00709 for (i=0; i < 4; i++)
00710 vpred[i] = fget2(ifp);
00711 csize = fget2(ifp);
00712 curve = calloc (csize, sizeof *curve);
00713 merror (curve, "nikon_compressed_load_raw()");
00714 for (i=0; i < csize; i++)
00715 curve[i] = fget2(ifp);
00716
00717 fseek (ifp, data_offset, SEEK_SET);
00718 getbits(-1);
00719
00720 for (row=0; row < height; row++)
00721 for (col=0; col < raw_width; col++)
00722 {
00723 for (dindex=first_decode; dindex->branch[0]; )
00724 dindex = dindex->branch[getbits(1)];
00725 len = dindex->leaf;
00726 diff = getbits(len);
00727 if ((diff & (1 << (len-1))) == 0)
00728 diff -= (1 << len) - 1;
00729 if (col < 2) {
00730 i = 2*(row & 1) + (col & 1);
00731 vpred[i] += diff;
00732 hpred[col] = vpred[i];
00733 } else
00734 hpred[col & 1] += diff;
00735 if ((unsigned) (col-left_margin) >= width) continue;
00736 diff = hpred[col & 1];
00737 if (diff < 0) diff = 0;
00738 if (diff >= csize) diff = csize-1;
00739 BAYER(row,col-left_margin) = curve[diff] << 2;
00740 }
00741 free(curve);
00742 }
00743
00744 void CLASS nikon_load_raw()
00745 {
00746 int irow, row, col, i;
00747
00748 getbits(-1);
00749 for (irow=0; irow < height; irow++) {
00750 row = irow;
00751 if (model[0] == 'E') {
00752 row = irow * 2 % height + irow / (height/2);
00753 if (row == 1 && atoi(model+1) < 5000) {
00754 fseek (ifp, 0, SEEK_END);
00755 fseek (ifp, ftell(ifp)/2, SEEK_SET);
00756 getbits(-1);
00757 }
00758 }
00759 for (col=0; col < raw_width; col++) {
00760 i = getbits(12);
00761 if ((unsigned) (col-left_margin) < width)
00762 BAYER(row,col-left_margin) = i << 2;
00763 if (tiff_data_compression == 34713 && (col % 10) == 9)
00764 getbits(8);
00765 }
00766 }
00767 }
00768
00769
00770
00771
00772
00773
00774 int CLASS nikon_is_compressed()
00775 {
00776 uchar test[256];
00777 int i;
00778
00779 if (tiff_data_compression != 34713)
00780 return 0;
00781 if (strcmp(model,"D100"))
00782 return 1;
00783 fseek (ifp, data_offset, SEEK_SET);
00784 fread (test, 1, 256, ifp);
00785 for (i=15; i < 256; i+=16)
00786 if (test[i]) return 1;
00787 return 0;
00788 }
00789
00790
00791
00792
00793 int CLASS nikon_e990()
00794 {
00795 int i, histo[256];
00796 const uchar often[] = { 0x00, 0x55, 0xaa, 0xff };
00797
00798 memset (histo, 0, sizeof histo);
00799 fseek (ifp, 2064*1540*3/4, SEEK_SET);
00800 for (i=0; i < 2000; i++)
00801 histo[fgetc(ifp)]++;
00802 for (i=0; i < 4; i++)
00803 if (histo[often[i]] > 400)
00804 return 1;
00805 return 0;
00806 }
00807
00808
00809
00810
00811 int CLASS nikon_e2100()
00812 {
00813 uchar t[12];
00814 int i;
00815
00816 fseek (ifp, 0, SEEK_SET);
00817 for (i=0; i < 1024; i++) {
00818 fread (t, 1, 12, ifp);
00819 if (((t[2] & t[4] & t[7] & t[9]) >> 4
00820 & t[1] & t[6] & t[8] & t[11] & 3) != 3)
00821 return 0;
00822 }
00823 return 1;
00824 }
00825
00826
00827
00828
00829 int CLASS minolta_z2()
00830 {
00831 int i;
00832 char tail[424];
00833
00834 fseek (ifp, -sizeof tail, SEEK_END);
00835 fread (tail, 1, sizeof tail, ifp);
00836 for (i=0; i < sizeof tail; i++)
00837 if (tail[i]) return 1;
00838 return 0;
00839 }
00840
00841 void CLASS nikon_e2100_load_raw()
00842 {
00843 uchar data[3432], *dp;
00844 ushort pixel[2288], *pix;
00845 int row, col;
00846
00847 for (row=0; row <= height; row+=2) {
00848 if (row == height) {
00849 fseek (ifp, width==1616 ? 8792:424, SEEK_CUR);
00850 row = 1;
00851 }
00852 fread (data, 1, width*3/2, ifp);
00853 for (dp=data, pix=pixel; pix < pixel+width; dp+=12, pix+=8) {
00854 pix[0] = (dp[2] >> 4) + (dp[ 3] << 4);
00855 pix[1] = (dp[2] << 8) + dp[ 1];
00856 pix[2] = (dp[7] >> 4) + (dp[ 0] << 4);
00857 pix[3] = (dp[7] << 8) + dp[ 6];
00858 pix[4] = (dp[4] >> 4) + (dp[ 5] << 4);
00859 pix[5] = (dp[4] << 8) + dp[11];
00860 pix[6] = (dp[9] >> 4) + (dp[10] << 4);
00861 pix[7] = (dp[9] << 8) + dp[ 8];
00862 }
00863 for (col=0; col < width; col++)
00864 BAYER(row,col) = (pixel[col] & 0xfff) << 2;
00865 }
00866 }
00867
00868 void CLASS nikon_e950_load_raw()
00869 {
00870 int irow, row, col;
00871
00872 getbits(-1);
00873 for (irow=0; irow < height; irow++) {
00874 row = irow * 2 % height;
00875 for (col=0; col < width; col++)
00876 BAYER(row,col) = getbits(10) << 4;
00877 for (col=28; col--; )
00878 getbits(8);
00879 }
00880 }
00881
00882
00883
00884
00885 void CLASS fuji_s2_load_raw()
00886 {
00887 ushort pixel[2944];
00888 int row, col, r, c;
00889
00890 fseek (ifp, (2944*24+32)*2, SEEK_CUR);
00891 for (row=0; row < 2144; row++) {
00892 fread (pixel, 2, 2944, ifp);
00893 for (col=0; col < 2880; col++) {
00894 r = row + ((col+1) >> 1);
00895 c = 2143 - row + (col >> 1);
00896 BAYER(r,c) = ntohs(pixel[col]) << 2;
00897 }
00898 }
00899 }
00900
00901 void CLASS fuji_common_load_raw (int ncol, int icol, int nrow)
00902 {
00903 ushort pixel[2048];
00904 int row, col, r, c;
00905
00906 for (row=0; row < nrow; row++) {
00907 fread (pixel, 2, ncol, ifp);
00908 if (ntohs(0xaa55) == 0xaa55)
00909 swab (pixel, pixel, ncol*2);
00910 for (col=0; col <= icol; col++) {
00911 r = icol - col + (row >> 1);
00912 c = col + ((row+1) >> 1);
00913 BAYER(r,c) = pixel[col] << 2;
00914 }
00915 }
00916 }
00917
00918 void CLASS fuji_s5000_load_raw()
00919 {
00920 fseek (ifp, (1472*4+24)*2, SEEK_CUR);
00921 fuji_common_load_raw (1472, 1423, 2152);
00922 }
00923
00924 void CLASS fuji_s7000_load_raw()
00925 {
00926 fuji_common_load_raw (2048, 2047, 3080);
00927 }
00928
00929
00930
00931
00932
00933
00934 void CLASS fuji_f700_load_raw()
00935 {
00936 ushort pixel[2944];
00937 int row, col, r, c, val;
00938
00939 for (row=0; row < 2168; row++) {
00940 fread (pixel, 2, 2944, ifp);
00941 if (ntohs(0xaa55) == 0xaa55)
00942 swab (pixel, pixel, 2944*2);
00943 for (col=0; col < 1440; col++) {
00944 r = 1439 - col + (row >> 1);
00945 c = col + ((row+1) >> 1);
00946 val = pixel[col+16 + use_secondary*1472];
00947 BAYER(r,c) = val;
00948 }
00949 }
00950 }
00951
00952 void CLASS rollei_load_raw()
00953 {
00954 uchar pixel[10];
00955 unsigned iten=0, isix, i, buffer=0, row, col, todo[16];
00956
00957 isix = raw_width * raw_height * 5 / 8;
00958 while (fread (pixel, 1, 10, ifp) == 10) {
00959 for (i=0; i < 10; i+=2) {
00960 todo[i] = iten++;
00961 todo[i+1] = pixel[i] << 8 | pixel[i+1];
00962 buffer = pixel[i] >> 2 | buffer << 6;
00963 }
00964 for ( ; i < 16; i+=2) {
00965 todo[i] = isix++;
00966 todo[i+1] = buffer >> (14-i)*5;
00967 }
00968 for (i=0; i < 16; i+=2) {
00969 row = todo[i] / raw_width - top_margin;
00970 col = todo[i] % raw_width - left_margin;
00971 if (row < height && col < width)
00972 BAYER(row,col) = (todo[i+1] & 0x3ff) << 4;
00973 }
00974 }
00975 }
00976
00977 void CLASS phase_one_load_raw()
00978 {
00979 int row, col, a, b;
00980 ushort pixel[4134], akey, bkey;
00981
00982 fseek (ifp, 8, SEEK_CUR);
00983 fseek (ifp, fget4(ifp) + 296, SEEK_CUR);
00984 akey = fget2(ifp);
00985 bkey = fget2(ifp);
00986 fseek (ifp, data_offset + 12 + top_margin*raw_width*2, SEEK_SET);
00987 for (row=0; row < height; row++) {
00988 fread (pixel, 2, raw_width, ifp);
00989 for (col=0; col < raw_width; col+=2) {
00990 a = ntohs(pixel[col+0]) ^ akey;
00991 b = ntohs(pixel[col+1]) ^ bkey;
00992 pixel[col+0] = (b & 0xaaaa) | (a & 0x5555);
00993 pixel[col+1] = (a & 0xaaaa) | (b & 0x5555);
00994 }
00995 for (col=0; col < width; col++)
00996 BAYER(row,col) = pixel[col+left_margin];
00997 }
00998 }
00999
01000 void CLASS ixpress_load_raw()
01001 {
01002 ushort pixel[4090];
01003 int row, col;
01004
01005 fseek (ifp, 304 + 6*2*4090, SEEK_SET);
01006 for (row=height; --row >= 0; ) {
01007 fread (pixel, 2, 4090, ifp);
01008 if (ntohs(0xaa55) == 0xaa55)
01009 swab (pixel, pixel, 4090*2);
01010 for (col=0; col < width; col++)
01011 BAYER(row,col) = pixel[width-1-col];
01012 }
01013 }
01014
01015
01016 void CLASS packed_12_load_raw()
01017 {
01018 int row, col;
01019
01020 getbits(-1);
01021 for (row=0; row < height; row++) {
01022 for (col=0; col < width; col++)
01023 BAYER(row,col) = getbits(12) << 2;
01024 for (col = width*3/2; col < raw_width; col++)
01025 getbits(8);
01026 }
01027 }
01028
01029 void CLASS unpacked_load_raw (int order, int rsh)
01030 {
01031 ushort *pixel;
01032 int row, col;
01033
01034 pixel = calloc (raw_width, sizeof *pixel);
01035 merror (pixel, "unpacked_load_raw()");
01036 for (row=0; row < height; row++) {
01037 fread (pixel, 2, raw_width, ifp);
01038 if (order != ntohs(0x55aa))
01039 swab (pixel, pixel, width*2);
01040 for (col=0; col < width; col++)
01041 BAYER(row,col) = pixel[col] << 8 >> (8+rsh);
01042 }
01043 free(pixel);
01044 }
01045
01046 void CLASS be_16_load_raw()
01047 {
01048 unpacked_load_raw (0x55aa, 0);
01049 }
01050
01051 void CLASS be_high_12_load_raw()
01052 {
01053 unpacked_load_raw (0x55aa, 2);
01054 }
01055
01056 void CLASS be_low_12_load_raw()
01057 {
01058 unpacked_load_raw (0x55aa,-2);
01059 }
01060
01061 void CLASS be_low_10_load_raw()
01062 {
01063 unpacked_load_raw (0x55aa,-4);
01064 }
01065
01066 void CLASS le_high_12_load_raw()
01067 {
01068 unpacked_load_raw (0xaa55, 2);
01069 }
01070
01071 void CLASS olympus_cseries_load_raw()
01072 {
01073 int irow, row, col;
01074
01075 for (irow=0; irow < height; irow++) {
01076 row = irow * 2 % height + irow / (height/2);
01077 if (row < 2) {
01078 fseek (ifp, data_offset - row*(-width*height*3/4 & -2048), SEEK_SET);
01079 getbits(-1);
01080 }
01081 for (col=0; col < width; col++)
01082 BAYER(row,col) = getbits(12) << 2;
01083 }
01084 }
01085
01086 void CLASS eight_bit_load_raw()
01087 {
01088 uchar *pixel;
01089 int row, col;
01090
01091 pixel = calloc (raw_width, sizeof *pixel);
01092 merror (pixel, "eight_bit_load_raw()");
01093 for (row=0; row < height; row++) {
01094 fread (pixel, 1, raw_width, ifp);
01095 for (col=0; col < width; col++)
01096 BAYER(row,col) = pixel[col] << 6;
01097 }
01098 free (pixel);
01099 }
01100
01101 void CLASS casio_qv5700_load_raw()
01102 {
01103 uchar data[3232], *dp;
01104 ushort pixel[2576], *pix;
01105 int row, col;
01106
01107 for (row=0; row < height; row++) {
01108 fread (data, 1, 3232, ifp);
01109 for (dp=data, pix=pixel; dp < data+3220; dp+=5, pix+=4) {
01110 pix[0] = (dp[0] << 2) + (dp[1] >> 6);
01111 pix[1] = (dp[1] << 4) + (dp[2] >> 4);
01112 pix[2] = (dp[2] << 6) + (dp[3] >> 2);
01113 pix[3] = (dp[3] << 8) + (dp[4] );
01114 }
01115 for (col=0; col < width; col++)
01116 BAYER(row,col) = (pixel[col] & 0x3ff) << 4;
01117 }
01118 }
01119
01120 void CLASS nucore_load_raw()
01121 {
01122 uchar *data, *dp;
01123 int irow, row, col;
01124
01125 data = calloc (width, 2);
01126 merror (data, "nucore_load_raw()");
01127 for (irow=0; irow < height; irow++) {
01128 fread (data, 2, width, ifp);
01129 if (model[0] == 'B' && width == 2598)
01130 row = height - 1 - irow/2 - height/2 * (irow & 1);
01131 else
01132 row = irow;
01133 for (dp=data, col=0; col < width; col++, dp+=2)
01134 BAYER(row,col) = (dp[0] << 2) + (dp[1] << 10);
01135 }
01136 free(data);
01137 }
01138
01139 const int * CLASS make_decoder_int (const int *source, int level)
01140 {
01141 struct decode *cur;
01142
01143 cur = free_decode++;
01144 if (level < source[0]) {
01145 cur->branch[0] = free_decode;
01146 source = make_decoder_int (source, level+1);
01147 cur->branch[1] = free_decode;
01148 source = make_decoder_int (source, level+1);
01149 } else {
01150 cur->leaf = source[1];
01151 source += 2;
01152 }
01153 return source;
01154 }
01155
01156 int CLASS radc_token (int tree)
01157 {
01158 int t;
01159 static struct decode *dstart[18], *dindex;
01160 static const int *s, source[] = {
01161 1,1, 2,3, 3,4, 4,2, 5,7, 6,5, 7,6, 7,8,
01162 1,0, 2,1, 3,3, 4,4, 5,2, 6,7, 7,6, 8,5, 8,8,
01163 2,1, 2,3, 3,0, 3,2, 3,4, 4,6, 5,5, 6,7, 6,8,
01164 2,0, 2,1, 2,3, 3,2, 4,4, 5,6, 6,7, 7,5, 7,8,
01165 2,1, 2,4, 3,0, 3,2, 3,3, 4,7, 5,5, 6,6, 6,8,
01166 2,3, 3,1, 3,2, 3,4, 3,5, 3,6, 4,7, 5,0, 5,8,
01167 2,3, 2,6, 3,0, 3,1, 4,4, 4,5, 4,7, 5,2, 5,8,
01168 2,4, 2,7, 3,3, 3,6, 4,1, 4,2, 4,5, 5,0, 5,8,
01169 2,6, 3,1, 3,3, 3,5, 3,7, 3,8, 4,0, 5,2, 5,4,
01170 2,0, 2,1, 3,2, 3,3, 4,4, 4,5, 5,6, 5,7, 4,8,
01171 1,0, 2,2, 2,-2,
01172 1,-3, 1,3,
01173 2,-17, 2,-5, 2,5, 2,17,
01174 2,-7, 2,2, 2,9, 2,18,
01175 2,-18, 2,-9, 2,-2, 2,7,
01176 2,-28, 2,28, 3,-49, 3,-9, 3,9, 4,49, 5,-79, 5,79,
01177 2,-1, 2,13, 2,26, 3,39, 4,-16, 5,55, 6,-37, 6,76,
01178 2,-26, 2,-13, 2,1, 3,-39, 4,16, 5,-55, 6,-76, 6,37
01179 };
01180
01181 if (free_decode == first_decode)
01182 for (s=source, t=0; t < 18; t++) {
01183 dstart[t] = free_decode;
01184 s = make_decoder_int (s, 0);
01185 }
01186 if (tree == 18) {
01187 if (model[2] == '4')
01188 return (getbits(5) << 3) + 4;
01189 else
01190 return (getbits(6) << 2) + 2;
01191 }
01192 for (dindex = dstart[tree]; dindex->branch[0]; )
01193 dindex = dindex->branch[getbits(1)];
01194 return dindex->leaf;
01195 }
01196
01197 #define FORYX for (y=1; y < 3; y++) for (x=col+1; x >= col; x--)
01198
01199 #define PREDICTOR (c ? (buf[c][y-1][x] + buf[c][y][x+1]) / 2 \
01200 : (buf[c][y-1][x+1] + 2*buf[c][y-1][x] + buf[c][y][x+1]) / 4)
01201
01202 void CLASS kodak_radc_load_raw()
01203 {
01204 int row, col, tree, nreps, rep, step, i, c, s, r, x, y, val;
01205 short last[3] = { 16,16,16 }, mul[3], buf[3][3][386];
01206
01207 init_decoder();
01208 getbits(-1);
01209 for (i=0; i < sizeof(buf)/sizeof(short); i++)
01210 buf[0][0][i] = 2048;
01211 for (row=0; row < height; row+=4) {
01212 for (i=0; i < 3; i++)
01213 mul[i] = getbits(6);
01214 for (c=0; c < 3; c++) {
01215 val = ((0x1000000/last[c] + 0x7ff) >> 12) * mul[c];
01216 s = val > 65564 ? 10:12;
01217 x = ~(-1 << (s-1));
01218 val <<= 12-s;
01219 for (i=0; i < sizeof(buf[0])/sizeof(short); i++)
01220 buf[c][0][i] = (buf[c][0][i] * val + x) >> s;
01221 last[c] = mul[c];
01222 for (r=0; r <= !c; r++) {
01223 buf[c][1][width/2] = buf[c][2][width/2] = mul[c] << 7;
01224 for (tree=1, col=width/2; col > 0; ) {
01225 if ((tree = radc_token(tree))) {
01226 col -= 2;
01227 if (tree == 8)
01228 FORYX buf[c][y][x] = radc_token(tree+10) * mul[c];
01229 else
01230 FORYX buf[c][y][x] = radc_token(tree+10) * 16 + PREDICTOR;
01231 } else
01232 do {
01233 nreps = (col > 2) ? radc_token(9) + 1 : 1;
01234 for (rep=0; rep < 8 && rep < nreps && col > 0; rep++) {
01235 col -= 2;
01236 FORYX buf[c][y][x] = PREDICTOR;
01237 if (rep & 1) {
01238 step = radc_token(10) << 4;
01239 FORYX buf[c][y][x] += step;
01240 }
01241 }
01242 } while (nreps == 9);
01243 }
01244 for (y=0; y < 2; y++)
01245 for (x=0; x < width/2; x++) {
01246 val = (buf[c][y+1][x] << 4) / mul[c];
01247 if (val < 0) val = 0;
01248 if (c)
01249 BAYER(row+y*2+c-1,x*2+2-c) = val;
01250 else
01251 BAYER(row+r*2+y,x*2+y) = val;
01252 }
01253 memcpy (buf[c][0]+!c, buf[c][2], sizeof buf[c][0]-2*!c);
01254 }
01255 }
01256 for (y=row; y < row+4; y++)
01257 for (x=0; x < width; x++)
01258 if ((x+y) & 1) {
01259 val = (BAYER(y,x)-2048)*2 + (BAYER(y,x-1)+BAYER(y,x+1))/2;
01260 if (val < 0) val = 0;
01261 BAYER(y,x) = val;
01262 }
01263 }
01264 }
01265
01266 #undef FORYX
01267 #undef PREDICTOR
01268
01269 #ifdef NO_JPEG
01270 void CLASS kodak_jpeg_load_raw() {}
01271 #else
01272
01273 METHODDEF(boolean)
01274 fill_input_buffer (j_decompress_ptr cinfo)
01275 {
01276 static char jpeg_buffer[4096];
01277 size_t nbytes;
01278
01279 nbytes = fread (jpeg_buffer, 1, 4096, ifp);
01280 swab (jpeg_buffer, jpeg_buffer, nbytes);
01281 cinfo->src->next_input_byte = jpeg_buffer;
01282 cinfo->src->bytes_in_buffer = nbytes;
01283 return TRUE;
01284 }
01285
01286 void CLASS kodak_jpeg_load_raw()
01287 {
01288 struct jpeg_decompress_struct cinfo;
01289 struct jpeg_error_mgr jerr;
01290 JSAMPARRAY buf;
01291 JSAMPLE (*pixel)[3];
01292 int row, col;
01293
01294 cinfo.err = jpeg_std_error (&jerr);
01295 jpeg_create_decompress (&cinfo);
01296 jpeg_stdio_src (&cinfo, ifp);
01297 cinfo.src->fill_input_buffer = fill_input_buffer;
01298 jpeg_read_header (&cinfo, TRUE);
01299 jpeg_start_decompress (&cinfo);
01300 if ((cinfo.output_width != width ) ||
01301 (cinfo.output_height*2 != height ) ||
01302 (cinfo.output_components != 3 )) {
01303 fprintf (stderr, "%s: incorrect JPEG dimensions\n", ifname);
01304 jpeg_destroy_decompress (&cinfo);
01305 longjmp (failure, 3);
01306 }
01307 buf = (*cinfo.mem->alloc_sarray)
01308 ((j_common_ptr) &cinfo, JPOOL_IMAGE, width*3, 1);
01309
01310 while (cinfo.output_scanline < cinfo.output_height) {
01311 row = cinfo.output_scanline * 2;
01312 jpeg_read_scanlines (&cinfo, buf, 1);
01313 pixel = (void *) buf[0];
01314 for (col=0; col < width; col+=2) {
01315 BAYER(row+0,col+0) = pixel[col+0][1] << 6;
01316 BAYER(row+1,col+1) = pixel[col+1][1] << 6;
01317 BAYER(row+0,col+1) = (pixel[col][0] + pixel[col+1][0]) << 5;
01318 BAYER(row+1,col+0) = (pixel[col][2] + pixel[col+1][2]) << 5;
01319 }
01320 }
01321 jpeg_finish_decompress (&cinfo);
01322 jpeg_destroy_decompress (&cinfo);
01323 }
01324
01325 #endif
01326
01327 void CLASS kodak_dc120_load_raw()
01328 {
01329 static const int mul[4] = { 162, 192, 187, 92 };
01330 static const int add[4] = { 0, 636, 424, 212 };
01331 uchar pixel[848];
01332 int row, shift, col;
01333
01334 for (row=0; row < height; row++)
01335 {
01336 fread (pixel, 848, 1, ifp);
01337 shift = row * mul[row & 3] + add[row & 3];
01338 for (col=0; col < width; col++)
01339 BAYER(row,col) = (ushort) pixel[(col + shift) % 848] << 6;
01340 }
01341 }
01342
01343 void CLASS kodak_dc20_coeff (float juice)
01344 {
01345 static const float my_coeff[3][4] =
01346 { { 2.25, 0.75, -1.75, -0.25 },
01347 { -0.25, 0.75, 0.75, -0.25 },
01348 { -0.25, -1.75, 0.75, 2.25 } };
01349 static const float flat[3][4] =
01350 { { 1, 0, 0, 0 },
01351 { 0, 0.5, 0.5, 0 },
01352 { 0, 0, 0, 1 } };
01353 int r, g;
01354
01355 if (juice != 0) {
01356 for (r=0; r < 3; r++)
01357 for (g=0; g < 4; g++)
01358 coeff[r][g] = my_coeff[r][g] * juice + flat[r][g] * (1-juice);
01359 use_coeff = 1;
01360 }
01361 }
01362
01363 void CLASS kodak_easy_load_raw()
01364 {
01365 uchar *pixel;
01366 ushort curve[0x1000];
01367 unsigned row, col, icol;
01368
01369 kodak_curve (curve);
01370 if (raw_width > width)
01371 black = 0;
01372 pixel = calloc (raw_width, sizeof *pixel);
01373 merror (pixel, "kodak_easy_load_raw()");
01374 for (row=0; row < height; row++) {
01375 fread (pixel, 1, raw_width, ifp);
01376 for (col=0; col < raw_width; col++) {
01377 icol = col - left_margin;
01378 if (icol < width)
01379 BAYER(row,icol) = (ushort) curve[pixel[col]] << 2;
01380 else
01381 black += curve[pixel[col]];
01382 }
01383 }
01384 if (raw_width > width)
01385 black = ((INT64) black << 2) / ((raw_width - width) * height);
01386 if (!strncmp(model,"DC2",3))
01387 black = 0;
01388 free(pixel);
01389 }
01390
01391 void CLASS kodak_compressed_load_raw()
01392 {
01393 uchar c, blen[256];
01394 ushort raw[6], curve[0x1000];
01395 unsigned row, col, len, save, i, israw=0, bits=0, pred[2];
01396 INT64 bitbuf=0;
01397 int diff;
01398
01399 kodak_curve (curve);
01400 for (row=0; row < height; row++)
01401 for (col=0; col < width; col++)
01402 {
01403 if ((col & 255) == 0) {
01404 len = width - col;
01405 if (len > 256) len = 256;
01406 save = ftell(ifp);
01407 for (israw=i=0; i < len; i+=2) {
01408 c = fgetc(ifp);
01409 if ((blen[i+0] = c & 15) > 12 ||
01410 (blen[i+1] = c >> 4) > 12 )
01411 israw = 1;
01412 }
01413 bitbuf = bits = pred[0] = pred[1] = 0;
01414 if (len % 8 == 4) {
01415 bitbuf = fgetc(ifp) << 8;
01416 bitbuf += fgetc(ifp);
01417 bits = 16;
01418 }
01419 if (israw)
01420 fseek (ifp, save, SEEK_SET);
01421 }
01422 if (israw) {
01423 switch (col & 7) {
01424 case 0:
01425 fread (raw, 2, 6, ifp);
01426 for (i=0; i < 6; i++)
01427 raw[i] = ntohs(raw[i]);
01428 diff = raw[0] >> 12 << 8 | raw[2] >> 12 << 4 | raw[4] >> 12;
01429 break;
01430 case 1:
01431 diff = raw[1] >> 12 << 8 | raw[3] >> 12 << 4 | raw[5] >> 12;
01432 break;
01433 default:
01434 diff = raw[(col & 7) - 2] & 0xfff;
01435 }
01436 } else {
01437 len = blen[col & 255];
01438 if (bits < len) {
01439 for (i=0; i < 32; i+=8)
01440 bitbuf += (INT64) fgetc(ifp) << (bits+(i^8));
01441 bits += 32;
01442 }
01443 diff = bitbuf & (0xffff >> (16-len));
01444 bitbuf >>= len;
01445 bits -= len;
01446 if ((diff & (1 << (len-1))) == 0)
01447 diff -= (1 << len) - 1;
01448 pred[col & 1] += diff;
01449 diff = pred[col & 1];
01450 }
01451 BAYER(row,col) = curve[diff] << 2;
01452 }
01453 }
01454
01455 void CLASS kodak_yuv_load_raw()
01456 {
01457 uchar c, blen[384];
01458 unsigned row, col, len, bits=0;
01459 INT64 bitbuf=0;
01460 int i, li=0, si, diff, six[6], y[4], cb=0, cr=0, rgb[3];
01461 ushort *ip, curve[0x1000];
01462
01463 kodak_curve (curve);
01464 for (row=0; row < height; row+=2)
01465 for (col=0; col < width; col+=2) {
01466 if ((col & 127) == 0) {
01467 len = (width - col + 1) * 3 & -4;
01468 if (len > 384) len = 384;
01469 for (i=0; i < len; ) {
01470 c = fgetc(ifp);
01471 blen[i++] = c & 15;
01472 blen[i++] = c >> 4;
01473 }
01474 li = bitbuf = bits = y[1] = y[3] = cb = cr = 0;
01475 if (len % 8 == 4) {
01476 bitbuf = fgetc(ifp) << 8;
01477 bitbuf += fgetc(ifp);
01478 bits = 16;
01479 }
01480 }
01481 for (si=0; si < 6; si++) {
01482 len = blen[li++];
01483 if (bits < len) {
01484 for (i=0; i < 32; i+=8)
01485 bitbuf += (INT64) fgetc(ifp) << (bits+(i^8));
01486 bits += 32;
01487 }
01488 diff = bitbuf & (0xffff >> (16-len));
01489 bitbuf >>= len;
01490 bits -= len;
01491 if ((diff & (1 << (len-1))) == 0)
01492 diff -= (1 << len) - 1;
01493 six[si] = diff;
01494 }
01495 y[0] = six[0] + y[1];
01496 y[1] = six[1] + y[0];
01497 y[2] = six[2] + y[3];
01498 y[3] = six[3] + y[2];
01499 cb += six[4];
01500 cr += six[5];
01501 for (i=0; i < 4; i++) {
01502 ip = image[(row+(i >> 1))*width + col+(i & 1)];
01503 rgb[0] = y[i] + cr;
01504 rgb[1] = y[i];
01505 rgb[2] = y[i] + cb;
01506 for (c=0; c < 3; c++)
01507 if (rgb[c] > 0) ip[c] = curve[rgb[c]] << 2;
01508 }
01509 }
01510 }
01511
01512 void CLASS sony_decrypt (unsigned *data, int len, int start, int key)
01513 {
01514 static unsigned pad[128], p;
01515
01516 if (start) {
01517 for (p=0; p < 4; p++)
01518 pad[p] = key = key * 48828125 + 1;
01519 pad[3] = pad[3] << 1 | (pad[0]^pad[2]) >> 31;
01520 for (p=4; p < 127; p++)
01521 pad[p] = (pad[p-4]^pad[p-2]) << 1 | (pad[p-3]^pad[p-1]) >> 31;
01522 for (p=0; p < 127; p++)
01523 pad[p] = htonl(pad[p]);
01524 }
01525 while (len--)
01526 *data++ ^= pad[p++ & 127] = pad[(p+1) & 127] ^ pad[(p+65) & 127];
01527 }
01528
01529 void CLASS sony_load_raw()
01530 {
01531 uchar head[40];
01532 ushort pixel[3360];
01533 unsigned i, key, row, col, icol;
01534 INT64 bblack=0;
01535
01536 fseek (ifp, 200896, SEEK_SET);
01537 fseek (ifp, (unsigned) fgetc(ifp)*4 - 1, SEEK_CUR);
01538 order = 0x4d4d;
01539 key = fget4(ifp);
01540 fseek (ifp, 164600, SEEK_SET);
01541 fread (head, 1, 40, ifp);
01542 sony_decrypt ((void *) head, 10, 1, key);
01543 for (i=26; i-- > 22; )
01544 key = key << 8 | head[i];
01545 fseek (ifp, 862144, SEEK_SET);
01546 for (row=0; row < height; row++) {
01547 fread (pixel, 2, raw_width, ifp);
01548 sony_decrypt ((void *) pixel, raw_width/2, !row, key);
01549 for (col=0; col < 3343; col++)
01550 if ((icol = col-left_margin) < width)
01551 BAYER(row,icol) = ntohs(pixel[col]);
01552 else
01553 bblack += ntohs(pixel[col]);
01554 }
01555 black = bblack / ((3343 - width) * height);
01556 }
01557
01558 void CLASS sony_rgbe_coeff()
01559 {
01560 int r, g;
01561 static const float my_coeff[3][4] =
01562 { { 1.321918, 0.000000, 0.149829, -0.471747 },
01563 { -0.288764, 1.129213, -0.486517, 0.646067 },
01564 { 0.061336, -0.199343, 1.138007, 0.000000 } };
01565
01566 for (r=0; r < 3; r++)
01567 for (g=0; g < 4; g++)
01568 coeff[r][g] = my_coeff[r][g];
01569 use_coeff = 1;
01570 }
01571
01572 void CLASS foveon_decoder (unsigned huff[1024], unsigned code)
01573 {
01574 struct decode *cur;
01575 int i, len;
01576
01577 cur = free_decode++;
01578 if (free_decode > first_decode+2048) {
01579 fprintf (stderr, "%s: decoder table overflow\n", ifname);
01580 longjmp (failure, 2);
01581 }
01582 if (code) {
01583 for (i=0; i < 1024; i++)
01584 if (huff[i] == code) {
01585 cur->leaf = i;
01586 return;
01587 }
01588 }
01589 if ((len = code >> 27) > 26) return;
01590 code = (len+1) << 27 | (code & 0x3ffffff) << 1;
01591
01592 cur->branch[0] = free_decode;
01593 foveon_decoder (huff, code);
01594 cur->branch[1] = free_decode;
01595 foveon_decoder (huff, code+1);
01596 }
01597
01598 void CLASS foveon_load_raw()
01599 {
01600 struct decode *dindex;
01601 short diff[1024], pred[3];
01602 unsigned huff[1024], bitbuf=0;
01603 int row, col, bit=-1, c, i;
01604
01605 fseek (ifp, 260, SEEK_SET);
01606 for (i=0; i < 1024; i++)
01607 diff[i] = fget2(ifp);
01608 for (i=0; i < 1024; i++)
01609 huff[i] = fget4(ifp);
01610
01611 init_decoder();
01612 foveon_decoder (huff, 0);
01613
01614 for (row=0; row < raw_height; row++) {
01615 memset (pred, 0, sizeof pred);
01616 if (!bit) fget4(ifp);
01617 for (col=bit=0; col < raw_width; col++) {
01618 for (c=0; c < 3; c++) {
01619 for (dindex=first_decode; dindex->branch[0]; ) {
01620 if ((bit = (bit-1) & 31) == 31)
01621 for (i=0; i < 4; i++)
01622 bitbuf = (bitbuf << 8) + fgetc(ifp);
01623 dindex = dindex->branch[bitbuf >> bit & 1];
01624 }
01625 pred[c] += diff[dindex->leaf];
01626 }
01627 if ((unsigned) (row-top_margin) >= height ||
01628 (unsigned) (col-left_margin) >= width ) continue;
01629 for (c=0; c < 3; c++)
01630 if (pred[c] > 0)
01631 image[(row-top_margin)*width+(col-left_margin)][c] = pred[c];
01632 }
01633 }
01634 }
01635
01636 int CLASS apply_curve (int i, const int *curve)
01637 {
01638 if (i <= -curve[0])
01639 return -curve[curve[0]]-1;
01640 else if (i < 0)
01641 return -curve[1-i];
01642 else if (i < curve[0])
01643 return curve[1+i];
01644 else
01645 return curve[curve[0]]+1;
01646 }
01647
01648 void CLASS foveon_interpolate()
01649 {
01650 float mul[3] =
01651 { 1.0321, 1.0, 1.1124 };
01652 static const int weight[3][3][3] =
01653 { { { 4141, 37726, 11265 },
01654 { -30437, 16066, -41102 },
01655 { 326, -413, 362 } },
01656 { { 1770, -1316, 3480 },
01657 { -2139, 213, -4998 },
01658 { -2381, 3496, -2008 } },
01659 { { -3838, -24025, -12968 },
01660 { 20144, -12195, 30272 },
01661 { -631, -2025, 822 } } },
01662 curve1[73] = { 72,
01663 0,1,2,2,3,4,5,6,6,7,8,9,9,10,11,11,12,13,13,14,14,
01664 15,16,16,17,17,18,18,18,19,19,20,20,20,21,21,21,22,
01665 22,22,23,23,23,23,23,24,24,24,24,24,25,25,25,25,25,
01666 25,25,25,26,26,26,26,26,26,26,26,26,26,26,26,26,26 },
01667 curve2[21] = { 20,
01668 0,1,1,2,3,3,4,4,5,5,6,6,6,7,7,7,7,7,7,7 },
01669 curve3[73] = { 72,
01670 0,1,1,2,2,3,4,4,5,5,6,6,7,7,8,8,8,9,9,10,10,10,10,
01671 11,11,11,12,12,12,12,12,12,13,13,13,13,13,13,13,13,
01672 14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,
01673 14,14,14,14,14,14,14,14,14,14,14,14,14,14,14 },
01674 curve4[37] = { 36,
01675 0,1,1,2,3,3,4,4,5,6,6,7,7,7,8,8,9,9,9,10,10,10,
01676 11,11,11,11,11,12,12,12,12,12,12,12,12,12 },
01677 curve5[111] = { 110,
01678 0,1,1,2,3,3,4,5,6,6,7,7,8,9,9,10,11,11,12,12,13,13,
01679 14,14,15,15,16,16,17,17,18,18,18,19,19,19,20,20,20,
01680 21,21,21,21,22,22,22,22,22,23,23,23,23,23,24,24,24,24,
01681 24,24,24,24,25,25,25,25,25,25,25,25,25,25,25,25,26,26,
01682 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,
01683 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26 },
01684 *curves[3] = { curve3, curve4, curve5 },
01685 trans[3][3] =
01686 { { 7576, -2933, 1279 },
01687 { -11594, 29911, -12394 },
01688 { 4000, -18850, 20772 } };
01689 ushort *pix, prev[3], (*shrink)[3];
01690 int row, col, c, i, j, diff, sum, ipix[3], work[3][3], total[4];
01691 int (*smrow[7])[3], smlast, smred, smred_p=0, hood[7], min, max;
01692
01693
01694 for (row=0; row < height; row++) {
01695 pix = image[row*width];
01696 memcpy (prev, pix, sizeof prev);
01697 for (col=0; col < width; col++) {
01698 for (c=0; c < 3; c++) {
01699 diff = pix[c] - prev[c];
01700 prev[c] = pix[c];
01701 ipix[c] = pix[c] + ((diff + (diff*diff >> 14)) * 0x3333 >> 14);
01702 }
01703 for (c=0; c < 3; c++) {
01704 work[0][c] = ipix[c]*ipix[c] >> 14;
01705 work[2][c] = ipix[c]*work[0][c] >> 14;
01706 work[1][2-c] = ipix[(c+1) % 3] * ipix[(c+2) % 3] >> 14;
01707 }
01708 for (c=0; c < 3; c++) {
01709 for (sum=i=0; i < 3; i++)
01710 for ( j=0; j < 3; j++)
01711 sum += weight[c][i][j] * work[i][j];
01712 ipix[c] = (ipix[c] + (sum >> 14)) * mul[c];
01713 if (ipix[c] < 0) ipix[c] = 0;
01714 if (ipix[c] > 32000) ipix[c] = 32000;
01715 pix[c] = ipix[c];
01716 }
01717 pix += 4;
01718 }
01719 }
01720
01721 smrow[6] = calloc (width*5, sizeof **smrow);
01722 merror (smrow[6], "foveon_interpolate()");
01723 for (i=0; i < 5; i++)
01724 smrow[i] = smrow[6] + i*width;
01725
01726
01727 for (smlast=-1, row=2; row < height-2; row++) {
01728 while (smlast < row+2) {
01729 for (i=0; i < 6; i++)
01730 smrow[(i+5) % 6] = smrow[i];
01731 pix = image[++smlast*width+2];
01732 for (col=2; col < width-2; col++) {
01733 smrow[4][col][0] =
01734 (pix[0]*6 + (pix[-4]+pix[4])*4 + pix[-8]+pix[8] + 8) >> 4;
01735 pix += 4;
01736 }
01737 }
01738 pix = image[row*width+2];
01739 for (col=2; col < width-2; col++) {
01740 smred = (smrow[2][col][0]*6 + (smrow[1][col][0]+smrow[3][col][0])*4
01741 + smrow[0][col][0]+smrow[4][col][0] + 8) >> 4;
01742 if (col == 2)
01743 smred_p = smred;
01744 i = pix[0] + ((pix[0] - ((smred*7 + smred_p) >> 3)) >> 2);
01745 if (i < 0) i = 0;
01746 if (i > 10000) i = 10000;
01747 pix[0] = i;
01748 smred_p = smred;
01749 pix += 4;
01750 }
01751 }
01752
01753 hood[0] = 4;
01754 for (i=0; i < 3; i++) {
01755 hood[i+1] = (i-width-1)*4;
01756 hood[i+4] = (i+width-1)*4;
01757 }
01758 for (row=1; row < height-1; row++) {
01759 pix = image[row*width+1];
01760 memcpy (prev, pix-4, sizeof prev);
01761 for (col=1; col < width-1; col++) {
01762 for (c=0; c < 3; c++) {
01763 for (min=max=prev[c], i=0; i < 7; i++) {
01764 j = pix[hood[i]];
01765 if (min > j) min = j;
01766 if (max < j) max = j;
01767 }
01768 prev[c] = *pix;
01769 if (*pix < min) *pix = min;
01770 if (*pix > max) *pix = max;
01771 pix++;
01772 }
01773 pix++;
01774 }
01775 }
01776
01777
01778
01779
01780
01781 for (smlast=-1, row=2; row < height-2; row++) {
01782 while (smlast < row+2) {
01783 for (i=0; i < 6; i++)
01784 smrow[(i+5) % 6] = smrow[i];
01785 pix = image[++smlast*width+2];
01786 for (col=2; col < width-2; col++) {
01787 for (c=0; c < 3; c++)
01788 smrow[4][col][c] = pix[c-8]+pix[c-4]+pix[c]+pix[c+4]+pix[c+8];
01789 pix += 4;
01790 }
01791 }
01792 pix = image[row*width+2];
01793 for (col=2; col < width-2; col++) {
01794 for (total[3]=1500, sum=60, c=0; c < 3; c++) {
01795 for (total[c]=i=0; i < 5; i++)
01796 total[c] += smrow[i][col][c];
01797 total[3] += total[c];
01798 sum += pix[c];
01799 }
01800 j = (sum << 16) / total[3];
01801 for (c=0; c < 3; c++) {
01802 i = apply_curve ((total[c] * j >> 16) - pix[c], curve1);
01803 i += pix[c] - 13 - (c==1);
01804 ipix[c] = i - apply_curve (i, curve2);
01805 }
01806 sum = (ipix[0]+ipix[1]+ipix[1]+ipix[2]) >> 2;
01807 for (c=0; c < 3; c++) {
01808 i = ipix[c] - apply_curve (ipix[c] - sum, curve2);
01809 if (i < 0) i = 0;
01810 pix[c] = i;
01811 }
01812 pix += 4;
01813 }
01814 }
01815
01816 for (pix=image[0]; pix < image[height*width]; pix+=4) {
01817 for (c=0; c < 3; c++) {
01818 for (i=j=0; j < 3; j++)
01819 i += trans[c][j] * pix[j];
01820 i = (i+0x1000) >> 13;
01821 if (i < 0) i = 0;
01822 if (i > 24000) i = 24000;
01823 ipix[c] = i;
01824 }
01825 for (c=0; c < 3; c++)
01826 pix[c] = ipix[c];
01827 }
01828
01829 shrink = calloc ((width/4) * (height/4), sizeof *shrink);
01830 merror (shrink, "foveon_interpolate()");
01831 for (row = height/4; row--; )
01832 for (col=0; col < width/4; col++) {
01833 ipix[0] = ipix[1] = ipix[2] = 0;
01834 for (i=0; i < 4; i++)
01835 for (j=0; j < 4; j++)
01836 for (c=0; c < 3; c++)
01837 ipix[c] += image[(row*4+i)*width+col*4+j][c];
01838 for (c=0; c < 3; c++)
01839 if (row+2 > height/4)
01840 shrink[row*(width/4)+col][c] = ipix[c] >> 4;
01841 else
01842 shrink[row*(width/4)+col][c] =
01843 (shrink[(row+1)*(width/4)+col][c]*1840 + ipix[c]*141) >> 12;
01844 }
01845
01846
01847 for (row=0; row < (height & ~3); row++) {
01848 ipix[0] = ipix[1] = ipix[2] = 0;
01849 if ((row & 3) == 0)
01850 for (col = width & ~3 ; col--; )
01851 for (c=0; c < 3; c++)
01852 smrow[0][col][c] = ipix[c] =
01853 (shrink[(row/4)*(width/4)+col/4][c]*1485 + ipix[c]*6707) >> 13;
01854
01855
01856 ipix[0] = ipix[1] = ipix[2] = 0;
01857 for (col=0; col < (width & ~3); col++)
01858 for (c=0; c < 3; c++)
01859 smrow[1][col][c] = ipix[c] =
01860 (smrow[0][col][c]*1485 + ipix[c]*6707) >> 13;
01861
01862
01863 if (row == 0)
01864 memcpy (smrow[2], smrow[1], sizeof **smrow * width);
01865 else
01866 for (col=0; col < (width & ~3); col++)
01867 for (c=0; c < 3; c++)
01868 smrow[2][col][c] =
01869 (smrow[2][col][c]*6707 + smrow[1][col][c]*1485) >> 13;
01870
01871
01872 for (col=0; col < (width & ~3); col++) {
01873 for (i=j=60, c=0; c < 3; c++) {
01874 i += smrow[2][col][c];
01875 j += image[row*width+col][c];
01876 }
01877 j = (j << 16) / i;
01878 for (sum=c=0; c < 3; c++) {
01879 i = (smrow[2][col][c] * j >> 16) - image[row*width+col][c];
01880 ipix[c] = apply_curve (i, curves[c]);
01881 sum += ipix[c];
01882 }
01883 sum >>= 3;
01884 for (c=0; c < 3; c++) {
01885 i = image[row*width+col][c] + ipix[c] - sum;
01886 if (i < 0) i = 0;
01887 image[row*width+col][c] = i;
01888 }
01889 }
01890 }
01891 free(shrink);
01892 free(smrow[6]);
01893 }
01894
01895
01896
01897
01898
01899 void CLASS bad_pixels()
01900 {
01901 FILE *fp=NULL;
01902 char *fname, *cp, line[128];
01903 int len, time, row, col, r, c, rad, tot, n, fixed=0;
01904
01905 if (!filters) return;
01906 for (len=16 ; ; len *= 2) {
01907 fname = malloc (len);
01908 if (!fname) return;
01909 if (getcwd (fname, len-12)) break;
01910 free (fname);
01911 if (errno != ERANGE) return;
01912 }
01913 #ifdef WIN32
01914 if (fname[1] == ':')
01915 memmove (fname, fname+2, len-2);
01916 for (cp=fname; *cp; cp++)
01917 if (*cp == '\\') *cp = '/';
01918 #endif
01919 cp = fname + strlen(fname);
01920 if (cp[-1] == '/') cp--;
01921 while (*fname == '/') {
01922 strcpy (cp, "/.badpixels");
01923 if ((fp = fopen (fname, "r"))) break;
01924 if (cp == fname) break;
01925 while (*--cp != '/');
01926 }
01927 free (fname);
01928 if (!fp) return;
01929 while (fgets (line, 128, fp)) {
01930 cp = strchr (line, '#');
01931 if (cp) *cp = 0;
01932 if (sscanf (line, "%d %d %d", &col, &row, &time) != 3) continue;
01933 if ((unsigned) col >= width || (unsigned) row >= height) continue;
01934 if (time > timestamp) continue;
01935 for (tot=n=0, rad=1; rad < 3 && n==0; rad++)
01936 for (r = row-rad; r <= row+rad; r++)
01937 for (c = col-rad; c <= col+rad; c++)
01938 if ((unsigned) r < height && (unsigned) c < width &&
01939 (r != row || c != col) && FC(r,c) == FC(row,col)) {
01940 tot += BAYER(r,c);
01941 n++;
01942 }
01943 BAYER(row,col) = tot/n;
01944 if (verbose) {
01945 if (!fixed++)
01946 fprintf (stderr, "Fixed bad pixels at:");
01947 fprintf (stderr, " %d,%d", col, row);
01948 }
01949 }
01950 if (fixed) fputc ('\n', stderr);
01951 fclose (fp);
01952 }
01953
01954 int CLASS get_generic_parameter(FILE *fp, const char *name, const char *line,
01955 const char *sequence, void *where, int *flag)
01956 {
01957 if (strcmp(line, name) == 0) {
01958 int status;
01959 char data[128];
01960 if (!fgets(data, 127, fp))
01961 return -1;
01962 if (feof(fp))
01963 return -1;
01964 status = sscanf (data, sequence, where);
01965 if (status != 1)
01966 return -1;
01967 if (flag)
01968 *flag = 1;
01969 return 1;
01970 } else
01971 return 0;
01972 }
01973
01974 int CLASS get_float_parameter(FILE *fp, const char *name, const char *line,
01975 float *where, int *flag)
01976 {
01977 return get_generic_parameter(fp, name, line, "%f", where, flag);
01978 }
01979
01980 int CLASS get_int_parameter(FILE *fp, const char *name, const char *line,
01981 int *where, int *flag)
01982 {
01983 return get_generic_parameter(fp, name, line, "%d", where, flag);
01984 }
01985
01986
01987
01988
01989 int get_parameter_value(FILE *fp)
01990 {
01991 char *cp, line[128], data[128];
01992 float my_coeff[3][4];
01993 int i, j;
01994 int got_coeff=0;
01995
01996 while (1) {
01997 fgets (line, 128, fp);
01998 if (feof(fp)) break;
01999 cp = strchr (line, '#');
02000 if (cp) *cp = 0;
02001
02002 if (get_float_parameter(fp, "gamma:\n", line,
02003 &gamma_val, NULL) == -1)
02004 break;
02005
02006 if (get_float_parameter(fp, "brightness:\n", line,
02007 &bright, NULL) == -1)
02008 break;
02009
02010 if (get_float_parameter(fp, "red scale:\n", line,
02011 &red_scale, NULL) == -1)
02012 break;
02013
02014 if (get_float_parameter(fp, "blue scale:\n", line,
02015 &blue_scale, NULL) == -1)
02016 break;
02017
02018 if (get_float_parameter(fp, "green scale:\n", line,
02019 &green_scale, NULL) == -1)
02020 break;
02021
02022 if (get_float_parameter(fp, "juice:\n", line,
02023 &juice, NULL) == -1)
02024 break;
02025
02026 if (get_float_parameter(fp, "white point fraction:\n", line,
02027 &white_point_fraction, NULL) == -1)
02028 break;
02029
02030 if (get_float_parameter(fp, "pivot value:\n", line,
02031 &pivot_value, NULL) == -1)
02032 break;
02033
02034 if (get_float_parameter(fp, "exposure compensation:\n", line,
02035 &exposure_compensation, NULL) == -1)
02036 break;
02037
02038 if (get_float_parameter(fp, "saturation:\n", line,
02039 &saturation, NULL) == -1)
02040 break;
02041
02042 if (get_float_parameter(fp, "contrast:\n", line,
02043 &contrast, NULL) == -1)
02044 break;
02045
02046 if (get_int_parameter(fp, "flip:\n", line,
02047 &flip, NULL) == -1)
02048 break;
02049
02050 if (!strcmp(line, "color matrix:\n")) {
02051 int status = 0;
02052 for (i=0; i < 3; i++) {
02053 fgets (data, 128, fp);
02054 if (feof(fp)) {
02055 got_coeff = 0;
02056 break;
02057 }
02058 status= sscanf (data, "%f %f %f %f",
02059 &my_coeff[i][0], &my_coeff[i][1],
02060 &my_coeff[i][2], &my_coeff[i][3]);
02061 if (status < 3 || status > 4 ||
02062 (got_coeff > 0 && got_coeff != status)) {
02063 got_coeff = 0;
02064 break;
02065 }
02066 if (got_coeff == 0)
02067 got_coeff = status;
02068 }
02069 }
02070 }
02071
02072 if (juice != 0.0) {
02073 if (got_coeff > 0) {
02074 if (verbose) {
02075 fprintf (stderr, "Color matrix with juice = %f:\n", juice);
02076 for (i=0; i < 3; i++)
02077 fprintf (stderr, " [%f %f %f %f]\n",
02078 my_coeff[i][0], my_coeff[i][1], my_coeff[i][2], my_coeff[i][3]);
02079 for (i=0; i < 3; i++)
02080 for (j=0; j < got_coeff; j++) {
02081 if (i == j || i == 1 && j == 3)
02082 coeff[i][j] = my_coeff[i][j] * juice + (1-juice);
02083 else
02084 coeff[i][j] = my_coeff[i][j] * juice;
02085 }
02086 use_coeff = 1;
02087 }
02088 }
02089 }
02090 }
02091
02092 void get_parameters()
02093 {
02094 FILE *fp=NULL;
02095 char *fname, *cp;
02096 const char *default_file="default.prm", *prm_ext = ".prm";
02097 int len;
02098
02099 fp = fopen (default_file, "r");
02100 if (fp) {
02101 get_parameter_value (fp);
02102 fclose (fp);
02103 }
02104
02105 fname = malloc (strlen(ifname) + 16);
02106 merror (fname, "get_parameters()");
02107 strcpy (fname, ifname);
02108 if ((cp = strrchr (fname, '.'))) *cp = 0;
02109 strcat (fname, prm_ext);
02110 fp = fopen (fname, "r");
02111 free (fname);
02112 if (!fp) return;
02113
02114 get_parameter_value (fp);
02115 fclose (fp);
02116 }
02117
02118 void CLASS scale_colors()
02119 {
02120 int row, col, c, val;
02121 int min[4], max[4], count[4];
02122 double sum[4], dmin, dmax;
02123 double *x_weights, *y_weights;
02124
02125 int i;
02126 ushort *lut[4];
02127 ushort abs_max = 0;
02128 ushort abs_min = ABS_MAX;
02129 int clipped_pixels[4];
02130 int total_clipped_pixels = 0;
02131 int total_pixels = 0;
02132 int weighted_total_pixels = 0;
02133 double pixels[4];
02134 double white_fraction = 1.0 - white_point_fraction;
02135 double total = 0.0;
02136 double totals[4];
02137 double means[4];
02138 int mean;
02139 float compensation = exp2(exposure_compensation);
02140 double post_mul = 1.0;
02141 double auto_compensation = 1.0;
02142 int original_rgb_max;
02143
02144 if (user_black >= 0)
02145 black = user_black;
02146 if (white_fraction > 1)
02147 white_fraction = 1;
02148 else if (white_fraction < 0)
02149 white_fraction = 0;
02150 if (use_neutral_wb) {
02151 for (c=0; c < 4; c++) {
02152 pre_mul[c] = 1.0;
02153 }
02154 }
02155 for (c = 0; c < 4; c++) {
02156 pixels[c] = 0;
02157 totals[c] = 0;
02158 clipped_pixels[c] = 0;
02159 }
02160 memset (histogram, 0, sizeof histogram);
02161 for (c=0; c < 4; c++) {
02162 min[c] = INT_MAX;
02163 max[c] = count[c] = sum[c] = 0;
02164 }
02165 if (center_weight) {
02166 x_weights = malloc(sizeof(double) * width);
02167 y_weights = malloc(sizeof(double) * height);
02168 for (row = 0; row < height; row++)
02169 y_weights[row]= exp(-pow(abs((row - (height / 2)) / (height / 4)), 3.0));
02170 for (col = 0; col < width; col++)
02171 x_weights[col] = exp(-pow(abs((col - (width / 2)) / (width / 4)), 3.0));
02172 }
02173 for (row=0; row < height; row++) {
02174 for (col=0; col < width; col++) {
02175 for (c=0; c < colors; c++) {
02176 double weight = 1;
02177 val = image[row*width+col][c];
02178 if (!val) continue;
02179 if (use_camera_black && val < black)
02180 val = black;
02181 histogram[val >> 3]++;
02182 if (val >= rgb_max - 100) {
02183 clipped_pixels[c]++;
02184 total_clipped_pixels++;
02185 }
02186 total += val;
02187 total_pixels++;
02188 if (center_weight) {
02189 double x_weight = x_weights[col];
02190 double y_weight = y_weights[row];
02191 weight = x_weight * y_weight;
02192 }
02193 totals[c] += val * weight;
02194 pixels[c] += weight;
02195 weighted_total_pixels += weight;
02196 if (min[c] > val) min[c] = val;
02197 if (max[c] < val) max[c] = val;
02198 if (val < abs_min)
02199 abs_min = val;
02200 if (val > abs_max)
02201 abs_max = val;
02202 }
02203 }
02204 }
02205 if (center_weight) {
02206 free(x_weights);
02207 free(y_weights);
02208 }
02209 if (rgb_max < abs_max)
02210 rgb_max = abs_max;
02211 if (black > abs_min)
02212 black = abs_min;
02213 abs_max -= black;
02214 abs_min -= black;
02215 mean = (total / total_pixels) - black;
02216 for (c = 0; c < 4; c++) {
02217 means[c] = 0;
02218 max[c] -= black;
02219 min[c] -= black;
02220 }
02221 for (c = 0; c < colors; c++)
02222 if (pixels[c])
02223 means[c] = (totals[c] / pixels[c]) - black;
02224
02225 rgb_max -= black;
02226 if (use_auto_wb || (use_camera_wb && camera_red == -1)) {
02227 for (c=0; c < 4; c++) {
02228 min[c] = INT_MAX;
02229 max[c] = count[c] = sum[c] = 0;
02230 }
02231 for (row=0; row < height; row++)
02232 for (col=0; col < width; col++)
02233 for (c=0; c < colors; c++) {
02234 val = image[row*width+col][c];
02235 if (!val) continue;
02236 if (use_camera_black && val < black)
02237 val = black;
02238 if (min[c] > val) min[c] = val;
02239 if (max[c] < val) max[c] = val;
02240 val -= black;
02241 if (val > rgb_max-100) continue;
02242 if (val < 0) val = 0;
02243 sum[c] += val;
02244 count[c]++;
02245 }
02246 for (dmax=c=0; c < colors; c++) {
02247 sum[c] /= count[c];
02248 if (dmax < sum[c]) dmax = sum[c];
02249 }
02250 for (c=0; c < colors; c++)
02251 pre_mul[c] = dmax / sum[c];
02252 }
02253 if (use_camera_wb && camera_red != -1) {
02254 for (c=0; c < 4; c++)
02255 count[c] = sum[c] = 0;
02256 for (row=0; row < 8; row++)
02257 for (col=0; col < 8; col++) {
02258 c = FC(row,col);
02259 if ((val = white[row][col] - black) > 0)
02260 sum[c] += val;
02261 count[c]++;
02262 }
02263 for (dmin=DBL_MAX, dmax=c=0; c < colors; c++) {
02264 sum[c] /= count[c];
02265 if (dmin > sum[c]) dmin = sum[c];
02266 if (dmax < sum[c]) dmax = sum[c];
02267 }
02268 if (dmin > 0)
02269 for (c=0; c < colors; c++)
02270 pre_mul[c] = dmax / sum[c];
02271 else if (camera_red && camera_blue) {
02272 pre_mul[0] = camera_red;
02273 pre_mul[2] = camera_blue;
02274 pre_mul[1] = pre_mul[3] = 1.0;
02275 } else
02276 fprintf (stderr, "%s: Cannot use camera white balance.\n", ifname);
02277 }
02278
02279 total = 0;
02280 for (c = 0; c < colors; c++) {
02281 if (pixels[c] > 0)
02282 total += means[c] * pixels[c] / pre_mul[c];
02283 }
02284 total /= weighted_total_pixels;
02285
02286 if (!use_coeff) {
02287 pre_mul[0] *= red_scale;
02288 pre_mul[2] *= blue_scale;
02289 pre_mul[1] *= green_scale;
02290 pre_mul[3] *= green_scale;
02291 }
02292 for (c = 0; c < 4; c++)
02293 pre_mul[c] *= compensation;
02294
02295 if (autoexposure) {
02296 auto_compensation = .3 / ((double) total / (double) rgb_max);
02297 if (auto_compensation > 4.0)
02298 auto_compensation = 4.0 * sqrt(auto_compensation / 4.0);
02299 for (c = 0; c < 4; c++)
02300 pre_mul[c] *= auto_compensation;
02301 if ((auto_compensation * compensation) > 1 && !use_pivot)
02302 pivot_value /= (auto_compensation * compensation);
02303 use_pivot = 1;
02304 }
02305 if (pivot_value > 1)
02306 use_pivot = 0;
02307
02308 for (c=0; c < 4; c++) {
02309 if (pre_mul[c] < post_mul) {
02310 post_mul = pre_mul[c];
02311 }
02312 }
02313 for (c=0; c < 4; c++) {
02314 pre_mul[c] /= post_mul;
02315 }
02316
02317 for (c = 0; c < 4; c++)
02318 lut[c] = NULL;
02319 if (use_pivot) {
02320 for (c=0; c < c; c++) {
02321 if (pre_mul[c] > 1.0) {
02322 double k = pre_mul[c];
02323 double rescale = 1.0 - (clipped_pixels[c] / pixels[c]);
02324 double start = pivot_value * rescale * rescale;
02325 double start_1 = 1 - start;
02326 double x_start = start / k;
02327 double x_start_1 = 1 - x_start;
02328 double end_slope = alternate_scale ? 1.0 / (3 * k) : 0;
02329 double end_intercept = 1.0 - end_slope;
02330 double end_start = end_intercept + x_start * end_slope;
02331 double end_start_1 = 1.0 - end_start;
02332 double diff = start_1 - end_start_1;
02333 double scale = 1 / x_start_1;
02334
02335
02336
02337
02338 double expt = ((k - end_slope) * x_start_1 / diff);
02339 if (verbose) {
02340 fprintf(stderr, "Pivot channel %d: k %f start %f x_start %f x_start_1 %f expt %f scale %f end_slope %f end_intercept %f end_start %f end_start_1 %f diff %f\n",
02341 c, k, start, x_start, x_start_1, expt, scale,
02342 end_slope, end_intercept, end_start, end_start_1, diff);
02343 }
02344 lut[c] = malloc (sizeof(ushort) * 65536);
02345 k = k * RGB_MAX / rgb_max;
02346 for (i = 0; i <= rgb_max; i++) {
02347 double base = i / (double) rgb_max;
02348 if (base <= x_start) {
02349 lut[c][i] = k * i;
02350 } else if (base > rgb_max) {
02351 lut[c][i] = RGB_MAX;
02352 } else {
02353
02354
02355
02356
02357 double x_base = 1 - ((base - x_start) * scale);
02358 if (x_base < 0)
02359 x_base = 0;
02360 lut[c][i] =
02361 (RGB_MAX *
02362 (end_intercept + (base * end_slope) -
02363 (diff * pow(x_base, expt))));
02364 }
02365 }
02366 }
02367 }
02368 }
02369 for (c = 0; c < colors; c++)
02370 pre_mul[c] = pre_mul[c] * RGB_MAX / rgb_max;
02371 original_rgb_max = rgb_max;
02372 rgb_max = RGB_MAX;
02373 if (verbose) {
02374 fprintf (stderr, "Scaling with black=%d, pre_mul[] =", black);
02375 for (c=0; c < colors; c++)
02376 fprintf (stderr, " %f", pre_mul[c]);
02377 fputc ('\n', stderr);
02378 fprintf (stderr, "Maximum level %d (%d, %.2f%%)\n", abs_max,
02379 abs_max * 65536 / original_rgb_max,
02380 100.0 * abs_max / original_rgb_max);
02381 fprintf (stderr, "Minimum level %d (%d, %.2f%%)\n", abs_min,
02382 abs_min * 65536 / original_rgb_max,
02383 100.0 * abs_min / original_rgb_max);
02384 fprintf (stderr, "Mean level %d (%d, %.2f%%)\n", mean,
02385 mean * 65536 / original_rgb_max,
02386 100.0 * mean / original_rgb_max);
02387 fprintf (stderr, "Weighted mean level %f (%f, %.2f%%)\n", total,
02388 total * 65536 / original_rgb_max,
02389 100.0 * total / original_rgb_max);
02390 for (c = 0; c < colors; c++)
02391 if (pixels[c] > 0)
02392 fprintf (stderr, "Mean[%d] level %f (%f, %.2f%%) %.2f pixels\n",
02393 c, means[c], means[c] * 65536 / original_rgb_max,
02394 100.0 * means[c] / original_rgb_max, pixels[c]);
02395 for (c = 0; c < colors; c++)
02396 if (pixels[c] > 0)
02397 fprintf (stderr, "Max[%d] level %d (%d, %.2f%%) %.2f pixels\n",
02398 c, max[c], max[c] * 65536 / original_rgb_max,
02399 100.0 * (double) max[c] / original_rgb_max, pixels[c]);
02400 fprintf (stderr, "Auto exposure compensation %f (%f stops)\n",
02401 auto_compensation,
02402 log(auto_compensation) / log(2));
02403 fprintf (stderr, "Manual exposure compensation %f (%f stops)\n",
02404 compensation, exposure_compensation);
02405 fprintf (stderr, "Total exposure compensation %f (%f stops)\n",
02406 auto_compensation * compensation,
02407 log(auto_compensation * compensation) / log(2));
02408 fprintf (stderr, "Post multiplier %f (%f stops)\n",
02409 post_mul, log(post_mul) / log(2));
02410 fprintf (stderr, "Clipped pixels: %d/%d, %.2f%%\n",
02411 total_clipped_pixels, total_pixels,
02412 (double) total_clipped_pixels / total_pixels * 100);
02413 for (c = 0; c < colors; c++)
02414 if (pixels[c] > 0)
02415 fprintf(stderr, "Clipped[%d] %d (%.2f%%)\n", c, clipped_pixels[c],
02416 100.0 * clipped_pixels[c] / pixels[c]);
02417 }
02418 for (row=0; row < height; row++)
02419 for (col=0; col < width; col++)
02420 for (c=0; c < colors; c++) {
02421 val = image[row*width+col][c];
02422 if (!val) continue;
02423 if (use_camera_black && val < black)
02424 val = black;
02425 val -= black;
02426 if (lut[c])
02427 val = lut[c][val];
02428 else
02429 val *= pre_mul[c];
02430 if (val < 0) val = 0;
02431 if (val > rgb_max) val = rgb_max;
02432 val *= post_mul;
02433 image[row*width+col][c] = val;
02434 }
02435 for (c = 0; c < colors; c++) {
02436 if (lut[c])
02437 free(lut[c]);
02438 }
02439 }
02440
02441
02442
02443
02444
02445
02446
02447
02448
02449
02450
02451 void CLASS vng_interpolate()
02452 {
02453 static const signed char *cp, terms[] = {
02454 -2,-2,+0,-1,0,0x01, -2,-2,+0,+0,1,0x01, -2,-1,-1,+0,0,0x01,
02455 -2,-1,+0,-1,0,0x02, -2,-1,+0,+0,0,0x03, -2,-1,+0,+1,1,0x01,
02456 -2,+0,+0,-1,0,0x06, -2,+0,+0,+0,1,0x02, -2,+0,+0,+1,0,0x03,
02457 -2,+1,-1,+0,0,0x04, -2,+1,+0,-1,1,0x04, -2,+1,+0,+0,0,0x06,
02458 -2,+1,+0,+1,0,0x02, -2,+2,+0,+0,1,0x04, -2,+2,+0,+1,0,0x04,
02459 -1,-2,-1,+0,0,0x80, -1,-2,+0,-1,0,0x01, -1,-2,+1,-1,0,0x01,
02460 -1,-2,+1,+0,1,0x01, -1,-1,-1,+1,0,0x88, -1,-1,+1,-2,0,0x40,
02461 -1,-1,+1,-1,0,0x22, -1,-1,+1,+0,0,0x33, -1,-1,+1,+1,1,0x11,
02462 -1,+0,-1,+2,0,0x08, -1,+0,+0,-1,0,0x44, -1,+0,+0,+1,0,0x11,
02463 -1,+0,+1,-2,1,0x40, -1,+0,+1,-1,0,0x66, -1,+0,+1,+0,1,0x22,
02464 -1,+0,+1,+1,0,0x33, -1,+0,+1,+2,1,0x10, -1,+1,+1,-1,1,0x44,
02465 -1,+1,+1,+0,0,0x66, -1,+1,+1,+1,0,0x22, -1,+1,+1,+2,0,0x10,
02466 -1,+2,+0,+1,0,0x04, -1,+2,+1,+0,1,0x04, -1,+2,+1,+1,0,0x04,
02467 +0,-2,+0,+0,1,0x80, +0,-1,+0,+1,1,0x88, +0,-1,+1,-2,0,0x40,
02468 +0,-1,+1,+0,0,0x11, +0,-1,+2,-2,0,0x40, +0,-1,+2,-1,0,0x20,
02469 +0,-1,+2,+0,0,0x30, +0,-1,+2,+1,1,0x10, +0,+0,+0,+2,1,0x08,
02470 +0,+0,+2,-2,1,0x40, +0,+0,+2,-1,0,0x60, +0,+0,+2,+0,1,0x20,
02471 +0,+0,+2,+1,0,0x30, +0,+0,+2,+2,1,0x10, +0,+1,+1,+0,0,0x44,
02472 +0,+1,+1,+2,0,0x10, +0,+1,+2,-1,1,0x40, +0,+1,+2,+0,0,0x60,
02473 +0,+1,+2,+1,0,0x20, +0,+1,+2,+2,0,0x10, +1,-2,+1,+0,0,0x80,
02474 +1,-1,+1,+1,0,0x88, +1,+0,+1,+2,0,0x08, +1,+0,+2,-1,0,0x40,
02475 +1,+0,+2,+1,0,0x10
02476 }, chood[] = { -1,-1, -1,0, -1,+1, 0,+1, +1,+1, +1,0, +1,-1, 0,-1 };
02477 ushort (*brow[5])[4], *pix;
02478 int code[8][2][320], *ip, gval[8], gmin, gmax, sum[4];
02479 int row, col, shift, x, y, x1, x2, y1, y2, t, weight, grads, color, diag;
02480 int g, diff, thold, num, c;
02481
02482 for (row=0; row < 8; row++) {
02483 for (col=1; col < 3; col++) {
02484 ip = code[row][col & 1];
02485 memset (sum, 0, sizeof sum);
02486 for (y=-1; y <= 1; y++)
02487 for (x=-1; x <= 1; x++) {
02488 shift = (y==0) + (x==0);
02489 if (shift == 2) continue;
02490 color = FC(row+y,col+x);
02491 *ip++ = (width*y + x)*4 + color;
02492 *ip++ = shift;
02493 *ip++ = color;
02494 sum[color] += 1 << shift;
02495 }
02496 for (c=0; c < colors; c++)
02497 if (c != FC(row,col)) {
02498 *ip++ = c;
02499 *ip++ = sum[c];
02500 }
02501 }
02502 }
02503
02504
02505
02506
02507 for (row=1; row < height-1; row++)
02508 {
02509 for (col=1; col < width-1; col++)
02510 {
02511 pix = image[row*width+col];
02512 ip = code[row & 7][col & 1];
02513 memset (sum, 0, sizeof sum);
02514
02515 for (g=8; g--; )
02516 {
02517 diff = pix[*ip++];
02518 diff <<= *ip++;
02519 sum[*ip++] += diff;
02520 }
02521
02522 for (g=colors; --g; )
02523 {
02524 c = *ip++;
02525 pix[c] = sum[c] / *ip++;
02526 }
02527
02528
02529 }
02530 }
02531
02532
02533 if (quick_interpolate)
02534 return;
02535
02536
02537
02538 for (row=0; row < 8; row++)
02539 {
02540 for (col=0; col < 2; col++)
02541 {
02542 ip = code[row][col];
02543 for (cp=terms, t=0; t < 64; t++)
02544 {
02545 y1 = *cp++; x1 = *cp++;
02546 y2 = *cp++; x2 = *cp++;
02547 weight = *cp++;
02548 grads = *cp++;
02549 color = FC(row+y1,col+x1);
02550 if (FC(row+y2,col+x2) != color) continue;
02551 diag = (FC(row,col+1) == color && FC(row+1,col) == color) ? 2:1;
02552 if (abs(y1-y2) == diag && abs(x1-x2) == diag) continue;
02553 *ip++ = (y1*width + x1)*4 + color;
02554 *ip++ = (y2*width + x2)*4 + color;
02555 *ip++ = weight;
02556 for (g=0; g < 8; g++)
02557 if (grads & 1<<g) *ip++ = g;
02558 *ip++ = -1;
02559 }
02560 *ip++ = INT_MAX;
02561 for (cp=chood, g=0; g < 8; g++) {
02562 y = *cp++; x = *cp++;
02563 *ip++ = (y*width + x) * 4;
02564 color = FC(row,col);
02565 if (FC(row+y,col+x) != color && FC(row+y*2,col+x*2) == color)
02566 *ip++ = (y*width + x) * 8 + color;
02567 else
02568 *ip++ = 0;
02569 }
02570 }
02571 }
02572
02573
02574
02575
02576 brow[4] = calloc (width*3, sizeof **brow);
02577 merror (brow[4], "vng_interpolate()");
02578 for (row=0; row < 3; row++)
02579 brow[row] = brow[4] + row*width;
02580
02581
02582 for (row=2; row < height-2; row++)
02583 {
02584
02585
02586
02587
02588
02589 for (col=2; col < width-2; col++)
02590 {
02591
02592
02593 pix = image[row*width+col];
02594 ip = code[row & 7][col & 1];
02595 memset (gval, 0, sizeof gval);
02596
02597
02598
02599 while ((g = ip[0]) != INT_MAX)
02600 {
02601 num = (diff = pix[g] - pix[ip[1]]) >> 31;
02602 gval[ip[3]] += (diff = ((diff ^ num) - num) << ip[2]);
02603 ip += 5;
02604 if ((g = ip[-1]) == -1) continue;
02605 gval[g] += diff;
02606 while ((g = *ip++) != -1)
02607 gval[g] += diff;
02608 }
02609 ip++;
02610
02611
02612
02613 gmin = gmax = gval[0];
02614 for (g=1; g < 8; g++)
02615 {
02616 if (gmin > gval[g]) gmin = gval[g];
02617 if (gmax < gval[g]) gmax = gval[g];
02618 }
02619
02620
02621
02622
02623 if (gmax == 0)
02624 {
02625 memcpy (brow[2][col], pix, sizeof *image);
02626 continue;
02627 }
02628
02629
02630
02631
02632
02633 thold = (k1-k2)*gmin + k2*gmax;
02634 memset (sum, 0, sizeof sum);
02635 color = FC(row,col);
02636
02637
02638
02639 for (num=g=0; g < 8; g++,ip+=2)
02640 {
02641 if (gval[g] <= thold)
02642 {
02643 for (c=0; c < colors; c++)
02644 if (c == color && ip[1])
02645 sum[c] += (pix[c] + pix[ip[1]]) >> 1;
02646 else
02647 sum[c] += pix[ip[0] + c];
02648 num++;
02649 }
02650 }
02651
02652
02653
02654
02655
02656
02657
02658 for (c=0; c < colors; c++)
02659 {
02660 t = pix[color];
02661 if (c != color)
02662 {
02663 t += (sum[c] - sum[color])/num;
02664 if (t < 0) t = 0;
02665 if (t > rgb_max) t = rgb_max;
02666 }
02667 brow[2][col][c] = t;
02668 }
02669
02670
02671
02672
02673
02674 }
02675
02676
02677
02678
02679
02680
02681
02682 if (row > 3)
02683 memcpy (image[(row-2)*width+2], brow[0]+2, (width-4)*sizeof *image);
02684 for (g=0; g < 4; g++)
02685 brow[(g-1) & 3] = brow[g];
02686 }
02687
02688
02689
02690
02691
02692
02693
02694
02695 memcpy (image[(row-2)*width+2], brow[0]+2, (width-4)*sizeof *image);
02696 memcpy (image[(row-1)*width+2], brow[1]+2, (width-4)*sizeof *image);
02697 free(brow[4]);
02698 }
02699
02700
02701
02702
02703
02704 void thm_interpolate()
02705 {
02706 int row, col, x, y, c;
02707 int sum[4];
02708
02709 for (row=0; row < height; row += 4) {
02710 for (col=0; col < width; col += 4) {
02711 memset (sum, 0, sizeof sum);
02712 for (y=0; y < 4; y++){
02713 for (x=0; x< 4; x++){
02714 sum[0] += (image[(row+y)*width+(col+x)][0] >> 2);
02715 sum[1] += (image[(row+y)*width+(col+x)][1] >> 3);
02716 sum[2] += (image[(row+y)*width+(col+x)][2] >> 2);
02717 }
02718 }
02719 for (c=0; c < 3; c++)
02720 image[row*width+col][c] = sum[c];
02721 }
02722 }
02723 }
02724
02725
02726 void CLASS tiff_parse_subifd (int base)
02727 {
02728 int entries, tag, type, len, val, save;
02729
02730 entries = fget2(ifp);
02731 while (entries--) {
02732 tag = fget2(ifp);
02733 type = fget2(ifp);
02734 len = fget4(ifp);
02735 if (type == 3 && len < 3) {
02736 val = fget2(ifp); fget2(ifp);
02737 } else
02738 val = fget4(ifp);
02739 switch (tag) {
02740 case 0x100:
02741 raw_width = val;
02742 break;
02743 case 0x101:
02744 raw_height = val;
02745 break;
02746 case 0x102:
02747 break;
02748 case 0x103:
02749 tiff_data_compression = val;
02750 break;
02751 case 0x106:
02752 kodak_data_compression = val;
02753 break;
02754 case 0x111:
02755 if (len == 1)
02756 data_offset = val;
02757 else {
02758 save = ftell(ifp);
02759 fseek (ifp, val+base, SEEK_SET);
02760 data_offset = fget4(ifp);
02761 fseek (ifp, save, SEEK_SET);
02762 }
02763 break;
02764 case 0x115:
02765 break;
02766 case 0x116:
02767 break;
02768 case 0x117:
02769 break;
02770 case 0x123:
02771 curve_offset = val;
02772 curve_length = len;
02773 }
02774 }
02775 }
02776
02777 void CLASS nef_parse_makernote()
02778 {
02779 int base=0, offset=0, entries, tag, type, len, val, save;
02780 short sorder;
02781 char buf[10];
02782
02783
02784
02785
02786
02787 sorder = order;
02788 fread (buf, 1, 10, ifp);
02789 if (!strcmp (buf,"Nikon")) {
02790 base = ftell(ifp);
02791 order = fget2(ifp);
02792 val = fget2(ifp);
02793 offset = fget4(ifp);
02794 fseek (ifp, offset-8, SEEK_CUR);
02795 } else if (!strcmp (buf,"OLYMP"))
02796 fseek (ifp, -2, SEEK_CUR);
02797 else
02798 fseek (ifp, -10, SEEK_CUR);
02799
02800 entries = fget2(ifp);
02801 while (entries--) {
02802 tag = fget2(ifp);
02803 type = fget2(ifp);
02804 len = fget4(ifp);
02805 if (type == 3) {
02806 val = fget2(ifp); fget2(ifp);
02807 } else
02808 val = fget4(ifp);
02809 save = ftell(ifp);
02810 if (tag == 0xc) {
02811 fseek (ifp, base+val, SEEK_SET);
02812 camera_red = fget4(ifp);
02813 camera_red /= fget4(ifp);
02814 camera_blue = fget4(ifp);
02815 camera_blue/= fget4(ifp);
02816 }
02817 if (tag == 0x8c)
02818 curve_offset = base+val + 2112;
02819 if (tag == 0x96)
02820 curve_offset = base+val + 2;
02821 if (tag == 0x97) {
02822 if (!strcmp(model,"NIKON D100 ")) {
02823 fseek (ifp, base+val + 72, SEEK_SET);
02824 camera_red = fget2(ifp) / 256.0;
02825 camera_blue = fget2(ifp) / 256.0;
02826 } else if (!strcmp(model,"NIKON D2H")) {
02827 fseek (ifp, base+val + 10, SEEK_SET);
02828 camera_red = fget2(ifp);
02829 camera_red /= fget2(ifp);
02830 camera_blue = fget2(ifp);
02831 camera_blue = fget2(ifp) / camera_blue;
02832 } else if (!strcmp(model,"NIKON D70")) {
02833 fseek (ifp, base+val + 20, SEEK_SET);
02834 camera_red = fget2(ifp);
02835 camera_red /= fget2(ifp);
02836 camera_blue = fget2(ifp);
02837 camera_blue/= fget2(ifp);
02838 }
02839 }
02840 if (tag == 0x1017)
02841 camera_red = val / 256.0;
02842 if (tag == 0x1018)
02843 camera_blue = val / 256.0;
02844 fseek (ifp, save, SEEK_SET);
02845 }
02846 order = sorder;
02847 }
02848
02849
02850
02851
02852
02853 void CLASS get_timestamp()
02854 {
02855 struct tm t;
02856 time_t ts;
02857
02858 if (fscanf (ifp, "%d:%d:%d %d:%d:%d", &t.tm_year, &t.tm_mon,
02859 &t.tm_mday, &t.tm_hour, &t.tm_min, &t.tm_sec) != 6)
02860 return;
02861 t.tm_year -= 1900;
02862 t.tm_mon -= 1;
02863 putenv ("TZ=UTC");
02864 if ((ts = mktime(&t)) > 0)
02865 timestamp = ts;
02866 }
02867
02868 void CLASS nef_parse_exif (int base)
02869 {
02870 int entries, tag, type, len, val, save;
02871
02872 entries = fget2(ifp);
02873 while (entries--) {
02874 tag = fget2(ifp);
02875 type = fget2(ifp);
02876 len = fget4(ifp);
02877 val = fget4(ifp);
02878 save = ftell(ifp);
02879 fseek (ifp, val+base, SEEK_SET);
02880 if (tag == 0x9003 || tag == 0x9004)
02881 get_timestamp();
02882 if (tag == 0x927c &&
02883 (!strncmp(make,"NIKON",5) || !strncmp(make,"OLYMPUS",7)))
02884 nef_parse_makernote();
02885 fseek (ifp, save, SEEK_SET);
02886 }
02887 }
02888
02889
02890
02891
02892 void CLASS parse_tiff (int base)
02893 {
02894 int doff, entries, tag, type, len, val, save;
02895 char software[64];
02896 int wide=0, high=0, cr2_offset=0, offset=0;
02897 static const int flip_map[] = { 0,1,3,2,4,6,7,5 };
02898
02899 fseek (ifp, base, SEEK_SET);
02900 order = fget2(ifp);
02901 val = fget2(ifp);
02902 while ((doff = fget4(ifp))) {
02903 fseek (ifp, doff+base, SEEK_SET);
02904 entries = fget2(ifp);
02905 while (entries--) {
02906 tag = fget2(ifp);
02907 type = fget2(ifp);
02908 len = fget4(ifp);
02909 if (type == 3 && len < 3) {
02910 val = fget2(ifp); fget2(ifp);
02911 } else
02912 val = fget4(ifp);
02913 save = ftell(ifp);
02914 fseek (ifp, val+base, SEEK_SET);
02915
02916
02917
02918
02919 switch (tag) {
02920 case 0x11:
02921 camera_red = val / 256.0;
02922 break;
02923 case 0x12:
02924 camera_blue = val / 256.0;
02925 break;
02926 case 0x100:
02927 wide = val;
02928 break;
02929 case 0x101:
02930 high = val;
02931 break;
02932 case 0x10f:
02933 fgets (make, 64, ifp);
02934 break;
02935 case 0x110:
02936 fgets (model, 64, ifp);
02937 break;
02938 case 0x111:
02939 cr2_offset = val;
02940 offset = fget4(ifp);
02941 break;
02942 case 0x112:
02943 flip = flip_map[(val-1) & 7];
02944 break;
02945 case 0x123:
02946 curve_offset = val;
02947 curve_length = len;
02948 break;
02949 case 0x827d:
02950 fgets (model2, 64, ifp);
02951 break;
02952 case 0x131:
02953 fgets (software, 64, ifp);
02954 if (!strncmp(software,"Adobe",5))
02955 make[0] = 0;
02956 break;
02957 case 0x132:
02958 get_timestamp();
02959 break;
02960 case 0x144:
02961 strcpy (make, "Leaf");
02962 raw_width = wide;
02963 raw_height = high;
02964 if (len > 1)
02965 data_offset = fget4(ifp);
02966 else
02967 data_offset = val;
02968 break;
02969 case 0x14a:
02970 if (len > 2 && !strcmp(make,"Kodak"))
02971 len = 2;
02972 if (len > 1)
02973 while (len--) {
02974 fseek (ifp, val+base, SEEK_SET);
02975 fseek (ifp, fget4(ifp)+base, SEEK_SET);
02976 tiff_parse_subifd(base);
02977 val += 4;
02978 }
02979 else
02980 tiff_parse_subifd(base);
02981 break;
02982 case 0x8769:
02983 nef_parse_exif(base);
02984 break;
02985 }
02986
02987 fseek (ifp, save, SEEK_SET);
02988 }
02989 }
02990
02991 if (!strncmp(make,"OLYMPUS",7)) {
02992 make[7] = 0;
02993 raw_width = wide;
02994 raw_height = - (-high & -2);
02995 data_offset = offset;
02996 }
02997 if (!strcmp(make,"Canon") && strcmp(model,"EOS D2000C"))
02998 data_offset = cr2_offset;
02999
03000 if (make[0] == 0 && wide == 680 && high == 680) {
03001 strcpy (make, "Imacon");
03002 strcpy (model, "Ixpress");
03003 }
03004 }
03005
03006
03007
03008
03009
03010 void CLASS ciff_block_1030()
03011 {
03012 static const ushort key[] = { 0x410, 0x45f3 };
03013 int i, bpp, row, col, vbits=0;
03014 unsigned long bitbuf=0;
03015
03016 fget2(ifp);
03017 if (fget4(ifp) != 0x80008) return;
03018 if (fget4(ifp) == 0) return;
03019 bpp = fget2(ifp);
03020 if (bpp != 10 && bpp != 12) return;
03021 for (i=row=0; row < 8; row++)
03022 for (col=0; col < 8; col++) {
03023 if (vbits < bpp) {
03024 bitbuf = bitbuf << 16 | (fget2(ifp) ^ key[i++ & 1]);
03025 vbits += 16;
03026 }
03027 white[row][col] =
03028 bitbuf << (LONG_BIT - vbits) >> (LONG_BIT - bpp) << (14-bpp);
03029 vbits -= bpp;
03030 }
03031 }
03032
03033
03034
03035
03036
03037 void CLASS parse_ciff (int offset, int length)
03038 {
03039 int tboff, nrecs, i, type, len, roff, aoff, save, wbi=-1;
03040 static const int remap[] = { 1,2,3,4,5,1 };
03041 static const int remap_10d[] = { 0,1,3,4,5,6,0,0,2,8 };
03042
03043 fseek (ifp, offset+length-4, SEEK_SET);
03044 tboff = fget4(ifp) + offset;
03045 fseek (ifp, tboff, SEEK_SET);
03046 nrecs = fget2(ifp);
03047 for (i = 0; i < nrecs; i++) {
03048 type = fget2(ifp);
03049 len = fget4(ifp);
03050 roff = fget4(ifp);
03051 aoff = offset + roff;
03052 save = ftell(ifp);
03053 if (type == 0x080a) {
03054 fseek (ifp, aoff, SEEK_SET);
03055 fread (make, 64, 1, ifp);
03056 fseek (ifp, aoff+strlen(make)+1, SEEK_SET);
03057 fread (model, 64, 1, ifp);
03058 }
03059 if (type == 0x102a) {
03060 fseek (ifp, aoff+14, SEEK_SET);
03061 wbi = fget2(ifp);
03062 if (((!strcmp(model,"Canon EOS DIGITAL REBEL") ||
03063 !strcmp(model,"Canon EOS 300D DIGITAL"))) && wbi == 6)
03064 wbi++;
03065 }
03066 if (type == 0x102c) {
03067 if (!strcmp(model,"Canon PowerShot G1") ||
03068 !strcmp(model,"Canon PowerShot Pro90 IS")) {
03069 fseek (ifp, aoff+120, SEEK_SET);
03070 white[0][1] = fget2(ifp) << 4;
03071 white[0][0] = fget2(ifp) << 4;
03072 white[1][0] = fget2(ifp) << 4;
03073 white[1][1] = fget2(ifp) << 4;
03074 } else {
03075 fseek (ifp, aoff+100, SEEK_SET);
03076 if (wbi == 6 && fget4(ifp) == 0)
03077 wbi = 15;
03078 else {
03079 fseek (ifp, aoff+100, SEEK_SET);
03080 goto common;
03081 }
03082 }
03083 }
03084 if (type == 0x0032) {
03085 if (!strcmp(model,"Canon EOS D30")) {
03086 fseek (ifp, aoff+72, SEEK_SET);
03087 common:
03088 camera_red = fget2(ifp);
03089 camera_red = fget2(ifp) / camera_red;
03090 camera_blue = fget2(ifp);
03091 camera_blue /= fget2(ifp);
03092 } else {
03093 fseek (ifp, aoff+80 + (wbi < 6 ? remap[wbi]*8 : 0), SEEK_SET);
03094 if (!camera_red)
03095 goto common;
03096 }
03097 }
03098 if (type == 0x10a9) {
03099 if (!strcmp(model,"Canon EOS 10D"))
03100 wbi = remap_10d[wbi];
03101 fseek (ifp, aoff+2 + wbi*8, SEEK_SET);
03102 camera_red = fget2(ifp);
03103 camera_red /= fget2(ifp);
03104 camera_blue = fget2(ifp);
03105 camera_blue = fget2(ifp) / camera_blue;
03106 }
03107 if (type == 0x1030 && wbi > 14) {
03108 fseek (ifp, aoff, SEEK_SET);
03109 ciff_block_1030();
03110 }
03111 if (type == 0x1031) {
03112 fseek (ifp, aoff+2, SEEK_SET);
03113 raw_width = fget2(ifp);
03114 raw_height = fget2(ifp);
03115 }
03116 if (type == 0x180e) {
03117 fseek (ifp, aoff, SEEK_SET);
03118 timestamp = fget4(ifp);
03119 }
03120 if (type == 0x580e)
03121 timestamp = len;
03122 if (type == 0x1810) {
03123 fseek (ifp, aoff+12, SEEK_SET);
03124 switch (fget4(ifp)) {
03125 case 270: flip = 5; break;
03126 case 180: flip = 3; break;
03127 case 90: flip = 6;
03128 }
03129 }
03130 if (type == 0x1835) {
03131 fseek (ifp, aoff, SEEK_SET);
03132 crw_init_tables (fget4(ifp));
03133 }
03134 if (type >> 8 == 0x28 || type >> 8 == 0x30)
03135 parse_ciff(aoff, len);
03136 fseek (ifp, save, SEEK_SET);
03137 }
03138 if (wbi == 0 && !strcmp(model,"Canon EOS D30"))
03139 camera_red = -1;
03140 }
03141
03142 void CLASS parse_rollei()
03143 {
03144 char line[128], *val;
03145 int tx=0, ty=0;
03146 struct tm t;
03147 time_t ts;
03148
03149 fseek (ifp, 0, SEEK_SET);
03150 do {
03151 fgets (line, 128, ifp);
03152 if ((val = strchr(line,'=')))
03153 *val++ = 0;
03154 else
03155 val = line + strlen(line);
03156 if (!strcmp(line,"DAT"))
03157 sscanf (val, "%d.%d.%d", &t.tm_mday, &t.tm_mon, &t.tm_year);
03158 if (!strcmp(line,"TIM"))
03159 sscanf (val, "%d:%d:%d", &t.tm_hour, &t.tm_min, &t.tm_sec);
03160 if (!strcmp(line,"HDR"))
03161 data_offset = atoi(val);
03162 if (!strcmp(line,"X "))
03163 raw_width = atoi(val);
03164 if (!strcmp(line,"Y "))
03165 raw_height = atoi(val);
03166 if (!strcmp(line,"TX "))
03167 tx = atoi(val);
03168 if (!strcmp(line,"TY "))
03169 ty = atoi(val);
03170 } while (strncmp(line,"EOHD",4));
03171 t.tm_year -= 1900;
03172 t.tm_mon -= 1;
03173 putenv ("TZ=");
03174 if ((ts = mktime(&t)) > 0)
03175 timestamp = ts;
03176 data_offset += tx * ty * 2;
03177 strcpy (make, "Rollei");
03178 strcpy (model, "d530flex");
03179 }
03180
03181 void CLASS parse_foveon()
03182 {
03183 char *buf, *bp, *np;
03184 int off1, off2, len, i;
03185
03186 order = 0x4949;
03187 fseek (ifp, -4, SEEK_END);
03188 off2 = fget4(ifp);
03189 fseek (ifp, off2, SEEK_SET);
03190 while (fget4(ifp) != 0x464d4143)
03191 if (feof(ifp)) return;
03192 off1 = fget4(ifp);
03193 fseek (ifp, off1+8, SEEK_SET);
03194 off1 += (fget4(ifp)+3) * 8;
03195 len = (off2 - off1)/2;
03196 fseek (ifp, off1, SEEK_SET);
03197 buf = malloc (len);
03198 merror (buf, "parse_foveon()");
03199 for (i=0; i < len; i++)
03200 buf[i] = fget2(ifp);
03201 for (bp=buf; bp < buf+len; bp=np) {
03202 np = bp + strlen(bp) + 1;
03203 if (!strcmp(bp,"CAMMANUF"))
03204 strcpy (make, np);
03205 if (!strcmp(bp,"CAMMODEL"))
03206 strcpy (model, np);
03207 if (!strcmp(bp,"TIME"))
03208 timestamp = atoi(np);
03209 }
03210 fseek (ifp, 248, SEEK_SET);
03211 raw_width = fget4(ifp);
03212 raw_height = fget4(ifp);
03213 free(buf);
03214 }
03215
03216 void CLASS foveon_coeff()
03217 {
03218 static const float foveon[3][3] = {
03219 { 2.0343955, -0.727533, -0.3067457 },
03220 { -0.2287194, 1.231793, -0.0028293 },
03221 { -0.0086152, -0.153336, 1.1617814 }
03222 };
03223 int i, j;
03224
03225 for (i=0; i < 3; i++)
03226 for (j=0; j < 3; j++)
03227 coeff[i][j] = foveon[i][j] * pre_mul[i];
03228 use_coeff = 1;
03229 }
03230
03231
03232
03233
03234
03235 void CLASS canon_rgb_coeff (float juice)
03236 {
03237 static const float my_coeff[3][3] =
03238 { { 1.116187, -0.107427, -0.008760 },
03239 { -1.551374, 4.157144, -1.605770 },
03240 { 0.090939, -0.399727, 1.308788 } };
03241 int i, j;
03242
03243 if (juice != 0) {
03244 for (i=0; i < 3; i++)
03245 for (j=0; j < 3; j++)
03246 coeff[i][j] = my_coeff[i][j] * juice + (i==j) * (1-juice);
03247 use_coeff = 1;
03248 }
03249 }
03250
03251 void CLASS nikon_e950_coeff()
03252 {
03253 int r, g;
03254 static const float my_coeff[3][4] =
03255 { { -1.936280, 1.800443, -1.448486, 2.584324 },
03256 { 1.405365, -0.524955, -0.289090, 0.408680 },
03257 { -1.204965, 1.082304, 2.941367, -1.818705 } };
03258
03259 for (r=0; r < 3; r++)
03260 for (g=0; g < 4; g++)
03261 coeff[r][g] = my_coeff[r][g];
03262 use_coeff = 1;
03263 }
03264
03265
03266
03267
03268
03269
03270
03271 void CLASS gmcy_coeff()
03272 {
03273 static const float gmcy[4][3] = {
03274
03275 { 0.11, 0.86, 0.08 },
03276 { 0.50, 0.29, 0.51 },
03277 { 0.11, 0.92, 0.75 },
03278 { 0.81, 0.98, 0.08 }
03279 };
03280 double invert[3][6], num;
03281 int ignore, i, j, k, r, g;
03282
03283 memset (coeff, 0, sizeof coeff);
03284 for (ignore=0; ignore < 4; ignore++) {
03285 for (j=0; j < 3; j++) {
03286 g = (j < ignore) ? j : j+1;
03287 for (r=0; r < 3; r++) {
03288 invert[j][r] = gmcy[g][r];
03289 invert[j][r+3] = (r == j);
03290 }
03291 }
03292 for (j=0; j < 3; j++) {
03293 num = invert[j][j];
03294 for (i=0; i < 6; i++)
03295 invert[j][i] /= num;
03296 for (k=0; k < 3; k++) {
03297 if (k==j) continue;
03298 num = invert[k][j];
03299 for (i=0; i < 6; i++)
03300 invert[k][i] -= invert[j][i] * num;
03301 }
03302 }
03303 for (j=0; j < 3; j++) {
03304 g = (j < ignore) ? j : j+1;
03305 for (r=0; r < 3; r++)
03306 coeff[r][g] += invert[r][j+3];
03307 }
03308 }
03309 for (r=0; r < 3; r++) {
03310 for (num=g=0; g < 4; g++)
03311 num += coeff[r][g];
03312 for (g=0; g < 4; g++)
03313 coeff[r][g] /= num;
03314 }
03315 use_coeff = 1;
03316 }
03317
03318
03319
03320
03321
03322 int CLASS identify()
03323 {
03324 char head[32], *c;
03325 unsigned hlen, fsize, i;
03326 static const struct {
03327 int fsize;
03328 char make[12], model[16];
03329 } table[] = {
03330 { 62464, "Kodak", "DC20" },
03331 { 124928, "Kodak", "DC20" },
03332 { 2465792, "NIKON", "E950" },
03333 { 2940928, "NIKON", "E2100" },
03334 { 4771840, "NIKON", "E990" },
03335 { 5865472, "NIKON", "E4500" },
03336 { 5869568, "NIKON", "E4300" },
03337 { 787456, "Creative", "PC-CAM 600" },
03338 { 1976352, "Casio", "QV-2000UX" },
03339 { 3217760, "Casio", "QV-3*00EX" },
03340 { 6218368, "Casio", "QV-5700" },
03341 { 7684000, "Casio", "QV-4000" },
03342 { 9313536, "Casio", "EX-P600" },
03343 { 4841984, "Pentax", "Optio S" },
03344 { 6114240, "Pentax", "Optio S4" },
03345 { 12582980, "Sinar", "" } };
03346 static const char *corp[] =
03347 { "Canon", "NIKON", "Kodak", "PENTAX", "MINOLTA", "Minolta", "Konica" };
03348
03349
03350
03351 raw_height = raw_width = flip = 0;
03352 make[0] = model[0] = model2[0] = 0;
03353 memset (white, 0, sizeof white);
03354 camera_red = camera_blue = timestamp = 0;
03355 data_offset = curve_offset = tiff_data_compression = 0;
03356 zero_after_ff = 0;
03357
03358 order = fget2(ifp);
03359 hlen = fget4(ifp);
03360 fseek (ifp, 0, SEEK_SET);
03361 fread (head, 1, 32, ifp);
03362 fseek (ifp, 0, SEEK_END);
03363 fsize = ftell(ifp);
03364 if ((c = memmem (head, 32, "MMMMRawT", 8))) {
03365 strcpy (make, "Phase One");
03366 data_offset = c - head;
03367 fseek (ifp, data_offset + 8, SEEK_SET);
03368 fseek (ifp, fget4(ifp) + 136, SEEK_CUR);
03369 raw_width = fget4(ifp);
03370 fseek (ifp, 12, SEEK_CUR);
03371 raw_height = fget4(ifp);
03372 } else if (order == 0x4949 || order == 0x4d4d) {
03373 if (!memcmp (head+6, "HEAPCCDR", 8)) {
03374 data_offset = hlen;
03375 parse_ciff (hlen, fsize - hlen);
03376 } else {
03377 parse_tiff(0);
03378 if (!strncmp(make,"NIKON",5) && raw_width == 0)
03379 make[0] = 0;
03380 }
03381 } else if (!memcmp (head, "\0MRM", 4)) {
03382 parse_tiff(48);
03383 fseek (ifp, 4, SEEK_SET);
03384 data_offset = fget4(ifp) + 8;
03385 fseek (ifp, 24, SEEK_SET);
03386 raw_height = fget2(ifp);
03387 raw_width = fget2(ifp);
03388 fseek (ifp, 12, SEEK_SET);
03389 fseek (ifp, fget4(ifp) + 4, SEEK_CUR);
03390 fseek (ifp, fget4(ifp) + 12, SEEK_CUR);
03391 camera_red = fget2(ifp);
03392 camera_red /= fget2(ifp);
03393 camera_blue = fget2(ifp);
03394 camera_blue = fget2(ifp) / camera_blue;
03395 } else if (!memcmp (head, "\xff\xd8\xff\xe1", 4) &&
03396 !memcmp (head+6, "Exif", 4)) {
03397 fseek (ifp, 4, SEEK_SET);
03398 fseek (ifp, 4 + fget2(ifp), SEEK_SET);
03399 if (fgetc(ifp) != 0xff)
03400 parse_tiff(12);
03401 } else if (!memcmp (head, "BM", 2)) {
03402 data_offset = 0x1000;
03403 order = 0x4949;
03404 fseek (ifp, 38, SEEK_SET);
03405 if (fget4(ifp) == 2834 && fget4(ifp) == 2834) {
03406 strcpy (model, "BMQ");
03407 goto nucore;
03408 }
03409 } else if (!memcmp (head, "BR", 2)) {
03410 strcpy (model, "RAW");
03411 nucore:
03412 strcpy (make, "Nucore");
03413 order = 0x4949;
03414 fseek (ifp, 10, SEEK_SET);
03415 data_offset += fget4(ifp);
03416 fget4(ifp);
03417 raw_width = fget4(ifp);
03418 raw_height = fget4(ifp);
03419 if (model[0] == 'B' && raw_width == 2597) {
03420 raw_width++;
03421 data_offset -= 0x1000;
03422 }
03423 } else if (!memcmp (head+25, "ARECOYK", 7)) {
03424 strcpy (make, "CONTAX");
03425 strcpy (model, "N DIGITAL");
03426 } else if (!memcmp (head, "FUJIFILM", 8)) {
03427 fseek (ifp, 84, SEEK_SET);
03428 parse_tiff (fget4(ifp)+12);
03429 order = 0x4d4d;
03430 fseek (ifp, 100, SEEK_SET);
03431 data_offset = fget4(ifp);
03432 } else if (!memcmp (head, "DSC-Image", 9))
03433 parse_rollei();
03434 else if (!memcmp (head, "FOVb", 4))
03435 parse_foveon();
03436 else
03437 for (i=0; i < sizeof table / sizeof *table; i++)
03438 if (fsize == table[i].fsize) {
03439 strcpy (make, table[i].make );
03440 strcpy (model, table[i].model);
03441 }
03442
03443 for (i=0; i < sizeof corp / sizeof *corp; i++)
03444 if (strstr (make, corp[i]))
03445 strcpy (make, corp[i]);
03446 if (!strncmp (make, "KODAK", 5))
03447 make[16] = model[16] = 0;
03448 c = make + strlen(make);
03449 while (*--c == ' ') *c = 0;
03450 c = model + strlen(model);
03451 while (*--c == ' ') *c = 0;
03452 i = strlen(make);
03453 if (!strncmp (model, make, i++))
03454 memmove (model, model+i, 64-i);
03455
03456
03457 if (make[0] == 0) {
03458
03459
03460 return 1;
03461 }
03462
03463
03464
03465
03466 load_raw = NULL;
03467 height = raw_height;
03468 width = raw_width;
03469 top_margin = left_margin = 0;
03470 colors = 3;
03471 filters = 0x94949494;
03472 black = is_cmy = is_foveon = use_coeff = 0;
03473 pre_mul[0] = pre_mul[1] = pre_mul[2] = pre_mul[3] = 1;
03474 xmag = ymag = 1;
03475 rgb_max = 0x4000;
03476
03477
03478
03479 if ((is_canon = !strcmp(make,"Canon"))) {
03480 canon_rgb_coeff (juice);
03481 if (memcmp (head+6, "HEAPCCDR", 8)) {
03482 filters = 0x61616161;
03483 load_raw = lossless_jpeg_load_raw;
03484 }
03485 else
03486 if (raw_width)
03487 {
03488 load_raw = canon_compressed_load_raw;
03489 }
03490 }
03491 if (!strcmp(make,"NIKON"))
03492 load_raw = nikon_is_compressed() ?
03493 nikon_compressed_load_raw : nikon_load_raw;
03494
03495 if (!strcmp(model,"PowerShot 600")) {
03496 height = 613;
03497 width = 854;
03498 colors = 4;
03499 filters = 0xe1e4e1e4;
03500 load_raw = canon_600_load_raw;
03501 pre_mul[0] = 1.137;
03502 pre_mul[1] = 1.257;
03503 } else if (!strcmp(model,"PowerShot A5") ||
03504 !strcmp(model,"PowerShot A5 Zoom")) {
03505 height = 776;
03506 width = 960;
03507 raw_width = 992;
03508 colors = 4;
03509 filters = 0x1e4e1e4e;
03510 load_raw = canon_a5_load_raw;
03511 pre_mul[0] = 1.5842;
03512 pre_mul[1] = 1.2966;
03513 pre_mul[2] = 1.0419;
03514 } else if (!strcmp(model,"PowerShot A50")) {
03515 height = 968;
03516 width = 1290;
03517 raw_width = 1320;
03518 colors = 4;
03519 filters = 0x1b4e4b1e;
03520 load_raw = canon_a5_load_raw;
03521 pre_mul[0] = 1.750;
03522 pre_mul[1] = 1.381;
03523 pre_mul[3] = 1.182;
03524 } else if (!strcmp(model,"PowerShot Pro70")) {
03525 height = 1024;
03526 width = 1552;
03527 colors = 4;
03528 filters = 0x1e4b4e1b;
03529 load_raw = canon_a5_load_raw;
03530 pre_mul[0] = 1.389;
03531 pre_mul[1] = 1.343;
03532 pre_mul[3] = 1.034;
03533 } else if (!strcmp(model,"PowerShot Pro90 IS")) {
03534 width = 1896;
03535 colors = 4;
03536 filters = 0xb4b4b4b4;
03537 pre_mul[0] = 1.496;
03538 pre_mul[1] = 1.509;
03539 pre_mul[3] = 1.009;
03540 } else if (is_canon && raw_width == 2144) {
03541 height = 1550;
03542 width = 2088;
03543 top_margin = 8;
03544 left_margin = 4;
03545 if (!strcmp(model,"PowerShot G1")) {
03546 colors = 4;
03547 filters = 0xb4b4b4b4;
03548 pre_mul[0] = 1.446;
03549 pre_mul[1] = 1.405;
03550 pre_mul[2] = 1.016;
03551 } else {
03552 pre_mul[0] = 1.785;
03553 pre_mul[2] = 1.266;
03554 }
03555 } else if (is_canon && raw_width == 2224) {
03556 height = 1448;
03557 width = 2176;
03558 top_margin = 6;
03559 left_margin = 48;
03560 pre_mul[0] = 1.592;
03561 pre_mul[2] = 1.261;
03562 } else if (is_canon && raw_width == 2376) {
03563 height = 1720;
03564 width = 2312;
03565 top_margin = 6;
03566 left_margin = 12;
03567 #ifdef CUSTOM
03568 if (write_fun == write_ppm)
03569 canon_rgb_coeff (0.1);
03570 #endif
03571 if (!strcmp(model,"PowerShot G2") ||
03572 !strcmp(model,"PowerShot S40")) {
03573 pre_mul[0] = 1.965;
03574 pre_mul[2] = 1.208;
03575 } else {
03576 pre_mul[0] = 1.855;
03577 pre_mul[2] = 1.339;
03578 }
03579 } else if (is_canon && raw_width == 2672) {
03580 height = 1960;
03581 width = 2616;
03582 top_margin = 6;
03583 left_margin = 12;
03584 pre_mul[0] = 1.895;
03585 pre_mul[2] = 1.403;
03586 } else if (is_canon && raw_width == 3152) {
03587 height = 2056;
03588 width = 3088;
03589 top_margin = 12;
03590 left_margin = 64;
03591 pre_mul[0] = 2.242;
03592 pre_mul[2] = 1.245;
03593 if (!strcmp(model,"EOS Kiss Digital")) {
03594 pre_mul[0] = 1.882;
03595 pre_mul[2] = 1.094;
03596 }
03597 rgb_max = 16000;
03598 } else if (is_canon && raw_width == 3160) {
03599 height = 2328;
03600 width = 3112;
03601 top_margin = 12;
03602 left_margin = 44;
03603 pre_mul[0] = 1.85;
03604 pre_mul[2] = 1.53;
03605 } else if (is_canon && raw_width == 3344) {
03606 height = 2472;
03607 width = 3288;
03608 top_margin = 6;
03609 left_margin = 4;
03610 pre_mul[0] = 1.621;
03611 pre_mul[2] = 1.528;
03612 } else if (!strcmp(model,"EOS-1D")) {
03613 height = 1662;
03614 width = 2496;
03615 data_offset = 288912;
03616 pre_mul[0] = 1.976;
03617 pre_mul[2] = 1.282;
03618 } else if (!strcmp(model,"EOS-1DS")) {
03619 height = 2718;
03620 width = 4082;
03621 data_offset = 289168;
03622 pre_mul[0] = 1.66;
03623 pre_mul[2] = 1.13;
03624 rgb_max = 14464;
03625 } else if (!strcmp(model,"EOS-1D Mark II") ||
03626 !strcmp(model,"EOS 20D")) {
03627 raw_height = 2360;
03628 raw_width = 3596;
03629 top_margin = 12;
03630 left_margin = 74;
03631 height = raw_height - top_margin;
03632 width = raw_width - left_margin;
03633 filters = 0x94949494;
03634 pre_mul[0] = 1.95;
03635 pre_mul[2] = 1.36;
03636 } else if (!strcmp(model,"EOS-1Ds Mark II")) {
03637 raw_height = 3349;
03638 raw_width = 5108;
03639 top_margin = 13;
03640 left_margin = 98;
03641 height = raw_height - top_margin;
03642 width = raw_width - left_margin;
03643 filters = 0x94949494;
03644 pre_mul[0] = 1.609;
03645 pre_mul[2] = 1.848;
03646 rgb_max = 0x3a00;
03647 } else if (!strcmp(model,"EOS D2000C")) {
03648 black = 800;
03649 pre_mul[2] = 1.25;
03650 } else if (!strcmp(model,"D1")) {
03651 filters = 0x16161616;
03652 pre_mul[0] = 0.838;
03653 pre_mul[2] = 1.095;
03654 } else if (!strcmp(model,"D1H")) {
03655 filters = 0x16161616;
03656 pre_mul[0] = 2.301;
03657 pre_mul[2] = 1.129;
03658 } else if (!strcmp(model,"D1X")) {
03659 width = 4024;
03660 filters = 0x16161616;
03661 ymag = 2;
03662 pre_mul[0] = 1.910;
03663 pre_mul[2] = 1.220;
03664 } else if (!strcmp(model,"D100")) {
03665 if (tiff_data_compression == 34713 && load_raw == nikon_load_raw)
03666 raw_width = (width += 3) + 3;
03667 filters = 0x61616161;
03668 pre_mul[0] = 2.374;
03669 pre_mul[2] = 1.677;
03670 rgb_max = 15632;
03671 } else if (!strcmp(model,"D2H")) {
03672 width = 2482;
03673 left_margin = 6;
03674 filters = 0x49494949;
03675 pre_mul[0] = 2.8;
03676 pre_mul[2] = 1.2;
03677 } else if (!strcmp(model,"D70")) {
03678 filters = 0x16161616;
03679 pre_mul[0] = 2.043;
03680 pre_mul[2] = 1.625;
03681 } else if (!strcmp(model,"E950")) {
03682 height = 1203;
03683 width = 1616;
03684 filters = 0x4b4b4b4b;
03685 colors = 4;
03686 load_raw = nikon_e950_load_raw;
03687 nikon_e950_coeff();
03688 pre_mul[0] = 1.18193;
03689 pre_mul[2] = 1.16452;
03690 pre_mul[3] = 1.17250;
03691 } else if (!strcmp(model,"E990")) {
03692 height = 1540;
03693 width = 2064;
03694 colors = 4;
03695 if (nikon_e990()) {
03696 filters = 0xb4b4b4b4;
03697 nikon_e950_coeff();
03698 pre_mul[0] = 1.196;
03699 pre_mul[1] = 1.246;
03700 pre_mul[2] = 1.018;
03701 } else {
03702 strcpy (model, "E995");
03703 filters = 0xe1e1e1e1;
03704 pre_mul[0] = 1.253;
03705 pre_mul[1] = 1.178;
03706 pre_mul[3] = 1.035;
03707 }
03708 } else if (!strcmp(model,"E2100")) {
03709 width = 1616;
03710 if (nikon_e2100()) {
03711 height = 1206;
03712 load_raw = nikon_e2100_load_raw;
03713 pre_mul[0] = 1.945;
03714 pre_mul[2] = 1.040;
03715 } else {
03716 strcpy (model, "E2500");
03717 height = 1204;
03718 filters = 0x4b4b4b4b;
03719 goto coolpix;
03720 }
03721 } else if (!strcmp(model,"E4300")) {
03722 height = 1710;
03723 width = 2288;
03724 filters = 0x16161616;
03725 if (minolta_z2()) {
03726 strcpy (make, "Minolta");
03727 strcpy (model, "DiMAGE Z2");
03728 load_raw = nikon_e2100_load_raw;
03729 }
03730 } else if (!strcmp(model,"E4500")) {
03731 height = 1708;
03732 width = 2288;
03733 filters = 0xb4b4b4b4;
03734 goto coolpix;
03735 } else if (!strcmp(model,"E5000") || !strcmp(model,"E5700")) {
03736 filters = 0xb4b4b4b4;
03737 coolpix:
03738 colors = 4;
03739 pre_mul[0] = 1.300;
03740 pre_mul[1] = 1.300;
03741 pre_mul[3] = 1.148;
03742 } else if (!strcmp(model,"E5400")) {
03743 filters = 0x16161616;
03744 pre_mul[0] = 1.700;
03745 pre_mul[2] = 1.344;
03746 } else if (!strcmp(model,"E8700") ||
03747 !strcmp(model,"E8800")) {
03748 filters = 0x16161616;
03749 pre_mul[0] = 2.131;
03750 pre_mul[2] = 1.300;
03751 } else if (!strcmp(model,"FinePixS2Pro")) {
03752 height = 3584;
03753 width = 3583;
03754 filters = 0x61616161;
03755 load_raw = fuji_s2_load_raw;
03756 black = 512;
03757 pre_mul[0] = 1.424;
03758 pre_mul[2] = 1.718;
03759 } else if (!strcmp(model,"FinePix S5000")) {
03760 height = 2499;
03761 width = 2500;
03762 filters = 0x49494949;
03763 load_raw = fuji_s5000_load_raw;
03764 pre_mul[0] = 1.639;
03765 pre_mul[2] = 1.438;
03766 rgb_max = 0xf800;
03767 } else if (!strcmp(model,"FinePix S7000")) {
03768 pre_mul[0] = 1.62;
03769 pre_mul[2] = 1.38;
03770 goto fuji_s7000;
03771 } else if (!strcmp(model,"FinePix E550")) {
03772 pre_mul[0] = 1.45;
03773 pre_mul[2] = 1.25;
03774 fuji_s7000:
03775 height = 3587;
03776 width = 3588;
03777 filters = 0x49494949;
03778 load_raw = fuji_s7000_load_raw;
03779 rgb_max = 0xf800;
03780 } else if (!strcmp(model,"FinePix F700") ||
03781 !strcmp(model,"FinePix S20Pro")) {
03782 height = 2523;
03783 width = 2524;
03784 filters = 0x49494949;
03785 load_raw = fuji_f700_load_raw;
03786 pre_mul[0] = 1.639;
03787 pre_mul[2] = 1.438;
03788 rgb_max = 0x3e00;
03789 } else if (!strcmp(model,"Digital Camera KD-400Z")) {
03790 height = 1712;
03791 width = 2312;
03792 raw_width = 2336;
03793 data_offset = 4034;
03794 fseek (ifp, 2032, SEEK_SET);
03795 goto konica_400z;
03796 } else if (!strcmp(model,"Digital Camera KD-510Z")) {
03797 data_offset = 4032;
03798 fseek (ifp, 2032, SEEK_SET);
03799 goto konica_510z;
03800 } else if (!strcasecmp(make,"MINOLTA")) {
03801 load_raw = be_low_12_load_raw;
03802 rgb_max = 15860;
03803 if (!strncmp(model,"DiMAGE A",8)) {
03804 load_raw = packed_12_load_raw;
03805 rgb_max = model[8] == '1' ? 15916:16380;
03806 } else if (!strncmp(model,"DiMAGE G",8)) {
03807 if (model[8] == '4') {
03808 data_offset = 5056;
03809 fseek (ifp, 2078, SEEK_SET);
03810 height = 1716;
03811 width = 2304;
03812 } else if (model[8] == '5') {
03813 data_offset = 4016;
03814 fseek (ifp, 1936, SEEK_SET);
03815 konica_510z:
03816 height = 1956;
03817 width = 2607;
03818 raw_width = 2624;
03819 } else if (model[8] == '6') {
03820 data_offset = 4032;
03821 fseek (ifp, 2030, SEEK_SET);
03822 height = 2136;
03823 width = 2848;
03824 }
03825 filters = 0x61616161;
03826 konica_400z:
03827 load_raw = be_low_10_load_raw;
03828 rgb_max = 15856;
03829 order = 0x4d4d;
03830 camera_red = fget2(ifp);
03831 camera_blue = fget2(ifp);
03832 camera_red /= fget2(ifp);
03833 camera_blue /= fget2(ifp);
03834 }
03835 pre_mul[0] = 1.42;
03836 pre_mul[2] = 1.25;
03837 } else if (!strcmp(model,"*ist D")) {
03838 height = 2024;
03839 width = 3040;
03840 data_offset = 0x10000;
03841 load_raw = be_low_12_load_raw;
03842 pre_mul[0] = 1.76;
03843 pre_mul[1] = 1.07;
03844 } else if (!strcmp(model,"Optio S")) {
03845 height = 1544;
03846 width = 2068;
03847 raw_width = 3136;
03848 load_raw = packed_12_load_raw;
03849 pre_mul[0] = 1.506;
03850 pre_mul[2] = 1.152;
03851 } else if (!strcmp(model,"Optio S4")) {
03852 height = 1737;
03853 width = 2324;
03854 raw_width = 3520;
03855 load_raw = packed_12_load_raw;
03856 pre_mul[0] = 1.308;
03857 pre_mul[2] = 1.275;
03858 } else if (!strcmp(make,"Phase One")) {
03859 switch (raw_height) {
03860 case 2060:
03861 strcpy (model, "LightPhase");
03862 height = 2048;
03863 width = 3080;
03864 top_margin = 5;
03865 left_margin = 22;
03866 pre_mul[0] = 1.331;
03867 pre_mul[2] = 1.154;
03868 break;
03869 case 2682:
03870 strcpy (model, "H10");
03871 height = 2672;
03872 width = 4012;
03873 top_margin = 5;
03874 left_margin = 26;
03875 break;
03876 case 4128:
03877 strcpy (model, "H20");
03878 height = 4098;
03879 width = 4098;
03880 top_margin = 20;
03881 left_margin = 26;
03882 pre_mul[0] = 1.963;
03883 pre_mul[2] = 1.430;
03884 break;
03885 case 5488:
03886 strcpy (model, "H25");
03887 height = 5458;
03888 width = 4098;
03889 top_margin = 20;
03890 left_margin = 26;
03891 pre_mul[0] = 2.80;
03892 pre_mul[2] = 1.20;
03893 }
03894 filters = top_margin & 1 ? 0x94949494 : 0x49494949;
03895 load_raw = phase_one_load_raw;
03896 rgb_max = 0xffff;
03897 } else if (!strcmp(model,"Ixpress")) {
03898 height = 4084;
03899 width = 4080;
03900 filters = 0x49494949;
03901 load_raw = ixpress_load_raw;
03902 pre_mul[0] = 1.963;
03903 pre_mul[2] = 1.430;
03904 rgb_max = 0xffff;
03905 } else if (!strcmp(make,"Sinar") && !memcmp(head,"8BPS",4)) {
03906 fseek (ifp, 14, SEEK_SET);
03907 height = fget4(ifp);
03908 width = fget4(ifp);
03909 filters = 0x61616161;
03910 data_offset = 68;
03911 load_raw = be_16_load_raw;
03912 rgb_max = 0xffff;
03913 } else if (!strcmp(make,"Leaf")) {
03914 if (height > width)
03915 filters = 0x16161616;
03916 load_raw = be_16_load_raw;
03917 pre_mul[0] = 1.1629;
03918 pre_mul[2] = 1.3556;
03919 rgb_max = 0xffff;
03920 } else if (!strcmp(model,"DIGILUX 2") || !strcmp(model,"DMC-LC1")) {
03921 height = 1928;
03922 width = 2568;
03923 data_offset = 1024;
03924 load_raw = le_high_12_load_raw;
03925 pre_mul[0] = 1.883;
03926 pre_mul[2] = 1.367;
03927 } else if (!strcmp(model,"E-1")) {
03928 filters = 0x61616161;
03929 load_raw = le_high_12_load_raw;
03930 pre_mul[0] = 1.57;
03931 pre_mul[2] = 1.48;
03932 } else if (!strcmp(model,"E-10")) {
03933 load_raw = be_high_12_load_raw;
03934 pre_mul[0] = 1.43;
03935 pre_mul[2] = 1.77;
03936 } else if (!strncmp(model,"E-20",4)) {
03937 load_raw = be_high_12_load_raw;
03938 black = 640;
03939 pre_mul[0] = 1.43;
03940 pre_mul[2] = 1.77;
03941 } else if (!strcmp(model,"C5050Z")) {
03942 filters = 0x16161616;
03943 load_raw = olympus_cseries_load_raw;
03944 pre_mul[0] = 1.533;
03945 pre_mul[2] = 1.880;
03946 } else if (!strcmp(model,"C5060WZ")) {
03947 load_raw = olympus_cseries_load_raw;
03948 pre_mul[0] = 2.285;
03949 pre_mul[2] = 1.023;
03950 } else if (!strcmp(model,"C8080WZ")) {
03951 filters = 0x16161616;
03952 load_raw = olympus_cseries_load_raw;
03953 pre_mul[0] = 2.335;
03954 pre_mul[2] = 1.323;
03955 } else if (!strcmp(model,"N DIGITAL")) {
03956 height = 2047;
03957 width = 3072;
03958 filters = 0x61616161;
03959 data_offset = 0x1a00;
03960 load_raw = packed_12_load_raw;
03961 pre_mul[0] = 1.366;
03962 pre_mul[2] = 1.251;
03963 } else if (!strcmp(model,"DSC-F828")) {
03964 height = 2460;
03965 width = 3288;
03966 raw_width = 3360;
03967 left_margin = 5;
03968 load_raw = sony_load_raw;
03969 sony_rgbe_coeff();
03970 filters = 0xb4b4b4b4;
03971 colors = 4;
03972 pre_mul[0] = 1.512;
03973 pre_mul[1] = 1.020;
03974 pre_mul[2] = 1.405;
03975 } else if (!strcasecmp(make,"KODAK")) {
03976 filters = 0x61616161;
03977 if (!strcmp(model,"NC2000F")) {
03978 width -= 4;
03979 left_margin = 1;
03980 curve_length = 176;
03981 pre_mul[0] = 1.509;
03982 pre_mul[2] = 2.686;
03983 } else if (!strcmp(model,"EOSDCS3B")) {
03984 width -= 4;
03985 left_margin = 2;
03986 pre_mul[0] = 1.629;
03987 pre_mul[2] = 2.767;
03988 } else if (!strcmp(model,"EOSDCS1")) {
03989 width -= 4;
03990 left_margin = 2;
03991 pre_mul[0] = 1.386;
03992 pre_mul[2] = 2.405;
03993 } else if (!strcmp(model,"DCS315C")) {
03994 black = 32;
03995 pre_mul[1] = 1.068;
03996 pre_mul[2] = 1.036;
03997 } else if (!strcmp(model,"DCS330C")) {
03998 black = 32;
03999 pre_mul[1] = 1.012;
04000 pre_mul[2] = 1.804;
04001 } else if (!strcmp(model,"DCS420")) {
04002 width -= 4;
04003 left_margin = 2;
04004 pre_mul[0] = 1.327;
04005 pre_mul[2] = 2.074;
04006 } else if (!strcmp(model,"DCS460")) {
04007 width -= 4;
04008 left_margin = 2;
04009 pre_mul[0] = 1.724;
04010 pre_mul[2] = 2.411;
04011 } else if (!strcmp(model,"DCS460A")) {
04012 width -= 4;
04013 left_margin = 2;
04014 colors = 1;
04015 filters = 0;
04016 } else if (!strcmp(model,"DCS520C")) {
04017 black = 720;
04018 pre_mul[0] = 1.006;
04019 pre_mul[2] = 1.858;
04020 } else if (!strcmp(model,"DCS560C")) {
04021 black = 750;
04022 pre_mul[1] = 1.053;
04023 pre_mul[2] = 1.703;
04024 } else if (!strcmp(model,"DCS620C")) {
04025 black = 720;
04026 pre_mul[1] = 1.002;
04027 pre_mul[2] = 1.818;
04028 } else if (!strcmp(model,"DCS620X")) {
04029 black = 740;
04030 pre_mul[0] = 1.486;
04031 pre_mul[2] = 1.280;
04032 is_cmy = 1;
04033 } else if (!strcmp(model,"DCS660C")) {
04034 black = 855;
04035 pre_mul[0] = 1.156;
04036 pre_mul[2] = 1.626;
04037 } else if (!strcmp(model,"DCS660M")) {
04038 black = 855;
04039 colors = 1;
04040 filters = 0;
04041 } else if (!strcmp(model,"DCS720X")) {
04042 pre_mul[0] = 1.35;
04043 pre_mul[2] = 1.18;
04044 is_cmy = 1;
04045 } else if (!strcmp(model,"DCS760C")) {
04046 pre_mul[0] = 1.06;
04047 pre_mul[2] = 1.72;
04048 } else if (!strcmp(model,"DCS760M")) {
04049 colors = 1;
04050 filters = 0;
04051 } else if (!strcmp(model,"ProBack")) {
04052 pre_mul[0] = 1.06;
04053 pre_mul[2] = 1.385;
04054 } else if (!strncmp(model2,"PB645C",6)) {
04055 pre_mul[0] = 1.0497;
04056 pre_mul[2] = 1.3306;
04057 } else if (!strncmp(model2,"PB645H",6)) {
04058 pre_mul[0] = 1.2010;
04059 pre_mul[2] = 1.5061;
04060 } else if (!strncmp(model2,"PB645M",6)) {
04061 pre_mul[0] = 1.01755;
04062 pre_mul[2] = 1.5424;
04063 } else if (!strcasecmp(model,"DCS Pro 14n")) {
04064 pre_mul[1] = 1.0323;
04065 pre_mul[2] = 1.258;
04066 } else if (!strcasecmp(model,"DCS Pro 14nx")) {
04067 pre_mul[0] = 1.336;
04068 pre_mul[2] = 1.3155;
04069 } else if (!strcasecmp(model,"DCS Pro SLR/c")) {
04070 pre_mul[0] = 1.425;
04071 pre_mul[2] = 1.293;
04072 } else if (!strcasecmp(model,"DCS Pro SLR/n")) {
04073 pre_mul[0] = 1.324;
04074 pre_mul[2] = 1.483;
04075 }
04076 switch (tiff_data_compression) {
04077 case 0:
04078 case 1:
04079 load_raw = kodak_easy_load_raw;
04080 break;
04081 case 7:
04082 load_raw = lossless_jpeg_load_raw;
04083 case 32867:
04084 break;
04085 case 65000:
04086 if (kodak_data_compression == 32803)
04087 load_raw = kodak_compressed_load_raw;
04088 else {
04089 load_raw = kodak_yuv_load_raw;
04090 height = (height+1) & -2;
04091 width = (width +1) & -2;
04092 filters = 0;
04093 }
04094 break;
04095 default:
04096 fprintf (stderr, "%s: %s %s uses unsupported compression method %d.\n",
04097 ifname, make, model, tiff_data_compression);
04098 return 1;
04099 }
04100 if (!strcmp(model,"DC20")) {
04101 height = 242;
04102 if (fsize < 100000) {
04103 width = 249;
04104 raw_width = 256;
04105 } else {
04106 width = 501;
04107 raw_width = 512;
04108 }
04109 data_offset = raw_width + 1;
04110 colors = 4;
04111 filters = 0x8d8d8d8d;
04112 kodak_dc20_coeff (0.5);
04113 pre_mul[1] = 1.179;
04114 pre_mul[2] = 1.209;
04115 pre_mul[3] = 1.036;
04116 load_raw = kodak_easy_load_raw;
04117 } else if (strstr(model,"DC25")) {
04118 strcpy (model, "DC25");
04119 height = 242;
04120 if (fsize < 100000) {
04121 width = 249;
04122 raw_width = 256;
04123 data_offset = 15681;
04124 } else {
04125 width = 501;
04126 raw_width = 512;
04127 data_offset = 15937;
04128 }
04129 colors = 4;
04130 filters = 0xb4b4b4b4;
04131 load_raw = kodak_easy_load_raw;
04132 } else if (!strcmp(model,"Digital Camera 40")) {
04133 strcpy (model, "DC40");
04134 height = 512;
04135 width = 768;
04136 data_offset = 1152;
04137 load_raw = kodak_radc_load_raw;
04138 } else if (strstr(model,"DC50")) {
04139 strcpy (model, "DC50");
04140 height = 512;
04141 width = 768;
04142 data_offset = 19712;
04143 load_raw = kodak_radc_load_raw;
04144 } else if (strstr(model,"DC120")) {
04145 strcpy (model, "DC120");
04146 height = 976;
04147 width = 848;
04148 if (tiff_data_compression == 7)
04149 load_raw = kodak_jpeg_load_raw;
04150 else
04151 load_raw = kodak_dc120_load_raw;
04152 }
04153 } else if (!strcmp(make,"Rollei")) {
04154 switch (raw_width) {
04155 case 1316:
04156 height = 1030;
04157 width = 1300;
04158 top_margin = 1;
04159 left_margin = 6;
04160 break;
04161 case 2568:
04162 height = 1960;
04163 width = 2560;
04164 top_margin = 2;
04165 left_margin = 8;
04166 }
04167 filters = 0x16161616;
04168 load_raw = rollei_load_raw;
04169 pre_mul[0] = 1.8;
04170 pre_mul[2] = 1.3;
04171 } else if (!strcmp(make,"SIGMA")) {
04172 switch (raw_height) {
04173 case 763: height = 756; top_margin = 2; break;
04174 case 1531: height = 1514; top_margin = 7; break;
04175 }
04176 switch (raw_width) {
04177 case 1152: width = 1136; left_margin = 8; break;
04178 case 2304: width = 2271; left_margin = 17; break;
04179 }
04180 if (height*2 < width) ymag = 2;
04181 filters = 0;
04182 load_raw = foveon_load_raw;
04183 is_foveon = 1;
04184 pre_mul[0] = 1.179;
04185 pre_mul[2] = 0.713;
04186 if (!strcmp(model,"SD10")) {
04187 pre_mul[0] *= 2.07;
04188 pre_mul[2] *= 2.30;
04189 }
04190 foveon_coeff();
04191 rgb_max = 5600;
04192 } else if (!strcmp(model,"PC-CAM 600")) {
04193 height = 768;
04194 data_offset = width = 1024;
04195 filters = 0x49494949;
04196 load_raw = eight_bit_load_raw;
04197 pre_mul[0] = 1.14;
04198 pre_mul[2] = 2.73;
04199 } else if (!strcmp(model,"QV-2000UX")) {
04200 height = 1208;
04201 width = 1632;
04202 data_offset = width * 2;
04203 load_raw = eight_bit_load_raw;
04204 } else if (!strcmp(model,"QV-3*00EX")) {
04205 height = 1546;
04206 width = 2070;
04207 raw_width = 2080;
04208 load_raw = eight_bit_load_raw;
04209 } else if (!strcmp(model,"QV-4000")) {
04210 height = 1700;
04211 width = 2260;
04212 load_raw = be_high_12_load_raw;
04213 } else if (!strcmp(model,"QV-5700")) {
04214 height = 1924;
04215 width = 2576;
04216 load_raw = casio_qv5700_load_raw;
04217 } else if (!strcmp(model,"EX-P600")) {
04218 height = 2142;
04219 width = 2844;
04220 raw_width = 4288;
04221 load_raw = packed_12_load_raw;
04222 pre_mul[0] = 2.356;
04223 pre_mul[1] = 1.069;
04224 } else if (!strcmp(make,"Nucore")) {
04225 filters = 0x61616161;
04226 load_raw = nucore_load_raw;
04227 }
04228 if (!load_raw || !height) {
04229 fprintf (stderr, "%s: %s %s is not yet supported.\n",
04230 ifname, make, model);
04231 return 1;
04232 }
04233 #ifdef NO_JPEG
04234 if (load_raw == kodak_jpeg_load_raw) {
04235 fprintf (stderr, "%s: decoder was not linked with libjpeg.\n", ifname);
04236 return 1;
04237 }
04238 #endif
04239 if (!raw_height) raw_height = height;
04240 if (!raw_width ) raw_width = width;
04241 if (colors == 4 && !use_coeff)
04242 gmcy_coeff();
04243 if (use_coeff)
04244 for (i=0; i < colors; i++) {
04245 coeff[0][i] *= red_scale;
04246 coeff[2][i] *= blue_scale;
04247 coeff[1][i] *= green_scale;
04248 }
04249 if (four_color_rgb && filters && colors == 3) {
04250 for (i=0; i < 32; i+=4) {
04251 if ((filters >> i & 15) == 9)
04252 filters |= 2 << i;
04253 if ((filters >> i & 15) == 6)
04254 filters |= 8 << i;
04255 }
04256 colors++;
04257 pre_mul[3] = pre_mul[1];
04258 if (use_coeff)
04259 for (i=0; i < 3; i++)
04260 coeff[i][3] = coeff[i][1] /= 2;
04261 }
04262 fseek (ifp, data_offset, SEEK_SET);
04263
04264
04265
04266 if (flip & 4)
04267 sprintf(dcraw_info, "%d %d", height, width);
04268 else
04269 sprintf(dcraw_info, "%d %d", width, height);
04270
04271
04272
04273
04274
04275 return 0;
04276 }
04277
04278
04279
04280
04281 void CLASS convert_to_rgb()
04282 {
04283 int row, col, r, g, c=0;
04284 ushort *img;
04285 float rgb[3], mag;
04286
04287 if (document_mode)
04288 colors = 1;
04289 memset (histogram, 0, sizeof histogram);
04290 for (row = trim; row < height-trim; row++)
04291 for (col = trim; col < width-trim; col++) {
04292 img = image[row*width+col];
04293 if (document_mode)
04294 c = FC(row,col);
04295 if (colors == 4 && !use_coeff)
04296 img[1] = (img[1] + img[3]) >> 1;
04297 if (colors == 1)
04298 for (r=0; r < 3; r++)
04299 rgb[r] = img[c];
04300 else if (use_coeff) {
04301 for (r=0; r < 3; r++)
04302 for (rgb[r]=g=0; g < colors; g++)
04303 rgb[r] += img[g] * coeff[r][g];
04304 } else if (is_cmy) {
04305 rgb[0] = img[0] + img[1] - img[2];
04306 rgb[1] = img[1] + img[2] - img[0];
04307 rgb[2] = img[2] + img[0] - img[1];
04308 } else
04309 goto norgb;
04310 for (r=0; r < 3; r++) {
04311 if (rgb[r] < 0)
04312 rgb[r] = 0;
04313 if (rgb[r] > rgb_max)
04314 rgb[r] = rgb_max;
04315 img[r] = rgb[r];
04316 }
04317 norgb:
04318
04319
04320 if (write_fun == write_ppm) {
04321 for (mag=r=0; r < 3; r++)
04322 mag += (unsigned) img[r]*img[r];
04323 mag = sqrt(mag)/2;
04324 if (mag > 0xffff)
04325 mag = 0xffff;
04326 img[3] = mag;
04327 histogram[img[3] >> 3]++;
04328 }
04329 }
04330 }
04331
04332 #define FMIN(a, b) ((a) < (b) ? (a) : (b))
04333
04334 static inline void calc_rgb_to_hsl(ushort *rgb, double *hue, double *sat,
04335 double *lightness)
04336 {
04337 double red, green, blue;
04338 double h, s, l;
04339 double min, max;
04340 double delta;
04341 int maxval;
04342
04343 red = rgb[0] / (double) rgb_max;
04344 green = rgb[1] / (double) rgb_max;
04345 blue = rgb[2] / (double) rgb_max;
04346
04347 if (red > green) {
04348 if (red > blue) {
04349 max = red;
04350 maxval = 0;
04351 } else {
04352 max = blue;
04353 maxval = 2;
04354 }
04355 min = FMIN(green, blue);
04356 } else {
04357 if (green > blue) {
04358 max = green;
04359 maxval = 1;
04360 } else {
04361 max = blue;
04362 maxval = 2;
04363 }
04364 min = FMIN(red, blue);
04365 }
04366
04367 l = (max + min) / 2.0;
04368 delta = max - min;
04369
04370 if (delta < .000001) {
04371 s = 0.0;
04372 h = 0.0;
04373 } else {
04374 if (l <= .5)
04375 s = delta / (max + min);
04376 else
04377 s = delta / (2 - max - min);
04378
04379 if (maxval == 0)
04380 h = (green - blue) / delta;
04381 else if (maxval == 1)
04382 h = 2 + (blue - red) / delta;
04383 else
04384 h = 4 + (red - green) / delta;
04385
04386 if (h < 0.0)
04387 h += 6.0;
04388 else if (h > 6.0)
04389 h -= 6.0;
04390 }
04391
04392 *hue = h;
04393 *sat = s;
04394 *lightness = l;
04395 }
04396
04397 static inline double hsl_value(double n1, double n2, double hue)
04398 {
04399 if (hue < 0)
04400 hue += 6.0;
04401 else if (hue > 6)
04402 hue -= 6.0;
04403 if (hue < 1.0)
04404 return (n1 + (n2 - n1) * hue);
04405 else if (hue < 3.0)
04406 return (n2);
04407 else if (hue < 4.0)
04408 return (n1 + (n2 - n1) * (4.0 - hue));
04409 else
04410 return (n1);
04411 }
04412
04413 static inline void calc_hsl_to_rgb(ushort *rgb, double h, double s, double l)
04414 {
04415 if (s < .0000001) {
04416 if (l > 1)
04417 l = 1;
04418 else if (l < 0)
04419 l = 0;
04420 rgb[0] = l * (double) rgb_max;
04421 rgb[1] = l * (double) rgb_max;
04422 rgb[2] = l * (double) rgb_max;
04423 } else {
04424 double m1, m2;
04425 double h1, h2;
04426 h1 = h + 2;
04427 h2 = h - 2;
04428
04429 if (l < .5)
04430 m2 = l * (1 + s);
04431 else
04432 m2 = l + s - (l * s);
04433 m1 = (l * 2) - m2;
04434 rgb[0] = (double) rgb_max * hsl_value(m1, m2, h1);
04435 rgb[1] = (double) rgb_max * hsl_value(m1, m2, h);
04436 rgb[2] = (double) rgb_max * hsl_value(m1, m2, h2);
04437 }
04438 }
04439
04440 static inline double update_saturation(double sat, double adjust)
04441 {
04442 if (adjust < 1)
04443 sat *= adjust;
04444 else if (adjust > 1) {
04445 double s1 = sat * adjust;
04446 double s2 = 1.0 - ((1.0 - sat) * (1.0 / adjust));
04447 sat = FMIN(s1, s2);
04448 }
04449 if (sat > 1)
04450 sat = 1.0;
04451 return sat;
04452 }
04453
04454 static inline double update_contrast(double lum, double adjust)
04455 {
04456 double retval = lum;
04457 if (lum >= .5)
04458 retval = 1.0 - lum;
04459 if (retval < .00001 && adjust < .0001)
04460 retval = .5;
04461 else
04462 retval = .5 - ((.5 - .5 * pow(2 * retval, adjust)));
04463 if (lum > .5)
04464 retval = 1 - retval;
04465 return retval;
04466 }
04467
04468 static inline void do_hsl_adjust(ushort *rgb)
04469 {
04470 double h, s, l;
04471 if (saturation != 1.0 || contrast != 1.0) {
04472 calc_rgb_to_hsl(rgb, &h, &s, &l);
04473 if (saturation != 1.0)
04474 s = update_saturation(s, saturation);
04475 if (contrast != 1.0)
04476 l = update_contrast(l, contrast);
04477 calc_hsl_to_rgb(rgb, h, s, l);
04478 }
04479 }
04480
04481 void CLASS flip_image()
04482 {
04483 unsigned *flag;
04484 int size, base, dest, next, row, col, temp;
04485 INT64 *img, hold;
04486
04487 img = (INT64 *) image;
04488 size = height * width;
04489 flag = calloc ((size+31) >> 5, sizeof *flag);
04490 merror (flag, "flip_image()");
04491 for (base = 0; base < size; base++) {
04492 if (flag[base >> 5] & (1 << (base & 31)))
04493 continue;
04494 dest = base;
04495 hold = img[base];
04496 while (1) {
04497 if (flip & 4) {
04498 row = dest % height;
04499 col = dest / height;
04500 } else {
04501 row = dest / width;
04502 col = dest % width;
04503 }
04504 if (flip & 2)
04505 row = height - 1 - row;
04506 if (flip & 1)
04507 col = width - 1 - col;
04508 next = row * width + col;
04509 if (next == base) break;
04510 flag[next >> 5] |= 1 << (next & 31);
04511 img[dest] = img[next];
04512 dest = next;
04513 }
04514 img[dest] = hold;
04515 }
04516 free (flag);
04517 if (flip & 4) {
04518 temp = height;
04519 height = width;
04520 width = temp;
04521 temp = ymag;
04522 ymag = xmag;
04523 xmag = temp;
04524 }
04525 }
04526
04527
04528
04529
04530 void CLASS write_ppm (FILE *ofp)
04531 {
04532 int row, col, i, c, val, total;
04533 float max, mul, scale[0x10000];
04534 ushort *rgb;
04535 uchar (*ppm)[3];
04536
04537 double white_fraction = 1.0 - white_point_fraction;
04538
04539 if (white_fraction > 1)
04540 white_fraction = 1;
04541 else if (white_fraction < 0)
04542 white_fraction = 0;
04543
04544 if (strcmp(make, "FUJIFILM") == 0)
04545 white_fraction /= 2;
04546
04547
04548
04549 i = width * height * white_fraction;
04550 for (val=0x2000, total=0; --val; )
04551 if ((total += histogram[val]) > i) break;
04552 max = val << 4;
04553
04554 fprintf (ofp, "P6\n%d %d\n255\n",
04555 xmag*(width-trim*2), ymag*(height-trim*2));
04556
04557 ppm = calloc (width-trim*2, 3*xmag);
04558 merror (ppm, "write_ppm()");
04559 mul = bright * 442 / max;
04560 scale[0] = 0;
04561 for (i=1; i < 0x10000; i++)
04562 scale[i] = mul * pow (i*2/max, gamma_val-1);
04563
04564 for (row=trim; row < height-trim; row++) {
04565 for (col=trim; col < width-trim; col++) {
04566 rgb = image[row*width+col];
04567 do_hsl_adjust(rgb);
04568 for (c=0; c < 3; c++) {
04569 val = rgb[c] * scale[rgb[3]];
04570 if (val > 255) val=255;
04571 for (i=0; i < xmag; i++)
04572 ppm[xmag*(col-trim)+i][c] = val;
04573 }
04574 }
04575 for (i=0; i < ymag; i++)
04576 fwrite (ppm, width-trim*2, 3*xmag, ofp);
04577 }
04578 free(ppm);
04579 }
04580
04581
04582
04583
04584 void CLASS write_psd16 (FILE *ofp)
04585 {
04586 char head[] = {
04587 '8','B','P','S',
04588 0,1,0,0,0,0,0,0,
04589 0,3,
04590 0,0,0,0,
04591 0,0,0,0,
04592 0,16,
04593 0,3,
04594 0,0,0,0,
04595 0,0,0,0,
04596 0,0,0,0,
04597 0,0
04598 };
04599 int hw[2], psize, row, col, c, val;
04600 ushort *buffer, *pred, *rgb;
04601
04602 hw[0] = htonl(height-trim*2);
04603 hw[1] = htonl(width-trim*2);
04604 memcpy (head+14, hw, sizeof hw);
04605 fwrite (head, 40, 1, ofp);
04606
04607 psize = (height-trim*2) * (width-trim*2);
04608 buffer = calloc (6, psize);
04609 merror (buffer, "write_psd()");
04610 pred = buffer;
04611
04612 for (row = trim; row < height-trim; row++) {
04613 for (col = trim; col < width-trim; col++) {
04614 rgb = image[row*width+col];
04615 do_hsl_adjust(rgb);
04616 for (c=0; c < 3; c++) {
04617 val = rgb[c] * bright;
04618 if (val > 0xffff)
04619 val = 0xffff;
04620 pred[c*psize] = htons(val);
04621 }
04622 pred++;
04623 }
04624 }
04625 fwrite(buffer, psize, 6, ofp);
04626 free(buffer);
04627 }
04628
04629
04630
04631 void CLASS write_ppm16 (FILE *ofp)
04632 {
04633 int row, col, c, val;
04634 ushort *rgb, (*ppm)[3];
04635
04636 val = rgb_max * bright;
04637 if (val < 256)
04638 val = 256;
04639 if (val > 0xffff)
04640 val = 0xffff;
04641 fprintf (ofp, "P6\n%d %d\n%d\n",
04642 width-trim*2, height-trim*2, val);
04643
04644 ppm = calloc (width-trim*2, 6);
04645 merror (ppm, "write_ppm16()");
04646
04647 for (row = trim; row < height-trim; row++) {
04648
04649 for (col = trim; col < width-trim; col++) {
04650
04651
04652 rgb = image[row*width+col];
04653 do_hsl_adjust(rgb);
04654 for (c=0; c < 3; c++) {
04655 val = rgb[c] * bright;
04656 if (val > 0xffff)
04657 val = 0xffff;
04658 ppm[col-trim][c] = htons(val);
04659
04660
04661
04662 }
04663 }
04664 fwrite (ppm, width-trim*2, 6, ofp);
04665 }
04666 free(ppm);
04667 }
04668
04669
04670
04671
04672
04673
04674
04675
04676 void CLASS write_cinelerra (FILE *ofp)
04677 {
04678 int row, col, c, val;
04679 float *output;
04680
04681 for (row = 0; row < height; row++)
04682 {
04683 output = dcraw_data[row];
04684 for (col = 0; col < width; col++)
04685 {
04686 ushort *pixel = image[row * width + col];
04687 for(c = 0; c < 3; c++)
04688 *output++ = (float)pixel[c] / 0xffff;
04689 if(dcraw_alpha) *output++ = 1.0;
04690 }
04691 }
04692
04693
04694
04695
04696
04697
04698 #if 0
04699 int row, col, i, c, total, j;
04700 float val;
04701 float max, mul, scale[0x10000];
04702 ushort *rgb;
04703
04704 double white_fraction = 1.0 - white_point_fraction;
04705
04706 if (white_fraction > 1)
04707 white_fraction = 1;
04708 else if (white_fraction < 0)
04709 white_fraction = 0;
04710
04711 if (strcmp(make, "FUJIFILM") == 0)
04712 white_fraction /= 2;
04713
04714
04715
04716
04717 i = width * height * white_fraction;
04718 for (j=0x2000, total=0; --j; )
04719 {
04720 if ((total += histogram[j]) > i) break;
04721 }
04722 max = j << 4;
04723
04724 mul = bright * 442 / max;
04725 scale[0] = 0;
04726 for (i=1; i < 0x10000; i++)
04727 {
04728 scale[i] = mul * pow (i*2/max, gamma_val-1);
04729 }
04730
04731 for (row=trim; row < height-trim; row++)
04732 {
04733 float *output = dcraw_data[row];
04734 for (col=trim; col < width-trim; col++)
04735 {
04736 rgb = image[row*width+col];
04737 do_hsl_adjust(rgb);
04738 for (c=0; c < 3; c++)
04739 {
04740 val = rgb[c] * scale[rgb[3]];
04741 *output++ = val / 255;
04742 }
04743 if(dcraw_alpha) *output++ = 1.0;
04744 }
04745 }
04746
04747 #endif
04748
04749
04750 }
04751
04752
04753
04754
04755
04756
04757
04758
04759 void CLASS write_ppm_16_8(FILE *ofp)
04760 {
04761 int row, col, c, i;
04762 float divisor;
04763 ushort *rgb;
04764 uchar (*ppm)[3];
04765 unsigned val;
04766 unsigned max = 0;
04767
04768 val = (double) rgb_max * bright;
04769 if (val < 256)
04770 val = 256;
04771 if (val > 0xffff)
04772 val = 0xffff;
04773 divisor = 256 * ((double) val / 65536.0);
04774 fprintf (ofp, "P6\n%d %d\n255\n",
04775 width-trim*2, ymag*(height-trim*2));
04776
04777 ppm = calloc (width-trim*2, 3);
04778 merror (ppm, "write_ppm16_8()");
04779
04780 for (row = trim; row < height-trim; row++) {
04781 for (col = trim; col < width-trim; col++) {
04782 rgb = image[row*width+col];
04783 do_hsl_adjust(rgb);
04784 for (c=0; c < 3; c++) {
04785 if (rgb[c] > max)
04786 max = rgb[c];
04787 val = rgb[c] * bright / divisor;
04788 if (val > 0xff)
04789 val = 0xff;
04790 ppm[col-trim][c] = val;
04791 }
04792 }
04793 for (i=0; i < ymag; i++)
04794 fwrite (ppm, width-trim*2, 3, ofp);
04795 }
04796 free(ppm);
04797 }
04798
04799
04800 int CLASS dcraw_main (int argc, char **argv)
04801 {
04802 int arg, status=0, user_flip=-1;
04803 int identify_only=0, write_to_stdout=0, half_size=0;
04804 char opt, *ofname, *cp;
04805 const char *write_ext = ".ppm";
04806 FILE *ofp = stdout;
04807
04808
04809 if (argc == 1)
04810 {
04811 fprintf (stderr,
04812 "\nRaw Photo Decoder \"dcraw\" v6.10"
04813 "\nby Dave Coffin, dcoffin a cybercom o net"
04814 "\n\nUsage: %s [options] file1 file2 ...\n"
04815 "\nValid options:"
04816 "\n-i Identify files but don't decode them"
04817 "\n-c Write to standard output"
04818 "\n-v Print verbose messages while decoding"
04819 "\n-f Interpolate RGBG as four colors"
04820 "\n-d Document Mode (no color, no interpolation)"
04821 "\n-q Quick, low-quality color interpolation"
04822 "\n-h Half-size color image (3x faster than -q)"
04823 "\n-s Use secondary pixels (Fuji Super CCD SR only)"
04824 "\n-g <num> Set gamma (0.6 by default, only for 24-bpp output)"
04825 "\n-b <num> Set brightness (1.0 by default)"
04826 "\n-a Use automatic white balance"
04827 "\n-w Use camera white balance, if possible"
04828 "\n-B <num> Use specified black level"
04829 "\n-L Use floating black level"
04830 "\n-n Use neutral (no correction) white balance"
04831 "\n-u Use auto exposure compensation"
04832 "\n-W Use center-weighted metering for exposure compensation"
04833 "\n-T Use alternate scaling to improve contrast in highlights"
04834 "\n-r <num> Set red multiplier (daylight = 1.0)"
04835 "\n-l <num> Set blue multiplier (daylight = 1.0)"
04836 "\n-t [0-7] Flip image (0 = none, 3 = 180, 5 = 90CCW, 6 = 90CW)"
04837 "\n-e <num> Set green multiplier (daylight = 1.0)"
04838 "\n-m <num> Set white point fraction (default 0.99)"
04839 "\n-p <num> Set white point correction start (default none)"
04840 "\n-P <num> Set relative white point correction start (default 0.75)"
04841 "\n-x <num> Set exposure compensation in stops (default 0.00)"
04842 "\n-S <num> Adjust saturation"
04843 "\n-C <num> Adjust contrast"
04844 "\n-k <num> Set interpolation threshold paramater k1\n\t for T = k1*Min + k2 * (Max - Min) (default = 1.5)"
04845 "\n-K <num> Set interpolation threshold paramater k2\n\t for T = k1*Min + k2 * (Max - Min) (default = 0.5)"
04846 "\n-j <num> Set parameter for color matrix"
04847 "\n-1 Write 24-bpp PPM using 16 bit calculation"
04848 "\n-2 Write 24-bpp PPM (default)"
04849 "\n-3 Write 48-bpp PSD (Adobe Photoshop)"
04850 "\n-4 Write 48-bpp PPM"
04851 "\n\n", argv[0]);
04852 return 1;
04853 }
04854
04855 argv[argc] = "";
04856 for (arg=1; argv[arg][0] == '-'; ) {
04857 opt = argv[arg++][1];
04858 if (strchr ("gbrlempPxSCB", opt) &&
04859 (!isdigit(argv[arg][0]) && argv[arg][0] != '.' &&
04860 (argv[arg][0] != '-' || (!isdigit(argv[arg][1]) &&
04861 argv[arg][1] != '.')))) {
04862 fprintf (stderr, "\"-%c\" requires a numeric argument.\n", opt);
04863 return 1;
04864 }
04865 switch (opt)
04866 {
04867 case 'g': gamma_val = atof(argv[arg++]); break;
04868 case 'b': bright = atof(argv[arg++]); break;
04869 case 'r': red_scale = atof(argv[arg++]); break;
04870 case 'l': blue_scale = atof(argv[arg++]); break;
04871 case 't': user_flip = atoi(argv[arg++]); break;
04872 case 'k': k1 = atof(argv[arg++]); break;
04873 case 'K': k2 = atof(argv[arg++]); break;
04874 case 'j': juice = atof(argv[arg++]); break;
04875
04876 case 'e': green_scale = atof(argv[arg++]); break;
04877 case 'm': white_point_fraction = atof(argv[arg++]); break;
04878 case 'P': pivot_value = atof(argv[arg++]); white_point_fraction = 1; break;
04879 case 'p': pivot_value = atof(argv[arg++]); white_point_fraction = 1; use_pivot = 1; break;
04880 case 'x': exposure_compensation = atof(argv[arg++]); break;
04881 case 'S': saturation = atof(argv[arg++]); break;
04882 case 'C': contrast = atof(argv[arg++]); break;
04883 case 'n': use_neutral_wb = 1; break;
04884 case 'u': autoexposure = 1; break;
04885 case 'B': user_black = atoi(argv[arg++]); use_camera_black = 1; break;
04886 case 'L': use_camera_black = 0; break;
04887 case 'T': alternate_scale = 1; white_point_fraction = 1; break;
04888
04889 case 'W': center_weight = 1; break;
04890
04891 case 'i': identify_only = 1; break;
04892 case 'c': write_to_stdout = 1; break;
04893 case 'v': verbose = 1; break;
04894 case 'h': half_size = 1;
04895 case 'f': four_color_rgb = 1; break;
04896 case 'd': document_mode = 1; break;
04897 case 'q': quick_interpolate = 1; break;
04898 case 'a': use_auto_wb = 1; break;
04899 case 'w': use_camera_wb = 1; break;
04900 case 's': use_secondary = 1; break;
04901
04902 case '1': write_fun = write_ppm_16_8; write_ext = ".ppm"; break;
04903 case '2': write_fun = write_ppm; write_ext = ".ppm"; break;
04904 case '3': write_fun = write_psd16; write_ext = ".psd"; break;
04905 case '4': write_fun = write_ppm16; write_ext = ".ppm"; break;
04906
04907 default:
04908 fprintf (stderr, "Unknown option \"-%c\".\n", opt);
04909 return 1;
04910 }
04911 }
04912
04913
04914
04915 write_fun = write_cinelerra;
04916
04917 if (arg == argc) {
04918 fprintf (stderr, "No files to process.\n");
04919 return 1;
04920 }
04921 if (write_to_stdout) {
04922
04923
04924
04925
04926 if (0 ) {
04927 fprintf (stderr, "Will not write an image to the terminal!\n");
04928 return 1;
04929 }
04930
04931
04932
04933
04934 #if defined(WIN32) || defined(DJGPP)
04935 if (setmode(1,O_BINARY) < 0) {
04936 perror("setmode()");
04937 return 1;
04938 }
04939 #endif
04940 }
04941
04942 for ( ; arg < argc; arg++)
04943 {
04944 status = 1;
04945 image = NULL;
04946 if (setjmp (failure)) {
04947 if (fileno(ifp) > 2) fclose(ifp);
04948 if (fileno(ofp) > 2) fclose(ofp);
04949 if (image) free(image);
04950 status = 1;
04951 continue;
04952 }
04953 ifname = argv[arg];
04954 if (!(ifp = fopen (ifname, "rb"))) {
04955 perror (ifname);
04956 continue;
04957 }
04958 if ((status = identify())) {
04959 fclose(ifp);
04960 continue;
04961 }
04962
04963
04964
04965 if (identify_only) {
04966
04967
04968 fclose(ifp);
04969 continue;
04970 }
04971 shrink = half_size && filters;
04972 iheight = (height + shrink) >> shrink;
04973 iwidth = (width + shrink) >> shrink;
04974 image = calloc (iheight * iwidth, sizeof *image);
04975 merror (image, "main()");
04976 if (verbose)
04977 fprintf (stderr,
04978 "Loading %s %s image from %s...\n", make, model, ifname);
04979 (*load_raw)();
04980 fclose(ifp);
04981 bad_pixels();
04982 height = iheight;
04983 width = iwidth;
04984 if (is_foveon) {
04985 if (verbose)
04986 fprintf (stderr, "Foveon interpolation...\n");
04987 foveon_interpolate();
04988 } else {
04989 scale_colors();
04990 }
04991
04992
04993 if (shrink) filters = 0;
04994 trim = 0;
04995 if (filters && !document_mode) {
04996 trim = 1;
04997 if (verbose)
04998 fprintf (stderr, "%s interpolation...\n",
04999 quick_interpolate ? "Bilinear":"VNG");
05000
05001
05002 vng_interpolate();
05003 }
05004 if (verbose)
05005 fprintf (stderr, "Converting to RGB colorspace...\n");
05006
05007
05008 convert_to_rgb();
05009
05010
05011 if (user_flip >= 0)
05012 flip = user_flip;
05013 if (flip) {
05014 if (verbose)
05015 fprintf (stderr, "Flipping image %c:%c:%c...\n",
05016 flip & 1 ? 'H':'0', flip & 2 ? 'V':'0', flip & 4 ? 'T':'0');
05017 flip_image();
05018 }
05019
05020
05021 ofname = malloc (strlen(ifname) + 16);
05022 merror (ofname, "main()");
05023 if (write_to_stdout)
05024 strcpy (ofname, "standard output");
05025 else {
05026 strcpy (ofname, ifname);
05027 if ((cp = strrchr (ofname, '.'))) *cp = 0;
05028 strcat (ofname, write_ext);
05029 ofp = fopen (ofname, "wb");
05030 if (!ofp) {
05031 status = 1;
05032 perror(ofname);
05033 goto cleanup;
05034 }
05035 }
05036
05037
05038 if (verbose)
05039 fprintf (stderr, "Writing data to %s...\n", ofname);
05040 (*write_fun)(ofp);
05041 if (ofp != stdout)
05042 fclose(ofp);
05043 cleanup:
05044 free(ofname);
05045 free(image);
05046 }
05047 return status;
05048 }