| /* |
| dcraw.c -- Dave Coffin's raw photo decoder |
| Copyright 1997-2009 by Dave Coffin, dcoffin a cybercom o net |
| |
| This is a command-line ANSI C program to convert raw photos from |
| any digital camera on any computer running any operating system. |
| |
| No license is required to download and use dcraw.c. However, |
| to lawfully redistribute dcraw, you must either (a) offer, at |
| no extra charge, full source code* for all executable files |
| containing RESTRICTED functions, (b) distribute this code under |
| the GPL Version 2 or later, (c) remove all RESTRICTED functions, |
| re-implement them, or copy them from an earlier, unrestricted |
| Revision of dcraw.c, or (d) purchase a license from the author. |
| |
| The functions that process Foveon images have been RESTRICTED |
| since Revision 1.237. All other code remains free for all uses. |
| |
| *If you have not modified dcraw.c in any way, a link to my |
| homepage qualifies as "full source code". |
| |
| $Revision: 1.1 $ |
| $Date: 2009/07/12 15:41:52 $ |
| */ |
| |
| #define VERSION "8.93" |
| |
| #define _GNU_SOURCE |
| #define _USE_MATH_DEFINES |
| #include <ctype.h> |
| #include <errno.h> |
| #include <fcntl.h> |
| #include <float.h> |
| #include <limits.h> |
| #include <math.h> |
| #include <setjmp.h> |
| #include <stdio.h> |
| #include <stdlib.h> |
| #include <string.h> |
| #include <time.h> |
| #include <sys/types.h> |
| /* |
| NO_JPEG disables decoding of compressed Kodak DC120 files. |
| NO_LCMS disables the "-p" option. |
| */ |
| #ifndef NO_JPEG |
| #include "../LibJPEG/jpeglib.h" |
| #endif |
| #ifndef NO_LCMS |
| #include <lcms.h> |
| #endif |
| #ifdef LOCALEDIR |
| #include <libintl.h> |
| #define _(String) gettext(String) |
| #else |
| #define _(String) (String) |
| #endif |
| #ifdef DJGPP |
| #define fseeko fseek |
| #define ftello ftell |
| #else |
| #define fgetc getc_unlocked |
| #endif |
| #ifdef __CYGWIN__ |
| #include <io.h> |
| #endif |
| #ifdef WIN32 |
| #include <sys/utime.h> |
| #include <winsock2.h> |
| #pragma comment(lib, "ws2_32.lib") |
| #define snprintf _snprintf |
| #define strcasecmp stricmp |
| #define strncasecmp strnicmp |
| typedef __int64 INT64; |
| typedef unsigned __int64 UINT64; |
| #else |
| #include <unistd.h> |
| #include <utime.h> |
| #include <netinet/in.h> |
| typedef long long INT64; |
| typedef unsigned long long UINT64; |
| #endif |
| |
| #ifdef LJPEG_DECODE |
| #error Please compile dcraw.c by itself. |
| #error Do not link it with ljpeg_decode. |
| #endif |
| |
| #ifndef LONG_BIT |
| #define LONG_BIT (8 * sizeof (long)) |
| #endif |
| |
| #define ushort UshORt |
| typedef unsigned char uchar; |
| typedef unsigned short ushort; |
| |
| /* |
| All global variables are defined here, and all functions that |
| access them are prefixed with "CLASS". Note that a thread-safe |
| C++ class cannot have non-const static local variables. |
| */ |
| FILE *ifp; |
| short order; |
| char *ifname, *meta_data; |
| char cdesc[5], desc[512], make[64], model[64], model2[64], artist[64]; |
| float flash_used, canon_ev, iso_speed, shutter, aperture, focal_len; |
| time_t timestamp; |
| unsigned shot_order, kodak_cbpp, filters, exif_cfa, unique_id; |
| off_t strip_offset, data_offset; |
| off_t thumb_offset, meta_offset, profile_offset; |
| unsigned thumb_length, meta_length, profile_length; |
| unsigned thumb_misc, *oprof, fuji_layout, shot_select=0, multi_out=0; |
| unsigned tiff_nifds, tiff_samples, tiff_bps, tiff_compress; |
| unsigned black, maximum, mix_green, raw_color, use_gamma, zero_is_bad; |
| unsigned zero_after_ff, is_raw, dng_version, is_foveon, data_error; |
| unsigned tile_width, tile_length, gpsdata[32], load_flags; |
| ushort raw_height, raw_width, height, width, top_margin, left_margin; |
| ushort shrink, iheight, iwidth, fuji_width, thumb_width, thumb_height; |
| int flip, tiff_flip, colors; |
| double pixel_aspect, aber[4]={1,1,1,1}, gamm[5]={ 0.45,4.5,0,0,0 }; |
| ushort (*image)[4], white[8][8], curve[0x4001], cr2_slice[3], sraw_mul[4]; |
| float bright=1, user_mul[4]={0,0,0,0}, threshold=0; |
| int half_size=0, four_color_rgb=0, document_mode=0, highlight=0; |
| int verbose=0, use_auto_wb=0, use_camera_wb=0, use_camera_matrix=-1; |
| int output_color=1, output_bps=8, output_tiff=0, med_passes=0; |
| int no_auto_bright=0; |
| unsigned greybox[4] = { 0, 0, UINT_MAX, UINT_MAX }; |
| float cam_mul[4], pre_mul[4], cmatrix[3][4], rgb_cam[3][4]; |
| const double xyz_rgb[3][3] = { /* XYZ from RGB */ |
| { 0.412453, 0.357580, 0.180423 }, |
| { 0.212671, 0.715160, 0.072169 }, |
| { 0.019334, 0.119193, 0.950227 } }; |
| const float d65_white[3] = { 0.950456, 1, 1.088754 }; |
| int histogram[4][0x2000]; |
| void (*write_thumb)(FILE *), (*write_fun)(FILE *); |
| void (*load_raw)(), (*thumb_load_raw)(); |
| jmp_buf failure; |
| |
| struct decode { |
| struct decode *branch[2]; |
| int leaf; |
| } first_decode[2048], *second_decode, *free_decode; |
| |
| struct { |
| int width, height, bps, comp, phint, offset, flip, samples, bytes; |
| } tiff_ifd[10]; |
| |
| struct { |
| int format, key_off, black, black_off, split_col, tag_21a; |
| float tag_210; |
| } ph1; |
| |
| #define CLASS |
| |
| #define FORC(cnt) for (c=0; c < cnt; c++) |
| #define FORC3 FORC(3) |
| #define FORC4 FORC(4) |
| #define FORCC FORC(colors) |
| |
| #define SQR(x) ((x)*(x)) |
| #define ABS(x) (((int)(x) ^ ((int)(x) >> 31)) - ((int)(x) >> 31)) |
| #define MIN(a,b) ((a) < (b) ? (a) : (b)) |
| #define MAX(a,b) ((a) > (b) ? (a) : (b)) |
| #define LIM(x,min,max) MAX(min,MIN(x,max)) |
| #define ULIM(x,y,z) ((y) < (z) ? LIM(x,y,z) : LIM(x,z,y)) |
| #define CLIP(x) LIM(x,0,65535) |
| #define SWAP(a,b) { a ^= b; a ^= (b ^= a); } |
| |
| /* |
| In order to inline this calculation, I make the risky |
| assumption that all filter patterns can be described |
| by a repeating pattern of eight rows and two columns |
| |
| Do not use the FC or BAYER macros with the Leaf CatchLight, |
| because its pattern is 16x16, not 2x8. |
| |
| Return values are either 0/1/2/3 = G/M/C/Y or 0/1/2/3 = R/G1/B/G2 |
| |
| PowerShot 600 PowerShot A50 PowerShot Pro70 Pro90 & G1 |
| 0xe1e4e1e4: 0x1b4e4b1e: 0x1e4b4e1b: 0xb4b4b4b4: |
| |
| 0 1 2 3 4 5 0 1 2 3 4 5 0 1 2 3 4 5 0 1 2 3 4 5 |
| 0 G M G M G M 0 C Y C Y C Y 0 Y C Y C Y C 0 G M G M G M |
| 1 C Y C Y C Y 1 M G M G M G 1 M G M G M G 1 Y C Y C Y C |
| 2 M G M G M G 2 Y C Y C Y C 2 C Y C Y C Y |
| 3 C Y C Y C Y 3 G M G M G M 3 G M G M G M |
| 4 C Y C Y C Y 4 Y C Y C Y C |
| PowerShot A5 5 G M G M G M 5 G M G M G M |
| 0x1e4e1e4e: 6 Y C Y C Y C 6 C Y C Y C Y |
| 7 M G M G M G 7 M G M G M G |
| 0 1 2 3 4 5 |
| 0 C Y C Y C Y |
| 1 G M G M G M |
| 2 C Y C Y C Y |
| 3 M G M G M G |
| |
| All RGB cameras use one of these Bayer grids: |
| |
| 0x16161616: 0x61616161: 0x49494949: 0x94949494: |
| |
| 0 1 2 3 4 5 0 1 2 3 4 5 0 1 2 3 4 5 0 1 2 3 4 5 |
| 0 B G B G B G 0 G R G R G R 0 G B G B G B 0 R G R G R G |
| 1 G R G R G R 1 B G B G B G 1 R G R G R G 1 G B G B G B |
| 2 B G B G B G 2 G R G R G R 2 G B G B G B 2 R G R G R G |
| 3 G R G R G R 3 B G B G B G 3 R G R G R G 3 G B G B G B |
| */ |
| |
| #define FC(row,col) \ |
| (filters >> ((((row) << 1 & 14) + ((col) & 1)) << 1) & 3) |
| |
| #define BAYER(row,col) \ |
| image[((row) >> shrink)*iwidth + ((col) >> shrink)][FC(row,col)] |
| |
| #define BAYER2(row,col) \ |
| image[((row) >> shrink)*iwidth + ((col) >> shrink)][fc(row,col)] |
| |
| int CLASS fc (int row, int col) |
| { |
| static const char filter[16][16] = |
| { { 2,1,1,3,2,3,2,0,3,2,3,0,1,2,1,0 }, |
| { 0,3,0,2,0,1,3,1,0,1,1,2,0,3,3,2 }, |
| { 2,3,3,2,3,1,1,3,3,1,2,1,2,0,0,3 }, |
| { 0,1,0,1,0,2,0,2,2,0,3,0,1,3,2,1 }, |
| { 3,1,1,2,0,1,0,2,1,3,1,3,0,1,3,0 }, |
| { 2,0,0,3,3,2,3,1,2,0,2,0,3,2,2,1 }, |
| { 2,3,3,1,2,1,2,1,2,1,1,2,3,0,0,1 }, |
| { 1,0,0,2,3,0,0,3,0,3,0,3,2,1,2,3 }, |
| { 2,3,3,1,1,2,1,0,3,2,3,0,2,3,1,3 }, |
| { 1,0,2,0,3,0,3,2,0,1,1,2,0,1,0,2 }, |
| { 0,1,1,3,3,2,2,1,1,3,3,0,2,1,3,2 }, |
| { 2,3,2,0,0,1,3,0,2,0,1,2,3,0,1,0 }, |
| { 1,3,1,2,3,2,3,2,0,2,0,1,1,0,3,0 }, |
| { 0,2,0,3,1,0,0,1,1,3,3,2,3,2,2,1 }, |
| { 2,1,3,2,3,1,2,1,0,3,0,2,0,2,0,2 }, |
| { 0,3,1,0,0,2,0,3,2,1,3,1,1,3,1,3 } }; |
| |
| if (filters != 1) return FC(row,col); |
| return filter[(row+top_margin) & 15][(col+left_margin) & 15]; |
| } |
| |
| #ifndef __GLIBC__ |
| char *my_memmem (char *haystack, size_t haystacklen, |
| char *needle, size_t needlelen) |
| { |
| char *c; |
| for (c = haystack; c <= haystack + haystacklen - needlelen; c++) |
| if (!memcmp (c, needle, needlelen)) |
| return c; |
| return 0; |
| } |
| #define memmem my_memmem |
| #endif |
| |
| void CLASS merror (void *ptr, char *where) |
| { |
| if (ptr) return; |
| fprintf (stderr,_("%s: Out of memory in %s\n"), ifname, where); |
| longjmp (failure, 1); |
| } |
| |
| void CLASS derror() |
| { |
| if (!data_error) { |
| fprintf (stderr, "%s: ", ifname); |
| if (feof(ifp)) |
| fprintf (stderr,_("Unexpected end of file\n")); |
| else |
| fprintf (stderr,_("Corrupt data near 0x%llx\n"), (INT64) ftello(ifp)); |
| } |
| data_error = 1; |
| } |
| |
| ushort CLASS sget2 (uchar *s) |
| { |
| if (order == 0x4949) /* "II" means little-endian */ |
| return s[0] | s[1] << 8; |
| else /* "MM" means big-endian */ |
| return s[0] << 8 | s[1]; |
| } |
| |
| ushort CLASS get2() |
| { |
| uchar str[2] = { 0xff,0xff }; |
| fread (str, 1, 2, ifp); |
| return sget2(str); |
| } |
| |
| unsigned CLASS sget4 (uchar *s) |
| { |
| if (order == 0x4949) |
| return s[0] | s[1] << 8 | s[2] << 16 | s[3] << 24; |
| else |
| return s[0] << 24 | s[1] << 16 | s[2] << 8 | s[3]; |
| } |
| #define sget4(s) sget4((uchar *)s) |
| |
| unsigned CLASS get4() |
| { |
| uchar str[4] = { 0xff,0xff,0xff,0xff }; |
| fread (str, 1, 4, ifp); |
| return sget4(str); |
| } |
| |
| unsigned CLASS getint (int type) |
| { |
| return type == 3 ? get2() : get4(); |
| } |
| |
| float CLASS int_to_float (int i) |
| { |
| union { int i; float f; } u; |
| u.i = i; |
| return u.f; |
| } |
| |
| double CLASS getreal (int type) |
| { |
| union { char c[8]; double d; } u; |
| int i, rev; |
| |
| switch (type) { |
| case 3: return (unsigned short) get2(); |
| case 4: return (unsigned int) get4(); |
| case 5: u.d = (unsigned int) get4(); |
| return u.d / (unsigned int) get4(); |
| case 8: return (signed short) get2(); |
| case 9: return (signed int) get4(); |
| case 10: u.d = (signed int) get4(); |
| return u.d / (signed int) get4(); |
| case 11: return int_to_float (get4()); |
| case 12: |
| rev = 7 * ((order == 0x4949) == (ntohs(0x1234) == 0x1234)); |
| for (i=0; i < 8; i++) |
| u.c[i ^ rev] = fgetc(ifp); |
| return u.d; |
| default: return fgetc(ifp); |
| } |
| } |
| |
| void CLASS read_shorts (ushort *pixel, int count) |
| { |
| if (fread (pixel, 2, count, ifp) < count) derror(); |
| if ((order == 0x4949) == (ntohs(0x1234) == 0x1234)) |
| swab (pixel, pixel, count*2); |
| } |
| |
| void CLASS canon_black (double dark[2]) |
| { |
| int c, diff, row, col; |
| |
| if (raw_width < width+4) return; |
| FORC(2) dark[c] /= (raw_width-width-2) * height >> 1; |
| if ((diff = dark[0] - dark[1])) |
| for (row=0; row < height; row++) |
| for (col=1; col < width; col+=2) |
| BAYER(row,col) += diff; |
| dark[1] += diff; |
| black = (dark[0] + dark[1] + 1) / 2; |
| } |
| |
| void CLASS canon_600_fixed_wb (int temp) |
| { |
| static const short mul[4][5] = { |
| { 667, 358,397,565,452 }, |
| { 731, 390,367,499,517 }, |
| { 1119, 396,348,448,537 }, |
| { 1399, 485,431,508,688 } }; |
| int lo, hi, i; |
| float frac=0; |
| |
| for (lo=4; --lo; ) |
| if (*mul[lo] <= temp) break; |
| for (hi=0; hi < 3; hi++) |
| if (*mul[hi] >= temp) break; |
| if (lo != hi) |
| frac = (float) (temp - *mul[lo]) / (*mul[hi] - *mul[lo]); |
| for (i=1; i < 5; i++) |
| pre_mul[i-1] = 1 / (frac * mul[hi][i] + (1-frac) * mul[lo][i]); |
| } |
| |
| /* Return values: 0 = white 1 = near white 2 = not white */ |
| int CLASS canon_600_color (int ratio[2], int mar) |
| { |
| int clipped=0, target, miss; |
| |
| if (flash_used) { |
| if (ratio[1] < -104) |
| { ratio[1] = -104; clipped = 1; } |
| if (ratio[1] > 12) |
| { ratio[1] = 12; clipped = 1; } |
| } else { |
| if (ratio[1] < -264 || ratio[1] > 461) return 2; |
| if (ratio[1] < -50) |
| { ratio[1] = -50; clipped = 1; } |
| if (ratio[1] > 307) |
| { ratio[1] = 307; clipped = 1; } |
| } |
| target = flash_used || ratio[1] < 197 |
| ? -38 - (398 * ratio[1] >> 10) |
| : -123 + (48 * ratio[1] >> 10); |
| if (target - mar <= ratio[0] && |
| target + 20 >= ratio[0] && !clipped) return 0; |
| miss = target - ratio[0]; |
| if (abs(miss) >= mar*4) return 2; |
| if (miss < -20) miss = -20; |
| if (miss > mar) miss = mar; |
| ratio[0] = target - miss; |
| return 1; |
| } |
| |
| void CLASS canon_600_auto_wb() |
| { |
| int mar, row, col, i, j, st, count[] = { 0,0 }; |
| int test[8], total[2][8], ratio[2][2], stat[2]; |
| |
| memset (&total, 0, sizeof total); |
| i = canon_ev + 0.5; |
| if (i < 10) mar = 150; |
| else if (i > 12) mar = 20; |
| else mar = 280 - 20 * i; |
| if (flash_used) mar = 80; |
| for (row=14; row < height-14; row+=4) |
| for (col=10; col < width; col+=2) { |
| for (i=0; i < 8; i++) |
| test[(i & 4) + FC(row+(i >> 1),col+(i & 1))] = |
| BAYER(row+(i >> 1),col+(i & 1)); |
| for (i=0; i < 8; i++) |
| if (test[i] < 150 || test[i] > 1500) goto next; |
| for (i=0; i < 4; i++) |
| if (abs(test[i] - test[i+4]) > 50) goto next; |
| for (i=0; i < 2; i++) { |
| for (j=0; j < 4; j+=2) |
| ratio[i][j >> 1] = ((test[i*4+j+1]-test[i*4+j]) << 10) / test[i*4+j]; |
| stat[i] = canon_600_color (ratio[i], mar); |
| } |
| if ((st = stat[0] | stat[1]) > 1) goto next; |
| for (i=0; i < 2; i++) |
| if (stat[i]) |
| for (j=0; j < 2; j++) |
| test[i*4+j*2+1] = test[i*4+j*2] * (0x400 + ratio[i][j]) >> 10; |
| for (i=0; i < 8; i++) |
| total[st][i] += test[i]; |
| count[st]++; |
| next: ; |
| } |
| if (count[0] | count[1]) { |
| st = count[0]*200 < count[1]; |
| for (i=0; i < 4; i++) |
| pre_mul[i] = 1.0 / (total[st][i] + total[st][i+4]); |
| } |
| } |
| |
| void CLASS canon_600_coeff() |
| { |
| static const short table[6][12] = { |
| { -190,702,-1878,2390, 1861,-1349,905,-393, -432,944,2617,-2105 }, |
| { -1203,1715,-1136,1648, 1388,-876,267,245, -1641,2153,3921,-3409 }, |
| { -615,1127,-1563,2075, 1437,-925,509,3, -756,1268,2519,-2007 }, |
| { -190,702,-1886,2398, 2153,-1641,763,-251, -452,964,3040,-2528 }, |
| { -190,702,-1878,2390, 1861,-1349,905,-393, -432,944,2617,-2105 }, |
| { -807,1319,-1785,2297, 1388,-876,769,-257, -230,742,2067,-1555 } }; |
| int t=0, i, c; |
| float mc, yc; |
| |
| mc = pre_mul[1] / pre_mul[2]; |
| yc = pre_mul[3] / pre_mul[2]; |
| if (mc > 1 && mc <= 1.28 && yc < 0.8789) t=1; |
| if (mc > 1.28 && mc <= 2) { |
| if (yc < 0.8789) t=3; |
| else if (yc <= 2) t=4; |
| } |
| if (flash_used) t=5; |
| for (raw_color = i=0; i < 3; i++) |
| FORCC rgb_cam[i][c] = table[t][i*4 + c] / 1024.0; |
| } |
| |
| void CLASS canon_600_load_raw() |
| { |
| uchar data[1120], *dp; |
| ushort pixel[896], *pix; |
| int irow, row, col, val; |
| static const short mul[4][2] = |
| { { 1141,1145 }, { 1128,1109 }, { 1178,1149 }, { 1128,1109 } }; |
| |
| for (irow=row=0; irow < height; irow++) { |
| if (fread (data, 1, raw_width*5/4, ifp) < raw_width*5/4) derror(); |
| for (dp=data, pix=pixel; dp < data+1120; dp+=10, pix+=8) { |
| pix[0] = (dp[0] << 2) + (dp[1] >> 6 ); |
| pix[1] = (dp[2] << 2) + (dp[1] >> 4 & 3); |
| pix[2] = (dp[3] << 2) + (dp[1] >> 2 & 3); |
| pix[3] = (dp[4] << 2) + (dp[1] & 3); |
| pix[4] = (dp[5] << 2) + (dp[9] & 3); |
| pix[5] = (dp[6] << 2) + (dp[9] >> 2 & 3); |
| pix[6] = (dp[7] << 2) + (dp[9] >> 4 & 3); |
| pix[7] = (dp[8] << 2) + (dp[9] >> 6 ); |
| } |
| for (col=0; col < width; col++) |
| BAYER(row,col) = pixel[col]; |
| for (col=width; col < raw_width; col++) |
| black += pixel[col]; |
| if ((row+=2) > height) row = 1; |
| } |
| if (raw_width > width) |
| black = black / ((raw_width - width) * height) - 4; |
| for (row=0; row < height; row++) |
| for (col=0; col < width; col++) { |
| if ((val = BAYER(row,col) - black) < 0) val = 0; |
| val = val * mul[row & 3][col & 1] >> 9; |
| BAYER(row,col) = val; |
| } |
| canon_600_fixed_wb(1311); |
| canon_600_auto_wb(); |
| canon_600_coeff(); |
| maximum = (0x3ff - black) * 1109 >> 9; |
| black = 0; |
| } |
| |
| void CLASS remove_zeroes() |
| { |
| unsigned row, col, tot, n, r, c; |
| |
| for (row=0; row < height; row++) |
| for (col=0; col < width; col++) |
| if (BAYER(row,col) == 0) { |
| tot = n = 0; |
| for (r = row-2; r <= row+2; r++) |
| for (c = col-2; c <= col+2; c++) |
| if (r < height && c < width && |
| FC(r,c) == FC(row,col) && BAYER(r,c)) |
| tot += (n++,BAYER(r,c)); |
| if (n) BAYER(row,col) = tot/n; |
| } |
| } |
| |
| int CLASS canon_s2is() |
| { |
| unsigned row; |
| |
| for (row=0; row < 100; row++) { |
| fseek (ifp, row*3340 + 3284, SEEK_SET); |
| if (getc(ifp) > 15) return 1; |
| } |
| return 0; |
| } |
| |
| void CLASS canon_a5_load_raw() |
| { |
| ushort data[2565], *dp, pixel; |
| int vbits=0, buf=0, row, col, bc=0; |
| |
| order = 0x4949; |
| for (row=-top_margin; row < raw_height-top_margin; row++) { |
| read_shorts (dp=data, raw_width * 10 / 16); |
| for (col=-left_margin; col < raw_width-left_margin; col++) { |
| if ((vbits -= 10) < 0) |
| buf = (vbits += 16, (buf << 16) + *dp++); |
| pixel = buf >> vbits & 0x3ff; |
| if ((unsigned) row < height && (unsigned) col < width) |
| BAYER(row,col) = pixel; |
| else if (col > 1-left_margin && col != width) |
| black += (bc++,pixel); |
| } |
| } |
| if (bc) black /= bc; |
| maximum = 0x3ff; |
| if (raw_width > 1600) remove_zeroes(); |
| } |
| |
| /* |
| getbits(-1) initializes the buffer |
| getbits(n) where 0 <= n <= 25 returns an n-bit integer |
| */ |
| unsigned CLASS getbits (int nbits) |
| { |
| static unsigned bitbuf=0; |
| static int vbits=0, reset=0; |
| unsigned c; |
| |
| if (nbits == -1) |
| return bitbuf = vbits = reset = 0; |
| if (nbits == 0 || reset) return 0; |
| while (vbits < nbits) { |
| if ((c = fgetc(ifp)) == EOF) derror(); |
| if ((reset = zero_after_ff && c == 0xff && fgetc(ifp))) return 0; |
| bitbuf = (bitbuf << 8) + (uchar) c; |
| vbits += 8; |
| } |
| vbits -= nbits; |
| return bitbuf << (32-nbits-vbits) >> (32-nbits); |
| } |
| |
| void CLASS init_decoder() |
| { |
| memset (first_decode, 0, sizeof first_decode); |
| free_decode = first_decode; |
| } |
| |
| /* |
| Construct a decode tree according the specification in *source. |
| The first 16 bytes specify how many codes should be 1-bit, 2-bit |
| 3-bit, etc. Bytes after that are the leaf values. |
| |
| For example, if the source is |
| |
| { 0,1,4,2,3,1,2,0,0,0,0,0,0,0,0,0, |
| 0x04,0x03,0x05,0x06,0x02,0x07,0x01,0x08,0x09,0x00,0x0a,0x0b,0xff }, |
| |
| then the code is |
| |
| 00 0x04 |
| 010 0x03 |
| 011 0x05 |
| 100 0x06 |
| 101 0x02 |
| 1100 0x07 |
| 1101 0x01 |
| 11100 0x08 |
| 11101 0x09 |
| 11110 0x00 |
| 111110 0x0a |
| 1111110 0x0b |
| 1111111 0xff |
| */ |
| uchar * CLASS make_decoder (const uchar *source, int level) |
| { |
| struct decode *cur; |
| static int leaf; |
| int i, next; |
| |
| if (level==0) leaf=0; |
| cur = free_decode++; |
| if (free_decode > first_decode+2048) { |
| fprintf (stderr,_("%s: decoder table overflow\n"), ifname); |
| longjmp (failure, 2); |
| } |
| for (i=next=0; i <= leaf && next < 16; ) |
| i += source[next++]; |
| if (i > leaf) { |
| if (level < next) { |
| cur->branch[0] = free_decode; |
| make_decoder (source, level+1); |
| cur->branch[1] = free_decode; |
| make_decoder (source, level+1); |
| } else |
| cur->leaf = source[16 + leaf++]; |
| } |
| return (uchar *) source + 16 + leaf; |
| } |
| |
| void CLASS crw_init_tables (unsigned table) |
| { |
| static const uchar first_tree[3][29] = { |
| { 0,1,4,2,3,1,2,0,0,0,0,0,0,0,0,0, |
| 0x04,0x03,0x05,0x06,0x02,0x07,0x01,0x08,0x09,0x00,0x0a,0x0b,0xff }, |
| { 0,2,2,3,1,1,1,1,2,0,0,0,0,0,0,0, |
| 0x03,0x02,0x04,0x01,0x05,0x00,0x06,0x07,0x09,0x08,0x0a,0x0b,0xff }, |
| { 0,0,6,3,1,1,2,0,0,0,0,0,0,0,0,0, |
| 0x06,0x05,0x07,0x04,0x08,0x03,0x09,0x02,0x00,0x0a,0x01,0x0b,0xff }, |
| }; |
| static const uchar second_tree[3][180] = { |
| { 0,2,2,2,1,4,2,1,2,5,1,1,0,0,0,139, |
| 0x03,0x04,0x02,0x05,0x01,0x06,0x07,0x08, |
| 0x12,0x13,0x11,0x14,0x09,0x15,0x22,0x00,0x21,0x16,0x0a,0xf0, |
| 0x23,0x17,0x24,0x31,0x32,0x18,0x19,0x33,0x25,0x41,0x34,0x42, |
| 0x35,0x51,0x36,0x37,0x38,0x29,0x79,0x26,0x1a,0x39,0x56,0x57, |
| 0x28,0x27,0x52,0x55,0x58,0x43,0x76,0x59,0x77,0x54,0x61,0xf9, |
| 0x71,0x78,0x75,0x96,0x97,0x49,0xb7,0x53,0xd7,0x74,0xb6,0x98, |
| 0x47,0x48,0x95,0x69,0x99,0x91,0xfa,0xb8,0x68,0xb5,0xb9,0xd6, |
| 0xf7,0xd8,0x67,0x46,0x45,0x94,0x89,0xf8,0x81,0xd5,0xf6,0xb4, |
| 0x88,0xb1,0x2a,0x44,0x72,0xd9,0x87,0x66,0xd4,0xf5,0x3a,0xa7, |
| 0x73,0xa9,0xa8,0x86,0x62,0xc7,0x65,0xc8,0xc9,0xa1,0xf4,0xd1, |
| 0xe9,0x5a,0x92,0x85,0xa6,0xe7,0x93,0xe8,0xc1,0xc6,0x7a,0x64, |
| 0xe1,0x4a,0x6a,0xe6,0xb3,0xf1,0xd3,0xa5,0x8a,0xb2,0x9a,0xba, |
| 0x84,0xa4,0x63,0xe5,0xc5,0xf3,0xd2,0xc4,0x82,0xaa,0xda,0xe4, |
| 0xf2,0xca,0x83,0xa3,0xa2,0xc3,0xea,0xc2,0xe2,0xe3,0xff,0xff }, |
| { 0,2,2,1,4,1,4,1,3,3,1,0,0,0,0,140, |
| 0x02,0x03,0x01,0x04,0x05,0x12,0x11,0x06, |
| 0x13,0x07,0x08,0x14,0x22,0x09,0x21,0x00,0x23,0x15,0x31,0x32, |
| 0x0a,0x16,0xf0,0x24,0x33,0x41,0x42,0x19,0x17,0x25,0x18,0x51, |
| 0x34,0x43,0x52,0x29,0x35,0x61,0x39,0x71,0x62,0x36,0x53,0x26, |
| 0x38,0x1a,0x37,0x81,0x27,0x91,0x79,0x55,0x45,0x28,0x72,0x59, |
| 0xa1,0xb1,0x44,0x69,0x54,0x58,0xd1,0xfa,0x57,0xe1,0xf1,0xb9, |
| 0x49,0x47,0x63,0x6a,0xf9,0x56,0x46,0xa8,0x2a,0x4a,0x78,0x99, |
| 0x3a,0x75,0x74,0x86,0x65,0xc1,0x76,0xb6,0x96,0xd6,0x89,0x85, |
| 0xc9,0xf5,0x95,0xb4,0xc7,0xf7,0x8a,0x97,0xb8,0x73,0xb7,0xd8, |
| 0xd9,0x87,0xa7,0x7a,0x48,0x82,0x84,0xea,0xf4,0xa6,0xc5,0x5a, |
| 0x94,0xa4,0xc6,0x92,0xc3,0x68,0xb5,0xc8,0xe4,0xe5,0xe6,0xe9, |
| 0xa2,0xa3,0xe3,0xc2,0x66,0x67,0x93,0xaa,0xd4,0xd5,0xe7,0xf8, |
| 0x88,0x9a,0xd7,0x77,0xc4,0x64,0xe2,0x98,0xa5,0xca,0xda,0xe8, |
| 0xf3,0xf6,0xa9,0xb2,0xb3,0xf2,0xd2,0x83,0xba,0xd3,0xff,0xff }, |
| { 0,0,6,2,1,3,3,2,5,1,2,2,8,10,0,117, |
| 0x04,0x05,0x03,0x06,0x02,0x07,0x01,0x08, |
| 0x09,0x12,0x13,0x14,0x11,0x15,0x0a,0x16,0x17,0xf0,0x00,0x22, |
| 0x21,0x18,0x23,0x19,0x24,0x32,0x31,0x25,0x33,0x38,0x37,0x34, |
| 0x35,0x36,0x39,0x79,0x57,0x58,0x59,0x28,0x56,0x78,0x27,0x41, |
| 0x29,0x77,0x26,0x42,0x76,0x99,0x1a,0x55,0x98,0x97,0xf9,0x48, |
| 0x54,0x96,0x89,0x47,0xb7,0x49,0xfa,0x75,0x68,0xb6,0x67,0x69, |
| 0xb9,0xb8,0xd8,0x52,0xd7,0x88,0xb5,0x74,0x51,0x46,0xd9,0xf8, |
| 0x3a,0xd6,0x87,0x45,0x7a,0x95,0xd5,0xf6,0x86,0xb4,0xa9,0x94, |
| 0x53,0x2a,0xa8,0x43,0xf5,0xf7,0xd4,0x66,0xa7,0x5a,0x44,0x8a, |
| 0xc9,0xe8,0xc8,0xe7,0x9a,0x6a,0x73,0x4a,0x61,0xc7,0xf4,0xc6, |
| 0x65,0xe9,0x72,0xe6,0x71,0x91,0x93,0xa6,0xda,0x92,0x85,0x62, |
| 0xf3,0xc5,0xb2,0xa4,0x84,0xba,0x64,0xa5,0xb3,0xd2,0x81,0xe5, |
| 0xd3,0xaa,0xc4,0xca,0xf2,0xb1,0xe4,0xd1,0x83,0x63,0xea,0xc3, |
| 0xe2,0x82,0xf1,0xa3,0xc2,0xa1,0xc1,0xe3,0xa2,0xe1,0xff,0xff } |
| }; |
| if (table > 2) table = 2; |
| init_decoder(); |
| make_decoder ( first_tree[table], 0); |
| second_decode = free_decode; |
| make_decoder (second_tree[table], 0); |
| } |
| |
| /* |
| Return 0 if the image starts with compressed data, |
| 1 if it starts with uncompressed low-order bits. |
| |
| In Canon compressed data, 0xff is always followed by 0x00. |
| */ |
| int CLASS canon_has_lowbits() |
| { |
| uchar test[0x4000]; |
| int ret=1, i; |
| |
| fseek (ifp, 0, SEEK_SET); |
| fread (test, 1, sizeof test, ifp); |
| for (i=540; i < sizeof test - 1; i++) |
| if (test[i] == 0xff) { |
| if (test[i+1]) return 1; |
| ret=0; |
| } |
| return ret; |
| } |
| |
| void CLASS canon_compressed_load_raw() |
| { |
| ushort *pixel, *prow; |
| int nblocks, lowbits, i, row, r, col, save, val; |
| unsigned irow, icol; |
| struct decode *decode, *dindex; |
| int block, diffbuf[64], leaf, len, diff, carry=0, pnum=0, base[2]; |
| double dark[2] = { 0,0 }; |
| uchar c; |
| |
| crw_init_tables (tiff_compress); |
| pixel = (ushort *) calloc (raw_width*8, sizeof *pixel); |
| merror (pixel, "canon_compressed_load_raw()"); |
| lowbits = canon_has_lowbits(); |
| if (!lowbits) maximum = 0x3ff; |
| fseek (ifp, 540 + lowbits*raw_height*raw_width/4, SEEK_SET); |
| zero_after_ff = 1; |
| getbits(-1); |
| for (row=0; row < raw_height; row+=8) { |
| nblocks = MIN (8, raw_height-row) * raw_width >> 6; |
| for (block=0; block < nblocks; block++) { |
| memset (diffbuf, 0, sizeof diffbuf); |
| decode = first_decode; |
| for (i=0; i < 64; i++ ) { |
| for (dindex=decode; dindex->branch[0]; ) |
| dindex = dindex->branch[getbits(1)]; |
| leaf = dindex->leaf; |
| decode = second_decode; |
| if (leaf == 0 && i) break; |
| if (leaf == 0xff) continue; |
| i += leaf >> 4; |
| len = leaf & 15; |
| if (len == 0) continue; |
| diff = getbits(len); |
| if ((diff & (1 << (len-1))) == 0) |
| diff -= (1 << len) - 1; |
| if (i < 64) diffbuf[i] = diff; |
| } |
| diffbuf[0] += carry; |
| carry = diffbuf[0]; |
| for (i=0; i < 64; i++ ) { |
| if (pnum++ % raw_width == 0) |
| base[0] = base[1] = 512; |
| if ((pixel[(block << 6) + i] = base[i & 1] += diffbuf[i]) >> 10) |
| derror(); |
| } |
| } |
| if (lowbits) { |
| save = ftell(ifp); |
| fseek (ifp, 26 + row*raw_width/4, SEEK_SET); |
| for (prow=pixel, i=0; i < raw_width*2; i++) { |
| c = fgetc(ifp); |
| for (r=0; r < 8; r+=2, prow++) { |
| val = (*prow << 2) + ((c >> r) & 3); |
| if (raw_width == 2672 && val < 512) val += 2; |
| *prow = val; |
| } |
| } |
| fseek (ifp, save, SEEK_SET); |
| } |
| for (r=0; r < 8; r++) { |
| irow = row - top_margin + r; |
| if (irow >= height) continue; |
| for (col=0; col < raw_width; col++) { |
| icol = col - left_margin; |
| if (icol < width) |
| BAYER(irow,icol) = pixel[r*raw_width+col]; |
| else if (col > 1) |
| dark[icol & 1] += pixel[r*raw_width+col]; |
| } |
| } |
| } |
| free (pixel); |
| canon_black (dark); |
| } |
| |
| /* |
| Not a full implementation of Lossless JPEG, just |
| enough to decode Canon, Kodak and Adobe DNG images. |
| */ |
| struct jhead { |
| int bits, high, wide, clrs, sraw, psv, restart, vpred[6]; |
| struct CLASS decode *huff[6]; |
| ushort *row; |
| }; |
| |
| int CLASS ljpeg_start (struct jhead *jh, int info_only) |
| { |
| int c, tag, len; |
| uchar data[0x10000], *dp; |
| |
| if (!info_only) init_decoder(); |
| memset (jh, 0, sizeof *jh); |
| FORC(6) jh->huff[c] = free_decode; |
| jh->restart = INT_MAX; |
| fread (data, 2, 1, ifp); |
| if (data[1] != 0xd8) return 0; |
| do { |
| fread (data, 2, 2, ifp); |
| tag = data[0] << 8 | data[1]; |
| len = (data[2] << 8 | data[3]) - 2; |
| if (tag <= 0xff00) return 0; |
| fread (data, 1, len, ifp); |
| switch (tag) { |
| case 0xffc3: |
| jh->sraw = ((data[7] >> 4) * (data[7] & 15) - 1) & 3; |
| case 0xffc0: |
| jh->bits = data[0]; |
| jh->high = data[1] << 8 | data[2]; |
| jh->wide = data[3] << 8 | data[4]; |
| jh->clrs = data[5] + jh->sraw; |
| if (len == 9 && !dng_version) getc(ifp); |
| break; |
| case 0xffc4: |
| if (info_only) break; |
| for (dp = data; dp < data+len && *dp < 4; ) { |
| jh->huff[*dp] = free_decode; |
| dp = make_decoder (++dp, 0); |
| } |
| break; |
| case 0xffda: |
| jh->psv = data[1+data[0]*2]; |
| jh->bits -= data[3+data[0]*2] & 15; |
| break; |
| case 0xffdd: |
| jh->restart = data[0] << 8 | data[1]; |
| } |
| } while (tag != 0xffda); |
| if (info_only) return 1; |
| if (jh->sraw) { |
| FORC(4) jh->huff[2+c] = jh->huff[1]; |
| FORC(jh->sraw) jh->huff[1+c] = jh->huff[0]; |
| } |
| jh->row = (ushort *) calloc (jh->wide*jh->clrs, 4); |
| merror (jh->row, "ljpeg_start()"); |
| return zero_after_ff = 1; |
| } |
| |
| int CLASS ljpeg_diff (struct decode *dindex) |
| { |
| int len, diff; |
| |
| while (dindex->branch[0]) |
| dindex = dindex->branch[getbits(1)]; |
| len = dindex->leaf; |
| if (len == 16 && (!dng_version || dng_version >= 0x1010000)) |
| return -32768; |
| diff = getbits(len); |
| if ((diff & (1 << (len-1))) == 0) |
| diff -= (1 << len) - 1; |
| return diff; |
| } |
| |
| ushort * CLASS ljpeg_row (int jrow, struct jhead *jh) |
| { |
| int col, c, diff, pred, spred=0; |
| ushort mark=0, *row[3]; |
| |
| if (jrow * jh->wide % jh->restart == 0) { |
| FORC(6) jh->vpred[c] = 1 << (jh->bits-1); |
| if (jrow) |
| do mark = (mark << 8) + (c = fgetc(ifp)); |
| while (c != EOF && mark >> 4 != 0xffd); |
| getbits(-1); |
| } |
| FORC3 row[c] = jh->row + jh->wide*jh->clrs*((jrow+c) & 1); |
| for (col=0; col < jh->wide; col++) |
| FORC(jh->clrs) { |
| diff = ljpeg_diff (jh->huff[c]); |
| if (jh->sraw && c <= jh->sraw && (col | c)) |
| pred = spred; |
| else if (col) pred = row[0][-jh->clrs]; |
| else pred = (jh->vpred[c] += diff) - diff; |
| if (jrow && col) switch (jh->psv) { |
| case 1: break; |
| case 2: pred = row[1][0]; break; |
| case 3: pred = row[1][-jh->clrs]; break; |
| case 4: pred = pred + row[1][0] - row[1][-jh->clrs]; break; |
| case 5: pred = pred + ((row[1][0] - row[1][-jh->clrs]) >> 1); break; |
| case 6: pred = row[1][0] + ((pred - row[1][-jh->clrs]) >> 1); break; |
| case 7: pred = (pred + row[1][0]) >> 1; break; |
| default: pred = 0; |
| } |
| if ((**row = pred + diff) >> jh->bits) derror(); |
| if (c <= jh->sraw) spred = **row; |
| row[0]++; row[1]++; |
| } |
| return row[2]; |
| } |
| |
| void CLASS lossless_jpeg_load_raw() |
| { |
| int jwide, jrow, jcol, val, jidx, i, j, row=0, col=0; |
| double dark[2] = { 0,0 }; |
| struct jhead jh; |
| int min=INT_MAX; |
| ushort *rp; |
| |
| if (!ljpeg_start (&jh, 0)) return; |
| jwide = jh.wide * jh.clrs; |
| |
| for (jrow=0; jrow < jh.high; jrow++) { |
| rp = ljpeg_row (jrow, &jh); |
| for (jcol=0; jcol < jwide; jcol++) { |
| val = *rp++; |
| if (jh.bits <= 12) |
| val = curve[val & 0xfff]; |
| if (cr2_slice[0]) { |
| jidx = jrow*jwide + jcol; |
| i = jidx / (cr2_slice[1]*jh.high); |
| if ((j = i >= cr2_slice[0])) |
| i = cr2_slice[0]; |
| jidx -= i * (cr2_slice[1]*jh.high); |
| row = jidx / cr2_slice[1+j]; |
| col = jidx % cr2_slice[1+j] + i*cr2_slice[1]; |
| } |
| if (raw_width == 3984 && (col -= 2) < 0) |
| col += (row--,raw_width); |
| if ((unsigned) (row-top_margin) < height) { |
| if ((unsigned) (col-left_margin) < width) { |
| BAYER(row-top_margin,col-left_margin) = val; |
| if (min > val) min = val; |
| } else if (col > 1) |
| dark[(col-left_margin) & 1] += val; |
| } |
| if (++col >= raw_width) |
| col = (row++,0); |
| } |
| } |
| free (jh.row); |
| canon_black (dark); |
| if (!strcasecmp(make,"KODAK")) |
| black = min; |
| } |
| |
| void CLASS canon_sraw_load_raw() |
| { |
| struct jhead jh; |
| short *rp=0, (*ip)[4]; |
| int jwide, slice, scol, ecol, row, col, jrow=0, jcol=0, pix[3], c; |
| int v[3]={0,0,0}, ver, hue; |
| char *cp; |
| |
| if (!ljpeg_start (&jh, 0)) return; |
| jwide = (jh.wide >>= 1) * jh.clrs; |
| |
| for (ecol=slice=0; slice <= cr2_slice[0]; slice++) { |
| scol = ecol; |
| ecol += cr2_slice[1] * 2 / jh.clrs; |
| if (!cr2_slice[0] || ecol > raw_width-1) ecol = raw_width & -2; |
| for (row=0; row < height; row += (jh.clrs >> 1) - 1) { |
| ip = (short (*)[4]) image + row*width; |
| for (col=scol; col < ecol; col+=2, jcol+=jh.clrs) { |
| if ((jcol %= jwide) == 0) |
| rp = (short *) ljpeg_row (jrow++, &jh); |
| if (col >= width) continue; |
| FORC (jh.clrs-2) |
| ip[col + (c >> 1)*width + (c & 1)][0] = rp[jcol+c]; |
| ip[col][1] = rp[jcol+jh.clrs-2] - 16384; |
| ip[col][2] = rp[jcol+jh.clrs-1] - 16384; |
| } |
| } |
| } |
| for (cp=model2; *cp && !isdigit(*cp); cp++); |
| sscanf (cp, "%d.%d.%d", v, v+1, v+2); |
| ver = (v[0]*1000 + v[1])*1000 + v[2]; |
| hue = (jh.sraw+1) << 2; |
| if (unique_id == 0x80000218 && ver > 1000006 && ver < 3000000) |
| hue = jh.sraw << 1; |
| ip = (short (*)[4]) image; |
| rp = ip[0]; |
| for (row=0; row < height; row++, ip+=width) { |
| if (row & (jh.sraw >> 1)) |
| for (col=0; col < width; col+=2) |
| for (c=1; c < 3; c++) |
| if (row == height-1) |
| ip[col][c] = ip[col-width][c]; |
| else ip[col][c] = (ip[col-width][c] + ip[col+width][c] + 1) >> 1; |
| for (col=1; col < width; col+=2) |
| for (c=1; c < 3; c++) |
| if (col == width-1) |
| ip[col][c] = ip[col-1][c]; |
| else ip[col][c] = (ip[col-1][c] + ip[col+1][c] + 1) >> 1; |
| } |
| for ( ; rp < ip[0]; rp+=4) { |
| if (unique_id < 0x80000200) { |
| pix[0] = rp[0] + rp[2] - 512; |
| pix[2] = rp[0] + rp[1] - 512; |
| pix[1] = rp[0] + ((-778*rp[1] - (rp[2] << 11)) >> 12) - 512; |
| } else { |
| rp[1] = (rp[1] << 2) + hue; |
| rp[2] = (rp[2] << 2) + hue; |
| pix[0] = rp[0] + (( 200*rp[1] + 22929*rp[2]) >> 14); |
| pix[1] = rp[0] + ((-5640*rp[1] - 11751*rp[2]) >> 14); |
| pix[2] = rp[0] + ((29040*rp[1] - 101*rp[2]) >> 14); |
| } |
| FORC3 rp[c] = CLIP(pix[c] * sraw_mul[c] >> 10); |
| } |
| free (jh.row); |
| maximum = 0x3fff; |
| } |
| |
| void CLASS adobe_copy_pixel (int row, int col, ushort **rp) |
| { |
| unsigned r, c; |
| |
| r = row -= top_margin; |
| c = col -= left_margin; |
| if (is_raw == 2 && shot_select) (*rp)++; |
| if (filters) { |
| if (fuji_width) { |
| r = row + fuji_width - 1 - (col >> 1); |
| c = row + ((col+1) >> 1); |
| } |
| if (r < height && c < width) |
| BAYER(r,c) = **rp < 0x1000 ? curve[**rp] : **rp; |
| *rp += is_raw; |
| } else { |
| if (r < height && c < width) |
| FORC(tiff_samples) |
| image[row*width+col][c] = (*rp)[c] < 0x1000 ? curve[(*rp)[c]]:(*rp)[c]; |
| *rp += tiff_samples; |
| } |
| if (is_raw == 2 && shot_select) (*rp)--; |
| } |
| |
| void CLASS adobe_dng_load_raw_lj() |
| { |
| unsigned save, trow=0, tcol=0, jwide, jrow, jcol, row, col; |
| struct jhead jh; |
| ushort *rp; |
| |
| while (trow < raw_height) { |
| save = ftell(ifp); |
| if (tile_length < INT_MAX) |
| fseek (ifp, get4(), SEEK_SET); |
| if (!ljpeg_start (&jh, 0)) break; |
| jwide = jh.wide; |
| if (filters) jwide *= jh.clrs; |
| jwide /= is_raw; |
| for (row=col=jrow=0; jrow < jh.high; jrow++) { |
| rp = ljpeg_row (jrow, &jh); |
| for (jcol=0; jcol < jwide; jcol++) { |
| adobe_copy_pixel (trow+row, tcol+col, &rp); |
| if (++col >= tile_width || col >= raw_width) |
| row += 1 + (col = 0); |
| } |
| } |
| fseek (ifp, save+4, SEEK_SET); |
| if ((tcol += tile_width) >= raw_width) |
| trow += tile_length + (tcol = 0); |
| free (jh.row); |
| } |
| } |
| |
| void CLASS adobe_dng_load_raw_nc() |
| { |
| ushort *pixel, *rp; |
| int row, col; |
| |
| pixel = (ushort *) calloc (raw_width * tiff_samples, sizeof *pixel); |
| merror (pixel, "adobe_dng_load_raw_nc()"); |
| for (row=0; row < raw_height; row++) { |
| if (tiff_bps == 16) |
| read_shorts (pixel, raw_width * tiff_samples); |
| else { |
| getbits(-1); |
| for (col=0; col < raw_width * tiff_samples; col++) |
| pixel[col] = getbits(tiff_bps); |
| } |
| for (rp=pixel, col=0; col < raw_width; col++) |
| adobe_copy_pixel (row, col, &rp); |
| } |
| free (pixel); |
| } |
| |
| void CLASS pentax_tree() |
| { |
| ushort bit[2][13]; |
| struct decode *cur; |
| int c, i, j; |
| |
| init_decoder(); |
| FORC(13) bit[0][c] = get2(); |
| FORC(13) bit[1][c] = fgetc(ifp) & 15; |
| FORC(13) { |
| cur = first_decode; |
| for (i=0; i < bit[1][c]; i++) { |
| j = bit[0][c] >> (11-i) & 1; |
| if (!cur->branch[j]) cur->branch[j] = ++free_decode; |
| cur = cur->branch[j]; |
| } |
| cur->leaf = c; |
| } |
| } |
| |
| void CLASS pentax_k10_load_raw() |
| { |
| int row, col, diff; |
| ushort vpred[2][2] = {{0,0},{0,0}}, hpred[2]; |
| |
| getbits(-1); |
| for (row=0; row < height; row++) |
| for (col=0; col < raw_width; col++) { |
| diff = ljpeg_diff (first_decode); |
| if (col < 2) hpred[col] = vpred[row & 1][col] += diff; |
| else hpred[col & 1] += diff; |
| if (col < width) |
| BAYER(row,col) = hpred[col & 1]; |
| if (hpred[col & 1] >> 12) derror(); |
| } |
| } |
| |
| void CLASS nikon_compressed_load_raw() |
| { |
| static const uchar nikon_tree[][32] = { |
| { 0,1,5,1,1,1,1,1,1,2,0,0,0,0,0,0, /* 12-bit lossy */ |
| 5,4,3,6,2,7,1,0,8,9,11,10,12 }, |
| { 0,1,5,1,1,1,1,1,1,2,0,0,0,0,0,0, /* 12-bit lossy after split */ |
| 0x39,0x5a,0x38,0x27,0x16,5,4,3,2,1,0,11,12,12 }, |
| { 0,1,4,2,3,1,2,0,0,0,0,0,0,0,0,0, /* 12-bit lossless */ |
| 5,4,6,3,7,2,8,1,9,0,10,11,12 }, |
| { 0,1,4,3,1,1,1,1,1,2,0,0,0,0,0,0, /* 14-bit lossy */ |
| 5,6,4,7,8,3,9,2,1,0,10,11,12,13,14 }, |
| { 0,1,5,1,1,1,1,1,1,1,2,0,0,0,0,0, /* 14-bit lossy after split */ |
| 8,0x5c,0x4b,0x3a,0x29,7,6,5,4,3,2,1,0,13,14 }, |
| { 0,1,4,2,2,3,1,2,0,0,0,0,0,0,0,0, /* 14-bit lossless */ |
| 7,6,8,5,9,4,10,3,11,12,2,0,1,13,14 } }; |
| struct decode *dindex; |
| ushort ver0, ver1, vpred[2][2], hpred[2], csize; |
| int i, min, max, step=0, huff=0, split=0, row, col, len, shl, diff; |
| |
| fseek (ifp, meta_offset, SEEK_SET); |
| ver0 = fgetc(ifp); |
| ver1 = fgetc(ifp); |
| if (ver0 == 0x49 || ver1 == 0x58) |
| fseek (ifp, 2110, SEEK_CUR); |
| if (ver0 == 0x46) huff = 2; |
| if (tiff_bps == 14) huff += 3; |
| read_shorts (vpred[0], 4); |
| max = 1 << tiff_bps & 0x7fff; |
| if ((csize = get2()) > 1) |
| step = max / (csize-1); |
| if (ver0 == 0x44 && ver1 == 0x20 && step > 0) { |
| for (i=0; i < csize; i++) |
| curve[i*step] = get2(); |
| for (i=0; i < max; i++) |
| curve[i] = ( curve[i-i%step]*(step-i%step) + |
| curve[i-i%step+step]*(i%step) ) / step; |
| fseek (ifp, meta_offset+562, SEEK_SET); |
| split = get2(); |
| } else if (ver0 != 0x46 && csize <= 0x4001) |
| read_shorts (curve, max=csize); |
| while (curve[max-2] == curve[max-1]) max--; |
| init_decoder(); |
| make_decoder (nikon_tree[huff], 0); |
| fseek (ifp, data_offset, SEEK_SET); |
| getbits(-1); |
| for (min=row=0; row < height; row++) { |
| if (split && row == split) { |
| init_decoder(); |
| make_decoder (nikon_tree[huff+1], 0); |
| max += (min = 16) << 1; |
| } |
| for (col=0; col < raw_width; col++) { |
| for (dindex=first_decode; dindex->branch[0]; ) |
| dindex = dindex->branch[getbits(1)]; |
| len = dindex->leaf & 15; |
| shl = dindex->leaf >> 4; |
| diff = ((getbits(len-shl) << 1) + 1) << shl >> 1; |
| if ((diff & (1 << (len-1))) == 0) |
| diff -= (1 << len) - !shl; |
| if (col < 2) hpred[col] = vpred[row & 1][col] += diff; |
| else hpred[col & 1] += diff; |
| if ((ushort)(hpred[col & 1] + min) >= max) derror(); |
| if ((unsigned) (col-left_margin) < width) |
| BAYER(row,col-left_margin) = curve[LIM((short)hpred[col & 1],0,0x3fff)]; |
| } |
| } |
| } |
| |
| /* |
| Figure out if a NEF file is compressed. These fancy heuristics |
| are only needed for the D100, thanks to a bug in some cameras |
| that tags all images as "compressed". |
| */ |
| int CLASS nikon_is_compressed() |
| { |
| uchar test[256]; |
| int i; |
| |
| fseek (ifp, data_offset, SEEK_SET); |
| fread (test, 1, 256, ifp); |
| for (i=15; i < 256; i+=16) |
| if (test[i]) return 1; |
| return 0; |
| } |
| |
| /* |
| Returns 1 for a Coolpix 995, 0 for anything else. |
| */ |
| int CLASS nikon_e995() |
| { |
| int i, histo[256]; |
| const uchar often[] = { 0x00, 0x55, 0xaa, 0xff }; |
| |
| memset (histo, 0, sizeof histo); |
| fseek (ifp, -2000, SEEK_END); |
| for (i=0; i < 2000; i++) |
| histo[fgetc(ifp)]++; |
| for (i=0; i < 4; i++) |
| if (histo[often[i]] < 200) |
| return 0; |
| return 1; |
| } |
| |
| /* |
| Returns 1 for a Coolpix 2100, 0 for anything else. |
| */ |
| int CLASS nikon_e2100() |
| { |
| uchar t[12]; |
| int i; |
| |
| fseek (ifp, 0, SEEK_SET); |
| for (i=0; i < 1024; i++) { |
| fread (t, 1, 12, ifp); |
| if (((t[2] & t[4] & t[7] & t[9]) >> 4 |
| & t[1] & t[6] & t[8] & t[11] & 3) != 3) |
| return 0; |
| } |
| return 1; |
| } |
| |
| void CLASS nikon_3700() |
| { |
| int bits, i; |
| uchar dp[24]; |
| static const struct { |
| int bits; |
| char make[12], model[15]; |
| } table[] = { |
| { 0x00, "PENTAX", "Optio 33WR" }, |
| { 0x03, "NIKON", "E3200" }, |
| { 0x32, "NIKON", "E3700" }, |
| { 0x33, "OLYMPUS", "C740UZ" } }; |
| |
| fseek (ifp, 3072, SEEK_SET); |
| fread (dp, 1, 24, ifp); |
| bits = (dp[8] & 3) << 4 | (dp[20] & 3); |
| for (i=0; i < sizeof table / sizeof *table; i++) |
| if (bits == table[i].bits) { |
| strcpy (make, table[i].make ); |
| strcpy (model, table[i].model); |
| } |
| } |
| |
| /* |
| Separates a Minolta DiMAGE Z2 from a Nikon E4300. |
| */ |
| int CLASS minolta_z2() |
| { |
| int i, nz; |
| char tail[424]; |
| |
| fseek (ifp, -sizeof tail, SEEK_END); |
| fread (tail, 1, sizeof tail, ifp); |
| for (nz=i=0; i < sizeof tail; i++) |
| if (tail[i]) nz++; |
| return nz > 20; |
| } |
| |
| /* Here raw_width is in bytes, not pixels. */ |
| void CLASS nikon_e900_load_raw() |
| { |
| int offset=0, irow, row, col; |
| |
| for (irow=0; irow < height; irow++) { |
| row = irow * 2 % height; |
| if (row == 1) |
| offset = - (-offset & -4096); |
| fseek (ifp, offset, SEEK_SET); |
| offset += raw_width; |
| getbits(-1); |
| for (col=0; col < width; col++) |
| BAYER(row,col) = getbits(10); |
| } |
| } |
| |
| /* |
| The Fuji Super CCD is just a Bayer grid rotated 45 degrees. |
| */ |
| void CLASS fuji_load_raw() |
| { |
| ushort *pixel; |
| int wide, row, col, r, c; |
| |
| fseek (ifp, (top_margin*raw_width + left_margin) * 2, SEEK_CUR); |
| wide = fuji_width << !fuji_layout; |
| pixel = (ushort *) calloc (wide, sizeof *pixel); |
| merror (pixel, "fuji_load_raw()"); |
| for (row=0; row < raw_height; row++) { |
| read_shorts (pixel, wide); |
| fseek (ifp, 2*(raw_width - wide), SEEK_CUR); |
| for (col=0; col < wide; col++) { |
| if (fuji_layout) { |
| r = fuji_width - 1 - col + (row >> 1); |
| c = col + ((row+1) >> 1); |
| } else { |
| r = fuji_width - 1 + row - (col >> 1); |
| c = row + ((col+1) >> 1); |
| } |
| BAYER(r,c) = pixel[col]; |
| } |
| } |
| free (pixel); |
| } |
| |
| void CLASS jpeg_thumb (FILE *tfp); |
| |
| void CLASS ppm_thumb (FILE *tfp) |
| { |
| char *thumb; |
| thumb_length = thumb_width*thumb_height*3; |
| thumb = (char *) malloc (thumb_length); |
| merror (thumb, "ppm_thumb()"); |
| fprintf (tfp, "P6\n%d %d\n255\n", thumb_width, thumb_height); |
| fread (thumb, 1, thumb_length, ifp); |
| fwrite (thumb, 1, thumb_length, tfp); |
| free (thumb); |
| } |
| |
| void CLASS layer_thumb (FILE *tfp) |
| { |
| int i, c; |
| char *thumb, map[][4] = { "012","102" }; |
| |
| colors = thumb_misc >> 5 & 7; |
| thumb_length = thumb_width*thumb_height; |
| thumb = (char *) calloc (colors, thumb_length); |
| merror (thumb, "layer_thumb()"); |
| fprintf (tfp, "P%d\n%d %d\n255\n", |
| 5 + (colors >> 1), thumb_width, thumb_height); |
| fread (thumb, thumb_length, colors, ifp); |
| for (i=0; i < thumb_length; i++) |
| FORCC putc (thumb[i+thumb_length*(map[thumb_misc >> 8][c]-'0')], tfp); |
| free (thumb); |
| } |
| |
| void CLASS rollei_thumb (FILE *tfp) |
| { |
| unsigned i; |
| ushort *thumb; |
| |
| thumb_length = thumb_width * thumb_height; |
| thumb = (ushort *) calloc (thumb_length, 2); |
| merror (thumb, "rollei_thumb()"); |
| fprintf (tfp, "P6\n%d %d\n255\n", thumb_width, thumb_height); |
| read_shorts (thumb, thumb_length); |
| for (i=0; i < thumb_length; i++) { |
| putc (thumb[i] << 3, tfp); |
| putc (thumb[i] >> 5 << 2, tfp); |
| putc (thumb[i] >> 11 << 3, tfp); |
| } |
| free (thumb); |
| } |
| |
| void CLASS rollei_load_raw() |
| { |
| uchar pixel[10]; |
| unsigned iten=0, isix, i, buffer=0, row, col, todo[16]; |
| |
| isix = raw_width * raw_height * 5 / 8; |
| while (fread (pixel, 1, 10, ifp) == 10) { |
| for (i=0; i < 10; i+=2) { |
| todo[i] = iten++; |
| todo[i+1] = pixel[i] << 8 | pixel[i+1]; |
| buffer = pixel[i] >> 2 | buffer << 6; |
| } |
| for ( ; i < 16; i+=2) { |
| todo[i] = isix++; |
| todo[i+1] = buffer >> (14-i)*5; |
| } |
| for (i=0; i < 16; i+=2) { |
| row = todo[i] / raw_width - top_margin; |
| col = todo[i] % raw_width - left_margin; |
| if (row < height && col < width) |
| BAYER(row,col) = (todo[i+1] & 0x3ff); |
| } |
| } |
| maximum = 0x3ff; |
| } |
| |
| int CLASS bayer (unsigned row, unsigned col) |
| { |
| return (row < height && col < width) ? BAYER(row,col) : 0; |
| } |
| |
| void CLASS phase_one_flat_field (int is_float, int nc) |
| { |
| ushort head[8]; |
| unsigned wide, y, x, c, rend, cend, row, col; |
| float *mrow, num, mult[4]; |
| |
| read_shorts (head, 8); |
| wide = head[2] / head[4]; |
| mrow = (float *) calloc (nc*wide, sizeof *mrow); |
| merror (mrow, "phase_one_flat_field()"); |
| for (y=0; y < head[3] / head[5]; y++) { |
| for (x=0; x < wide; x++) |
| for (c=0; c < nc; c+=2) { |
| num = is_float ? getreal(11) : get2()/32768.0; |
| if (y==0) mrow[c*wide+x] = num; |
| else mrow[(c+1)*wide+x] = (num - mrow[c*wide+x]) / head[5]; |
| } |
| if (y==0) continue; |
| rend = head[1]-top_margin + y*head[5]; |
| for (row = rend-head[5]; row < height && row < rend; row++) { |
| for (x=1; x < wide; x++) { |
| for (c=0; c < nc; c+=2) { |
| mult[c] = mrow[c*wide+x-1]; |
| mult[c+1] = (mrow[c*wide+x] - mult[c]) / head[4]; |
| } |
| cend = head[0]-left_margin + x*head[4]; |
| for (col = cend-head[4]; col < width && col < cend; col++) { |
| c = nc > 2 ? FC(row,col) : 0; |
| if (!(c & 1)) { |
| c = BAYER(row,col) * mult[c]; |
| BAYER(row,col) = LIM(c,0,65535); |
| } |
| for (c=0; c < nc; c+=2) |
| mult[c] += mult[c+1]; |
| } |
| } |
| for (x=0; x < wide; x++) |
| for (c=0; c < nc; c+=2) |
| mrow[c*wide+x] += mrow[(c+1)*wide+x]; |
| } |
| } |
| free (mrow); |
| } |
| |
| void CLASS phase_one_correct() |
| { |
| unsigned entries, tag, data, save, col, row, type; |
| int len, i, j, k, cip, val[4], dev[4], sum, max; |
| int head[9], diff, mindiff=INT_MAX, off_412=0; |
| static const signed char dir[12][2] = |
| { {-1,-1}, {-1,1}, {1,-1}, {1,1}, {-2,0}, {0,-2}, {0,2}, {2,0}, |
| {-2,-2}, {-2,2}, {2,-2}, {2,2} }; |
| float poly[8], num, cfrac, frac, mult[2], *yval[2]; |
| ushort curve[0x10000], *xval[2]; |
| |
| if (half_size || !meta_length) return; |
| if (verbose) fprintf (stderr,_("Phase One correction...\n")); |
| fseek (ifp, meta_offset, SEEK_SET); |
| order = get2(); |
| fseek (ifp, 6, SEEK_CUR); |
| fseek (ifp, meta_offset+get4(), SEEK_SET); |
| entries = get4(); get4(); |
| while (entries--) { |
| tag = get4(); |
| len = get4(); |
| data = get4(); |
| save = ftell(ifp); |
| fseek (ifp, meta_offset+data, SEEK_SET); |
| if (tag == 0x419) { /* Polynomial curve */ |
| for (get4(), i=0; i < 8; i++) |
| poly[i] = getreal(11); |
| poly[3] += (ph1.tag_210 - poly[7]) * poly[6] + 1; |
| for (i=0; i < 0x10000; i++) { |
| num = (poly[5]*i + poly[3])*i + poly[1]; |
| curve[i] = LIM(num,0,65535); |
| } goto apply; /* apply to right half */ |
| } else if (tag == 0x41a) { /* Polynomial curve */ |
| for (i=0; i < 4; i++) |
| poly[i] = getreal(11); |
| for (i=0; i < 0x10000; i++) { |
| for (num=0, j=4; j--; ) |
| num = num * i + poly[j]; |
| curve[i] = LIM(num+i,0,65535); |
| } apply: /* apply to whole image */ |
| for (row=0; row < height; row++) |
| for (col = (tag & 1)*ph1.split_col; col < width; col++) |
| BAYER(row,col) = curve[BAYER(row,col)]; |
| } else if (tag == 0x400) { /* Sensor defects */ |
| while ((len -= 8) >= 0) { |
| col = get2() - left_margin; |
| row = get2() - top_margin; |
| type = get2(); get2(); |
| if (col >= width) continue; |
| if (type == 131) /* Bad column */ |
| for (row=0; row < height; row++) |
| if (FC(row,col) == 1) { |
| for (sum=i=0; i < 4; i++) |
| sum += val[i] = bayer (row+dir[i][0], col+dir[i][1]); |
| for (max=i=0; i < 4; i++) { |
| dev[i] = abs((val[i] << 2) - sum); |
| if (dev[max] < dev[i]) max = i; |
| } |
| BAYER(row,col) = (sum - val[max])/3.0 + 0.5; |
| } else { |
| for (sum=0, i=8; i < 12; i++) |
| sum += bayer (row+dir[i][0], col+dir[i][1]); |
| BAYER(row,col) = 0.5 + sum * 0.0732233 + |
| (bayer(row,col-2) + bayer(row,col+2)) * 0.3535534; |
| } |
| else if (type == 129) { /* Bad pixel */ |
| if (row >= height) continue; |
| j = (FC(row,col) != 1) * 4; |
| for (sum=0, i=j; i < j+8; i++) |
| sum += bayer (row+dir[i][0], col+dir[i][1]); |
| BAYER(row,col) = (sum + 4) >> 3; |
| } |
| } |
| } else if (tag == 0x401) { /* All-color flat fields */ |
| phase_one_flat_field (1, 2); |
| } else if (tag == 0x416 || tag == 0x410) { |
| phase_one_flat_field (0, 2); |
| } else if (tag == 0x40b) { /* Red+blue flat field */ |
| phase_one_flat_field (0, 4); |
| } else if (tag == 0x412) { |
| fseek (ifp, 36, SEEK_CUR); |
| diff = abs (get2() - ph1.tag_21a); |
| if (mindiff > diff) { |
| mindiff = diff; |
| off_412 = ftell(ifp) - 38; |
| } |
| } |
| fseek (ifp, save, SEEK_SET); |
| } |
| if (off_412) { |
| fseek (ifp, off_412, SEEK_SET); |
| for (i=0; i < 9; i++) head[i] = get4() & 0x7fff; |
| yval[0] = (float *) calloc (head[1]*head[3] + head[2]*head[4], 6); |
| merror (yval[0], "phase_one_correct()"); |
| yval[1] = (float *) (yval[0] + head[1]*head[3]); |
| xval[0] = (ushort *) (yval[1] + head[2]*head[4]); |
| xval[1] = (ushort *) (xval[0] + head[1]*head[3]); |
| get2(); |
| for (i=0; i < 2; i++) |
| for (j=0; j < head[i+1]*head[i+3]; j++) |
| yval[i][j] = getreal(11); |
| for (i=0; i < 2; i++) |
| for (j=0; j < head[i+1]*head[i+3]; j++) |
| xval[i][j] = get2(); |
| for (row=0; row < height; row++) |
| for (col=0; col < width; col++) { |
| cfrac = (float) col * head[3] / raw_width; |
| cfrac -= cip = cfrac; |
| num = BAYER(row,col) * 0.5; |
| for (i=cip; i < cip+2; i++) { |
| for (k=j=0; j < head[1]; j++) |
| if (num < xval[0][k = head[1]*i+j]) break; |
| frac = (j == 0 || j == head[1]) ? 0 : |
| (xval[0][k] - num) / (xval[0][k] - xval[0][k-1]); |
| mult[i-cip] = yval[0][k-1] * frac + yval[0][k] * (1-frac); |
| } |
| i = ((mult[0] * (1-cfrac) + mult[1] * cfrac) |
| * (row + top_margin) + num) * 2; |
| BAYER(row,col) = LIM(i,0,65535); |
| } |
| free (yval[0]); |
| } |
| } |
| |
| void CLASS phase_one_load_raw() |
| { |
| int row, col, a, b; |
| ushort *pixel, akey, bkey, mask; |
| |
| fseek (ifp, ph1.key_off, SEEK_SET); |
| akey = get2(); |
| bkey = get2(); |
| mask = ph1.format == 1 ? 0x5555:0x1354; |
| fseek (ifp, data_offset + top_margin*raw_width*2, SEEK_SET); |
| pixel = (ushort *) calloc (raw_width, sizeof *pixel); |
| merror (pixel, "phase_one_load_raw()"); |
| for (row=0; row < height; row++) { |
| read_shorts (pixel, raw_width); |
| for (col=0; col < raw_width; col+=2) { |
| a = pixel[col+0] ^ akey; |
| b = pixel[col+1] ^ bkey; |
| pixel[col+0] = (a & mask) | (b & ~mask); |
| pixel[col+1] = (b & mask) | (a & ~mask); |
| } |
| for (col=0; col < width; col++) |
| BAYER(row,col) = pixel[col+left_margin]; |
| } |
| free (pixel); |
| phase_one_correct(); |
| } |
| |
| unsigned CLASS ph1_bits (int nbits) |
| { |
| static UINT64 bitbuf=0; |
| static int vbits=0; |
| |
| if (nbits == -1) |
| return bitbuf = vbits = 0; |
| if (nbits == 0) return 0; |
| if ((vbits -= nbits) < 0) { |
| bitbuf = bitbuf << 32 | get4(); |
| vbits += 32; |
| } |
| return bitbuf << (64-nbits-vbits) >> (64-nbits); |
| } |
| |
| void CLASS phase_one_load_raw_c() |
| { |
| static const int length[] = { 8,7,6,9,11,10,5,12,14,13 }; |
| int *offset, len[2], pred[2], row, col, i, j; |
| ushort *pixel; |
| short (*black)[2]; |
| |
| pixel = (ushort *) calloc (raw_width + raw_height*4, 2); |
| merror (pixel, "phase_one_load_raw_c()"); |
| offset = (int *) (pixel + raw_width); |
| fseek (ifp, strip_offset, SEEK_SET); |
| for (row=0; row < raw_height; row++) |
| offset[row] = get4(); |
| black = (short (*)[2]) offset + raw_height; |
| fseek (ifp, ph1.black_off, SEEK_SET); |
| if (ph1.black_off) |
| read_shorts ((ushort *) black[0], raw_height*2); |
| for (i=0; i < 256; i++) |
| curve[i] = i*i / 3.969 + 0.5; |
| for (row=0; row < raw_height; row++) { |
| fseek (ifp, data_offset + offset[row], SEEK_SET); |
| ph1_bits(-1); |
| pred[0] = pred[1] = 0; |
| for (col=0; col < raw_width; col++) { |
| if (col >= (raw_width & -8)) |
| len[0] = len[1] = 14; |
| else if ((col & 7) == 0) |
| for (i=0; i < 2; i++) { |
| for (j=0; j < 5 && !ph1_bits(1); j++); |
| if (j--) len[i] = length[j*2 + ph1_bits(1)]; |
| } |
| if ((i = len[col & 1]) == 14) |
| pixel[col] = pred[col & 1] = ph1_bits(16); |
| else |
| pixel[col] = pred[col & 1] += ph1_bits(i) + 1 - (1 << (i - 1)); |
| if (pred[col & 1] >> 16) derror(); |
| if (ph1.format == 5 && pixel[col] < 256) |
| pixel[col] = curve[pixel[col]]; |
| } |
| if ((unsigned) (row-top_margin) < height) |
| for (col=0; col < width; col++) { |
| i = (pixel[col+left_margin] << 2) |
| - ph1.black + black[row][col >= ph1.split_col]; |
| if (i > 0) BAYER(row-top_margin,col) = i; |
| } |
| } |
| free (pixel); |
| phase_one_correct(); |
| maximum = 0xfffc - ph1.black; |
| } |
| |
| void CLASS hasselblad_load_raw() |
| { |
| struct jhead jh; |
| struct decode *dindex; |
| int row, col, pred[2], len[2], diff, i; |
| |
| if (!ljpeg_start (&jh, 0)) return; |
| free (jh.row); |
| order = 0x4949; |
| ph1_bits(-1); |
| for (row=-top_margin; row < height; row++) { |
| pred[0] = pred[1] = 0x8000; |
| for (col=-left_margin; col < raw_width-left_margin; col+=2) { |
| for (i=0; i < 2; i++) { |
| for (dindex=jh.huff[0]; dindex->branch[0]; ) |
| dindex = dindex->branch[ph1_bits(1)]; |
| len[i] = dindex->leaf; |
| } |
| for (i=0; i < 2; i++) { |
| diff = ph1_bits(len[i]); |
| if ((diff & (1 << (len[i]-1))) == 0) |
| diff -= (1 << len[i]) - 1; |
| if (diff == 65535) diff = -32768; |
| pred[i] += diff; |
| if (row >= 0 && (unsigned)(col+i) < width) |
| BAYER(row,col+i) = pred[i]; |
| } |
| } |
| } |
| maximum = 0xffff; |
| } |
| |
| void CLASS leaf_hdr_load_raw() |
| { |
| ushort *pixel; |
| unsigned tile=0, r, c, row, col; |
| |
| pixel = (ushort *) calloc (raw_width, sizeof *pixel); |
| merror (pixel, "leaf_hdr_load_raw()"); |
| FORC(tiff_samples) |
| for (r=0; r < raw_height; r++) { |
| if (r % tile_length == 0) { |
| fseek (ifp, data_offset + 4*tile++, SEEK_SET); |
| fseek (ifp, get4() + 2*left_margin, SEEK_SET); |
| } |
| if (filters && c != shot_select) continue; |
| read_shorts (pixel, raw_width); |
| if ((row = r - top_margin) >= height) continue; |
| for (col=0; col < width; col++) |
| if (filters) BAYER(row,col) = pixel[col]; |
| else image[row*width+col][c] = pixel[col]; |
| } |
| free (pixel); |
| if (!filters) { |
| maximum = 0xffff; |
| raw_color = 1; |
| } |
| } |
| |
| void CLASS unpacked_load_raw(); |
| |
| void CLASS sinar_4shot_load_raw() |
| { |
| ushort *pixel; |
| unsigned shot, row, col, r, c; |
| |
| if ((shot = shot_select) || half_size) { |
| if (shot) shot--; |
| if (shot > 3) shot = 3; |
| fseek (ifp, data_offset + shot*4, SEEK_SET); |
| fseek (ifp, get4(), SEEK_SET); |
| unpacked_load_raw(); |
| return; |
| } |
| free (image); |
| image = (ushort (*)[4]) |
| calloc ((iheight=height)*(iwidth=width), sizeof *image); |
| merror (image, "sinar_4shot_load_raw()"); |
| pixel = (ushort *) calloc (raw_width, sizeof *pixel); |
| merror (pixel, "sinar_4shot_load_raw()"); |
| for (shot=0; shot < 4; shot++) { |
| fseek (ifp, data_offset + shot*4, SEEK_SET); |
| fseek (ifp, get4(), SEEK_SET); |
| for (row=0; row < raw_height; row++) { |
| read_shorts (pixel, raw_width); |
| if ((r = row-top_margin - (shot >> 1 & 1)) >= height) continue; |
| for (col=0; col < raw_width; col++) { |
| if ((c = col-left_margin - (shot & 1)) >= width) continue; |
| image[r*width+c][FC(row,col)] = pixel[col]; |
| } |
| } |
| } |
| free (pixel); |
| shrink = filters = 0; |
| } |
| |
| void CLASS imacon_full_load_raw() |
| { |
| int row, col; |
| |
| for (row=0; row < height; row++) |
| for (col=0; col < width; col++) |
| read_shorts (image[row*width+col], 3); |
| } |
| |
| void CLASS packed_12_load_raw() |
| { |
| int vbits=0, rbits=0, irow, row, col; |
| UINT64 bitbuf=0; |
| |
| if (raw_width * 2 >= width * 3) { /* If raw_width is in bytes, */ |
| rbits = raw_width * 8; |
| raw_width = raw_width * 2 / 3; /* convert it to pixels and */ |
| rbits -= raw_width * 12; /* save the remainder. */ |
| } |
| order = load_flags & 1 ? 0x4949 : 0x4d4d; |
| for (irow=0; irow < height; irow++) { |
| row = irow; |
| if (load_flags & 2 && |
| (row = irow * 2 % height + irow / (height/2)) == 1 && |
| load_flags & 4) { |
| if (vbits=0, tiff_compress) |
| fseek (ifp, data_offset - (-width*height*3/4 & -2048), SEEK_SET); |
| else { |
| fseek (ifp, 0, SEEK_END); |
| fseek (ifp, ftell(ifp)/2, SEEK_SET); |
| } |
| } |
| for (col=0; col < raw_width; col++) { |
| if ((vbits -= 12) < 0) { |
| bitbuf = bitbuf << 32 | get4(); |
| vbits += 32; |
| } |
| if ((unsigned) (col-left_margin) < width) |
| BAYER(row,col-left_margin) = bitbuf << (52-vbits) >> 52; |
| if (load_flags & 8 && (col % 10) == 9) |
| if (vbits=0, bitbuf & 255) derror(); |
| } |
| vbits -= rbits; |
| } |
| if (!strcmp(make,"OLYMPUS")) black >>= 4; |
| } |
| |
| void CLASS unpacked_load_raw() |
| { |
| ushort *pixel; |
| int row, col, bits=0; |
| |
| while (1 << ++bits < maximum); |
| fseek (ifp, (top_margin*raw_width + left_margin) * 2, SEEK_CUR); |
| pixel = (ushort *) calloc (width, sizeof *pixel); |
| merror (pixel, "unpacked_load_raw()"); |
| for (row=0; row < height; row++) { |
| read_shorts (pixel, width); |
| fseek (ifp, 2*(raw_width - width), SEEK_CUR); |
| for (col=0; col < width; col++) |
| if ((BAYER2(row,col) = pixel[col]) >> bits) derror(); |
| } |
| free (pixel); |
| } |
| |
| void CLASS nokia_load_raw() |
| { |
| uchar *data, *dp; |
| ushort *pixel, *pix; |
| int dwide, row, c; |
| |
| dwide = raw_width * 5 / 4; |
| data = (uchar *) malloc (dwide + raw_width*2); |
| merror (data, "nokia_load_raw()"); |
| pixel = (ushort *) (data + dwide); |
| for (row=0; row < raw_height; row++) { |
| if (fread (data, 1, dwide, ifp) < dwide) derror(); |
| for (dp=data, pix=pixel; pix < pixel+raw_width; dp+=5, pix+=4) |
| FORC4 pix[c] = (dp[c] << 2) | (dp[4] >> (c << 1) & 3); |
| if (row < top_margin) |
| FORC(width) black += pixel[c]; |
| else |
| FORC(width) BAYER(row-top_margin,c) = pixel[c]; |
| } |
| free (data); |
| if (top_margin) black /= top_margin * width; |
| maximum = 0x3ff; |
| } |
| |
| unsigned CLASS pana_bits (int nbits) |
| { |
| static uchar buf[0x4000]; |
| static int vbits; |
| int byte; |
| |
| if (!nbits) return vbits=0; |
| if (!vbits) { |
| fread (buf+load_flags, 1, 0x4000-load_flags, ifp); |
| fread (buf, 1, load_flags, ifp); |
| } |
| vbits = (vbits - nbits) & 0x1ffff; |
| byte = vbits >> 3 ^ 0x3ff0; |
| return (buf[byte] | buf[byte+1] << 8) >> (vbits & 7) & ~(-1 << nbits); |
| } |
| |
| void CLASS panasonic_load_raw() |
| { |
| int row, col, i, j, sh=0, pred[2], nonz[2]; |
| |
| pana_bits(0); |
| for (row=0; row < height; row++) |
| for (col=0; col < raw_width; col++) { |
| if ((i = col % 14) == 0) |
| pred[0] = pred[1] = nonz[0] = nonz[1] = 0; |
| if (i % 3 == 2) sh = 4 >> (3 - pana_bits(2)); |
| if (nonz[i & 1]) { |
| if ((j = pana_bits(8))) { |
| if ((pred[i & 1] -= 0x80 << sh) < 0 || sh == 4) |
| pred[i & 1] &= ~(-1 << sh); |
| pred[i & 1] += j << sh; |
| } |
| } else if ((nonz[i & 1] = pana_bits(8)) || i > 11) |
| pred[i & 1] = nonz[i & 1] << 4 | pana_bits(4); |
| if (col < width) |
| if ((BAYER(row,col) = pred[col & 1]) > 4098) derror(); |
| } |
| } |
| |
| void CLASS olympus_e300_load_raw() |
| { |
| uchar *data, *dp; |
| ushort *pixel, *pix; |
| int dwide, row, col; |
| |
| dwide = raw_width * 16 / 10; |
| fseek (ifp, dwide*top_margin, SEEK_CUR); |
| data = (uchar *) malloc (dwide + raw_width*2); |
| merror (data, "olympus_e300_load_raw()"); |
| pixel = (ushort *) (data + dwide); |
| for (row=0; row < height; row++) { |
| if (fread (data, 1, dwide, ifp) < dwide) derror(); |
| for (dp=data, pix=pixel; pix < pixel+raw_width; dp+=3, pix+=2) { |
| if (((dp-data) & 15) == 15) |
| if (*dp++ && pix < pixel+width+left_margin) derror(); |
| pix[0] = dp[1] << 8 | dp[0]; |
| pix[1] = dp[2] << 4 | dp[1] >> 4; |
| } |
| for (col=0; col < width; col++) |
| BAYER(row,col) = (pixel[col+left_margin] & 0xfff); |
| } |
| free (data); |
| maximum >>= 4; |
| black >>= 4; |
| } |
| |
| void CLASS olympus_e410_load_raw() |
| { |
| int row, col, nbits, sign, low, high, i, w, n, nw; |
| int acarry[2][3], *carry, pred, diff; |
| |
| fseek (ifp, 7, SEEK_CUR); |
| getbits(-1); |
| for (row=0; row < height; row++) { |
| memset (acarry, 0, sizeof acarry); |
| for (col=0; col < width; col++) { |
| carry = acarry[col & 1]; |
| i = 2 * (carry[2] < 3); |
| for (nbits=2+i; (ushort) carry[0] >> (nbits+i); nbits++); |
| sign = getbits(1) * -1; |
| low = getbits(2); |
| for (high=0; high < 12; high++) |
| if (getbits(1)) break; |
| if (high == 12) |
| high = getbits(16-nbits) >> 1; |
| carry[0] = (high << nbits) | getbits(nbits); |
| diff = (carry[0] ^ sign) + carry[1]; |
| carry[1] = (diff*3 + carry[1]) >> 5; |
| carry[2] = carry[0] > 16 ? 0 : carry[2]+1; |
| if (row < 2 && col < 2) pred = 0; |
| else if (row < 2) pred = BAYER(row,col-2); |
| else if (col < 2) pred = BAYER(row-2,col); |
| else { |
| w = BAYER(row,col-2); |
| n = BAYER(row-2,col); |
| nw = BAYER(row-2,col-2); |
| if ((w < nw && nw < n) || (n < nw && nw < w)) { |
| if (ABS(w-nw) > 32 || ABS(n-nw) > 32) |
| pred = w + n - nw; |
| else pred = (w + n) >> 1; |
| } else pred = ABS(w-nw) > ABS(n-nw) ? w : n; |
| } |
| if ((BAYER(row,col) = pred + ((diff << 2) | low)) >> 12) derror(); |
| } |
| } |
| } |
| |
| void CLASS minolta_rd175_load_raw() |
| { |
| uchar pixel[768]; |
| unsigned irow, box, row, col; |
| |
| for (irow=0; irow < 1481; irow++) { |
| if (fread (pixel, 1, 768, ifp) < 768) derror(); |
| box = irow / 82; |
| row = irow % 82 * 12 + ((box < 12) ? box | 1 : (box-12)*2); |
| switch (irow) { |
| case 1477: case 1479: continue; |
| case 1476: row = 984; break; |
| case 1480: row = 985; break; |
| case 1478: row = 985; box = 1; |
| } |
| if ((box < 12) && (box & 1)) { |
| for (col=0; col < 1533; col++, row ^= 1) |
| if (col != 1) BAYER(row,col) = (col+1) & 2 ? |
| pixel[col/2-1] + pixel[col/2+1] : pixel[col/2] << 1; |
| BAYER(row,1) = pixel[1] << 1; |
| BAYER(row,1533) = pixel[765] << 1; |
| } else |
| for (col=row & 1; col < 1534; col+=2) |
| BAYER(row,col) = pixel[col/2] << 1; |
| } |
| maximum = 0xff << 1; |
| } |
| |
| void CLASS casio_qv5700_load_raw() |
| { |
| uchar data[3232], *dp; |
| ushort pixel[2576], *pix; |
| int row, col; |
| |
| for (row=0; row < height; row++) { |
| fread (data, 1, 3232, ifp); |
| for (dp=data, pix=pixel; dp < data+3220; dp+=5, pix+=4) { |
| pix[0] = (dp[0] << 2) + (dp[1] >> 6); |
| pix[1] = (dp[1] << 4) + (dp[2] >> 4); |
| pix[2] = (dp[2] << 6) + (dp[3] >> 2); |
| pix[3] = (dp[3] << 8) + (dp[4] ); |
| } |
| for (col=0; col < width; col++) |
| BAYER(row,col) = (pixel[col] & 0x3ff); |
| } |
| maximum = 0x3fc; |
| } |
| |
| void CLASS quicktake_100_load_raw() |
| { |
| uchar pixel[484][644]; |
| static const short gstep[16] = |
| { -89,-60,-44,-32,-22,-15,-8,-2,2,8,15,22,32,44,60,89 }; |
| static const short rstep[6][4] = |
| { { -3,-1,1,3 }, { -5,-1,1,5 }, { -8,-2,2,8 }, |
| { -13,-3,3,13 }, { -19,-4,4,19 }, { -28,-6,6,28 } }; |
| static const short curve[256] = |
| { 0,1,2,3,4,5,6,7,8,9,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27, |
| 28,29,30,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,53, |
| 54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,74,75,76,77,78, |
| 79,80,81,82,83,84,86,88,90,92,94,97,99,101,103,105,107,110,112,114,116, |
| 118,120,123,125,127,129,131,134,136,138,140,142,144,147,149,151,153,155, |
| 158,160,162,164,166,168,171,173,175,177,179,181,184,186,188,190,192,195, |
| 197,199,201,203,205,208,210,212,214,216,218,221,223,226,230,235,239,244, |
| 248,252,257,261,265,270,274,278,283,287,291,296,300,305,309,313,318,322, |
| 326,331,335,339,344,348,352,357,361,365,370,374,379,383,387,392,396,400, |
| 405,409,413,418,422,426,431,435,440,444,448,453,457,461,466,470,474,479, |
| 483,487,492,496,500,508,519,531,542,553,564,575,587,598,609,620,631,643, |
| 654,665,676,687,698,710,721,732,743,754,766,777,788,799,810,822,833,844, |
| 855,866,878,889,900,911,922,933,945,956,967,978,989,1001,1012,1023 }; |
| int rb, row, col, sharp, val=0; |
| |
| getbits(-1); |
| memset (pixel, 0x80, sizeof pixel); |
| for (row=2; row < height+2; row++) { |
| for (col=2+(row & 1); col < width+2; col+=2) { |
| val = ((pixel[row-1][col-1] + 2*pixel[row-1][col+1] + |
| pixel[row][col-2]) >> 2) + gstep[getbits(4)]; |
| pixel[row][col] = val = LIM(val,0,255); |
| if (col < 4) |
| pixel[row][col-2] = pixel[row+1][~row & 1] = val; |
| if (row == 2) |
| pixel[row-1][col+1] = pixel[row-1][col+3] = val; |
| } |
| pixel[row][col] = val; |
| } |
| for (rb=0; rb < 2; rb++) |
| for (row=2+rb; row < height+2; row+=2) |
| for (col=3-(row & 1); col < width+2; col+=2) { |
| if (row < 4 || col < 4) sharp = 2; |
| else { |
| val = ABS(pixel[row-2][col] - pixel[row][col-2]) |
| + ABS(pixel[row-2][col] - pixel[row-2][col-2]) |
| + ABS(pixel[row][col-2] - pixel[row-2][col-2]); |
| sharp = val < 4 ? 0 : val < 8 ? 1 : val < 16 ? 2 : |
| val < 32 ? 3 : val < 48 ? 4 : 5; |
| } |
| val = ((pixel[row-2][col] + pixel[row][col-2]) >> 1) |
| + rstep[sharp][getbits(2)]; |
| pixel[row][col] = val = LIM(val,0,255); |
| if (row < 4) pixel[row-2][col+2] = val; |
| if (col < 4) pixel[row+2][col-2] = val; |
| } |
| for (row=2; row < height+2; row++) |
| for (col=3-(row & 1); col < width+2; col+=2) { |
| val = ((pixel[row][col-1] + (pixel[row][col] << 2) + |
| pixel[row][col+1]) >> 1) - 0x100; |
| pixel[row][col] = LIM(val,0,255); |
| } |
| for (row=0; row < height; row++) |
| for (col=0; col < width; col++) |
| BAYER(row,col) = curve[pixel[row+2][col+2]]; |
| maximum = 0x3ff; |
| } |
| |
| const int * CLASS make_decoder_int (const int *source, int level) |
| { |
| struct decode *cur; |
| |
| cur = free_decode++; |
| if (level < source[0]) { |
| cur->branch[0] = free_decode; |
| source = make_decoder_int (source, level+1); |
| cur->branch[1] = free_decode; |
| source = make_decoder_int (source, level+1); |
| } else { |
| cur->leaf = source[1]; |
| source += 2; |
| } |
| return source; |
| } |
| |
| int CLASS radc_token (int tree) |
| { |
| int t; |
| static struct decode *dstart[18], *dindex; |
| static const int *s, source[] = { |
| 1,1, 2,3, 3,4, 4,2, 5,7, 6,5, 7,6, 7,8, |
| 1,0, 2,1, 3,3, 4,4, 5,2, 6,7, 7,6, 8,5, 8,8, |
| 2,1, 2,3, 3,0, 3,2, 3,4, 4,6, 5,5, 6,7, 6,8, |
| 2,0, 2,1, 2,3, 3,2, 4,4, 5,6, 6,7, 7,5, 7,8, |
| 2,1, 2,4, 3,0, 3,2, 3,3, 4,7, 5,5, 6,6, 6,8, |
| 2,3, 3,1, 3,2, 3,4, 3,5, 3,6, 4,7, 5,0, 5,8, |
| 2,3, 2,6, 3,0, 3,1, 4,4, 4,5, 4,7, 5,2, 5,8, |
| 2,4, 2,7, 3,3, 3,6, 4,1, 4,2, 4,5, 5,0, 5,8, |
| 2,6, 3,1, 3,3, 3,5, 3,7, 3,8, 4,0, 5,2, 5,4, |
| 2,0, 2,1, 3,2, 3,3, 4,4, 4,5, 5,6, 5,7, 4,8, |
| 1,0, 2,2, 2,-2, |
| 1,-3, 1,3, |
| 2,-17, 2,-5, 2,5, 2,17, |
| 2,-7, 2,2, 2,9, 2,18, |
| 2,-18, 2,-9, 2,-2, 2,7, |
| 2,-28, 2,28, 3,-49, 3,-9, 3,9, 4,49, 5,-79, 5,79, |
| 2,-1, 2,13, |