1 /*******************************************************************************
2 **
3 ** Photivo
4 **
5 ** Copyright (C) 2008,2009 Jos De Laender <jos.de_laender@telenet.be>
6 ** Copyright (C) 2009-2012 Michael Munzert <mail@mm-log.com>
7 ** Copyright (C) 2011 Bernd Schoeler <brjohn@brother-john.net>
8 **
9 ** This file is part of Photivo.
10 **
11 ** Photivo is free software: you can redistribute it and/or modify
12 ** it under the terms of the GNU General Public License version 3
13 ** as published by the Free Software Foundation.
14 **
15 ** Photivo is distributed in the hope that it will be useful,
16 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 ** GNU General Public License for more details.
19 **
20 ** You should have received a copy of the GNU General Public License
21 ** along with Photivo.  If not, see <http://www.gnu.org/licenses/>.
22 **
23 *******************************************************************************/
24 /*
25 ** This is basically the translation into a more or less C++ object of
26 ** dcraw.c -- Dave Coffin's raw photo decoder
27 ** Copyright 1997-2008 by Dave Coffin, dcoffin a cybercom o net
28 **
29 *******************************************************************************/
30 
31 #include "ptDcRaw.h"
32 
33 #include "ptDefines.h"
34 #include "ptError.h"
35 #include "ptConstants.h"
36 #include "ptCalloc.h"
37 
38 #include <cassert>
39 
40 #define NO_JASPER
41 #ifndef NO_JASPER
42 #include <jasper/jasper.h>
43 #endif
44 
45 // Macro fix for explicit fread returnvalue check.
46 #define ptfread(ptr,size,n,stream)              \
47 {                                               \
48 size_t RV = fread(ptr,size,n,stream);           \
49 if (RV != (size_t) n) assert(!ferror(stream));  \
50 }
51 #define ptfwrite(ptr,size,n,stream)    \
52 {                                      \
53 size_t RV = fwrite(ptr,size,n,stream); \
54 assert(RV == (size_t) n);              \
55 }
56 #define ptfscanf(file,format,arg)      \
57 {                                      \
58 int RV = fscanf(file,format,arg);      \
59 assert (RV == 1);                      \
60 }
61 #define ptfgets(str,num,file)   \
62 {                               \
63 char* RV = fgets(str,num,file); \
64 assert (RV);                    \
65 }
66 
VAppend(TImage8RawData & AVector,char * AArray,const int ALength)67 inline void VAppend(TImage8RawData &AVector, char* AArray, const int ALength) {
68   char* hEnd = AArray + ALength * sizeof(char);
69   AVector.insert(AVector.end(), AArray, hEnd);
70 }
71 
72 // The class.
73 #define CLASS ptDcRaw::
ptDcRaw()74 CLASS ptDcRaw() {
75   //printf("(%s,%d) '%s'\n",__FILE__,__LINE__,__PRETTY_FUNCTION__);
76 
77   // This were the original global variables initialized.
78   // Now moved into constructor.
79   // All m_UserSetting* are obviously ,uh, usersettings
80   // that were done via the command line parameters.
81   m_UserSetting_ShotSelect=0;
82   m_UserSetting_MaxMultiplier=0;
83   m_UserSetting_Multiplier[0]=0;
84   m_UserSetting_Multiplier[1]=0;
85   m_UserSetting_Multiplier[2]=0;
86   m_UserSetting_Multiplier[3]=0;
87   m_UserSetting_HalfSize=0;
88   m_UserSetting_HotpixelReduction=0;
89   m_UserSetting_BayerDenoise=0;
90   m_UserSetting_CfaLineDn=0;
91   m_UserSetting_GreenEquil=0;
92   m_UserSetting_CaCorrect=0;
93   m_UserSetting_CaRed=0;
94   m_UserSetting_CaBlue=0;
95   m_UserSetting_AutoWb=0;
96   m_UserSetting_CameraWb=0;
97   m_UserSetting_CameraMatrix=-1;
98   m_UserSetting_GreyBox[0] = 0;
99   m_UserSetting_GreyBox[1] = 0;
100   m_UserSetting_GreyBox[2] = 0xFFFF;
101   m_UserSetting_GreyBox[3] = 0xFFFF;
102   m_UserSetting_photivo_ClipMode = ptClipMode_Clip;
103   m_UserSetting_photivo_ClipParameter = 0;
104   m_UserSetting_Quality = 3;
105   m_UserSetting_BlackPoint = -1;
106   m_UserSetting_Saturation = -1;
107   m_UserSetting_InputFileName       = NULL;
108   m_UserSetting_DetailView          = 0;
109   m_UserSetting_DetailViewCropX     = 0;
110   m_UserSetting_DetailViewCropY     = 0;
111   m_UserSetting_DetailViewCropW     = 0;
112   m_UserSetting_DetailViewCropH     = 0;
113   m_UserSetting_BadPixelsFileName   = NULL;
114   m_UserSetting_DarkFrameFileName   = NULL;
115   m_UserSetting_AdjustMaximum       = 0;
116   m_UserSetting_DenoiseThreshold    = 0;
117   m_UserSetting_InterpolationPasses = 0;
118   m_UserSetting_MedianPasses        = 0;
119   m_UserSetting_ESMedianPasses      = 0;
120 
121 
122   // Safety settings to have NULL on uninitialized images.
123   m_Image = NULL;
124   m_Image_AfterPhase1 = NULL;
125   m_Image_AfterPhase2 = NULL;
126   m_Image_AfterPhase3 = NULL;
127   m_Image_AfterPhase4 = NULL;
128 
129   // Some other pointers that are in a dynamic environment better NULL.
130   m_MetaData    = NULL;
131   m_InputFile   = NULL;
132 
133   m_Thumb.clear();
134   ResetNonUserSettings();
135 }
136 
137 ////////////////////////////////////////////////////////////////////////////////
138 //
139 // Destructor
140 // Deallocate everything dynamic.
141 //
142 ////////////////////////////////////////////////////////////////////////////////
143 
~ptDcRaw()144 CLASS ~ptDcRaw() {
145 
146 //printf("(%s,%d) '%s'\n",__FILE__,__LINE__,__PRETTY_FUNCTION__);
147 
148   FREE(m_UserSetting_InputFileName);
149   FREE(m_UserSetting_BadPixelsFileName);
150   FREE(m_UserSetting_DarkFrameFileName);
151   FREE(m_Image);
152   FREE(m_Image_AfterPhase1);
153   FREE(m_Image_AfterPhase2);
154   FREE(m_Image_AfterPhase3);
155   FCLOSE(m_InputFile);
156   FREE(m_MetaData);
157 }
158 
159 ////////////////////////////////////////////////////////////////////////////////
160 //
161 // ResetNonUserSettings
162 // Reset all variables except user settings.
163 // This is for second entry support.
164 //
165 ////////////////////////////////////////////////////////////////////////////////
166 
ResetNonUserSettings()167 void CLASS ResetNonUserSettings() {
168   // Safety settings to have NULL on uninitialized images.
169   // And freeing the underlying memory (which was long time a leak !)
170   // FREE(NULL) is safe, so the beginsituation is fine too.
171   // FREE implies setting of the pointer to NULL
172   FREE(m_Image);
173   FREE(m_Image_AfterPhase1);
174   FREE(m_Image_AfterPhase2);
175   FREE(m_Image_AfterPhase3);
176   FREE(m_Image_AfterPhase4);
177 
178   // Some other pointers that are in a dynamic environment better NULL.
179   // Same remarks as above.
180   FREE(m_MetaData);
181   FCLOSE(m_InputFile);
182 
183   // This was originally in the identify code, but which is called
184   // anyway in the beginning. So this is simply global initialization like
185   // anything else.
186 
187   m_Tiff_Flip = m_Flip = -1; /* 0 is valid, so -1 is unknown */
188   m_Filters = (unsigned)(-1); // hack not to change dcraw.
189   m_RawHeight = m_RawWidth = m_Fuji_Width = m_IsFuji = fuji_layout = cr2_slice[0] = 0;
190   m_WhiteLevel = m_Height = m_Width = m_TopMargin = m_LeftMargin = 0;
191   m_ColorDescriptor[0] = m_Description[0] = m_Artist[0] = m_CameraMake[0] = m_CameraModel[0] = m_CameraModelBis[0] = 0;
192   m_IsoSpeed = m_Shutter = m_Aperture = m_FocalLength = unique_id = 0;
193   m_Tiff_NrIFDs = 0;
194   memset (m_Tiff_IFD, 0, sizeof m_Tiff_IFD);
195   memset (white, 0, sizeof white);
196   m_ThumbOffset = m_ThumbLength = m_ThumbWidth = m_ThumbHeight = 0;
197   m_LoadRawFunction = m_ThumbLoadRawFunction = 0;
198   m_WriteThumb = &CLASS jpeg_thumb;
199   m_Data_Offset = m_MetaLength = m_Tiff_bps = m_Tiff_Compress = 0;
200   m_Kodak_cbpp = zero_after_ff = m_DNG_Version = m_Load_Flags = 0;
201   m_TimeStamp = m_ShotOrder = m_Tiff_Samples = m_BlackLevel = m_IsFoveon = 0;
202   for (int k=0; k<8; k++) m_CBlackLevel[k] = 0;
203   m_MixGreen = m_ProfileLength = data_error = m_ZeroIsBad = 0;
204   m_PixelAspect = m_IsRaw = m_RawColor = 1; m_RawColorPhotivo = 0;
205   m_TileWidth = m_TileLength = 0;
206   m_Raw_Image = 0;
207   memset (m_Mask, 0, sizeof m_Mask);
208   for (int i=0; i < 4; i++) {
209     short c;
210     ASSIGN(m_CameraMultipliers[i], i == 1);
211     ASSIGN(m_PreMultipliers[i], i < 3);
212     ASSIGN(m_D65Multipliers[i], i < 3);
213     for (c=0; c<3; c++) m_cmatrix[c][i] = 0;
214     for (c=0; c<3; c++) m_MatrixCamRGBToSRGB[c][i] = c == i;
215   }
216   m_Colors = 3;
217   for (int i=0; i < 0x10000; i++) m_Curve[i] = i;
218 
219   m_Gamma[0] = 0.45;
220   m_Gamma[1] = 4.50;
221   m_Gamma[2] = 0;
222   m_Gamma[3] = 0;
223   m_Gamma[4] = 0;
224   m_Gamma[5] = 0;
225 
226   m_getbithuff_bitbuf=0;
227   m_getbithuff_reset=0;
228   m_getbithuff_vbits=0;
229   m_ph1_bithuffbitbuf=0;
230   m_ph1_bithuffvbits=0;
231   for (int i = 0; i < 0x4000; i++) m_pana_bits_buf[i] = 0;
232   m_pana_bits_vbits = 0;
233   for (int i = 0; i < 4096; i++) jpeg_buffer[i] = 0;
234   for (int i = 0; i < 128; i++) m_sony_decrypt_pad[i] = 0;
235   m_sony_decrypt_p = 0;
236   for (int i = 0; i < 1024; i++) m_foveon_decoder_huff[i] = 0;
237 
238   for (int i = 0; i < 4; i++) {
239     for (int j = 0; j < 3; j++) {
240       MatrixXYZToCam[i][j] = 0.0;
241     }
242   }
243 
244   ToCamFunctionInited = 0;
245   for (int i = 0; i < 0x20000; i++) ToLABFunctionTable[i] = 0.0;
246   ToLABFunctionInited = 0;
247 
248   for (int i = 0; i < 3; i++) {
249     for (int j = 0; j < 4; j++) {
250       MatrixCamToXYZ[i][j] = 0.0;
251     }
252   }
253 
254 }
255 
256 /*
257    In order to inline this calculation, I make the risky
258    assumption that all filter patterns can be described
259    by a repeating pattern of eight rows and two columns
260 
261    Do not use the FC or BAYER macros with the Leaf CatchLight,
262    because its pattern is 16x16, not 2x8.
263 
264    Return values are either 0/1/2/3 = G/M/C/Y or 0/1/2/3 = R/G1/B/G2
265 
266   PowerShot 600 PowerShot A50 PowerShot Pro70 Pro90 & G1
267   0xe1e4e1e4: 0x1b4e4b1e: 0x1e4b4e1b: 0xb4b4b4b4:
268 
269     0 1 2 3 4 5   0 1 2 3 4 5   0 1 2 3 4 5   0 1 2 3 4 5
270   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
271   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
272   2 M G M G M G 2 Y C Y C Y C 2 C Y C Y C Y
273   3 C Y C Y C Y 3 G M G M G M 3 G M G M G M
274       4 C Y C Y C Y 4 Y C Y C Y C
275   PowerShot A5  5 G M G M G M 5 G M G M G M
276   0x1e4e1e4e: 6 Y C Y C Y C 6 C Y C Y C Y
277       7 M G M G M G 7 M G M G M G
278     0 1 2 3 4 5
279   0 C Y C Y C Y
280   1 G M G M G M
281   2 C Y C Y C Y
282   3 M G M G M G
283 
284    All RGB cameras use one of these Bayer grids:
285 
286   0x16161616: 0x61616161: 0x49494949: 0x94949494:
287 
288     0 1 2 3 4 5   0 1 2 3 4 5   0 1 2 3 4 5   0 1 2 3 4 5
289   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
290   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
291   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
292   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
293  */
294 
295 #define RAW(row,col) \
296   m_Raw_Image[(row)*m_RawWidth+(col)]
297 
298 #define FC(row,col) \
299   (m_Filters >> ((((row) << 1 & 14) + ((col) & 1)) << 1) & 3)
300 
301 #define BAYER(row,col) \
302   m_Image[(row)*m_Width + (col)][FC(row,col)]
303   // old: m_Image[((row) >> m_Shrink)*m_OutWidth + ((col) >> m_Shrink)][FC(row,col)]
304 
305 #define BAYER2(row,col) \
306   m_Image[(row)*m_Width + (col)][fcol(row,col)]
307 
fcol(int row,int col)308 int CLASS fcol (int row, int col)
309 {
310   static const char filter[16][16] =
311   { { 2,1,1,3,2,3,2,0,3,2,3,0,1,2,1,0 },
312     { 0,3,0,2,0,1,3,1,0,1,1,2,0,3,3,2 },
313     { 2,3,3,2,3,1,1,3,3,1,2,1,2,0,0,3 },
314     { 0,1,0,1,0,2,0,2,2,0,3,0,1,3,2,1 },
315     { 3,1,1,2,0,1,0,2,1,3,1,3,0,1,3,0 },
316     { 2,0,0,3,3,2,3,1,2,0,2,0,3,2,2,1 },
317     { 2,3,3,1,2,1,2,1,2,1,1,2,3,0,0,1 },
318     { 1,0,0,2,3,0,0,3,0,3,0,3,2,1,2,3 },
319     { 2,3,3,1,1,2,1,0,3,2,3,0,2,3,1,3 },
320     { 1,0,2,0,3,0,3,2,0,1,1,2,0,1,0,2 },
321     { 0,1,1,3,3,2,2,1,1,3,3,0,2,1,3,2 },
322     { 2,3,2,0,0,1,3,0,2,0,1,2,3,0,1,0 },
323     { 1,3,1,2,3,2,3,2,0,2,0,1,1,0,3,0 },
324     { 0,2,0,3,1,0,0,1,1,3,3,2,3,2,2,1 },
325     { 2,1,3,2,3,1,2,1,0,3,0,2,0,2,0,2 },
326     { 0,3,1,0,0,2,0,3,2,1,3,1,1,3,1,3 } };
327   static const char filter2[6][6] =
328   { { 1,1,0,1,1,2 },
329     { 1,1,2,1,1,0 },
330     { 2,0,1,0,2,1 },
331     { 1,1,2,1,1,0 },
332     { 1,1,0,1,1,2 },
333     { 0,2,1,2,0,1 } };
334 
335   if (m_Filters == 1) return filter[(row+m_TopMargin)&15][(col+m_LeftMargin)&15];
336   if (m_Filters == 2) return filter2[(row+6) % 6][(col+6) % 6];
337   return FC(row,col);
338 }
339 
340 #ifndef __GLIBC__
my_memmem(char * haystack,size_t haystacklen,char * neepte,size_t neeptelen)341 char* CLASS my_memmem (char *haystack, size_t haystacklen,
342         char *neepte, size_t neeptelen)
343 {
344   char *c;
345   for (c = haystack; c <= haystack + haystacklen - neeptelen; c++)
346     if (!memcmp (c, neepte, neeptelen))
347       return c;
348   return 0;
349 }
350 #define memmem my_memmem
351 #endif
352 
353 float rgb_cam[3][4];
354 const double xyz_rgb[3][3] = {      /* XYZ from RGB */
355   { 0.412453, 0.357580, 0.180423 },
356   { 0.212671, 0.715160, 0.072169 },
357   { 0.019334, 0.119193, 0.950227 } };
358 const float d65_white[3] = { 0.950456, 1, 1.088754 };
359 
360 // Now everything importent is set up, so we can include external demosaicers
361 #include "dcb/dcb_demosaicing.c"
362 #include "dcb/dcb_demosaicing_old.c"
363 #include "vcd/ahd_interpolate_mod.c"
364 #include "vcd/ahd_partial_interpolate.c"
365 #include "vcd/refinement.c"
366 #include "vcd/vcd_interpolate.c"
367 #include "vcd/es_median_filter.c"
368 #include "vcd/median_filter_new.c"
369 #include "perfectraw/lmmse_interpolate.c"
370 #include "rawtherapee/amaze_interpolate.c"
371 #include "rawtherapee/cfa_line_dn.c"
372 #include "rawtherapee/ca_correct.c"
373 #include "rawtherapee/green_equil.c"
374 
merror(void * ptr,const char * where)375 void CLASS merror (void *ptr, const char *where)
376 {
377   if (ptr) return;
378   fprintf (stderr,_("%s: Out of memory in %s\n"), m_UserSetting_InputFileName, where);
379   longjmp (m_Failure, 1);
380 }
381 
derror()382 void CLASS derror()
383 {
384   if (!data_error) {
385     fprintf (stderr, "%s: ", m_UserSetting_InputFileName);
386     if (feof(m_InputFile))
387       fprintf (stderr,_("Unexpected end of file\n"));
388     else
389       //fprintf (stderr,_("Corrupt data near 0x%lx\n"), (int64_t) ftell(m_InputFile));
390       fprintf (stderr,_("Corrupt data near 0x%lx\n"), (long unsigned int) ftell(m_InputFile));
391   }
392   data_error++;
393 }
394 
sget2(uint8_t * s)395 uint16_t CLASS sget2 (uint8_t *s)
396 {
397   if (m_ByteOrder == 0x4949)    /* "II" means little-endian */
398     return s[0] | s[1] << 8;
399   else        /* "MM" means big-endian */
400     return s[0] << 8 | s[1];
401 }
402 
get2()403 uint16_t CLASS get2()
404 {
405   uint8_t str[2] = { 0xff,0xff };
406   ptfread (str, 1, 2, m_InputFile);
407   return sget2(str);
408 }
409 
sget4(uint8_t * s)410 unsigned CLASS sget4 (uint8_t *s)
411 {
412   if (m_ByteOrder == 0x4949)
413     return s[0] | s[1] << 8 | s[2] << 16 | s[3] << 24;
414   else
415     return s[0] << 24 | s[1] << 16 | s[2] << 8 | s[3];
416 }
417 #define sget4(s) sget4((uint8_t *)s)
418 
get4()419 unsigned CLASS get4()
420 {
421   uint8_t str[4] = { 0xff,0xff,0xff,0xff };
422   ptfread (str, 1, 4, m_InputFile);
423   return sget4(str);
424 }
425 
getint(int type)426 unsigned CLASS getint (int type)
427 {
428   return type == 3 ? get2() : get4();
429 }
430 
int_to_float(int i)431 float CLASS int_to_float (int i)
432 {
433   union { int i; float f; } u;
434   u.i = i;
435   return u.f;
436 }
437 
getreal(int type)438 double CLASS getreal (int type)
439 {
440   union { char c[8]; double d; } u;
441   int i, rev;
442 
443   switch (type) {
444     case 3: return (unsigned short) get2();
445     case 4: return (unsigned int) get4();
446     case 5:  u.d = (unsigned int) get4();
447       return u.d / (unsigned int) get4();
448     case 8: return (signed short) get2();
449     case 9: return (signed int) get4();
450     case 10: u.d = (signed int) get4();
451       return u.d / (signed int) get4();
452     case 11: return int_to_float (get4());
453     case 12:
454       rev = 7 * ((m_ByteOrder == 0x4949) == (ntohs(0x1234) == 0x1234));
455       for (i=0; i < 8; i++)
456   u.c[i ^ rev] = fgetc(m_InputFile);
457       return u.d;
458     default: return fgetc(m_InputFile);
459   }
460 }
461 
read_shorts(uint16_t * pixel,int count)462 void CLASS read_shorts (uint16_t *pixel, int count)
463 {
464   if (fread (pixel, 2, count, m_InputFile) < (size_t) count) derror();
465   if ((m_ByteOrder == 0x4949) == (ntohs(0x1234) == 0x1234))
466     swab ((char *)pixel, (char *)pixel, count*2);
467 }
468 
469 /* -> 1438
470 void CLASS canon_black (double dark[2], int nblack)
471 {
472   int c, diff, row, col;
473 
474   if (!nblack) return;
475   for (c=0; c<2; c++) dark[c] /= nblack >> 1;
476   if ((diff = (int)(dark[0] - dark[1])))
477     for (row=0; row < m_Height; row++)
478       for (col=1; col < m_Width; col+=2)
479   BAYER(row,col) += diff;
480   dark[1] += diff;
481   m_BlackLevel = (unsigned)((dark[0] + dark[1] + 1) / 2);
482 }
483 */
484 
canon_600_fixed_wb(int temp)485 void CLASS canon_600_fixed_wb (int temp)
486 {
487   static const short mul[4][5] = {
488     {  667, 358,397,565,452 },
489     {  731, 390,367,499,517 },
490     { 1119, 396,348,448,537 },
491     { 1399, 485,431,508,688 } };
492   int lo, hi, i;
493   float frac=0;
494 
495   for (lo=4; --lo; )
496     if (*mul[lo] <= temp) break;
497   for (hi=0; hi < 3; hi++)
498     if (*mul[hi] >= temp) break;
499   if (lo != hi)
500     frac = (float) (temp - *mul[lo]) / (*mul[hi] - *mul[lo]);
501   for (i=1; i < 5; i++)
502     ASSIGN(m_D65Multipliers[i-1],1/(frac * mul[hi][i] + (1-frac) * mul[lo][i]));
503 }
504 
505 /* Return values:  0 = white  1 = near white  2 = not white */
canon_600_color(int ratio[2],int mar)506 int CLASS canon_600_color (int ratio[2], int mar)
507 {
508   int clipped=0, target, miss;
509 
510   if (flash_used) {
511     if (ratio[1] < -104)
512       { ratio[1] = -104; clipped = 1; }
513     if (ratio[1] >   12)
514       { ratio[1] =   12; clipped = 1; }
515   } else {
516     if (ratio[1] < -264 || ratio[1] > 461) return 2;
517     if (ratio[1] < -50)
518       { ratio[1] = -50; clipped = 1; }
519     if (ratio[1] > 307)
520       { ratio[1] = 307; clipped = 1; }
521   }
522   target = flash_used || ratio[1] < 197
523   ? -38 - (398 * ratio[1] >> 10)
524   : -123 + (48 * ratio[1] >> 10);
525   if (target - mar <= ratio[0] &&
526       target + 20  >= ratio[0] && !clipped) return 0;
527   miss = target - ratio[0];
528   if (abs(miss) >= mar*4) return 2;
529   if (miss < -20) miss = -20;
530   if (miss > mar) miss = mar;
531   ratio[0] = target - miss;
532   return 1;
533 }
534 
canon_600_auto_wb()535 void CLASS canon_600_auto_wb()
536 {
537   int mar, row, col, i, j, st, count[] = { 0,0 };
538   int test[8], total[2][8], ratio[2][2], stat[2];
539 
540   memset (&total, 0, sizeof total);
541   i = int ( canon_ev + 0.5 );
542   if      (i < 10) mar = 150;
543   else if (i > 12) mar = 20;
544   else mar = 280 - 20 * i;
545   if (flash_used) mar = 80;
546   for (row=14; row < m_Height-14; row+=4)
547     for (col=10; col < m_Width; col+=2) {
548       for (i=0; i < 8; i++)
549   test[(i & 4) + FC(row+(i >> 1),col+(i & 1))] =
550         BAYER(row+(i >> 1),col+(i & 1));
551       for (i=0; i < 8; i++)
552   if (test[i] < 150 || test[i] > 1500) goto next;
553       for (i=0; i < 4; i++)
554   if (abs(test[i] - test[i+4]) > 50) goto next;
555       for (i=0; i < 2; i++) {
556   for (j=0; j < 4; j+=2)
557     ratio[i][j >> 1] = ((test[i*4+j+1]-test[i*4+j]) << 10) / test[i*4+j];
558   stat[i] = canon_600_color (ratio[i], mar);
559       }
560       if ((st = stat[0] | stat[1]) > 1) goto next;
561       for (i=0; i < 2; i++)
562   if (stat[i])
563     for (j=0; j < 2; j++)
564       test[i*4+j*2+1] = test[i*4+j*2] * (0x400 + ratio[i][j]) >> 10;
565       for (i=0; i < 8; i++)
566   total[st][i] += test[i];
567       count[st]++;
568 next: ;
569     }
570   if (count[0] | count[1]) {
571     st = count[0]*200 < count[1];
572     for (i=0; i < 4; i++)
573       ASSIGN(m_D65Multipliers[i], 1.0 / (total[st][i] + total[st][i+4]));
574   }
575 }
576 
canon_600_coeff()577 void CLASS canon_600_coeff()
578 {
579   static const short table[6][12] = {
580     { -190,702,-1878,2390,   1861,-1349,905,-393, -432,944,2617,-2105  },
581     { -1203,1715,-1136,1648, 1388,-876,267,245,  -1641,2153,3921,-3409 },
582     { -615,1127,-1563,2075,  1437,-925,509,3,     -756,1268,2519,-2007 },
583     { -190,702,-1886,2398,   2153,-1641,763,-251, -452,964,3040,-2528  },
584     { -190,702,-1878,2390,   1861,-1349,905,-393, -432,944,2617,-2105  },
585     { -807,1319,-1785,2297,  1388,-876,769,-257,  -230,742,2067,-1555  } };
586   int t=0, i, c;
587   float mc, yc;
588 
589   mc = VALUE(m_D65Multipliers[1]) / VALUE(m_D65Multipliers[2]);
590   yc = VALUE(m_D65Multipliers[3]) / VALUE(m_D65Multipliers[2]);
591   if (mc > 1 && mc <= 1.28 && yc < 0.8789) t=1;
592   if (mc > 1.28 && mc <= 2) {
593     if  (yc < 0.8789) t=3;
594     else if (yc <= 2) t=4;
595   }
596   if (flash_used) t=5;
597   for (m_RawColor = i=0; i < 3; i++)
598     for (c=0; c < m_Colors; c++)
599       m_MatrixCamRGBToSRGB[i][c] = table[t][i*4 + c] / 1024.0;
600 }
601 
canon_600_load_raw()602 void CLASS canon_600_load_raw()
603 {
604   uint8_t  data[1120], *dp;
605   uint16_t *pix;
606   int irow, row;
607 
608   for (irow=row=0; irow < m_Height; irow++) {
609     if (fread (data, 1, 1120, m_InputFile) < 1120) derror();
610     pix = m_Raw_Image + row*m_RawWidth;
611     for (dp=data; dp < data+1120;  dp+=10, pix+=8) {
612       pix[0] = (dp[0] << 2) + (dp[1] >> 6    );
613       pix[1] = (dp[2] << 2) + (dp[1] >> 4 & 3);
614       pix[2] = (dp[3] << 2) + (dp[1] >> 2 & 3);
615       pix[3] = (dp[4] << 2) + (dp[1]      & 3);
616       pix[4] = (dp[5] << 2) + (dp[9]      & 3);
617       pix[5] = (dp[6] << 2) + (dp[9] >> 2 & 3);
618       pix[6] = (dp[7] << 2) + (dp[9] >> 4 & 3);
619       pix[7] = (dp[8] << 2) + (dp[9] >> 6    );
620     }
621     if ((row+=2) > m_Height) row = 1;
622   }
623 }
624 
canon_600_correct()625 void CLASS canon_600_correct()
626 {
627   int row, col, val;
628   static const short mul[4][2] =
629   { { 1141,1145 }, { 1128,1109 }, { 1178,1149 }, { 1128,1109 } };
630 
631   for (row=0; row < m_Height; row++)
632     for (col=0; col < m_Width; col++) {
633       if ((val = BAYER(row,col) - m_BlackLevel) < 0) val = 0;
634       val = val * mul[row & 3][col & 1] >> 9;
635       BAYER(row,col) = val;
636     }
637   canon_600_fixed_wb(1311);
638   canon_600_auto_wb();
639   canon_600_coeff();
640   m_WhiteLevel = (0x3ff - m_BlackLevel) * 1109 >> 9;
641   m_BlackLevel = 0;
642 }
643 
canon_s2is()644 int CLASS canon_s2is()
645 {
646   unsigned row;
647 
648   for (row=0; row < 100; row++) {
649     fseek (m_InputFile, row*3340 + 3284, SEEK_SET);
650     if (getc(m_InputFile) > 15) return 1;
651   }
652   return 0;
653 }
654 
655 /*
656    getbits(-1) initializes the buffer
657    getbits(n) where 0 <= n <= 25 returns an n-bit integer
658  */
getbithuff(int nbits,uint16_t * huff)659 unsigned CLASS getbithuff(int nbits,uint16_t *huff)
660 {
661   // unsigned c;
662   int c;
663 
664   if (nbits == -1)
665     return m_getbithuff_bitbuf = m_getbithuff_vbits = m_getbithuff_reset = 0;
666   if (nbits == 0 || m_getbithuff_vbits < 0) return 0;
667   while (!m_getbithuff_reset && m_getbithuff_vbits < nbits && (c = fgetc(m_InputFile)) != EOF &&
668     !(m_getbithuff_reset = zero_after_ff && c == 0xff && fgetc(m_InputFile))) {
669     m_getbithuff_bitbuf = (m_getbithuff_bitbuf << 8) + (uint8_t) c;
670     m_getbithuff_vbits += 8;
671   }
672   c = m_getbithuff_bitbuf << (32-m_getbithuff_vbits) >> (32-nbits);
673   if (huff) {
674     m_getbithuff_vbits -= huff[c] >> 8;
675     c = (uint8_t) huff[c];
676   } else
677     m_getbithuff_vbits -= nbits;
678   if (m_getbithuff_vbits < 0) derror();
679   return c;
680 }
681 
682 #define getbits(n) getbithuff(n,0)
683 #define gethuff(h) getbithuff(*h,h+1)
684 
685 /*
686    Construct a decode tree according the specification in *source.
687    The first 16 bytes specify how many codes should be 1-bit, 2-bit
688    3-bit, etc.  Bytes after that are the leaf values.
689 
690    For example, if the source is
691 
692     { 0,1,4,2,3,1,2,0,0,0,0,0,0,0,0,0,
693       0x04,0x03,0x05,0x06,0x02,0x07,0x01,0x08,0x09,0x00,0x0a,0x0b,0xff  },
694 
695    then the code is
696 
697   00    0x04
698   010   0x03
699   011   0x05
700   100   0x06
701   101   0x02
702   1100    0x07
703   1101    0x01
704   11100   0x08
705   11101   0x09
706   11110   0x00
707   111110    0x0a
708   1111110   0x0b
709   1111111   0xff
710  */
make_decoder_ref(const uint8_t ** source)711 uint16_t * CLASS make_decoder_ref (const uint8_t **source)
712 {
713   int max, len, h, i, j;
714   const uint8_t *count;
715   uint16_t *huff;
716 
717   count = (*source += 16) - 17;
718   for (max=16; max && !count[max]; max--) {} ;
719   huff = (uint16_t *) CALLOC (1 + (1 << max), sizeof *huff);
720   merror (huff, "make_decoder()");
721   huff[0] = max;
722   for (h=len=1; len <= max; len++)
723     for (i=0; i < count[len]; i++, ++*source)
724       for (j=0; j < 1 << (max-len); j++)
725   if (h <= 1 << max)
726     huff[h++] = len << 8 | **source;
727   return huff;
728 }
729 
730 
make_decoder(const uint8_t * source)731 uint16_t * CLASS make_decoder (const uint8_t *source)
732 {
733   return make_decoder_ref (&source);
734 }
735 
crw_init_tables(unsigned table,uint16_t * huff[2])736 void CLASS crw_init_tables (unsigned table, uint16_t *huff[2])
737 {
738   static const uint8_t first_tree[3][29] = {
739     { 0,1,4,2,3,1,2,0,0,0,0,0,0,0,0,0,
740       0x04,0x03,0x05,0x06,0x02,0x07,0x01,0x08,0x09,0x00,0x0a,0x0b,0xff  },
741     { 0,2,2,3,1,1,1,1,2,0,0,0,0,0,0,0,
742       0x03,0x02,0x04,0x01,0x05,0x00,0x06,0x07,0x09,0x08,0x0a,0x0b,0xff  },
743     { 0,0,6,3,1,1,2,0,0,0,0,0,0,0,0,0,
744       0x06,0x05,0x07,0x04,0x08,0x03,0x09,0x02,0x00,0x0a,0x01,0x0b,0xff  },
745   };
746   static const uint8_t second_tree[3][180] = {
747     { 0,2,2,2,1,4,2,1,2,5,1,1,0,0,0,139,
748       0x03,0x04,0x02,0x05,0x01,0x06,0x07,0x08,
749       0x12,0x13,0x11,0x14,0x09,0x15,0x22,0x00,0x21,0x16,0x0a,0xf0,
750       0x23,0x17,0x24,0x31,0x32,0x18,0x19,0x33,0x25,0x41,0x34,0x42,
751       0x35,0x51,0x36,0x37,0x38,0x29,0x79,0x26,0x1a,0x39,0x56,0x57,
752       0x28,0x27,0x52,0x55,0x58,0x43,0x76,0x59,0x77,0x54,0x61,0xf9,
753       0x71,0x78,0x75,0x96,0x97,0x49,0xb7,0x53,0xd7,0x74,0xb6,0x98,
754       0x47,0x48,0x95,0x69,0x99,0x91,0xfa,0xb8,0x68,0xb5,0xb9,0xd6,
755       0xf7,0xd8,0x67,0x46,0x45,0x94,0x89,0xf8,0x81,0xd5,0xf6,0xb4,
756       0x88,0xb1,0x2a,0x44,0x72,0xd9,0x87,0x66,0xd4,0xf5,0x3a,0xa7,
757       0x73,0xa9,0xa8,0x86,0x62,0xc7,0x65,0xc8,0xc9,0xa1,0xf4,0xd1,
758       0xe9,0x5a,0x92,0x85,0xa6,0xe7,0x93,0xe8,0xc1,0xc6,0x7a,0x64,
759       0xe1,0x4a,0x6a,0xe6,0xb3,0xf1,0xd3,0xa5,0x8a,0xb2,0x9a,0xba,
760       0x84,0xa4,0x63,0xe5,0xc5,0xf3,0xd2,0xc4,0x82,0xaa,0xda,0xe4,
761       0xf2,0xca,0x83,0xa3,0xa2,0xc3,0xea,0xc2,0xe2,0xe3,0xff,0xff  },
762     { 0,2,2,1,4,1,4,1,3,3,1,0,0,0,0,140,
763       0x02,0x03,0x01,0x04,0x05,0x12,0x11,0x06,
764       0x13,0x07,0x08,0x14,0x22,0x09,0x21,0x00,0x23,0x15,0x31,0x32,
765       0x0a,0x16,0xf0,0x24,0x33,0x41,0x42,0x19,0x17,0x25,0x18,0x51,
766       0x34,0x43,0x52,0x29,0x35,0x61,0x39,0x71,0x62,0x36,0x53,0x26,
767       0x38,0x1a,0x37,0x81,0x27,0x91,0x79,0x55,0x45,0x28,0x72,0x59,
768       0xa1,0xb1,0x44,0x69,0x54,0x58,0xd1,0xfa,0x57,0xe1,0xf1,0xb9,
769       0x49,0x47,0x63,0x6a,0xf9,0x56,0x46,0xa8,0x2a,0x4a,0x78,0x99,
770       0x3a,0x75,0x74,0x86,0x65,0xc1,0x76,0xb6,0x96,0xd6,0x89,0x85,
771       0xc9,0xf5,0x95,0xb4,0xc7,0xf7,0x8a,0x97,0xb8,0x73,0xb7,0xd8,
772       0xd9,0x87,0xa7,0x7a,0x48,0x82,0x84,0xea,0xf4,0xa6,0xc5,0x5a,
773       0x94,0xa4,0xc6,0x92,0xc3,0x68,0xb5,0xc8,0xe4,0xe5,0xe6,0xe9,
774       0xa2,0xa3,0xe3,0xc2,0x66,0x67,0x93,0xaa,0xd4,0xd5,0xe7,0xf8,
775       0x88,0x9a,0xd7,0x77,0xc4,0x64,0xe2,0x98,0xa5,0xca,0xda,0xe8,
776       0xf3,0xf6,0xa9,0xb2,0xb3,0xf2,0xd2,0x83,0xba,0xd3,0xff,0xff  },
777     { 0,0,6,2,1,3,3,2,5,1,2,2,8,10,0,117,
778       0x04,0x05,0x03,0x06,0x02,0x07,0x01,0x08,
779       0x09,0x12,0x13,0x14,0x11,0x15,0x0a,0x16,0x17,0xf0,0x00,0x22,
780       0x21,0x18,0x23,0x19,0x24,0x32,0x31,0x25,0x33,0x38,0x37,0x34,
781       0x35,0x36,0x39,0x79,0x57,0x58,0x59,0x28,0x56,0x78,0x27,0x41,
782       0x29,0x77,0x26,0x42,0x76,0x99,0x1a,0x55,0x98,0x97,0xf9,0x48,
783       0x54,0x96,0x89,0x47,0xb7,0x49,0xfa,0x75,0x68,0xb6,0x67,0x69,
784       0xb9,0xb8,0xd8,0x52,0xd7,0x88,0xb5,0x74,0x51,0x46,0xd9,0xf8,
785       0x3a,0xd6,0x87,0x45,0x7a,0x95,0xd5,0xf6,0x86,0xb4,0xa9,0x94,
786       0x53,0x2a,0xa8,0x43,0xf5,0xf7,0xd4,0x66,0xa7,0x5a,0x44,0x8a,
787       0xc9,0xe8,0xc8,0xe7,0x9a,0x6a,0x73,0x4a,0x61,0xc7,0xf4,0xc6,
788       0x65,0xe9,0x72,0xe6,0x71,0x91,0x93,0xa6,0xda,0x92,0x85,0x62,
789       0xf3,0xc5,0xb2,0xa4,0x84,0xba,0x64,0xa5,0xb3,0xd2,0x81,0xe5,
790       0xd3,0xaa,0xc4,0xca,0xf2,0xb1,0xe4,0xd1,0x83,0x63,0xea,0xc3,
791       0xe2,0x82,0xf1,0xa3,0xc2,0xa1,0xc1,0xe3,0xa2,0xe1,0xff,0xff  }
792   };
793   if (table > 2) table = 2;
794   huff[0] = make_decoder ( first_tree[table]);
795   huff[1] = make_decoder (second_tree[table]);
796 }
797 
798 /*
799    Return 0 if the image starts with compressed data,
800    1 if it starts with uncompressed low-order bits.
801 
802    In Canon compressed data, 0xff is always followed by 0x00.
803  */
canon_has_lowbits()804 int CLASS canon_has_lowbits()
805 {
806   uint8_t test[0x4000];
807   int ret=1, i;
808 
809   fseek (m_InputFile, 0, SEEK_SET);
810   ptfread (test, 1, sizeof test, m_InputFile);
811   for (i=540; i < (int)(sizeof test) - 1; i++)
812     if (test[i] == 0xff) {
813       if (test[i+1]) return 1;
814       ret=0;
815     }
816   return ret;
817 }
818 
canon_load_raw()819 void CLASS canon_load_raw()
820 {
821   uint16_t *pixel, *prow, *huff[2];
822   int nblocks, lowbits, i, c, row, r, save, val;
823   int block, diffbuf[64], leaf, len, diff, carry=0, pnum=0, base[2];
824 
825   crw_init_tables (m_Tiff_Compress,huff);
826   lowbits = canon_has_lowbits();
827   if (!lowbits) m_WhiteLevel = 0x3ff;
828   fseek (m_InputFile, 540 + lowbits*m_RawHeight*m_RawWidth/4, SEEK_SET);
829   zero_after_ff = 1;
830   getbits(-1);
831   for (row=0; row < m_RawHeight; row+=8) {
832     pixel = m_Raw_Image + row*m_RawWidth;
833     nblocks = MIN (8, m_RawHeight-row) * m_RawWidth >> 6;
834     for (block=0; block < nblocks; block++) {
835       memset (diffbuf, 0, sizeof diffbuf);
836       for (i=0; i < 64; i++ ) {
837         leaf = gethuff(huff[i>0]);
838   if (leaf == 0 && i) break;
839   if (leaf == 0xff) continue;
840   i  += leaf >> 4;
841   len = leaf & 15;
842   if (len == 0) continue;
843   diff = getbits(len);
844   if ((diff & (1 << (len-1))) == 0)
845     diff -= (1 << len) - 1;
846   if (i < 64) diffbuf[i] = diff;
847       }
848       diffbuf[0] += carry;
849       carry = diffbuf[0];
850       for (i=0; i < 64; i++ ) {
851   if (pnum++ % m_RawWidth == 0)
852     base[0] = base[1] = 512;
853   if ((pixel[(block << 6) + i] = base[i & 1] += diffbuf[i]) >> 10)
854     derror();
855       }
856     }
857     if (lowbits) {
858       save = ftell(m_InputFile);
859       fseek (m_InputFile, 26 + row*m_RawWidth/4, SEEK_SET);
860       for (prow=pixel, i=0; i < m_RawWidth*2; i++) {
861         c = fgetc(m_InputFile);
862         for (r=0; r < 8; r+=2, prow++) {
863           val = (*prow << 2) + ((c >> r) & 3);
864           if (m_RawWidth == 2672 && val < 512) val += 2;
865           *prow = val;
866         }
867       }
868       fseek (m_InputFile, save, SEEK_SET);
869     }
870   }
871   FREE(huff[0]);
872   FREE(huff[1]);
873 }
874 
875 /*
876    Not a full implementation of Lossless JPEG, just
877    enough to decode Canon, Kodak and Adobe DNG images.
878  */
879 struct jhead {
880   int bits, high, wide, clrs, sraw, psv, restart, vpred[6];
881   uint16_t *huff[6], *free[4], *row;
882 };
883 
ljpeg_start(struct jhead * jh,int info_only)884 int CLASS ljpeg_start (struct jhead *jh, int info_only)
885 {
886   int c, tag, len;
887   uint8_t data[0x10000];
888   const uint8_t *dp;
889 
890   memset (jh, 0, sizeof *jh);
891   jh->restart = INT_MAX;
892   ptfread (data, 2, 1, m_InputFile);
893   if (data[1] != 0xd8) return 0;
894   do {
895     ptfread (data, 2, 2, m_InputFile);
896     tag =  data[0] << 8 | data[1];
897     len = (data[2] << 8 | data[3]) - 2;
898     if (tag <= 0xff00) return 0;
899     ptfread (data, 1, len, m_InputFile);
900     switch (tag) {
901       case 0xffc3:
902         jh->sraw = ((data[7] >> 4) * (data[7] & 15) - 1) & 3;
903       case 0xffc0:
904   jh->bits = data[0];
905   jh->high = data[1] << 8 | data[2];
906   jh->wide = data[3] << 8 | data[4];
907   jh->clrs = data[5] + jh->sraw;
908   if (len == 9 && !m_DNG_Version) getc(m_InputFile);
909   break;
910       case 0xffc4:
911   if (info_only) break;
912   for (dp = data; dp < data+len && (c = *dp++) < 4; )
913     jh->free[c] = jh->huff[c] = make_decoder_ref (&dp);
914   break;
915       case 0xffda:
916   jh->psv = data[1+data[0]*2];
917         jh->bits -= data[3+data[0]*2] & 15;
918   break;
919       case 0xffdd:
920   jh->restart = data[0] << 8 | data[1];
921     }
922   } while (tag != 0xffda);
923   if (info_only) return 1;
924   for (c=0;c<5;c++) if (!jh->huff[c+1]) jh->huff[c+1] = jh->huff[c];
925   if (jh->sraw) {
926     for (c=0;c<4;c++) jh->huff[2+c] = jh->huff[1];
927     for (c=0;c<(jh->sraw);c++) jh->huff[1+c] = jh->huff[0];
928   }
929   jh->row = (uint16_t *) CALLOC (jh->wide*jh->clrs, 4);
930   merror (jh->row, "ljpeg_start()");
931   return zero_after_ff = 1;
932 }
933 
ljpeg_end(struct jhead * jh)934 void CLASS ljpeg_end (struct jhead *jh)
935 {
936   int c;
937   for(c=0;c<4;c++) if (jh->free[c]) FREE (jh->free[c]);
938   FREE (jh->row);
939 }
940 
ljpeg_diff(uint16_t * huff)941 int CLASS ljpeg_diff (uint16_t *huff)
942 {
943   int len, diff;
944 
945   len = gethuff(huff);
946 
947   if (len == 16 && (!m_DNG_Version || m_DNG_Version >= 0x1010000))
948     return -32768;
949   diff = getbits(len);
950   if ((diff & (1 << (len-1))) == 0)
951     diff -= (1 << len) - 1;
952   return diff;
953 }
954 
ljpeg_row(int jrow,struct jhead * jh)955 uint16_t * CLASS ljpeg_row (int jrow, struct jhead *jh)
956 {
957   int col, c, diff, pred, spred=0;
958   uint16_t mark=0, *row[3];
959 
960   if (jrow * jh->wide % jh->restart == 0) {
961     for (c=0;c<6;c++) jh->vpred[c] = 1 << (jh->bits-1);
962     if (jrow) {
963       fseek(m_InputFile,-2,SEEK_CUR);
964       do mark = (mark << 8) + (c = fgetc(m_InputFile));
965       while (c != EOF && mark >> 4 != 0xffd);
966     }
967     getbits(-1);
968   }
969   for (c=0; c<3; c++) row[c] = jh->row + jh->wide*jh->clrs*((jrow+c) & 1);
970   for (col=0; col < jh->wide; col++)
971     for (c=0; c < jh->clrs; c++) {
972       diff = ljpeg_diff (jh->huff[c]);
973       if (jh->sraw && c <= jh->sraw && (col | c))
974         pred = spred;
975       else if (col) pred = row[0][-jh->clrs];
976       else      pred = (jh->vpred[c] += diff) - diff;
977       if (jrow && col) switch (jh->psv) {
978   case 1: break;
979   case 2: pred = row[1][0];         break;
980   case 3: pred = row[1][-jh->clrs];       break;
981   case 4: pred = pred +   row[1][0] - row[1][-jh->clrs];    break;
982   case 5: pred = pred + ((row[1][0] - row[1][-jh->clrs]) >> 1); break;
983   case 6: pred = row[1][0] + ((pred - row[1][-jh->clrs]) >> 1); break;
984   case 7: pred = (pred + row[1][0]) >> 1;       break;
985   default: pred = 0;
986       }
987       if ((**row = pred + diff) >> jh->bits) derror();
988       if (c <= jh->sraw) spred = **row;
989       row[0]++; row[1]++;
990     }
991   return row[2];
992 }
993 
lossless_jpeg_load_raw()994 void CLASS lossless_jpeg_load_raw()
995 {
996   int jwide, jrow, jcol, val, jidx, i, j, row=0, col=0;
997   struct jhead jh;
998   uint16_t *rp;
999 
1000   if (!ljpeg_start (&jh, 0)) return;
1001   jwide = jh.wide * jh.clrs;
1002 
1003   TRACEKEYVALS("jh.high","%d",jh.high);
1004   TRACEKEYVALS("jwide","%d",jwide);
1005   for (jrow=0; jrow < jh.high; jrow++) {
1006     rp = ljpeg_row (jrow, &jh);
1007     if (m_Load_Flags & 1)
1008       row = jrow & 1 ? m_Height-1-jrow/2 : jrow/2;
1009     for (jcol=0; jcol < jwide; jcol++) {
1010       val = m_Curve[*rp++];
1011       if (cr2_slice[0]) {
1012   jidx = jrow*jwide + jcol;
1013   i = jidx / (cr2_slice[1]*jh.high);
1014   if ((j = i >= cr2_slice[0]))
1015      i  = cr2_slice[0];
1016   jidx -= i * (cr2_slice[1]*jh.high);
1017   row = jidx / cr2_slice[1+j];
1018   col = jidx % cr2_slice[1+j] + i*cr2_slice[1];
1019       }
1020       if (m_RawWidth == 3984 && (col -= 2) < 0)
1021         col += (row--,m_RawWidth);
1022       if (row >= 0) RAW(row,col) = val;
1023       if (++col >= m_RawWidth)
1024   col = (row++,0);
1025     }
1026   }
1027   ljpeg_end(&jh);
1028 // printf("TIEDELIE dark[0]:%f dark[1]:%f nblack:%d\n",dark[0],dark[1],nblack);
1029 }
1030 
canon_sraw_load_raw()1031 void CLASS canon_sraw_load_raw()
1032 {
1033   struct jhead jh;
1034   short *rp=0, (*ip)[4];
1035   int jwide, slice, scol, ecol, row, col, jrow=0, jcol=0, pix[3], c;
1036   int v[3]={0,0,0}, ver, hue;
1037   char *cp;
1038 
1039   if (!ljpeg_start (&jh, 0)) return;
1040   jwide = (jh.wide >>= 1) * jh.clrs;
1041 
1042   for (ecol=slice=0; slice <= cr2_slice[0]; slice++) {
1043     scol = ecol;
1044     ecol += cr2_slice[1] * 2 / jh.clrs;
1045     if (!cr2_slice[0] || ecol > m_RawWidth-1) ecol = m_RawWidth & -2;
1046     for (row=0; row < m_Height; row += (jh.clrs >> 1) - 1) {
1047       ip = (short (*)[4]) m_Image + row*m_Width;
1048       for (col=scol; col < ecol; col+=2, jcol+=jh.clrs) {
1049   if ((jcol %= jwide) == 0)
1050     rp = (short *) ljpeg_row (jrow++, &jh);
1051   if (col >= m_Width) continue;
1052   for (c=0; c< (jh.clrs-2); c++)
1053     ip[col + (c >> 1)*m_Width + (c & 1)][0] = rp[jcol+c];
1054   ip[col][1] = rp[jcol+jh.clrs-2] - 16384;
1055   ip[col][2] = rp[jcol+jh.clrs-1] - 16384;
1056       }
1057     }
1058   }
1059   for (cp=m_CameraModelBis; *cp && !isdigit(*cp); cp++) {};
1060   sscanf (cp, "%d.%d.%d", v, v+1, v+2);
1061   ver = (v[0]*1000 + v[1])*1000 + v[2];
1062   hue = (jh.sraw+1) << 2;
1063   if (unique_id >= 0x80000281 || (unique_id == 0x80000218 && ver > 1000006))
1064     hue = jh.sraw << 1;
1065   ip = (short (*)[4]) m_Image;
1066   rp = ip[0];
1067   for (row=0; row < m_Height; row++, ip+=m_Width) {
1068     if (row & (jh.sraw >> 1))
1069       for (col=0; col < m_Width; col+=2)
1070   for (c=1; c < 3; c++)
1071     if (row == m_Height-1) {
1072       ip[col][c] =  ip[col-m_Width][c];
1073     } else {
1074       ip[col][c] = (ip[col-m_Width][c] + ip[col+m_Width][c] + 1) >> 1;
1075     }
1076     for (col=1; col < m_Width; col+=2)
1077       for (c=1; c < 3; c++)
1078   if (col == m_Width-1)
1079        ip[col][c] =  ip[col-1][c];
1080   else ip[col][c] = (ip[col-1][c] + ip[col+1][c] + 1) >> 1;
1081   }
1082   for ( ; rp < ip[0]; rp+=4) {
1083     if (unique_id == 0x80000218 ||
1084 	unique_id == 0x80000250 ||
1085 	unique_id == 0x80000261 ||
1086 	unique_id == 0x80000281 ||
1087 	unique_id == 0x80000287) {
1088       rp[1] = (rp[1] << 2) + hue;
1089       rp[2] = (rp[2] << 2) + hue;
1090       pix[0] = rp[0] + ((  200*rp[1] + 22929*rp[2]) >> 14);
1091       pix[1] = rp[0] + ((-5640*rp[1] - 11751*rp[2]) >> 14);
1092       pix[2] = rp[0] + ((29040*rp[1] -   101*rp[2]) >> 14);
1093     } else {
1094       if (unique_id < 0x80000218) rp[0] -= 512;
1095       pix[0] = rp[0] + rp[2];
1096       pix[2] = rp[0] + rp[1];
1097       pix[1] = rp[0] + ((-778*rp[1] - (rp[2] << 11)) >> 12);
1098     }
1099     for (c=0;c<3;c++) rp[c] = CLIP(pix[c] * sraw_mul[c] >> 10);
1100   }
1101   ljpeg_end(&jh);
1102   m_WhiteLevel = 0x3fff;
1103 }
1104 
adobe_copy_pixel(unsigned row,unsigned col,uint16_t ** rp)1105 void CLASS adobe_copy_pixel (unsigned row, unsigned col, uint16_t **rp)
1106 {
1107   int c;
1108 
1109   if (m_IsRaw == 2 && m_UserSetting_ShotSelect) (*rp)++;
1110   if (m_Raw_Image) {
1111     if (row < m_RawHeight && col < m_RawWidth)
1112       RAW(row,col) = m_Curve[**rp];
1113     *rp += m_IsRaw;
1114   } else {
1115     if (row < m_Height && col < m_Width)
1116       for (c=0; c < (int32_t)m_Tiff_Samples; c++)
1117   m_Image[row*m_Width+col][c] = m_Curve[(*rp)[c]];
1118     *rp += m_Tiff_Samples;
1119   }
1120   if (m_IsRaw == 2 && m_UserSetting_ShotSelect) (*rp)--;
1121 }
1122 
lossless_dng_load_raw()1123 void CLASS lossless_dng_load_raw()
1124 {
1125   unsigned save, trow=0, tcol=0, jwide, jrow, jcol, row, col;
1126   struct jhead jh;
1127   uint16_t *rp;
1128 
1129   while (trow < m_RawHeight) {
1130     save = ftell(m_InputFile);
1131     if (m_TileLength < INT_MAX)
1132       fseek (m_InputFile, get4(), SEEK_SET);
1133     if (!ljpeg_start (&jh, 0)) break;
1134     jwide = jh.wide;
1135     if (m_Filters) jwide *= jh.clrs;
1136     jwide /= m_IsRaw;
1137     for (row=col=jrow=0; jrow < (unsigned) jh.high; jrow++) {
1138       rp = ljpeg_row (jrow, &jh);
1139       for (jcol=0; jcol < jwide; jcol++) {
1140   adobe_copy_pixel (trow+row, tcol+col, &rp);
1141   if (++col >= m_TileWidth || col >= m_RawWidth)
1142     row += 1 + (col = 0);
1143       }
1144     }
1145     fseek (m_InputFile, save+4, SEEK_SET);
1146     if ((tcol += m_TileWidth) >= m_RawWidth)
1147       trow += m_TileLength + (tcol = 0);
1148     ljpeg_end(&jh);
1149   }
1150 }
1151 
packed_dng_load_raw()1152 void CLASS packed_dng_load_raw()
1153 {
1154   uint16_t *pixel, *rp;
1155   // int row, col;
1156   unsigned row, col;
1157 
1158   pixel = (uint16_t *) CALLOC (m_RawWidth * m_Tiff_Samples, sizeof *pixel);
1159   merror (pixel, "packed_dng_load_raw()");
1160   for (row=0; row < m_RawHeight; row++) {
1161     if (m_Tiff_bps == 16)
1162       read_shorts (pixel, m_RawWidth * m_Tiff_Samples);
1163     else {
1164       getbits(-1);
1165       for (col=0; col < m_RawWidth * m_Tiff_Samples; col++)
1166   pixel[col] = getbits(m_Tiff_bps);
1167     }
1168     for (rp=pixel, col=0; col < m_RawWidth; col++)
1169       adobe_copy_pixel (row, col, &rp);
1170   }
1171   FREE (pixel);
1172 }
1173 
pentax_load_raw()1174 void CLASS pentax_load_raw()
1175 {
1176   uint16_t bit[2][15], huff[4097];
1177   int dep, row, col, diff, c, i;
1178   uint16_t vpred[2][2] = {{0,0},{0,0}}, hpred[2];
1179 
1180   fseek (m_InputFile, meta_offset, SEEK_SET);
1181   dep = (get2() + 12) & 15;
1182   fseek (m_InputFile, 12, SEEK_CUR);
1183   for(c=0;c<dep;c++) bit[0][c] = get2();
1184   for(c=0;c<dep;c++) bit[1][c] = fgetc(m_InputFile);
1185   for(c=0;c<dep;c++)
1186     for (i=bit[0][c]; i <= ((bit[0][c]+(4096 >> bit[1][c])-1) & 4095); )
1187       huff[++i] = bit[1][c] << 8 | c;
1188   huff[0] = 12;
1189   fseek (m_InputFile, m_Data_Offset, SEEK_SET);
1190   getbits(-1);
1191   for (row=0; row < m_RawHeight; row++)
1192     for (col=0; col < m_RawWidth; col++) {
1193       diff = ljpeg_diff (huff);
1194       if (col < 2) hpred[col] = vpred[row & 1][col] += diff;
1195       else     hpred[col & 1] += diff;
1196       RAW(row,col) = hpred[col & 1];
1197       if (hpred[col & 1] >> m_Tiff_bps) derror();
1198     }
1199 }
1200 
nikon_load_raw()1201 void CLASS nikon_load_raw()
1202 {
1203   static const uint8_t nikon_tree[][32] = {
1204     { 0,1,5,1,1,1,1,1,1,2,0,0,0,0,0,0,  /* 12-bit lossy */
1205       5,4,3,6,2,7,1,0,8,9,11,10,12 },
1206     { 0,1,5,1,1,1,1,1,1,2,0,0,0,0,0,0,  /* 12-bit lossy after split */
1207       0x39,0x5a,0x38,0x27,0x16,5,4,3,2,1,0,11,12,12 },
1208     { 0,1,4,2,3,1,2,0,0,0,0,0,0,0,0,0,  /* 12-bit lossless */
1209       5,4,6,3,7,2,8,1,9,0,10,11,12 },
1210     { 0,1,4,3,1,1,1,1,1,2,0,0,0,0,0,0,  /* 14-bit lossy */
1211       5,6,4,7,8,3,9,2,1,0,10,11,12,13,14 },
1212     { 0,1,5,1,1,1,1,1,1,1,2,0,0,0,0,0,  /* 14-bit lossy after split */
1213       8,0x5c,0x4b,0x3a,0x29,7,6,5,4,3,2,1,0,13,14 },
1214     { 0,1,4,2,2,3,1,2,0,0,0,0,0,0,0,0,  /* 14-bit lossless */
1215       7,6,8,5,9,4,10,3,11,12,2,0,1,13,14 } };
1216   uint16_t *huff, ver0, ver1, vpred[2][2], hpred[2], csize;
1217   int i, min, max, step=0, tree=0, split=0, row, col, len, shl, diff;
1218 
1219   fseek (m_InputFile, meta_offset, SEEK_SET);
1220   ver0 = fgetc(m_InputFile);
1221   ver1 = fgetc(m_InputFile);
1222   if (ver0 == 0x49 || ver1 == 0x58)
1223     fseek (m_InputFile, 2110, SEEK_CUR);
1224   if (ver0 == 0x46) tree = 2;
1225   if (m_Tiff_bps == 14) tree += 3;
1226   read_shorts (vpred[0], 4);
1227   max = 1 << m_Tiff_bps & 0x7fff;
1228   if ((csize = get2()) > 1)
1229     step = max / (csize-1);
1230   if (ver0 == 0x44 && ver1 == 0x20 && step > 0) {
1231     for (i=0; i < csize; i++)
1232       m_Curve[i*step] = get2();
1233     for (i=0; i < max; i++)
1234       m_Curve[i] = ( m_Curve[i-i%step]*(step-i%step) +
1235        m_Curve[i-i%step+step]*(i%step) ) / step;
1236     fseek (m_InputFile, meta_offset+562, SEEK_SET);
1237     split = get2();
1238   } else if (ver0 != 0x46 && csize <= 0x4001)
1239     read_shorts (m_Curve, max=csize);
1240   while (m_Curve[max-2] == m_Curve[max-1]) max--;
1241   huff = make_decoder(nikon_tree[tree]);
1242   fseek (m_InputFile, m_Data_Offset, SEEK_SET);
1243   getbits(-1);
1244   for (min=row=0; row < m_Height; row++) {
1245     if (split && row == split) {
1246       FREE(huff);
1247       huff = make_decoder(nikon_tree[tree+1]);
1248       max += (min = 16) << 1;
1249     }
1250     for (col=0; col < m_RawWidth; col++) {
1251       i = gethuff(huff);
1252       len = i & 15;
1253       shl = i >> 4;
1254       diff = ((getbits(len-shl) << 1) + 1) << shl >> 1;
1255       if ((diff & (1 << (len-1))) == 0)
1256   diff -= (1 << len) - !shl;
1257       if (col < 2) hpred[col] = vpred[row & 1][col] += diff;
1258       else     hpred[col & 1] += diff;
1259       if ((uint16_t)(hpred[col & 1] + min) >= max) derror();
1260       RAW(row,col) = m_Curve[LIM((int16_t)hpred[col & 1],(int16_t)0,(int16_t)0x3fff)];
1261     }
1262   }
1263   FREE(huff);
1264 }
1265 
1266 /*
1267    Returns 1 for a Coolpix 995, 0 for anything else.
1268  */
nikon_e995()1269 int CLASS nikon_e995()
1270 {
1271   int i, histo[256];
1272   const uint8_t often[] = { 0x00, 0x55, 0xaa, 0xff };
1273 
1274   memset (histo, 0, sizeof histo);
1275   fseek (m_InputFile, -2000, SEEK_END);
1276   for (i=0; i < 2000; i++)
1277     histo[fgetc(m_InputFile)]++;
1278   for (i=0; i < 4; i++)
1279     if (histo[often[i]] < 200)
1280       return 0;
1281   return 1;
1282 }
1283 
1284 /*
1285    Returns 1 for a Coolpix 2100, 0 for anything else.
1286  */
nikon_e2100()1287 int CLASS nikon_e2100()
1288 {
1289   uint8_t t[12];
1290   int i;
1291 
1292   fseek (m_InputFile, 0, SEEK_SET);
1293   for (i=0; i < 1024; i++) {
1294     ptfread (t, 1, 12, m_InputFile);
1295     if (((t[2] & t[4] & t[7] & t[9]) >> 4
1296   & t[1] & t[6] & t[8] & t[11] & 3) != 3)
1297       return 0;
1298   }
1299   return 1;
1300 }
1301 
nikon_3700()1302 void CLASS nikon_3700()
1303 {
1304   int bits; // i;
1305   uint8_t dp[24];
1306   static const struct {
1307     int bits;
1308     char make[12], model[15];
1309   } table[] = {
1310     { 0x00, "PENTAX",  "Optio 33WR" },
1311     { 0x03, "NIKON",   "E3200" },
1312     { 0x32, "NIKON",   "E3700" },
1313     { 0x33, "OLYMPUS", "C740UZ" } };
1314 
1315   fseek (m_InputFile, 3072, SEEK_SET);
1316   ptfread (dp, 1, 24, m_InputFile);
1317   bits = (dp[8] & 3) << 4 | (dp[20] & 3);
1318   for (unsigned i=0; i < sizeof table / sizeof *table; i++)
1319     if (bits == table[i].bits) {
1320       strcpy (m_CameraMake,  table[i].make );
1321       strcpy (m_CameraModel, table[i].model);
1322     }
1323 }
1324 
1325 /*
1326    Separates a Minolta DiMAGE Z2 from a Nikon E4300.
1327  */
minolta_z2()1328 int CLASS minolta_z2()
1329 {
1330   unsigned i,nz;
1331   char tail[424];
1332 
1333   fseek (m_InputFile, (long)(-sizeof tail), SEEK_END);
1334   ptfread (tail, 1, sizeof tail, m_InputFile);
1335   for (nz=i=0; i < sizeof tail; i++)
1336     if (tail[i]) nz++;
1337   return nz > 20;
1338 }
1339 
1340 //void CLASS jpeg_thumb ();
1341 
ppm_thumb()1342 void CLASS ppm_thumb ()
1343 /* Remember: This function is modified to write the raw’s thumbnail to the
1344    m_Thumb instead of a file on disk. Always access thumbnails via DcRaw::thumbnail()!
1345 */
1346 {
1347   char *thumb;
1348   m_ThumbLength = m_ThumbWidth*m_ThumbHeight*3;
1349   thumb = (char *) MALLOC (m_ThumbLength);
1350   merror (thumb, "ppm_thumb()");
1351   //fprintf (m_OutputFile, "P6\n%d %d\n255\n", m_ThumbWidth, m_ThumbHeight);
1352   QString dummy = QString("P6\n%1 %2\n255\n").arg(m_ThumbWidth).arg(m_ThumbHeight);
1353   VAppend(m_Thumb, dummy.toLocal8Bit().data(), dummy.length());
1354   ptfread  (thumb, 1, m_ThumbLength, m_InputFile);
1355   VAppend(m_Thumb, thumb, m_ThumbLength);
1356   FREE (thumb);
1357 }
1358 
ppm16_thumb()1359 void CLASS ppm16_thumb()
1360 {
1361   int i;
1362   char *thumb;
1363   m_ThumbLength = m_ThumbWidth*m_ThumbHeight*3;
1364   thumb = (char *) CALLOC (m_ThumbLength,2);
1365   merror (thumb, "ppm16_thumb()");
1366   read_shorts ((uint16_t *) thumb, m_ThumbLength);
1367   for (i=0; i < (int32_t)m_ThumbLength; i++)
1368     thumb[i] = ((uint16_t *) thumb)[i] >> 8;
1369   QString dummy = QString("P6\n%1 %2\n255\n").arg(m_ThumbWidth).arg(m_ThumbHeight);
1370   VAppend(m_Thumb, dummy.toLocal8Bit().data(), dummy.length());
1371   //fprintf (ofp, "P6\n%d %d\n255\n", m_ThumbWidth, m_ThumbHeight);
1372   //fwrite (thumb, 1, m_ThumbLength, ofp);
1373   VAppend(m_Thumb, thumb, m_ThumbLength);
1374   FREE (thumb);
1375 }
1376 
layer_thumb()1377 void CLASS layer_thumb ()
1378 /* Remember: This function is modified to write the raw’s thumbnail to the
1379    m_Thumb instead of a file on disk. Always access thumbnails via DcRaw::thumbnail()!
1380 */
1381 // TODO: Tests needed: What format is this? Can it be read by QPixmap?
1382 {
1383   // int i, c;
1384   int c;
1385   char *thumb, map[][4] = { "012","102" };
1386 
1387   m_Colors = m_ThumbMisc >> 5 & 7;
1388   m_ThumbLength = m_ThumbWidth*m_ThumbHeight;
1389   thumb = (char *) CALLOC (m_Colors, m_ThumbLength);
1390   merror (thumb, "layer_thumb()");
1391   //fprintf (m_OutputFile, "P%d\n%d %d\n255\n", 5 + (m_Colors >> 1), m_ThumbWidth, m_ThumbHeight);
1392   QString dummy = QString("P%1\n%2 %3\n255\n")
1393       .arg(5 + (m_Colors >> 1)).arg(m_ThumbWidth).arg(m_ThumbHeight);
1394   VAppend(m_Thumb, dummy.toLocal8Bit().data(), dummy.length());
1395   ptfread (thumb, m_ThumbLength, m_Colors, m_InputFile);
1396   for (unsigned i=0; i < m_ThumbLength; i++) {
1397     for (c=0; c < m_Colors; c++) {
1398       //putc (thumb[i+m_ThumbLength*(map[m_ThumbMisc >> 8][c]-'0')], m_OutputFile);
1399 #pragma GCC diagnostic push
1400 #pragma GCC diagnostic ignored "-Wint-to-pointer-cast"
1401       m_Thumb.push_back(thumb[i+m_ThumbLength*(map[m_ThumbMisc >> 8][c]-'0')]);
1402 #pragma GCC diagnostic pop
1403     }
1404   }
1405   FREE (thumb);
1406 }
1407 
rollei_thumb()1408 void CLASS rollei_thumb ()
1409 /* Remember: This function is modified to write the raw’s thumbnail to the
1410    m_Thumb instead of a file on disk. Always access thumbnails via DcRaw::thumbnail()!
1411 */
1412 // TODO: Tests needed: What format is this? Can it be read by QPixmap?
1413 {
1414   unsigned i;
1415   uint16_t *thumb;
1416 
1417   m_ThumbLength = m_ThumbWidth * m_ThumbHeight;
1418   thumb = (uint16_t *) CALLOC (m_ThumbLength, 2);
1419   merror (thumb, "rollei_thumb()");
1420   //fprintf (m_OutputFile, "P6\n%d %d\n255\n", m_ThumbWidth, m_ThumbHeight);
1421   QString dummy = QString("P6\n%1 %2\n255\n").arg(m_ThumbWidth).arg(m_ThumbHeight);
1422   VAppend(m_Thumb, dummy.toLocal8Bit().data(), dummy.length());
1423   read_shorts (thumb, m_ThumbLength);
1424   for (i=0; i < m_ThumbLength; i++) {
1425     //putc (thumb[i] << 3, m_OutputFile);
1426     //putc (thumb[i] >> 5  << 2, m_OutputFile);
1427     //putc (thumb[i] >> 11 << 3, m_OutputFile);
1428 #pragma GCC diagnostic push
1429 #pragma GCC diagnostic ignored "-Wint-to-pointer-cast"
1430     m_Thumb.push_back(thumb[i] << 3);
1431     m_Thumb.push_back(thumb[i] >> 5 << 2);
1432     m_Thumb.push_back(thumb[i] >> 11 << 3);
1433 #pragma GCC diagnostic pop
1434   }
1435   FREE (thumb);
1436 }
1437 
rollei_load_raw()1438 void CLASS rollei_load_raw()
1439 {
1440   uint8_t pixel[10];
1441   unsigned iten=0, isix, i, buffer=0, todo[16];
1442 
1443   isix = m_RawWidth * m_RawHeight * 5 / 8;
1444   while (fread (pixel, 1, 10, m_InputFile) == 10) {
1445     for (i=0; i < 10; i+=2) {
1446       todo[i]   = iten++;
1447       todo[i+1] = pixel[i] << 8 | pixel[i+1];
1448       buffer    = pixel[i] >> 2 | buffer << 6;
1449     }
1450     for (   ; i < 16; i+=2) {
1451       todo[i]   = isix++;
1452       todo[i+1] = buffer >> (14-i)*5;
1453     }
1454     for (i=0; i < 16; i+=2)
1455       m_Raw_Image[todo[i]] = (todo[i+1] & 0x3ff);
1456   }
1457   m_WhiteLevel = 0x3ff;
1458 }
1459 
raw(unsigned row,unsigned col)1460 int CLASS raw (unsigned row, unsigned col)
1461 {
1462   return (row < m_RawHeight && col < m_RawWidth) ? RAW(row,col) : 0;
1463 }
1464 
phase_one_flat_field(int is_float,int nc)1465 void CLASS phase_one_flat_field (int is_float, int nc)
1466 {
1467   uint16_t head[8];
1468   unsigned wide, y, x, c, rend, cend, row, col;
1469   float *mrow, num, mult[4];
1470 
1471   read_shorts (head, 8);
1472   wide = head[2] / head[4];
1473   mrow = (float *) CALLOC (nc*wide, sizeof *mrow);
1474   merror (mrow, "phase_one_flat_field()");
1475   for (y=0; y < (unsigned) (head[3] / head[5]); y++) {
1476     for (x=0; x < wide; x++)
1477       for (c=0; c < (unsigned) nc; c+=2) {
1478   num = is_float ? getreal(11) : get2()/32768.0;
1479   if (y==0) mrow[c*wide+x] = num;
1480   else mrow[(c+1)*wide+x] = (num - mrow[c*wide+x]) / head[5];
1481       }
1482     if (y==0) continue;
1483     rend = head[1] + y*head[5];
1484     for (row = rend-head[5]; row < m_RawHeight && row < rend; row++) {
1485       for (x=1; x < wide; x++) {
1486   for (c=0; c < (unsigned) nc; c+=2) {
1487     mult[c] = mrow[c*wide+x-1];
1488     mult[c+1] = (mrow[c*wide+x] - mult[c]) / head[4];
1489   }
1490   cend = head[0] + x*head[4];
1491   for (col = cend-head[4]; col < m_RawWidth && col < cend; col++) {
1492     c = nc > 2 ? FC(row-m_TopMargin,col-m_LeftMargin) : 0;
1493     if (!(c & 1)) {
1494       c = unsigned(RAW(row,col) * mult[c]);
1495       RAW(row,col) = MIN((int32_t)c,65535);
1496     }
1497     for (c=0; c < (unsigned) nc; c+=2)
1498       mult[c] += mult[c+1];
1499   }
1500       }
1501       for (x=0; x < wide; x++)
1502   for (c=0; c < (unsigned) nc; c+=2)
1503     mrow[c*wide+x] += mrow[(c+1)*wide+x];
1504     }
1505   }
1506   FREE (mrow);
1507 }
1508 
phase_one_correct()1509 void CLASS phase_one_correct()
1510 {
1511   unsigned entries, tag, data, save, col, row, type;
1512   int len, i, j, k, cip, val[4], dev[4], sum, max;
1513   int head[9], diff, mindiff=INT_MAX, off_412=0;
1514   static const signed char dir[12][2] =
1515     { {-1,-1}, {-1,1}, {1,-1}, {1,1}, {-2,0}, {0,-2}, {0,2}, {2,0},
1516       {-2,-2}, {-2,2}, {2,-2}, {2,2} };
1517   float poly[8], num, cfrac, frac, mult[2], *yval[2];
1518   uint16_t *xval[2];
1519 
1520   if (m_UserSetting_HalfSize || !m_MetaLength) return;
1521   TRACEKEYVALS("Phase One correction","%s","");
1522   fseek (m_InputFile, meta_offset, SEEK_SET);
1523   m_ByteOrder = get2();
1524   fseek (m_InputFile, 6, SEEK_CUR);
1525   fseek (m_InputFile, meta_offset+get4(), SEEK_SET);
1526   entries = get4();  get4();
1527   while (entries--) {
1528     tag  = get4();
1529     len  = get4();
1530     data = get4();
1531     save = ftell(m_InputFile);
1532     fseek (m_InputFile, meta_offset+data, SEEK_SET);
1533     if (tag == 0x419) {       /* Polynomial curve */
1534       for (get4(), i=0; i < 8; i++)
1535   poly[i] = getreal(11);
1536       poly[3] += (ph1.tag_210 - poly[7]) * poly[6] + 1;
1537       for (i=0; i < 0x10000; i++) {
1538   num = (poly[5]*i + poly[3])*i + poly[1];
1539   m_Curve[i] = (uint16_t) LIM((int32_t)num,0,65535);
1540       } goto apply;       /* apply to right half */
1541     } else if (tag == 0x41a) {      /* Polynomial curve */
1542       for (i=0; i < 4; i++)
1543   poly[i] = getreal(11);
1544       for (i=0; i < 0x10000; i++) {
1545   for (num=0, j=4; j--; )
1546     num = num * i + poly[j];
1547   m_Curve[i] = (uint16_t) LIM((int32_t)(num+i),0,65535);
1548       } apply:          /* apply to whole image */
1549       for (row=0; row < m_RawHeight; row++)
1550   for (col = (tag & 1)*ph1.split_col; col < m_RawWidth; col++)
1551     RAW(row,col) = m_Curve[RAW(row,col)];
1552     } else if (tag == 0x400) {      /* Sensor defects */
1553       while ((len -= 8) >= 0) {
1554   col  = get2();
1555   row  = get2();
1556   type = get2(); get2();
1557   if (col >= m_RawWidth) continue;
1558   if (type == 131)      /* Bad column */
1559     for (row=0; row < m_RawHeight; row++)
1560       if (FC(row-m_TopMargin,col-m_LeftMargin) == 1) {
1561         for (sum=i=0; i < 4; i++)
1562     sum += val[i] = raw (row+dir[i][0], col+dir[i][1]);
1563         for (max=i=0; i < 4; i++) {
1564     dev[i] = abs((val[i] << 2) - sum);
1565     if (dev[max] < dev[i]) max = i;
1566         }
1567         RAW(row,col) = (uint16_t) ((sum - val[max])/3.0 + 0.5);
1568       } else {
1569         for (sum=0, i=8; i < 12; i++)
1570     sum += raw (row+dir[i][0], col+dir[i][1]);
1571         RAW(row,col) = (uint16_t) (0.5 + sum * 0.0732233 +
1572     (raw(row,col-2) + raw(row,col+2)) * 0.3535534);
1573       }
1574   else if (type == 129) {     /* Bad pixel */
1575     if (row >= m_RawHeight) continue;
1576     j = (FC(row-m_TopMargin,col-m_LeftMargin) != 1) * 4;
1577     for (sum=0, i=j; i < j+8; i++)
1578       sum += raw (row+dir[i][0], col+dir[i][1]);
1579     RAW(row,col) = (sum + 4) >> 3;
1580   }
1581       }
1582     } else if (tag == 0x401) {      /* All-color flat fields */
1583       phase_one_flat_field (1, 2);
1584     } else if (tag == 0x416 || tag == 0x410) {
1585       phase_one_flat_field (0, 2);
1586     } else if (tag == 0x40b) {      /* Red+blue flat field */
1587       phase_one_flat_field (0, 4);
1588     } else if (tag == 0x412) {
1589       fseek (m_InputFile, 36, SEEK_CUR);
1590       diff = abs (get2() - ph1.tag_21a);
1591       if (mindiff > diff) {
1592   mindiff = diff;
1593   off_412 = ftell(m_InputFile) - 38;
1594       }
1595     }
1596     fseek (m_InputFile, save, SEEK_SET);
1597   }
1598   if (off_412) {
1599     fseek (m_InputFile, off_412, SEEK_SET);
1600     for (i=0; i < 9; i++) head[i] = get4() & 0x7fff;
1601     yval[0] = (float *) CALLOC (head[1]*head[3] + head[2]*head[4], 6);
1602     merror (yval[0], "phase_one_correct()");
1603     yval[1] = (float  *) (yval[0] + head[1]*head[3]);
1604     xval[0] = (uint16_t *) (yval[1] + head[2]*head[4]);
1605     xval[1] = (uint16_t *) (xval[0] + head[1]*head[3]);
1606     get2();
1607     for (i=0; i < 2; i++)
1608       for (j=0; j < head[i+1]*head[i+3]; j++)
1609   yval[i][j] = getreal(11);
1610     for (i=0; i < 2; i++)
1611       for (j=0; j < head[i+1]*head[i+3]; j++)
1612   xval[i][j] = get2();
1613     for (row=0; row < m_RawHeight; row++)
1614       for (col=0; col < m_RawWidth; col++) {
1615   cfrac = (float) col * head[3] / m_RawWidth;
1616   cfrac -= (cip = (int) cfrac);
1617   num = RAW(row,col) * 0.5;
1618   for (i=cip; i < cip+2; i++) {
1619     for (k=j=0; j < head[1]; j++)
1620       if (num < xval[0][k = head[1]*i+j]) break;
1621     frac = (j == 0 || j == head[1]) ? 0 :
1622     (xval[0][k] - num) / (xval[0][k] - xval[0][k-1]);
1623     mult[i-cip] = yval[0][k-1] * frac + yval[0][k] * (1-frac);
1624   }
1625   i = (int) (((mult[0] * (1-cfrac) + mult[1] * cfrac) * row + num) * 2);
1626   RAW(row,col) = LIM(i,0,65535);
1627       }
1628     FREE (yval[0]);
1629   }
1630 }
1631 
phase_one_load_raw()1632 void CLASS phase_one_load_raw()
1633 {
1634   int a, b, i;
1635   uint16_t akey, bkey, m_Mask;
1636 
1637   fseek (m_InputFile, ph1.key_off, SEEK_SET);
1638   akey = get2();
1639   bkey = get2();
1640   m_Mask = ph1.format == 1 ? 0x5555:0x1354;
1641   fseek (m_InputFile, m_Data_Offset, SEEK_SET);
1642   read_shorts (m_Raw_Image, m_RawWidth*m_RawHeight);
1643   if (ph1.format)
1644     for (i=0; i < m_RawWidth*m_RawHeight; i+=2) {
1645       a = m_Raw_Image[i+0] ^ akey;
1646       b = m_Raw_Image[i+1] ^ bkey;
1647       m_Raw_Image[i+0] = (a & m_Mask) | (b & ~m_Mask);
1648       m_Raw_Image[i+1] = (b & m_Mask) | (a & ~m_Mask);
1649     }
1650 }
1651 
ph1_bithuff(int nbits,uint16_t * huff)1652 unsigned CLASS ph1_bithuff (int nbits, uint16_t *huff)
1653 {
1654   unsigned c;
1655 
1656   if (nbits == -1)
1657     return m_ph1_bithuffbitbuf = m_ph1_bithuffvbits = 0;
1658   if (nbits == 0) return 0;
1659   if (m_ph1_bithuffvbits < nbits) {
1660     m_ph1_bithuffbitbuf = m_ph1_bithuffbitbuf << 32 | get4();
1661     m_ph1_bithuffvbits += 32;
1662   }
1663   c = m_ph1_bithuffbitbuf << (64-m_ph1_bithuffvbits) >> (64-nbits);
1664   if (huff) {
1665     m_ph1_bithuffvbits -= huff[c] >> 8;
1666     return (unsigned char) huff[c];
1667   }
1668   m_ph1_bithuffvbits -= nbits;
1669   return c;
1670 }
1671 #define ph1_bits(n) ph1_bithuff(n,0)
1672 #define ph1_huff(h) ph1_bithuff(*h,h+1)
1673 
phase_one_load_raw_c()1674 void CLASS phase_one_load_raw_c()
1675 {
1676   static const int length[] = { 8,7,6,9,11,10,5,12,14,13 };
1677   int *offset, len[2], pred[2], row, col, i, j;
1678   uint16_t *pixel;
1679   short (*black)[2];
1680 
1681   pixel = (uint16_t *) CALLOC (m_RawWidth + m_RawHeight*4, 2);
1682   merror (pixel, "phase_one_load_raw_c()");
1683   offset = (int *) (pixel + m_RawWidth);
1684   fseek (m_InputFile, strip_offset, SEEK_SET);
1685   for (row=0; row < m_RawHeight; row++)
1686     offset[row] = get4();
1687   black = (short (*)[2]) offset + m_RawHeight;
1688   fseek (m_InputFile, ph1.black_off, SEEK_SET);
1689   if (ph1.black_off)
1690     read_shorts ((uint16_t *) black[0], m_RawHeight*2);
1691   for (i=0; i < 256; i++)
1692     m_Curve[i] = (uint16_t) (i*i / 3.969 + 0.5);
1693   for (row=0; row < m_RawHeight; row++) {
1694     fseek (m_InputFile, m_Data_Offset + offset[row], SEEK_SET);
1695     ph1_bits(-1);
1696     pred[0] = pred[1] = 0;
1697     for (col=0; col < m_RawWidth; col++) {
1698       if (col >= (m_RawWidth & -8))
1699   len[0] = len[1] = 14;
1700       else if ((col & 7) == 0)
1701   for (i=0; i < 2; i++) {
1702     for (j=0; j < 5 && !ph1_bits(1); j++) {};
1703     if (j--) len[i] = length[j*2 + ph1_bits(1)];
1704   }
1705       if ((i = len[col & 1]) == 14)
1706   pixel[col] = pred[col & 1] = ph1_bits(16);
1707       else
1708   pixel[col] = pred[col & 1] += ph1_bits(i) + 1 - (1 << (i - 1));
1709       if (pred[col & 1] >> 16) derror();
1710       if (ph1.format == 5 && pixel[col] < 256)
1711   pixel[col] = m_Curve[pixel[col]];
1712     }
1713     for (col=0; col < m_RawWidth; col++) {
1714       i = (pixel[col] << 2) - ph1.black + black[row][col >= ph1.split_col];
1715   if (i > 0) RAW(row,col) = i;
1716     }
1717   }
1718   FREE (pixel);
1719   m_WhiteLevel = 0xfffc - ph1.black;
1720 }
1721 
hasselblad_load_raw()1722 void CLASS hasselblad_load_raw()
1723 {
1724   struct jhead jh;
1725   int row, col, pred[2], len[2], diff, c;
1726 
1727   if (!ljpeg_start (&jh, 0)) return;
1728   m_ByteOrder = 0x4949;
1729   ph1_bits(-1);
1730   for (row=0; row < m_RawHeight; row++) {
1731     pred[0] = pred[1] = 0x8000 + m_Load_Flags;
1732     for (col=0; col < m_RawWidth; col+=2) {
1733       for(c=0;c<2;c++) len[c] = ph1_huff(jh.huff[0]);
1734       for(c=0;c<2;c++) {
1735   diff = ph1_bits(len[c]);
1736   if ((diff & (1 << (len[c]-1))) == 0)
1737     diff -= (1 << len[c]) - 1;
1738   if (diff == 65535) diff = -32768;
1739 	RAW(row,col+c) = pred[c] += diff;
1740       }
1741     }
1742   }
1743   ljpeg_end (&jh);
1744   m_WhiteLevel = 0xffff;
1745 }
1746 
leaf_hdr_load_raw()1747 void CLASS leaf_hdr_load_raw()
1748 {
1749   uint16_t *pixel=0;
1750   unsigned tile=0, r, c, row, col;
1751 
1752   if (!m_Filters) {
1753     pixel = (uint16_t *) CALLOC (m_RawWidth, sizeof *pixel);
1754     merror (pixel, "leaf_hdr_load_raw()");
1755   }
1756   for (c=0; c < m_Tiff_Samples; c++) {
1757     for (r=0; r < m_RawHeight; r++) {
1758       if (r % m_TileLength == 0) {
1759   fseek (m_InputFile, m_Data_Offset + 4*tile++, SEEK_SET);
1760   fseek (m_InputFile, get4(), SEEK_SET);
1761       }
1762       if (m_Filters && c != m_UserSetting_ShotSelect) continue;
1763       if (m_Filters) pixel = m_Raw_Image + r*m_RawWidth;
1764       read_shorts (pixel, m_RawWidth);
1765       if (!m_Filters && (row = r - m_TopMargin) < m_Height)
1766   for (col=0; col < m_Width; col++)
1767     m_Image[row*m_Width+col][c] = pixel[col+m_LeftMargin];
1768     }
1769 }
1770   if (!m_Filters) {
1771     m_WhiteLevel = 0xffff;
1772     m_RawColor = 1;
1773     FREE (pixel);
1774   }
1775 }
1776 
unpacked_load_raw()1777 void CLASS unpacked_load_raw()
1778 {
1779   int row, col, bits=0;
1780 
1781   while ((1 << ++bits) < (int32_t)m_WhiteLevel);
1782   read_shorts (m_Raw_Image, m_RawWidth*m_RawHeight);
1783   for (row=0; row < m_RawHeight; row++)
1784     for (col=0; col < m_RawWidth; col++)
1785       if ((RAW(row,col) >>= m_Load_Flags) >> bits
1786   && (unsigned) (row-m_TopMargin) < m_Height
1787   && (unsigned) (col-m_LeftMargin) < m_Width) derror();
1788 }
1789 
sinar_4shot_load_raw()1790 void CLASS sinar_4shot_load_raw()
1791 {
1792   uint16_t *pixel;
1793   unsigned shot, row, col, r, c;
1794 
1795   if ((shot = m_UserSetting_ShotSelect) || m_UserSetting_HalfSize) {
1796     if (shot) shot--;
1797     if (shot > 3) shot = 3;
1798     fseek (m_InputFile, m_Data_Offset + shot*4, SEEK_SET);
1799     fseek (m_InputFile, get4(), SEEK_SET);
1800     unpacked_load_raw();
1801     return;
1802   }
1803   FREE (m_Raw_Image);
1804   m_Raw_Image = 0;
1805   m_Image = (uint16_t (*)[4])
1806   CALLOC ((m_OutHeight=m_Height)*(m_OutWidth=m_Width), sizeof *m_Image);
1807   merror (m_Image, "sinar_4shot_load_raw()");
1808   pixel = (uint16_t *) CALLOC (m_RawWidth, sizeof *pixel);
1809   merror (pixel, "sinar_4shot_load_raw()");
1810   for (shot=0; shot < 4; shot++) {
1811     fseek (m_InputFile, m_Data_Offset + shot*4, SEEK_SET);
1812     fseek (m_InputFile, get4(), SEEK_SET);
1813     for (row=0; row < m_RawHeight; row++) {
1814       read_shorts (pixel, m_RawWidth);
1815       if ((r = row-m_TopMargin - (shot >> 1 & 1)) >= m_Height) continue;
1816       for (col=0; col < m_RawWidth; col++) {
1817   if ((c = col-m_LeftMargin - (shot & 1)) >= m_Width) continue;
1818         m_Image[r*m_Width+c][FC(row,col)] = pixel[col];
1819       }
1820     }
1821   }
1822   FREE (pixel);
1823   m_Shrink = m_Filters = 0;
1824 }
1825 
imacon_full_load_raw()1826 void CLASS imacon_full_load_raw()
1827 {
1828   int row, col;
1829 
1830   for (row=0; row < m_Height; row++)
1831     for (col=0; col < m_Width; col++)
1832       read_shorts (m_Image[row*m_Width+col], 3);
1833 }
1834 
packed_load_raw()1835 void CLASS packed_load_raw()
1836 {
1837   int vbits=0, bwide, pwide, rbits, bite, half, irow, row, col, val, i;
1838   uint64_t bitbuf=0;
1839 
1840   if (m_RawWidth * 8U >= m_Width * m_Tiff_bps)  /* Is m_RawWidth in bytes? */
1841        pwide = (bwide = m_RawWidth) * 8 / m_Tiff_bps;
1842   else bwide = (pwide = m_RawWidth) * m_Tiff_bps / 8;
1843   rbits = bwide * 8 - pwide * m_Tiff_bps;
1844   if (m_Load_Flags & 1) bwide = bwide * 16 / 15;
1845   bite = 8 + (m_Load_Flags & 24);
1846   half = (m_RawHeight+1) >> 1;
1847   for (irow=0; irow < m_RawHeight; irow++) {
1848     row = irow;
1849     if (m_Load_Flags & 2 &&
1850   (row = irow % half * 2 + irow / half) == 1 &&
1851   m_Load_Flags & 4) {
1852       if (vbits=0, m_Tiff_Compress)
1853   fseek (m_InputFile, m_Data_Offset - (-half*bwide & -2048), SEEK_SET);
1854       else {
1855   fseek (m_InputFile, 0, SEEK_END);
1856   fseek (m_InputFile, ftell(m_InputFile) >> 3 << 2, SEEK_SET);
1857       }
1858     }
1859     for (col=0; col < pwide; col++) {
1860       for (vbits -= m_Tiff_bps; vbits < 0; vbits += bite) {
1861   bitbuf <<= bite;
1862   for (i=0; i < bite; i+=8)
1863     bitbuf |= (unsigned) (fgetc(m_InputFile) << i);
1864       }
1865       val = bitbuf << (64-m_Tiff_bps-vbits) >> (64-m_Tiff_bps);
1866       RAW(row,col ^ (m_Load_Flags >> 6)) = val;
1867       if (m_Load_Flags & 1 && (col % 10) == 9 &&
1868   fgetc(m_InputFile) && col < m_Width+m_LeftMargin) derror();
1869     }
1870     vbits -= rbits;
1871   }
1872 }
1873 
nokia_load_raw()1874 void CLASS nokia_load_raw()
1875 {
1876   uint8_t  *data,  *dp;
1877   int rev, dwide, row, col, c;
1878 
1879   rev = 3 * (m_ByteOrder == 0x4949);
1880   dwide = m_RawWidth * 5 / 4;
1881   data = (uint8_t *) MALLOC (dwide*2);
1882   merror (data, "nokia_load_raw()");
1883   for (row=0; row < m_RawHeight; row++) {
1884     if (fread (data+dwide, 1, dwide, m_InputFile) < (size_t) dwide) derror();
1885     for(c=0;c<dwide;c++) data[c] = data[dwide+(c ^ rev)];
1886     for (dp=data, col=0; col < m_RawWidth; dp+=5, col+=4)
1887       for (c=0; c<4; c++) RAW(row,col+c) = (dp[c] << 2) | (dp[4] >> (c << 1) & 3);
1888   }
1889   FREE (data);
1890   m_WhiteLevel = 0x3ff;
1891 }
1892 
pana_bits(int nbits)1893 unsigned CLASS pana_bits (int nbits)
1894 {
1895   int byte;
1896 
1897 
1898 
1899   if (!nbits) return m_pana_bits_vbits=0;
1900   if (!m_pana_bits_vbits) {
1901     ptfread (m_pana_bits_buf+m_Load_Flags, 1, 0x4000-m_Load_Flags, m_InputFile);
1902     ptfread (m_pana_bits_buf, 1, m_Load_Flags, m_InputFile);
1903   }
1904   m_pana_bits_vbits = (m_pana_bits_vbits - nbits) & 0x1ffff;
1905   byte = m_pana_bits_vbits >> 3 ^ 0x3ff0;
1906   return (m_pana_bits_buf[byte] | m_pana_bits_buf[byte+1] << 8) >> (m_pana_bits_vbits & 7) & ~(-1 << nbits);
1907 }
1908 
panasonic_load_raw()1909 void CLASS panasonic_load_raw()
1910 {
1911   int row, col, i, j, sh=0, pred[2], nonz[2];
1912 
1913   pana_bits(0);
1914   for (row=0; row < m_Height; row++)
1915     for (col=0; col < m_RawWidth; col++) {
1916       if ((i = col % 14) == 0)
1917   pred[0] = pred[1] = nonz[0] = nonz[1] = 0;
1918       if (i % 3 == 2) sh = 4 >> (3 - pana_bits(2));
1919       if (nonz[i & 1]) {
1920   if ((j = pana_bits(8))) {
1921     if ((pred[i & 1] -= 0x80 << sh) < 0 || sh == 4)
1922          pred[i & 1] &= ~(-1 << sh);
1923     pred[i & 1] += j << sh;
1924   }
1925       } else if ((nonz[i & 1] = pana_bits(8)) || i > 11)
1926   pred[i & 1] = nonz[i & 1] << 4 | pana_bits(4);
1927       if ((RAW(row,col) = pred[col & 1]) > 4098 && col < m_Width) derror();
1928     }
1929 }
1930 
olympus_load_raw()1931 void CLASS olympus_load_raw()
1932 {
1933   uint16_t huff[4096];
1934   int row, col, nbits, sign, low, high, i, c, w, n, nw;
1935   int acarry[2][3], *carry, pred, diff;
1936 
1937   huff[n=0] = 0xc0c;
1938   for (i=12; i--; )
1939     for (c=0;c<(2048>>i);c++) huff[++n] = (i+1) << 8 | i;
1940   fseek (m_InputFile, 7, SEEK_CUR);
1941   getbits(-1);
1942   for (row=0; row < m_Height; row++) {
1943     memset (acarry, 0, sizeof acarry);
1944     for (col=0; col < m_RawWidth; col++) {
1945       carry = acarry[col & 1];
1946       i = 2 * (carry[2] < 3);
1947       for (nbits=2+i; (uint16_t) carry[0] >> (nbits+i); nbits++){} ;
1948       low = (sign = getbits(3)) & 3;
1949       sign = sign << 29 >> 31;
1950       if ((high = getbithuff(12,huff)) == 12)
1951         high = getbits(16-nbits) >> 1;
1952       carry[0] = (high << nbits) | getbits(nbits);
1953       diff = (carry[0] ^ sign) + carry[1];
1954       carry[1] = (diff*3 + carry[1]) >> 5;
1955       carry[2] = carry[0] > 16 ? 0 : carry[2]+1;
1956       if (col >= m_Width) continue;
1957       if (row < 2 && col < 2) pred = 0;
1958       else if (row < 2) pred = RAW(row,col-2);
1959       else if (col < 2) pred = RAW(row-2,col);
1960       else {
1961   w  = RAW(row,col-2);
1962   n  = RAW(row-2,col);
1963   nw = RAW(row-2,col-2);
1964   if ((w < nw && nw < n) || (n < nw && nw < w)) {
1965     if (ABS(w-nw) > 32 || ABS(n-nw) > 32)
1966       pred = w + n - nw;
1967     else pred = (w + n) >> 1;
1968   } else pred = ABS(w-nw) > ABS(n-nw) ? w : n;
1969       }
1970       if ((RAW(row,col) = pred + ((diff << 2) | low)) >> 12) derror();
1971     }
1972   }
1973 }
1974 
olympus_cseries_load_raw()1975 void CLASS olympus_cseries_load_raw()
1976 {
1977   int irow, row, col;
1978 
1979   for (irow=0; irow < m_Height; irow++) {
1980     row = irow * 2 % m_Height + irow / (m_Height/2);
1981     if (row < 2) {
1982       fseek (m_InputFile, m_Data_Offset - row*(-m_Width*m_Height*3/4 & -2048), SEEK_SET);
1983       getbits(-1);
1984     }
1985     for (col=0; col < m_Width; col++)
1986       BAYER(row,col) = getbits(12);
1987   }
1988   m_BlackLevel >>= 4;
1989 }
1990 
minolta_rd175_load_raw()1991 void CLASS minolta_rd175_load_raw()
1992 {
1993   uint8_t pixel[768];
1994   unsigned irow, box, row, col;
1995 
1996   for (irow=0; irow < 1481; irow++) {
1997     if (fread (pixel, 1, 768, m_InputFile) < 768) derror();
1998     box = irow / 82;
1999     row = irow % 82 * 12 + ((box < 12) ? box | 1 : (box-12)*2);
2000     switch (irow) {
2001       case 1477: case 1479: continue;
2002       case 1476: row = 984; break;
2003       case 1480: row = 985; break;
2004       case 1478: row = 985; box = 1;
2005     }
2006     if ((box < 12) && (box & 1)) {
2007       for (col=0; col < 1533; col++, row ^= 1)
2008   if (col != 1) RAW(row,col) = (col+1) & 2 ?
2009        pixel[col/2-1] + pixel[col/2+1] : pixel[col/2] << 1;
2010       RAW(row,1)    = pixel[1]   << 1;
2011       RAW(row,1533) = pixel[765] << 1;
2012     } else
2013       for (col=row & 1; col < 1534; col+=2)
2014   RAW(row,col) = pixel[col/2] << 1;
2015   }
2016   m_WhiteLevel = 0xff << 1;
2017 }
2018 
quicktake_100_load_raw()2019 void CLASS quicktake_100_load_raw()
2020 {
2021   uint8_t pixel[484][644];
2022   static const short gstep[16] =
2023   { -89,-60,-44,-32,-22,-15,-8,-2,2,8,15,22,32,44,60,89 };
2024   static const short rstep[6][4] =
2025   { {  -3,-1,1,3  }, {  -5,-1,1,5  }, {  -8,-2,2,8  },
2026     { -13,-3,3,13 }, { -19,-4,4,19 }, { -28,-6,6,28 } };
2027   int rb, row, col, sharp, val=0;
2028 
2029   getbits(-1);
2030   memset (pixel, 0x80, sizeof pixel);
2031   for (row=2; row < m_Height+2; row++) {
2032     for (col=2+(row & 1); col < m_Width+2; col+=2) {
2033       val = ((pixel[row-1][col-1] + 2*pixel[row-1][col+1] +
2034     pixel[row][col-2]) >> 2) + gstep[getbits(4)];
2035       pixel[row][col] = val = LIM(val,0,255);
2036       if (col < 4)
2037   pixel[row][col-2] = pixel[row+1][~row & 1] = val;
2038       if (row == 2)
2039   pixel[row-1][col+1] = pixel[row-1][col+3] = val;
2040     }
2041     pixel[row][col] = val;
2042   }
2043   for (rb=0; rb < 2; rb++)
2044     for (row=2+rb; row < m_Height+2; row+=2)
2045       for (col=3-(row & 1); col < m_Width+2; col+=2) {
2046   if (row < 4 || col < 4) sharp = 2;
2047   else {
2048     val = ABS(pixel[row-2][col] - pixel[row][col-2])
2049         + ABS(pixel[row-2][col] - pixel[row-2][col-2])
2050         + ABS(pixel[row][col-2] - pixel[row-2][col-2]);
2051     sharp = val <  4 ? 0 : val <  8 ? 1 : val < 16 ? 2 :
2052       val < 32 ? 3 : val < 48 ? 4 : 5;
2053   }
2054   val = ((pixel[row-2][col] + pixel[row][col-2]) >> 1)
2055         + rstep[sharp][getbits(2)];
2056   pixel[row][col] = val = LIM(val,0,255);
2057   if (row < 4) pixel[row-2][col+2] = val;
2058   if (col < 4) pixel[row+2][col-2] = val;
2059       }
2060   for (row=2; row < m_Height+2; row++)
2061     for (col=3-(row & 1); col < m_Width+2; col+=2) {
2062       val = ((pixel[row][col-1] + (pixel[row][col] << 2) +
2063         pixel[row][col+1]) >> 1) - 0x100;
2064       pixel[row][col] = LIM(val,0,255);
2065     }
2066   for (row=0; row < m_Height; row++)
2067     for (col=0; col < m_Width; col++)
2068       RAW(row,col) = m_Curve[pixel[row+2][col+2]];
2069   m_WhiteLevel = 0x3ff;
2070 }
2071 
2072 #define radc_token(tree) ((signed char) getbithuff(8,huff[tree]))
2073 
2074 #define FORYX for (y=1; y < 3; y++) for (x=col+1; x >= col; x--)
2075 
2076 #define PREDICTOR (c ? (buf[c][y-1][x] + buf[c][y][x+1]) / 2 \
2077 : (buf[c][y-1][x+1] + 2*buf[c][y-1][x] + buf[c][y][x+1]) / 4)
2078 
kodak_radc_load_raw()2079 void CLASS kodak_radc_load_raw()
2080 {
2081   static const int8_t src[] = {
2082     1,1, 2,3, 3,4, 4,2, 5,7, 6,5, 7,6, 7,8,
2083     1,0, 2,1, 3,3, 4,4, 5,2, 6,7, 7,6, 8,5, 8,8,
2084     2,1, 2,3, 3,0, 3,2, 3,4, 4,6, 5,5, 6,7, 6,8,
2085     2,0, 2,1, 2,3, 3,2, 4,4, 5,6, 6,7, 7,5, 7,8,
2086     2,1, 2,4, 3,0, 3,2, 3,3, 4,7, 5,5, 6,6, 6,8,
2087     2,3, 3,1, 3,2, 3,4, 3,5, 3,6, 4,7, 5,0, 5,8,
2088     2,3, 2,6, 3,0, 3,1, 4,4, 4,5, 4,7, 5,2, 5,8,
2089     2,4, 2,7, 3,3, 3,6, 4,1, 4,2, 4,5, 5,0, 5,8,
2090     2,6, 3,1, 3,3, 3,5, 3,7, 3,8, 4,0, 5,2, 5,4,
2091     2,0, 2,1, 3,2, 3,3, 4,4, 4,5, 5,6, 5,7, 4,8,
2092     1,0, 2,2, 2,-2,
2093     1,-3, 1,3,
2094     2,-17, 2,-5, 2,5, 2,17,
2095     2,-7, 2,2, 2,9, 2,18,
2096     2,-18, 2,-9, 2,-2, 2,7,
2097     2,-28, 2,28, 3,-49, 3,-9, 3,9, 4,49, 5,-79, 5,79,
2098     2,-1, 2,13, 2,26, 3,39, 4,-16, 5,55, 6,-37, 6,76,
2099     2,-26, 2,-13, 2,1, 3,-39, 4,16, 5,-55, 6,-76, 6,37
2100   };
2101   uint16_t huff[19][256];
2102   int row, col, tree, nreps, rep, step, /* i,*/ c, s, r, x, y, val;
2103   constexpr unsigned int bufi1 = 3;
2104   constexpr unsigned int bufi2 = 386;
2105   short last[3] = { 16,16,16 }, mul[3], buf[3][bufi1][bufi2];
2106   static const uint16_t pt[] =
2107     { 0,0, 1280,1344, 2320,3616, 3328,8000, 4095,16383, 65535,16383 };
2108   int i;
2109 
2110   for (i=2; i < 12; i+=2)
2111     for (c=pt[i-2]; c <= pt[i]; c++)
2112       m_Curve[c] = (float)
2113   (c-pt[i-2]) / (pt[i]-pt[i-2]) * (pt[i+1]-pt[i-1]) + pt[i-1] + 0.5;
2114   for (s=i=0; i < (int)(sizeof(src)); i+=2)
2115     for(c=0;c<(256>>src[i]);c++)
2116       huff[0][s++] = src[i] << 8 | (unsigned char) src[i+1];
2117   s = m_Kodak_cbpp == 243 ? 2 : 3;
2118   for(c=0;c<256;c++) huff[18][c] = (8-s) << 8 | c >> s << s | 1 << (s-1);
2119   getbits(-1);
2120   memset(buf, 2048, sizeof(buf)/sizeof(short));
2121 //  for (unsigned i=0; i < sizeof(buf)/sizeof(short); i++)
2122 //    buf[0][0][i] = 2048;
2123   for (row=0; row < m_Height; row+=4) {
2124     for (c=0; c<3; c++) mul[c] = getbits(6);
2125     for (c=0; c<3; c++) {
2126       val = ((0x1000000/last[c] + 0x7ff) >> 12) * mul[c];
2127       s = val > 65564 ? 10:12;
2128       x = ~(-1 << (s-1));
2129       val <<= 12-s;
2130       for (unsigned i=0; i < bufi1; i++)
2131         for (unsigned j=0; j < bufi2; j++)
2132           buf[c][i][j] = (buf[c][i][j] * val + x) >> s;
2133 //      for (unsigned i=0; i < sizeof(buf[0])/sizeof(short); i++)
2134 //        buf[c][0][i] = (buf[c][0][i] * val + x) >> s;
2135       last[c] = mul[c];
2136       for (r=0; r <= !c; r++) {
2137   buf[c][1][m_Width/2] = buf[c][2][m_Width/2] = mul[c] << 7;
2138   for (tree=1, col=m_Width/2; col > 0; ) {
2139     if ((tree = radc_token(tree))) {
2140       col -= 2;
2141       if (tree == 8)
2142         FORYX buf[c][y][x] = (uint8_t) radc_token(18) * mul[c];
2143       else
2144         FORYX buf[c][y][x] = radc_token(tree+10) * 16 + PREDICTOR;
2145     } else
2146       do {
2147         nreps = (col > 2) ? radc_token(9) + 1 : 1;
2148         for (rep=0; rep < 8 && rep < nreps && col > 0; rep++) {
2149     col -= 2;
2150     FORYX buf[c][y][x] = PREDICTOR;
2151     if (rep & 1) {
2152       step = radc_token(10) << 4;
2153       FORYX buf[c][y][x] += step;
2154     }
2155         }
2156       } while (nreps == 9);
2157   }
2158   for (y=0; y < 2; y++)
2159     for (x=0; x < m_Width/2; x++) {
2160       val = (buf[c][y+1][x] << 4) / mul[c];
2161       if (val < 0) val = 0;
2162       if (c) RAW(row+y*2+c-1,x*2+2-c) = val;
2163       else   RAW(row+r*2+y,x*2+y) = val;
2164     }
2165   memcpy (buf[c][0]+!c, buf[c][2], sizeof buf[c][0]-2*!c);
2166       }
2167     }
2168     for (y=row; y < row+4; y++)
2169       for (x=0; x < m_Width; x++)
2170   if ((x+y) & 1) {
2171     r = x ? x-1 : x+1;
2172     s = x+1 < m_Width ? x+1 : x-1;
2173     val = (RAW(y,x)-2048)*2 + (RAW(y,r)+RAW(y,s))/2;
2174     if (val < 0) val = 0;
2175     RAW(y,x) = val;
2176   }
2177   }
2178   for (i=0; i < m_Height*m_Width; i++)
2179     m_Raw_Image[i] = m_Curve[m_Raw_Image[i]];
2180 
2181   m_WhiteLevel = 0xfff;
2182 }
2183 
2184 #undef FORYX
2185 #undef PREDICTOR
2186 
2187 #ifdef NO_JPEG
kodak_jpeg_load_raw()2188 void CLASS kodak_jpeg_load_raw() {}
lossy_dng_load_raw()2189 void CLASS lossy_dng_load_raw() {}
2190 #else
2191 
2192 METHODDEF(boolean)
fill_input_buffer(j_decompress_ptr cinfo)2193 fill_input_buffer (j_decompress_ptr cinfo)
2194 {
2195   static uint8_t jpeg_buffer[4096];
2196   size_t nbytes;
2197   ptDcRaw *data = (ptDcRaw*) cinfo->client_data;
2198 
2199   nbytes = fread (jpeg_buffer, 1, 4096, data->m_InputFile);
2200   swab ((char *)jpeg_buffer, (char *)jpeg_buffer, nbytes);
2201   cinfo->src->next_input_byte = jpeg_buffer;
2202   cinfo->src->bytes_in_buffer = nbytes;
2203   return TRUE;
2204 }
2205 
kodak_jpeg_load_raw()2206 void CLASS kodak_jpeg_load_raw()
2207 {
2208   struct jpeg_decompress_struct cinfo;
2209   struct jpeg_error_mgr jerr;
2210   JSAMPARRAY buf;
2211   JSAMPLE (*pixel)[3];
2212   int row, col;
2213 
2214   cinfo.client_data = this;
2215   cinfo.err = jpeg_std_error (&jerr);
2216   jpeg_create_decompress (&cinfo);
2217   jpeg_stdio_src (&cinfo, m_InputFile);
2218   cinfo.src->fill_input_buffer = fill_input_buffer;
2219   jpeg_read_header (&cinfo, TRUE);
2220   jpeg_start_decompress (&cinfo);
2221   if ((cinfo.output_width      != m_Width  ) ||
2222       (cinfo.output_height*2   != m_Height ) ||
2223       (cinfo.output_components != 3      )) {
2224     fprintf (stderr,_("%s: incorrect JPEG dimensions\n"), m_UserSetting_InputFileName);
2225     jpeg_destroy_decompress (&cinfo);
2226     longjmp (m_Failure, 3);
2227   }
2228   buf = (*cinfo.mem->alloc_sarray)
2229     ((j_common_ptr) &cinfo, JPOOL_IMAGE, m_Width*3, 1);
2230 
2231   while (cinfo.output_scanline < cinfo.output_height) {
2232     row = cinfo.output_scanline * 2;
2233     jpeg_read_scanlines (&cinfo, buf, 1);
2234     pixel = (JSAMPLE (*)[3]) buf[0];
2235     for (col=0; col < m_Width; col+=2) {
2236       RAW(row+0,col+0) = pixel[col+0][1] << 1;
2237       RAW(row+1,col+1) = pixel[col+1][1] << 1;
2238       RAW(row+0,col+1) = pixel[col][0] + pixel[col+1][0];
2239       RAW(row+1,col+0) = pixel[col][2] + pixel[col+1][2];
2240     }
2241   }
2242   jpeg_finish_decompress (&cinfo);
2243   jpeg_destroy_decompress (&cinfo);
2244   m_WhiteLevel = 0xff << 1;
2245 }
2246 
lossy_dng_load_raw()2247 void CLASS lossy_dng_load_raw()
2248 {
2249   struct jpeg_decompress_struct cinfo;
2250   struct jpeg_error_mgr jerr;
2251   JSAMPARRAY buf;
2252   JSAMPLE (*pixel)[3];
2253   unsigned sm_ByteOrder=m_ByteOrder, ntags, opcode, deg, i, j, c;
2254   unsigned save=m_Data_Offset-4, trow=0, tcol=0, row, col;
2255   ushort curve[3][256];
2256   double coeff[9], tot;
2257 
2258   fseek (m_InputFile, meta_offset, SEEK_SET);
2259   m_ByteOrder = 0x4d4d;
2260   ntags = get4();
2261   while (ntags--) {
2262     opcode = get4(); get4(); get4();
2263     if (opcode != 8)
2264     { fseek (m_InputFile, get4(), SEEK_CUR); continue; }
2265     fseek (m_InputFile, 20, SEEK_CUR);
2266     if ((c = get4()) > 2) break;
2267     fseek (m_InputFile, 12, SEEK_CUR);
2268     if ((deg = get4()) > 8) break;
2269     for (i=0; i <= deg && i < 9; i++)
2270       coeff[i] = getreal(12);
2271     for (i=0; i < 256; i++) {
2272       for (tot=j=0; j <= deg; j++)
2273   tot += coeff[j] * pow(i/255.0, j);
2274       curve[c][i] = tot*0xffff;
2275     }
2276   }
2277   m_ByteOrder = sm_ByteOrder;
2278   cinfo.err = jpeg_std_error (&jerr);
2279   jpeg_create_decompress (&cinfo);
2280   while (trow < m_RawHeight) {
2281     fseek (m_InputFile, save+=4, SEEK_SET);
2282     if (m_TileLength < INT_MAX)
2283       fseek (m_InputFile, get4(), SEEK_SET);
2284     jpeg_stdio_src (&cinfo, m_InputFile);
2285     jpeg_read_header (&cinfo, TRUE);
2286     jpeg_start_decompress (&cinfo);
2287     buf = (*cinfo.mem->alloc_sarray)
2288   ((j_common_ptr) &cinfo, JPOOL_IMAGE, cinfo.output_width*3, 1);
2289     while (cinfo.output_scanline < cinfo.output_height &&
2290   (row = trow + cinfo.output_scanline) < m_Height) {
2291       jpeg_read_scanlines (&cinfo, buf, 1);
2292       pixel = (JSAMPLE (*)[3]) buf[0];
2293       for (col=0; col < cinfo.output_width && tcol+col < m_Width; col++) {
2294   for (c=0; c<3; c++) m_Image[row*m_Width+tcol+col][c] = curve[c][pixel[col][c]];
2295       }
2296     }
2297     jpeg_abort_decompress (&cinfo);
2298     if ((tcol += m_TileWidth) >= m_RawWidth)
2299       trow += m_TileLength + (tcol = 0);
2300   }
2301   jpeg_destroy_decompress (&cinfo);
2302   m_WhiteLevel = 0xffff;
2303 }
2304 #endif
2305 
kodak_dc120_load_raw()2306 void CLASS kodak_dc120_load_raw()
2307 {
2308   static const int mul[4] = { 162, 192, 187,  92 };
2309   static const int add[4] = {   0, 636, 424, 212 };
2310   uint8_t pixel[848];
2311   int row, shift, col;
2312 
2313   for (row=0; row < m_Height; row++) {
2314     if (fread (pixel, 1, 848, m_InputFile) < 848) derror();
2315     shift = row * mul[row & 3] + add[row & 3];
2316     for (col=0; col < m_Width; col++)
2317       RAW(row,col) = (uint16_t) pixel[(col + shift) % 848];
2318   }
2319   m_WhiteLevel = 0xff;
2320 }
2321 
eight_bit_load_raw()2322 void CLASS eight_bit_load_raw()
2323 {
2324   uint8_t *pixel;
2325   unsigned row, col;
2326 
2327   pixel = (uint8_t *) CALLOC (m_RawWidth, sizeof *pixel);
2328   merror (pixel, "eight_bit_load_raw()");
2329   for (row=0; row < m_RawHeight; row++) {
2330     if (fread (pixel, 1, m_RawWidth, m_InputFile) < m_RawWidth) derror();
2331     for (col=0; col < m_RawWidth; col++)
2332       RAW(row,col) = m_Curve[pixel[col]];
2333   }
2334   FREE (pixel);
2335   m_WhiteLevel = m_Curve[0xff];
2336 }
2337 
kodak_yrgb_load_raw()2338 void CLASS kodak_yrgb_load_raw()
2339 {
2340   uint8_t *pixel;
2341   int row, col, y, cb, cr, rgb[3], c;
2342 
2343   pixel = (uint8_t *) CALLOC (m_RawWidth, 3*sizeof *pixel);
2344   merror (pixel, "kodak_yrgb_load_raw()");
2345   for (row=0; row < m_Height; row++) {
2346     if (~row & 1)
2347       if (fread (pixel, m_RawWidth, 3, m_InputFile) < 3) derror();
2348     for (col=0; col < m_RawWidth; col++) {
2349       y  = pixel[m_Width*2*(row & 1) + col];
2350       cb = pixel[m_Width + (col & -2)]   - 128;
2351       cr = pixel[m_Width + (col & -2)+1] - 128;
2352       rgb[1] = y-((cb + cr + 2) >> 2);
2353       rgb[2] = rgb[1] + cb;
2354       rgb[0] = rgb[1] + cr;
2355       for (c=0;c<3;c++) m_Image[row*m_Width+col][c] = m_Curve[LIM(rgb[c],0,255)];
2356     }
2357   }
2358   FREE (pixel);
2359   m_WhiteLevel = m_Curve[0xff];
2360 }
2361 
kodak_262_load_raw()2362 void CLASS kodak_262_load_raw()
2363 {
2364   static const uint8_t kodak_tree[2][26] =
2365   { { 0,1,5,1,1,2,0,0,0,0,0,0,0,0,0,0, 0,1,2,3,4,5,6,7,8,9 },
2366     { 0,3,1,1,1,1,1,2,0,0,0,0,0,0,0,0, 0,1,2,3,4,5,6,7,8,9 } };
2367   uint16_t *huff[2];
2368   uint8_t *pixel;
2369   int *strip, ns, c, row, col, chess, pi=0, pi1, pi2, pred, val;
2370   huff[0] = make_decoder (kodak_tree[0]);
2371   huff[1] = make_decoder (kodak_tree[1]);
2372   ns = (m_RawHeight+63) >> 5;
2373   pixel = (uint8_t *) MALLOC (m_RawWidth*32 + ns*4);
2374   merror (pixel, "kodak_262_load_raw()");
2375   strip = (int *) (pixel + m_RawWidth*32);
2376   m_ByteOrder = 0x4d4d;
2377   for(c=0;c<ns;c++) strip[c] = get4();
2378   for (row=0; row < m_RawHeight; row++) {
2379     if ((row & 31) == 0) {
2380       fseek (m_InputFile, strip[row >> 5], SEEK_SET);
2381       getbits(-1);
2382       pi = 0;
2383     }
2384     for (col=0; col < m_RawWidth; col++) {
2385       chess = (row + col) & 1;
2386       pi1 = chess ? pi-2           : pi-m_RawWidth-1;
2387       pi2 = chess ? pi-2*m_RawWidth : pi-m_RawWidth+1;
2388       if (col <= chess) pi1 = -1;
2389       if (pi1 < 0) pi1 = pi2;
2390       if (pi2 < 0) pi2 = pi1;
2391       if (pi1 < 0 && col > 1) pi1 = pi2 = pi-2;
2392       pred = (pi1 < 0) ? 0 : (pixel[pi1] + pixel[pi2]) >> 1;
2393       pixel[pi] = val = pred + ljpeg_diff (huff[chess]);
2394       if (val >> 8) derror();
2395       val = m_Curve[pixel[pi++]];
2396       RAW(row,col) = val;
2397     }
2398   }
2399   FREE (pixel);
2400   FREE (huff[0]);
2401   FREE (huff[1]);
2402 }
2403 
kodak_65000_decode(short * out,int bsize)2404 int CLASS kodak_65000_decode (short *out, int bsize)
2405 {
2406   uint8_t c, blen[768];
2407   uint16_t raw[6];
2408   int64_t bitbuf=0;
2409   int save, bits=0, i, j, len, diff;
2410 
2411   save = ftell(m_InputFile);
2412   bsize = (bsize + 3) & -4;
2413   for (i=0; i < bsize; i+=2) {
2414     c = fgetc(m_InputFile);
2415     if ((blen[i  ] = c & 15) > 12 ||
2416   (blen[i+1] = c >> 4) > 12 ) {
2417       fseek (m_InputFile, save, SEEK_SET);
2418       for (i=0; i < bsize; i+=8) {
2419   read_shorts (raw, 6);
2420   out[i  ] = raw[0] >> 12 << 8 | raw[2] >> 12 << 4 | raw[4] >> 12;
2421   out[i+1] = raw[1] >> 12 << 8 | raw[3] >> 12 << 4 | raw[5] >> 12;
2422   for (j=0; j < 6; j++)
2423     out[i+2+j] = raw[j] & 0xfff;
2424       }
2425       return 1;
2426     }
2427   }
2428   if ((bsize & 7) == 4) {
2429     bitbuf  = fgetc(m_InputFile) << 8;
2430     bitbuf += fgetc(m_InputFile);
2431     bits = 16;
2432   }
2433   for (i=0; i < bsize; i++) {
2434     len = blen[i];
2435     if (bits < len) {
2436       for (j=0; j < 32; j+=8)
2437   bitbuf += (int64_t) fgetc(m_InputFile) << (bits+(j^8));
2438       bits += 32;
2439     }
2440     diff = bitbuf & (0xffff >> (16-len));
2441     bitbuf >>= len;
2442     bits -= len;
2443     if ((diff & (1 << (len-1))) == 0)
2444       diff -= (1 << len) - 1;
2445     out[i] = diff;
2446   }
2447   return 0;
2448 }
2449 
kodak_65000_load_raw()2450 void CLASS kodak_65000_load_raw()
2451 {
2452   short buf[256];
2453   int row, col, len, pred[2], ret, i;
2454 
2455   for (row=0; row < m_Height; row++)
2456     for (col=0; col < m_Width; col+=256) {
2457       pred[0] = pred[1] = 0;
2458       len = MIN (256, m_Width-col);
2459       ret = kodak_65000_decode (buf, len);
2460       for (i=0; i < len; i++)
2461   if ((RAW(row,col+i) =	m_Curve[ret ? buf[i] :
2462     (pred[i & 1] += buf[i])]) >> 12) derror();
2463     }
2464 }
2465 
kodak_ycbcr_load_raw()2466 void CLASS kodak_ycbcr_load_raw()
2467 {
2468   short buf[384], *bp;
2469   int row, col, len, c, i, j, k, y[2][2], cb, cr, rgb[3];
2470   uint16_t *ip;
2471 
2472   for (row=0; row < m_Height; row+=2)
2473     for (col=0; col < m_Width; col+=128) {
2474       len = MIN (128, m_Width-col);
2475       kodak_65000_decode (buf, len*3);
2476       y[0][1] = y[1][1] = cb = cr = 0;
2477       for (bp=buf, i=0; i < len; i+=2, bp+=2) {
2478   cb += bp[4];
2479   cr += bp[5];
2480   rgb[1] = -((cb + cr + 2) >> 2);
2481   rgb[2] = rgb[1] + cb;
2482   rgb[0] = rgb[1] + cr;
2483   for (j=0; j < 2; j++)
2484     for (k=0; k < 2; k++) {
2485       if ((y[j][k] = y[j][k^1] + *bp++) >> 10) derror();
2486       ip = m_Image[(row+j)*m_Width + col+i+k];
2487       for (c=0; c<3; c++) ip[c] = m_Curve[LIM(y[j][k]+rgb[c], 0, 0xfff)];
2488     }
2489       }
2490     }
2491 }
2492 
kodak_rgb_load_raw()2493 void CLASS kodak_rgb_load_raw()
2494 {
2495   short buf[768], *bp;
2496   int row, col, len, c, i, rgb[3];
2497   uint16_t *ip=m_Image[0];
2498 
2499   if (m_Raw_Image) FREE (m_Raw_Image);
2500   m_Raw_Image = 0;
2501   for (row=0; row < m_Height; row++)
2502     for (col=0; col < m_Width; col+=256) {
2503       len = MIN (256, m_Width-col);
2504       kodak_65000_decode (buf, len*3);
2505       memset (rgb, 0, sizeof rgb);
2506       for (bp=buf, i=0; i < len; i++, ip+=4)
2507   for (c=0; c<3; c++) if ((ip[c] = rgb[c] += *bp++) >> 12) derror();
2508     }
2509 }
2510 
kodak_thumb_load_raw()2511 void CLASS kodak_thumb_load_raw()
2512 {
2513   int row, col;
2514   m_Colors = m_ThumbMisc >> 5;
2515   for (row=0; row < m_Height; row++)
2516     for (col=0; col < m_Width; col++)
2517       read_shorts (m_Image[row*m_Width+col], m_Colors);
2518   m_WhiteLevel = (1 << (m_ThumbMisc & 31)) - 1;
2519 }
2520 
sony_decrypt(unsigned * data,int len,int start,int key)2521 void CLASS sony_decrypt (unsigned *data, int len, int start, int key)
2522 {
2523   if (start) {
2524     for (m_sony_decrypt_p=0; m_sony_decrypt_p < 4; m_sony_decrypt_p++)
2525       m_sony_decrypt_pad[m_sony_decrypt_p] = key = key * 48828125 + 1;
2526     m_sony_decrypt_pad[3] = m_sony_decrypt_pad[3] << 1 | (m_sony_decrypt_pad[0]^m_sony_decrypt_pad[2]) >> 31;
2527     for (m_sony_decrypt_p=4; m_sony_decrypt_p < 127; m_sony_decrypt_p++)
2528       m_sony_decrypt_pad[m_sony_decrypt_p] = (m_sony_decrypt_pad[m_sony_decrypt_p-4]^m_sony_decrypt_pad[m_sony_decrypt_p-2]) << 1 | (m_sony_decrypt_pad[m_sony_decrypt_p-3]^m_sony_decrypt_pad[m_sony_decrypt_p-1]) >> 31;
2529     for (m_sony_decrypt_p=0; m_sony_decrypt_p < 127; m_sony_decrypt_p++)
2530       m_sony_decrypt_pad[m_sony_decrypt_p] = htonl(m_sony_decrypt_pad[m_sony_decrypt_p]);
2531   }
2532   while (len--)
2533     *data++ ^= m_sony_decrypt_pad[m_sony_decrypt_p++ & 127] = m_sony_decrypt_pad[(m_sony_decrypt_p+1) & 127] ^ m_sony_decrypt_pad[(m_sony_decrypt_p+65) & 127];
2534 }
2535 
sony_load_raw()2536 void CLASS sony_load_raw()
2537 {
2538   uint8_t head[40];
2539   uint16_t *pixel;
2540   unsigned i, key; // row, col;
2541   uint16_t row,col;
2542 
2543   fseek (m_InputFile, 200896, SEEK_SET);
2544   fseek (m_InputFile, (unsigned) fgetc(m_InputFile)*4 - 1, SEEK_CUR);
2545   m_ByteOrder = 0x4d4d;
2546   key = get4();
2547   fseek (m_InputFile, 164600, SEEK_SET);
2548   ptfread (head, 1, 40, m_InputFile);
2549   sony_decrypt ((unsigned int *) head, 10, 1, key);
2550   for (i=26; i-- > 22; )
2551     key = key << 8 | head[i];
2552   fseek (m_InputFile, m_Data_Offset, SEEK_SET);
2553   for (row=0; row < m_RawHeight; row++) {
2554     pixel = m_Raw_Image + row*m_RawWidth;
2555     if (fread (pixel, 2, m_RawWidth, m_InputFile) < m_RawWidth) derror();
2556     sony_decrypt ((unsigned int *) pixel, m_RawWidth/2, !row, key);
2557     for (col=0; col < m_RawWidth; col++)
2558       if ((pixel[col] = ntohs(pixel[col])) >> 14) derror();
2559   }
2560   m_WhiteLevel = 0x3ff0;
2561 }
2562 
sony_arw_load_raw()2563 void CLASS sony_arw_load_raw()
2564 {
2565   uint16_t huff[32768];
2566   static const uint16_t tab[18] =
2567   { 0xf11,0xf10,0xe0f,0xd0e,0xc0d,0xb0c,0xa0b,0x90a,0x809,
2568     0x708,0x607,0x506,0x405,0x304,0x303,0x300,0x202,0x201 };
2569   int i, c, n, col, row, len, diff, sum=0;
2570 
2571   for (n=i=0; i < 18; i++)
2572     for (c=0;c<(32768 >> (tab[i] >> 8));c++) huff[n++] = tab[i];
2573 
2574   getbits(-1);
2575   for (col = m_RawWidth; col--; )
2576     for (row=0; row < m_RawHeight+1; row+=2) {
2577       if (row == m_RawHeight) row = 1;
2578       len = getbithuff(15,huff);
2579       diff = getbits(len);
2580       if ((diff & (1 << (len-1))) == 0)
2581   diff -= (1 << len) - 1;
2582       if ((sum += diff) >> 12) derror();
2583       if (row < m_Height) RAW(row,col) = sum;
2584     }
2585 }
2586 
sony_arw2_load_raw()2587 void CLASS sony_arw2_load_raw()
2588 {
2589   uint8_t *data, *dp;
2590   uint16_t pix[16];
2591   int row, col, val, max, min, imax, imin, sh, bit, i;
2592 
2593   data = (uint8_t *) MALLOC (m_RawWidth);
2594   merror (data, "sony_arw2_load_raw()");
2595   for (row=0; row < m_Height; row++) {
2596     ptfread (data, 1, m_RawWidth, m_InputFile);
2597     for (dp=data, col=0; col < m_RawWidth-30; dp+=16) {
2598       max = 0x7ff & (val = sget4(dp));
2599       min = 0x7ff & val >> 11;
2600       imax = 0x0f & val >> 22;
2601       imin = 0x0f & val >> 26;
2602       for (sh=0; sh < 4 && 0x80 << sh <= max-min; sh++) {};
2603       for (bit=30, i=0; i < 16; i++)
2604   if      (i == imax) pix[i] = max;
2605   else if (i == imin) pix[i] = min;
2606   else {
2607     pix[i] = ((sget2(dp+(bit >> 3)) >> (bit & 7) & 0x7f) << sh) + min;
2608     if (pix[i] > 0x7ff) pix[i] = 0x7ff;
2609     bit += 7;
2610   }
2611       for (i=0; i < 16; i++, col+=2)
2612 	RAW(row,col) = m_Curve[pix[i] << 1] >> 2;
2613       col -= col & 1 ? 1:31;
2614     }
2615   }
2616   FREE (data);
2617 }
2618 
2619 #define HOLE(row) ((holes >> (((row) - m_RawHeight) & 7)) & 1)
2620 
2621 /* Kudos to Rich Taylor for figuring out SMaL's compression algorithm. */
smal_decode_segment(unsigned seg[2][2],int holes)2622 void CLASS smal_decode_segment (unsigned seg[2][2], int holes)
2623 {
2624   uint8_t hist[3][13] = {
2625     { 7, 7, 0, 0, 63, 55, 47, 39, 31, 23, 15, 7, 0 },
2626     { 7, 7, 0, 0, 63, 55, 47, 39, 31, 23, 15, 7, 0 },
2627     { 3, 3, 0, 0, 63,     47,     31,     15,    0 } };
2628   int low, high=0xff, carry=0, nbits=8;
2629   int pix, s, count, bin, next, i, sym[3];
2630   uint8_t diff, pred[]={0,0};
2631   uint16_t data=0, range=0;
2632 
2633   fseek (m_InputFile, seg[0][1]+1, SEEK_SET);
2634   getbits(-1);
2635   for (pix=seg[0][0]; pix < (int32_t)seg[1][0]; pix++) {
2636     for (s=0; s < 3; s++) {
2637       data = data << nbits | getbits(nbits);
2638       if (carry < 0)
2639   carry = (nbits += carry+1) < 1 ? nbits-1 : 0;
2640       while (--nbits >= 0)
2641   if ((data >> nbits & 0xff) == 0xff) break;
2642       if (nbits > 0)
2643     data = ((data & ((1 << (nbits-1)) - 1)) << 1) |
2644   ((data + (((data & (1 << (nbits-1)))) << 1)) & (-1 << nbits));
2645       if (nbits >= 0) {
2646   data += getbits(1);
2647   carry = nbits - 8;
2648       }
2649       count = ((((data-range+1) & 0xffff) << 2) - 1) / (high >> 4);
2650       for (bin=0; hist[s][bin+5] > count; bin++) {} ;
2651     low = hist[s][bin+5] * (high >> 4) >> 2;
2652       if (bin) high = hist[s][bin+4] * (high >> 4) >> 2;
2653       high -= low;
2654       for (nbits=0; high << nbits < 128; nbits++) {} ;
2655       range = (range+low) << nbits;
2656       high <<= nbits;
2657       next = hist[s][1];
2658       if (++hist[s][2] > hist[s][3]) {
2659         next = (next+1) & hist[s][0];
2660         hist[s][3] = (hist[s][next+4] - hist[s][next+5]) >> 2;
2661         hist[s][2] = 1;
2662       }
2663       if (hist[s][hist[s][1]+4] - hist[s][hist[s][1]+5] > 1) {
2664   if (bin < hist[s][1]) {
2665 #pragma GCC diagnostic push
2666 #pragma GCC diagnostic ignored "-Warray-bounds"
2667     for (i=bin; i < hist[s][1]; i++) hist[s][i+5]--;
2668 #pragma GCC diagnostic pop
2669   } else if (next <= bin)
2670     for (i=hist[s][1]; i < bin; i++) hist[s][i+5]++;
2671       }
2672       hist[s][1] = next;
2673       sym[s] = bin;
2674     }
2675     diff = sym[2] << 5 | sym[1] << 2 | (sym[0] & 3);
2676     if (sym[0] & 4)
2677       diff = diff ? -diff : 0x80;
2678     if (unsigned(ftell(m_InputFile) + 12) >= seg[1][1])
2679       diff = 0;
2680     m_Raw_Image[pix] = pred[pix & 1] += diff;
2681     if (!(pix & 1) && HOLE(pix / m_RawWidth)) pix += 2;
2682   }
2683   m_WhiteLevel = 0xff;
2684 }
2685 
smal_v6_load_raw()2686 void CLASS smal_v6_load_raw()
2687 {
2688   unsigned seg[2][2];
2689 
2690   fseek (m_InputFile, 16, SEEK_SET);
2691   seg[0][0] = 0;
2692   seg[0][1] = get2();
2693   seg[1][0] = m_RawWidth * m_RawHeight;
2694   seg[1][1] = INT_MAX;
2695   smal_decode_segment (seg, 0);
2696 }
2697 
median4(int * p)2698 int CLASS median4 (int *p)
2699 {
2700   int min, max, sum, i;
2701 
2702   min = max = sum = p[0];
2703   for (i=1; i < 4; i++) {
2704     sum += p[i];
2705     if (min > p[i]) min = p[i];
2706     if (max < p[i]) max = p[i];
2707   }
2708   return (sum - min - max) >> 1;
2709 }
2710 
fill_holes(int holes)2711 void CLASS fill_holes (int holes)
2712 {
2713   int row, col, val[4];
2714 
2715   for (row=2; row < m_Height-2; row++) {
2716     if (!HOLE(row)) continue;
2717     for (col=1; col < m_Width-1; col+=4) {
2718       val[0] = RAW(row-1,col-1);
2719       val[1] = RAW(row-1,col+1);
2720       val[2] = RAW(row+1,col-1);
2721       val[3] = RAW(row+1,col+1);
2722       RAW(row,col) = median4(val);
2723     }
2724     for (col=2; col < m_Width-2; col+=4)
2725       if (HOLE(row-2) || HOLE(row+2))
2726   RAW(row,col) = (RAW(row,col-2) + RAW(row,col+2)) >> 1;
2727       else {
2728   val[0] = RAW(row,col-2);
2729   val[1] = RAW(row,col+2);
2730   val[2] = RAW(row-2,col);
2731   val[3] = RAW(row+2,col);
2732   RAW(row,col) = median4(val);
2733       }
2734   }
2735 }
2736 
smal_v9_load_raw()2737 void CLASS smal_v9_load_raw()
2738 {
2739   unsigned seg[256][2], offset, nseg, holes, i;
2740 
2741   fseek (m_InputFile, 67, SEEK_SET);
2742   offset = get4();
2743   nseg = fgetc(m_InputFile);
2744   fseek (m_InputFile, offset, SEEK_SET);
2745   for (i=0; i < nseg*2; i++)
2746     seg[0][i] = get4() + m_Data_Offset*(i & 1);
2747   fseek (m_InputFile, 78, SEEK_SET);
2748   holes = fgetc(m_InputFile);
2749   fseek (m_InputFile, 88, SEEK_SET);
2750   seg[nseg][0] = m_RawHeight * m_RawWidth;
2751   seg[nseg][1] = get4() + m_Data_Offset;
2752   for (i=0; i < nseg; i++)
2753     smal_decode_segment (seg+i, holes);
2754   if (holes) fill_holes (holes);
2755 }
2756 
redcine_load_raw()2757 void CLASS redcine_load_raw()
2758 {
2759 #ifndef NO_JASPER
2760   int c, row, col;
2761   jas_stream_t *in;
2762   jas_m_Image_t *jimg;
2763   jas_matrix_t *jmat;
2764   jas_seqent_t *data;
2765   uint16_t *img, *pix;
2766 
2767   jas_init();
2768   in = jas_stream_fopen (ifname, "rb");
2769   jas_stream_seek (in, m_Data_Offset+20, SEEK_SET);
2770   jimg = jas_m_Image_decode (in, -1, 0);
2771   if (!jimg) longjmp (failure, 3);
2772   jmat = jas_matrix_create (m_Height/2, m_Width/2);
2773   merror (jmat, "redcine_m_load_raw()");
2774   img = (uint16_t *) calloc ((m_Height+2)*(m_Width+2), 2);
2775   merror (img, "redcine_m_load_raw()");
2776   for (c=0; c<4; c++) {
2777     jas_m_Image_readcmpt (jimg, c, 0, 0, m_Width/2, m_Height/2, jmat);
2778     data = jas_matrix_getref (jmat, 0, 0);
2779     for (row = c >> 1; row < m_Height; row+=2)
2780       for (col = c & 1; col < m_Width; col+=2)
2781   img[(row+1)*(m_Width+2)+col+1] = data[(row/2)*(m_Width/2)+col/2];
2782   }
2783   for (col=1; col <= m_Width; col++) {
2784     img[col] = img[2*(m_Width+2)+col];
2785     img[(m_Height+1)*(m_Width+2)+col] = img[(m_Height-1)*(m_Width+2)+col];
2786   }
2787   for (row=0; row < m_Height+2; row++) {
2788     img[row*(m_Width+2)] = img[row*(m_Width+2)+2];
2789     img[(row+1)*(m_Width+2)-1] = img[(row+1)*(m_Width+2)-3];
2790   }
2791   for (row=1; row <= m_Height; row++) {
2792     pix = img + row*(m_Width+2) + (col = 1 + (FC(row,1) & 1));
2793     for (   ; col <= m_Width; col+=2, pix+=2) {
2794       c = (((pix[0] - 0x800) << 3) +
2795   pix[-(m_Width+2)] + pix[m_Width+2] + pix[-1] + pix[1]) >> 2;
2796       pix[0] = LIM(c,0,4095);
2797     }
2798   }
2799   for (row=0; row < m_Height; row++)
2800     for (col=0; col < m_Width; col++)
2801       RAW(row,col) = m_Curve[img[(row+1)*(m_Width+2)+col+1]];
2802   free (img);
2803   jas_matrix_destroy (jmat);
2804   jas_m_Image_destroy (jimg);
2805   jas_stream_close (in);
2806 #endif
2807 }
2808 
2809 /* RESTRICTED code starts here */
2810 
foveon_decoder(unsigned size,unsigned code)2811 void CLASS foveon_decoder (unsigned size, unsigned code)
2812 {
2813   struct decode *cur;
2814   // int i, len;
2815   unsigned i,len;
2816 
2817   if (!code) {
2818     for (unsigned i=0; i < size; i++)
2819       m_foveon_decoder_huff[i] = get4();
2820     memset (first_decode, 0, sizeof first_decode);
2821     free_decode = first_decode;
2822   }
2823   cur = free_decode++;
2824   if (free_decode > first_decode+2048) {
2825     fprintf (stderr,_("%s: decoder table overflow\n"), m_UserSetting_InputFileName);
2826     longjmp (m_Failure, 2);
2827   }
2828   if (code)
2829     for (i=0; i < size; i++)
2830       if (m_foveon_decoder_huff[i] == code) {
2831   cur->leaf = i;
2832   return;
2833       }
2834   if ((len = code >> 27) > 26) return;
2835   code = (len+1) << 27 | (code & 0x3ffffff) << 1;
2836 
2837   cur->branch[0] = free_decode;
2838   foveon_decoder (size, code);
2839   cur->branch[1] = free_decode;
2840   foveon_decoder (size, code+1);
2841 }
2842 
foveon_thumb()2843 void CLASS foveon_thumb ()
2844 /* Remember: This function is modified to write the raw’s thumbnail to the
2845    m_Thumb instead of a file on disk. Always access thumbnails via DcRaw::thumbnail()!
2846 */
2847 // TODO: Tests needed: What format is this? Can it be read by QPixmap?
2848 {
2849   unsigned bwide, row, col, bitbuf=0, bit=1, c, i;
2850   char *buf;
2851   struct decode *dindex;
2852   short pred[3];
2853 
2854   bwide = get4();
2855   //fprintf (m_OutputFile, "P6\n%d %d\n255\n", m_ThumbWidth, m_ThumbHeight);
2856   QString dummy = QString("P6\n%1 %2\n255\n").arg(m_ThumbWidth).arg(m_ThumbHeight);
2857   VAppend(m_Thumb, dummy.toLocal8Bit().data(), dummy.length());
2858   if (bwide > 0) {
2859     if (bwide < (unsigned)(m_ThumbWidth*3)) return;
2860     buf = (char *) MALLOC (bwide);
2861     merror (buf, "foveon_thumb()");
2862     for (row=0; row < m_ThumbHeight; row++) {
2863       ptfread  (buf, 1, bwide, m_InputFile);
2864       //ptfwrite (buf, 3, m_ThumbWidth, m_OutputFile);
2865       VAppend(m_Thumb, buf, 3 * m_ThumbWidth);
2866     }
2867     FREE (buf);
2868     return;
2869   }
2870   foveon_decoder (256, 0);
2871 
2872   for (row=0; row < m_ThumbHeight; row++) {
2873     memset (pred, 0, sizeof pred);
2874     if (!bit) get4();
2875     for (bit=col=0; col < m_ThumbWidth; col++)
2876       for (c=0; c<3; c++) {
2877   for (dindex=first_decode; dindex->branch[0]; ) {
2878     if ((bit = (bit-1) & 31) == 31)
2879       for (i=0; i < 4; i++)
2880         bitbuf = (bitbuf << 8) + fgetc(m_InputFile);
2881     dindex = dindex->branch[bitbuf >> bit & 1];
2882   }
2883   pred[c] += dindex->leaf;
2884   //fputc (pred[c], m_OutputFile);
2885 #pragma GCC diagnostic push
2886 #pragma GCC diagnostic ignored "-Wint-to-pointer-cast"
2887   m_Thumb.push_back(pred[c]);
2888 #pragma GCC diagnostic pop
2889       }
2890   }
2891 }
2892 
foveon_sd_load_raw()2893 void CLASS foveon_sd_load_raw()
2894 {
2895   struct decode *dindex;
2896   short diff[1024];
2897   unsigned bitbuf=0;
2898   int pred[3], row, col, bit=-1, c, i;
2899 
2900   read_shorts ((uint16_t *) diff, 1024);
2901   if (!m_Load_Flags) foveon_decoder (1024, 0);
2902 
2903   for (row=0; row < m_Height; row++) {
2904     memset (pred, 0, sizeof pred);
2905     if (!bit && !m_Load_Flags && atoi(m_CameraModel+2) < 14) get4();
2906     for (col=bit=0; col < m_Width; col++) {
2907       if (m_Load_Flags) {
2908   bitbuf = get4();
2909   for (c=0; c<3; c++) pred[2-c] += diff[bitbuf >> c*10 & 0x3ff];
2910       }
2911       else for (c=0; c<3; c++) {
2912   for (dindex=first_decode; dindex->branch[0]; ) {
2913     if ((bit = (bit-1) & 31) == 31)
2914       for (i=0; i < 4; i++)
2915         bitbuf = (bitbuf << 8) + fgetc(m_InputFile);
2916     dindex = dindex->branch[bitbuf >> bit & 1];
2917   }
2918   pred[c] += diff[dindex->leaf];
2919   if (pred[c] >> 16 && ~pred[c] >> 16) derror();
2920       }
2921       for (c=0; c<3; c++) m_Image[row*m_Width+col][c] = pred[c];
2922     }
2923   }
2924 }
2925 
foveon_huff(uint16_t * huff)2926 void CLASS foveon_huff (uint16_t *huff)
2927 {
2928   int i, j, clen, code;
2929 
2930   huff[0] = 8;
2931   for (i=0; i < 13; i++) {
2932     clen = getc(m_InputFile);
2933     code = getc(m_InputFile);
2934     for (j=0; j < 256 >> clen; )
2935       huff[code+ ++j] = clen << 8 | i;
2936   }
2937   get2();
2938 }
2939 
foveon_dp_load_raw()2940 void CLASS foveon_dp_load_raw()
2941 {
2942   unsigned c, roff[4], row, col, diff;
2943   uint16_t huff[258], vpred[2][2], hpred[2];
2944 
2945   fseek (m_InputFile, 8, SEEK_CUR);
2946   foveon_huff (huff);
2947   roff[0] = 48;
2948   for (c=0; c<3; c++) roff[c+1] = -(-(roff[c] + get4()) & -16);
2949   for (c=0; c<3; c++) {
2950     fseek (m_InputFile, m_Data_Offset+roff[c], SEEK_SET);
2951     getbits(-1);
2952     vpred[0][0] = vpred[0][1] = vpred[1][0] = vpred[1][1] = 512;
2953     for (row=0; row < m_Height; row++) {
2954       for (col=0; col < m_Width; col++) {
2955   diff = ljpeg_diff(huff);
2956   if (col < 2) hpred[col] = vpred[row & 1][col] += diff;
2957   else hpred[col & 1] += diff;
2958   m_Image[row*m_Width+col][c] = hpred[col & 1];
2959       }
2960     }
2961   }
2962 }
2963 
foveon_load_camf()2964 void CLASS foveon_load_camf()
2965 {
2966   unsigned type, wide, high, i, j, row, col, diff;
2967   uint16_t huff[258], vpred[2][2] = {{512,512},{512,512}}, hpred[2];
2968 
2969   fseek (m_InputFile, meta_offset, SEEK_SET);
2970   type = get4();  get4();  get4();
2971   wide = get4();
2972   high = get4();
2973   if (type == 2) {
2974     ptfread (m_MetaData, 1, m_MetaLength, m_InputFile);
2975     for (i=0; i < m_MetaLength; i++) {
2976       high = (high * 1597 + 51749) % 244944;
2977       wide = high * (INT64) 301593171 >> 24;
2978       m_MetaData[i] ^= ((((high << 8) - wide) >> 1) + wide) >> 17;
2979     }
2980   } else if (type == 4) {
2981     FREE (m_MetaData);
2982     m_MetaData = (char *) MALLOC (m_MetaLength = wide*high*3/2);
2983     merror (m_MetaData, "foveon_load_camf()");
2984     foveon_huff (huff);
2985     get4();
2986     getbits(-1);
2987     for (j=row=0; row < high; row++) {
2988       for (col=0; col < wide; col++) {
2989   diff = ljpeg_diff(huff);
2990   if (col < 2) hpred[col] = vpred[row & 1][col] += diff;
2991   else         hpred[col & 1] += diff;
2992   if (col & 1) {
2993     m_MetaData[j++] = hpred[0] >> 4;
2994     m_MetaData[j++] = hpred[0] << 4 | hpred[1] >> 8;
2995     m_MetaData[j++] = hpred[1];
2996         }
2997       }
2998     }
2999   } else
3000     fprintf (stderr,_("%s has unknown CAMF type %d.\n"), m_UserSetting_InputFileName, type);
3001 }
3002 
foveon_camf_param(const char * block,const char * param)3003 const char * CLASS foveon_camf_param (const char *block, const char *param)
3004 {
3005   unsigned idx, num;
3006   char *pos, *cp, *dp;
3007 
3008   for (idx=0; idx < m_MetaLength; idx += sget4(pos+8)) {
3009     pos = m_MetaData + idx;
3010     if (strncmp (pos, "CMb", 3)) break;
3011     if (pos[3] != 'P') continue;
3012     if (strcmp (block, pos+sget4(pos+12))) continue;
3013     cp = pos + sget4(pos+16);
3014     num = sget4(cp);
3015     dp = pos + sget4(cp+4);
3016     while (num--) {
3017       cp += 8;
3018       if (!strcmp (param, dp+sget4(cp)))
3019   return dp+sget4(cp+4);
3020     }
3021   }
3022   return 0;
3023 }
3024 
foveon_camf_matrix(unsigned dim[3],const char * name)3025 void * CLASS foveon_camf_matrix (unsigned dim[3], const char *name)
3026 {
3027   unsigned i, idx, type, ndim, size, *mat;
3028   char *pos, *cp, *dp;
3029   double dsize;
3030 
3031   for (idx=0; idx < m_MetaLength; idx += sget4(pos+8)) {
3032     pos = m_MetaData + idx;
3033     if (strncmp (pos, "CMb", 3)) break;
3034     if (pos[3] != 'M') continue;
3035     if (strcmp (name, pos+sget4(pos+12))) continue;
3036     dim[0] = dim[1] = dim[2] = 1;
3037     cp = pos + sget4(pos+16);
3038     type = sget4(cp);
3039     if ((ndim = sget4(cp+4)) > 3) break;
3040     dp = pos + sget4(cp+8);
3041     for (i=ndim; i--; ) {
3042       cp += 12;
3043       dim[i] = sget4(cp);
3044     }
3045     if ((dsize = (double) dim[0]*dim[1]*dim[2]) > m_MetaLength/4) break;
3046     mat = (unsigned *) MALLOC ((size = (unsigned) dsize) * 4);
3047     merror (mat, "foveon_camf_matrix()");
3048     for (i=0; i < size; i++)
3049       if (type && type != 6)
3050   mat[i] = sget4(dp + i*4);
3051       else
3052   mat[i] = sget4(dp + i*2) & 0xffff;
3053     return mat;
3054   }
3055   fprintf (stderr,_("%s: \"%s\" matrix not found!\n"), m_UserSetting_InputFileName, name);
3056   return 0;
3057 }
3058 
foveon_fixed(void * ptr,int size,const char * name)3059 int CLASS foveon_fixed (void *ptr, int size, const char *name)
3060 {
3061   void *dp;
3062   unsigned dim[3];
3063 
3064   if (!name) return 0;
3065   dp = foveon_camf_matrix (dim, name);
3066   if (!dp) return 0;
3067   memcpy (ptr, dp, size*4);
3068   FREE (dp);
3069   return 1;
3070 }
3071 
foveon_avg(short * pix,int range[2],float cfilt)3072 float CLASS foveon_avg (short *pix, int range[2], float cfilt)
3073 {
3074   int i;
3075   float val, min=FLT_MAX, max=-FLT_MAX, sum=0;
3076 
3077   for (i=range[0]; i <= range[1]; i++) {
3078     sum += val = pix[i*4] + (pix[i*4]-pix[(i-1)*4]) * cfilt;
3079     if (min > val) min = val;
3080     if (max < val) max = val;
3081   }
3082   if (range[1] - range[0] == 1) return sum/2;
3083   return (sum - min - max) / (range[1] - range[0] - 1);
3084 }
3085 
foveon_make_curve(double max,double mul,double filt)3086 short * CLASS foveon_make_curve (double max, double mul, double filt)
3087 {
3088   short *curve;
3089   unsigned i, size;
3090   double x;
3091 
3092   if (!filt) filt = 0.8;
3093   size = (unsigned) (4*ptPI*max / filt);
3094   if (size == UINT_MAX) size--;
3095   curve = (short *) CALLOC (size+1, sizeof *curve);
3096   merror (curve, "foveon_make_curve()");
3097   curve[0] = size;
3098   for (i=0; i < size; i++) {
3099     x = i*filt/max/4;
3100     curve[i+1] = (short) ((cos(x)+1)/2 * tanh(i*filt/mul) * mul + 0.5);
3101   }
3102   return curve;
3103 }
3104 
foveon_make_curves(short ** curvep,float dq[3],float div[3],float filt)3105 void CLASS foveon_make_curves
3106   (short **curvep, float dq[3], float div[3], float filt)
3107 {
3108   double mul[3], max=0;
3109   int c;
3110 
3111   for (c=0; c<3; c++) mul[c] = dq[c]/div[c];
3112   for (c=0; c<3; c++) if (max < mul[c]) max = mul[c];
3113   for (c=0; c<3; c++) curvep[c] = foveon_make_curve (max, mul[c], filt);
3114 }
3115 
foveon_apply_curve(short * l_Curve,int i)3116 int CLASS foveon_apply_curve (short *l_Curve, int i)
3117 {
3118   if (abs(i) >= l_Curve[0]) return 0;
3119   return i < 0 ? -l_Curve[1-i] : l_Curve[1+i];
3120 }
3121 
3122 #define m_Image ((short (*)[4]) m_Image)
3123 
foveon_interpolate()3124 void CLASS foveon_interpolate()
3125 {
3126 // Loop optimization causes an "undefined behaviour" compiler warning. I just disable
3127 // the warning here instead of fixing the problem because Photivo does not support
3128 // Foveon anyway, but I’m not positive that removing this function wouldn’t break
3129 // DCRaw in some way.
3130 #pragma GCC diagnostic push
3131 #pragma GCC diagnostic ignored "-Warray-bounds"
3132 #pragma GCC diagnostic ignored "-Waggressive-loop-optimizations"
3133   static const short hood[] = { -1,-1, -1,0, -1,1, 0,-1, 0,1, 1,-1, 1,0, 1,1 };
3134   short *pix, prev[3], *l_curve[8], (*shrink)[3];
3135   float cfilt=0, ddft[3][3][2], ppm[3][3][3];
3136   float cam_xyz[3][3], correct[3][3], last[3][3], trans[3][3];
3137   float chroma_dq[3], color_dq[3], diag[3][3], div[3];
3138   float (*black)[3], (*sgain)[3], (*sgrow)[3];
3139   float fsum[3], val, frow, num;
3140   int row, col, c, i, j, diff, sgx, irow, sum, min, max, limit;
3141   int dscr[2][2], dstb[4], (*smrow[7])[3], total[4], ipix[3];
3142   int work[3][3], smlast, smred, smred_p=0, dev[3];
3143   int satlev[3], keep[4], active[4];
3144   unsigned dim[3], *badpix;
3145   double dsum=0, trsum[3];
3146   char str[128];
3147   const char* cp;
3148 
3149   memset(cam_xyz, 0, sizeof(cam_xyz));
3150   memset(dscr,    0, sizeof(dscr));
3151   memset(dstb,    0, sizeof(dstb));
3152   memset(active,  0, sizeof(active));
3153   memset(keep,    0, sizeof(keep));
3154 
3155   TRACEKEYVALS("Foveon interpolation","%s","");
3156 
3157   foveon_load_camf();
3158   foveon_fixed (dscr, 4, "DarkShieldColRange");
3159   foveon_fixed (ppm[0][0], 27, "PostPolyMatrix");
3160   foveon_fixed (satlev, 3, "SaturationLevel");
3161   foveon_fixed (keep, 4, "KeepImageArea");
3162   foveon_fixed (active, 4, "ActiveImageArea");
3163   foveon_fixed (chroma_dq, 3, "ChromaDQ");
3164   foveon_fixed (color_dq, 3,
3165   foveon_camf_param ("IncludeBlocks", "ColorDQ") ?
3166     "ColorDQ" : "ColorDQCamRGB");
3167   if (foveon_camf_param ("IncludeBlocks", "ColumnFilter"))
3168        foveon_fixed (&cfilt, 1, "ColumnFilter");
3169 
3170   memset (ddft, 0, sizeof ddft);
3171   if (!foveon_camf_param ("IncludeBlocks", "DarkDrift")
3172    || !foveon_fixed (ddft[1][0], 12, "DarkDrift"))
3173     for (i=0; i < 2; i++) {
3174       foveon_fixed (dstb, 4, i ? "DarkShieldBottom":"DarkShieldTop");
3175       for (row = dstb[1]; row <= dstb[3]; row++)
3176   for (col = dstb[0]; col <= dstb[2]; col++)
3177     for (c=0; c<3; c++) ddft[i+1][c][1] += (short) m_Image[row*m_Width+col][c];
3178       for (c=0; c<3; c++) ddft[i+1][c][1] /= (dstb[3]-dstb[1]+1) * (dstb[2]-dstb[0]+1);
3179     }
3180 
3181   if (!(cp = foveon_camf_param ("WhiteBalanceIlluminants", m_CameraModelBis)))
3182   { fprintf (stderr,_("%s: Invalid white balance \"%s\"\n"), m_UserSetting_InputFileName, m_CameraModelBis);
3183     return; }
3184   foveon_fixed (cam_xyz, 9, cp);
3185   foveon_fixed (correct, 9,
3186   foveon_camf_param ("WhiteBalanceCorrections", m_CameraModelBis));
3187   memset (last, 0, sizeof last);
3188   for (i=0; i < 3; i++)
3189     for (j=0; j < 3; j++)
3190       for (c=0; c<3; c++) last[i][j] += correct[i][c] * cam_xyz[c][j];
3191 
3192   #define LAST(x,y) last[(i+x)%3][(c+y)%3]
3193   for (i=0; i < 3; i++)
3194     for (c=0; c<3; c++) diag[c][i] = LAST(1,1)*LAST(2,2) - LAST(1,2)*LAST(2,1);
3195   #undef LAST
3196   for (c=0; c<3; c++) div[c] = diag[c][0]*0.3127 + diag[c][1]*0.329 + diag[c][2]*0.3583;
3197   sprintf (str, "%sRGBNeutral", m_CameraModelBis);
3198   if (foveon_camf_param ("IncludeBlocks", str))
3199     foveon_fixed (div, 3, str);
3200   num = 0;
3201   for (c=0; c<3; c++) if (num < div[c]) num = div[c];
3202   for (c=0; c<3; c++) div[c] /= num;
3203 
3204   memset (trans, 0, sizeof trans);
3205   for (i=0; i < 3; i++)
3206     for (j=0; j < 3; j++)
3207       for (c=0; c<3; c++) trans[i][j] += m_MatrixCamRGBToSRGB[i][c] * last[c][j] * div[j];
3208   for (c=0; c<3; c++) trsum[c] = trans[c][0] + trans[c][1] + trans[c][2];
3209   dsum = (6*trsum[0] + 11*trsum[1] + 3*trsum[2]) / 20;
3210   for (i=0; i < 3; i++)
3211     for (c=0; c<3; c++) last[i][c] = trans[i][c] * dsum / trsum[i];
3212   memset (trans, 0, sizeof trans);
3213   for (i=0; i < 3; i++)
3214     for (j=0; j < 3; j++)
3215       for (c=0; c<3; c++) trans[i][j] += (i==c ? 32 : -1) * last[c][j] / 30;
3216 
3217   foveon_make_curves (l_curve, color_dq, div, cfilt);
3218   for (c=0; c<3; c++) chroma_dq[c] /= 3;
3219   foveon_make_curves (l_curve+3, chroma_dq, div, cfilt);
3220   for (c=0; c<3; c++) dsum += chroma_dq[c] / div[c];
3221   l_curve[6] = foveon_make_curve (dsum, dsum, cfilt);
3222   l_curve[7] = foveon_make_curve (dsum*2, dsum*2, cfilt);
3223 
3224   sgain = (float (*)[3]) foveon_camf_matrix (dim, "SpatialGain");
3225   if (!sgain) return;
3226   sgrow = (float (*)[3]) CALLOC (dim[1], sizeof *sgrow);
3227   sgx = (m_Width + dim[1]-2) / (dim[1]-1);
3228 
3229   black = (float (*)[3]) CALLOC (m_Height, sizeof *black);
3230   for (row=0; row < m_Height; row++) {
3231     for (i=0; i < 6; i++)
3232       ddft[0][0][i] = ddft[1][0][i] +
3233   row / (m_Height-1.0) * (ddft[2][0][i] - ddft[1][0][i]);
3234     for (c=0; c<3; c++) black[row][c] =
3235   ( foveon_avg (m_Image[row*m_Width]+c, dscr[0], cfilt) +
3236     foveon_avg (m_Image[row*m_Width]+c, dscr[1], cfilt) * 3
3237     - ddft[0][c][0] ) / 4 - ddft[0][c][1];
3238   }
3239   memcpy (black, black+8, sizeof *black*8);
3240   memcpy (black+m_Height-11, black+m_Height-22, 11*sizeof *black);
3241   memcpy (last, black, sizeof last);
3242 
3243   for (row=1; row < m_Height-1; row++) {
3244     for (c=0; c<3; c++) if (last[1][c] > last[0][c]) {
3245   if (last[1][c] > last[2][c])
3246     black[row][c] = (last[0][c] > last[2][c]) ? last[0][c]:last[2][c];
3247       } else
3248   if (last[1][c] < last[2][c])
3249     black[row][c] = (last[0][c] < last[2][c]) ? last[0][c]:last[2][c];
3250     memmove (last, last+1, 2*sizeof last[0]);
3251     memcpy (last[2], black[row+1], sizeof last[2]);
3252   }
3253   for (c=0; c<3; c++) black[row][c] = (last[0][c] + last[1][c])/2;
3254   for (c=0; c<3; c++) black[0][c] = (black[1][c] + black[3][c])/2;
3255 
3256   val = 1 - exp(-1/24.0);
3257   memcpy (fsum, black, sizeof fsum);
3258   for (row=1; row < m_Height; row++)
3259     for (c=0; c<3; c++) fsum[c] += black[row][c] =
3260   (black[row][c] - black[row-1][c])*val + black[row-1][c];
3261   memcpy (last[0], black[m_Height-1], sizeof last[0]);
3262   for (c=0; c<3; c++) fsum[c] /= m_Height;
3263   for (row = m_Height; row--; )
3264     for (c=0; c<3; c++) last[0][c] = black[row][c] =
3265   (black[row][c] - fsum[c] - last[0][c])*val + last[0][c];
3266 
3267   memset (total, 0, sizeof total);
3268   for (row=2; row < m_Height; row+=4)
3269     for (col=2; col < m_Width; col+=4) {
3270       for (c=0; c<3; c++) total[c] += (short) m_Image[row*m_Width+col][c];
3271       total[3]++;
3272     }
3273   for (row=0; row < m_Height; row++)
3274     for (c=0; c<3; c++) black[row][c] += fsum[c]/2 + total[c]/(total[3]*100.0);
3275 
3276   for (row=0; row < m_Height; row++) {
3277     for (i=0; i < 6; i++)
3278       ddft[0][0][i] = ddft[1][0][i] +
3279   row / (m_Height-1.0) * (ddft[2][0][i] - ddft[1][0][i]);
3280     pix = m_Image[row*m_Width];
3281     memcpy (prev, pix, sizeof prev);
3282     frow = row / (m_Height-1.0) * (dim[2]-1);
3283     if ((unsigned)(irow = (int)(frow)) == dim[2]-1) irow--;
3284     frow -= irow;
3285     for (i=0; (unsigned) i < dim[1]; i++)
3286       for (c=0; c<3; c++) sgrow[i][c] = sgain[ irow   *dim[1]+i][c] * (1-frow) +
3287         sgain[(irow+1)*dim[1]+i][c] *    frow;
3288     for (col=0; col < m_Width; col++) {
3289       for (c=0; c<3; c++) {
3290   diff = pix[c] - prev[c];
3291   prev[c] = pix[c];
3292   ipix[c] = (int)(pix[c] + floor ((diff + (diff*diff >> 14)) * cfilt
3293     - ddft[0][c][1] - ddft[0][c][0] * ((float) col/m_Width - 0.5)
3294     - black[row][c] ));
3295       }
3296       for (c=0; c<3; c++) {
3297   work[0][c] = ipix[c] * ipix[c] >> 14;
3298   work[2][c] = ipix[c] * work[0][c] >> 14;
3299   work[1][2-c] = ipix[(c+1) % 3] * ipix[(c+2) % 3] >> 14;
3300       }
3301       for (c=0; c<3; c++) {
3302   for (val=i=0; i < 3; i++)
3303     for (  j=0; j < 3; j++)
3304       val += ppm[c][i][j] * work[i][j];
3305   ipix[c] = (int) (floor ((ipix[c] + floor(val)) *
3306     ( sgrow[col/sgx  ][c] * (sgx - col%sgx) +
3307       sgrow[col/sgx+1][c] * (col%sgx) ) / sgx / div[c]));
3308   if (ipix[c] > 32000) ipix[c] = 32000;
3309   pix[c] = ipix[c];
3310       }
3311       pix += 4;
3312     }
3313   }
3314   FREE (black);
3315   FREE (sgrow);
3316   FREE (sgain);
3317 
3318   if ((badpix = (unsigned int *) foveon_camf_matrix (dim, "BadPixels"))) {
3319     for (i=0; (unsigned) i < dim[0]; i++) {
3320       col = (badpix[i] >> 8 & 0xfff) - keep[0];
3321       row = (badpix[i] >> 20       ) - keep[1];
3322       if ((unsigned)(row-1) > (unsigned)(m_Height-3) || (unsigned)(col-1) > (unsigned)(m_Width-3))
3323   continue;
3324       memset (fsum, 0, sizeof fsum);
3325       for (sum=j=0; j < 8; j++)
3326   if (badpix[i] & (1 << j)) {
3327     for (c=0; c<3; c++) fsum[c] += (short)
3328     m_Image[(row+hood[j*2])*m_Width+col+hood[j*2+1]][c];
3329     sum++;
3330   }
3331       if (sum) for (c=0; c<3; c++) m_Image[row*m_Width+col][c] = (short) (fsum[c]/sum);
3332     }
3333     FREE (badpix);
3334   }
3335 
3336   /* Array for 5x5 Gaussian averaging of red values */
3337   smrow[6] = (int (*)[3]) CALLOC (m_Width*5, sizeof **smrow);
3338   merror (smrow[6], "foveon_interpolate()");
3339   for (i=0; i < 5; i++)
3340     smrow[i] = smrow[6] + i*m_Width;
3341 
3342   /* Sharpen the reds against these Gaussian averages */
3343   for (smlast=-1, row=2; row < m_Height-2; row++) {
3344     while (smlast < row+2) {
3345       for (i=0; i < 6; i++)
3346   smrow[(i+5) % 6] = smrow[i];
3347       pix = m_Image[++smlast*m_Width+2];
3348       for (col=2; col < m_Width-2; col++) {
3349   smrow[4][col][0] =
3350     (pix[0]*6 + (pix[-4]+pix[4])*4 + pix[-8]+pix[8] + 8) >> 4;
3351   pix += 4;
3352       }
3353     }
3354     pix = m_Image[row*m_Width+2];
3355     for (col=2; col < m_Width-2; col++) {
3356       smred = ( 6 *  smrow[2][col][0]
3357         + 4 * (smrow[1][col][0] + smrow[3][col][0])
3358         +      smrow[0][col][0] + smrow[4][col][0] + 8 ) >> 4;
3359       if (col == 2)
3360   smred_p = smred;
3361       i = pix[0] + ((pix[0] - ((smred*7 + smred_p) >> 3)) >> 3);
3362       if (i > 32000) i = 32000;
3363       pix[0] = i;
3364       smred_p = smred;
3365       pix += 4;
3366     }
3367   }
3368 
3369   /* Adjust the brighter pixels for better linearity */
3370   min = 0xffff;
3371   for (c=0; c<3; c++) {
3372     i = (int)(satlev[c] / div[c]);
3373     if (min > i) min = i;
3374   }
3375   limit = min * 9 >> 4;
3376   for (pix=m_Image[0]; pix < m_Image[m_Height*m_Width]; pix+=4) {
3377     if (pix[0] <= limit || pix[1] <= limit || pix[2] <= limit)
3378       continue;
3379     min = max = pix[0];
3380     for (c=1; c < 3; c++) {
3381       if (min > pix[c]) min = pix[c];
3382       if (max < pix[c]) max = pix[c];
3383     }
3384     if (min >= limit*2) {
3385       pix[0] = pix[1] = pix[2] = max;
3386     } else {
3387       i = 0x4000 - ((min - limit) << 14) / limit;
3388       i = 0x4000 - (i*i >> 14);
3389       i = i*i >> 14;
3390       for (c=0; c<3; c++) pix[c] += (max - pix[c]) * i >> 14;
3391     }
3392   }
3393 /*
3394    Because photons that miss one detector often hit another,
3395    the sum R+G+B is much less noisy than the individual colors.
3396    So smooth the hues without smoothing the total.
3397  */
3398   for (smlast=-1, row=2; row < m_Height-2; row++) {
3399     while (smlast < row+2) {
3400       for (i=0; i < 6; i++)
3401   smrow[(i+5) % 6] = smrow[i];
3402       pix = m_Image[++smlast*m_Width+2];
3403       for (col=2; col < m_Width-2; col++) {
3404   for (c=0; c<3; c++) smrow[4][col][c] = (pix[c-4]+2*pix[c]+pix[c+4]+2) >> 2;
3405   pix += 4;
3406       }
3407     }
3408     pix = m_Image[row*m_Width+2];
3409     for (col=2; col < m_Width-2; col++) {
3410       for (c=0; c<3; c++) dev[c] = -foveon_apply_curve (l_curve[7], pix[c] -
3411   ((smrow[1][col][c] + 2*smrow[2][col][c] + smrow[3][col][c]) >> 2));
3412       sum = (dev[0] + dev[1] + dev[2]) >> 3;
3413       for (c=0; c<3; c++) pix[c] += dev[c] - sum;
3414       pix += 4;
3415     }
3416   }
3417   for (smlast=-1, row=2; row < m_Height-2; row++) {
3418     while (smlast < row+2) {
3419       for (i=0; i < 6; i++)
3420   smrow[(i+5) % 6] = smrow[i];
3421       pix = m_Image[++smlast*m_Width+2];
3422       for (col=2; col < m_Width-2; col++) {
3423   for (c=0; c<3; c++) smrow[4][col][c] =
3424     (pix[c-8]+pix[c-4]+pix[c]+pix[c+4]+pix[c+8]+2) >> 2;
3425   pix += 4;
3426       }
3427     }
3428     pix = m_Image[row*m_Width+2];
3429     for (col=2; col < m_Width-2; col++) {
3430       for (total[3]=375, sum=60, c=0; c < 3; c++) {
3431   for (total[c]=i=0; i < 5; i++)
3432     total[c] += smrow[i][col][c];
3433   total[3] += total[c];
3434   sum += pix[c];
3435       }
3436       if (sum < 0) sum = 0;
3437       j = total[3] > 375 ? (sum << 16) / total[3] : sum * 174;
3438       for (c=0; c<3; c++) pix[c] += foveon_apply_curve (l_curve[6],
3439     ((j*total[c] + 0x8000) >> 16) - pix[c]);
3440       pix += 4;
3441     }
3442   }
3443 
3444   /* Transform the image to a different colorspace */
3445   for (pix=m_Image[0]; pix < m_Image[m_Height*m_Width]; pix+=4) {
3446     for (c=0; c<3; c++) pix[c] -= foveon_apply_curve (l_curve[c], pix[c]);
3447     sum = (pix[0]+pix[1]+pix[1]+pix[2]) >> 2;
3448     for (c=0; c<3; c++) pix[c] -= foveon_apply_curve (l_curve[c], pix[c]-sum);
3449     for (c=0; c<3; c++) {
3450       for (dsum=i=0; i < 3; i++)
3451   dsum += trans[c][i] * pix[i];
3452       if (dsum < 0)  dsum = 0;
3453       if (dsum > 24000) dsum = 24000;
3454       ipix[c] = (int)(dsum + 0.5);
3455     }
3456     for (c=0; c<3; c++) pix[c] = ipix[c];
3457   }
3458 
3459   /* Smooth the image bottom-to-top and save at 1/4 scale */
3460   shrink = (short (*)[3]) CALLOC ((m_Width/4) * (m_Height/4), sizeof *shrink);
3461   merror (shrink, "foveon_interpolate()");
3462   for (row = m_Height/4; row--; )
3463     for (col=0; col < m_Width/4; col++) {
3464       ipix[0] = ipix[1] = ipix[2] = 0;
3465       for (i=0; i < 4; i++)
3466   for (j=0; j < 4; j++)
3467     for (c=0; c<3; c++) ipix[c] += m_Image[(row*4+i)*m_Width+col*4+j][c];
3468       for (c=0; c<3; c++)
3469   if (row+2 > m_Height/4)
3470     shrink[row*(m_Width/4)+col][c] = ipix[c] >> 4;
3471   else
3472     shrink[row*(m_Width/4)+col][c] =
3473       (shrink[(row+1)*(m_Width/4)+col][c]*1840 + ipix[c]*141 + 2048) >> 12;
3474     }
3475   /* From the 1/4-scale image, smooth right-to-left */
3476   for (row=0; row < (m_Height & ~3); row++) {
3477     ipix[0] = ipix[1] = ipix[2] = 0;
3478     if ((row & 3) == 0)
3479       for (col = m_Width & ~3 ; col--; )
3480   for (c=0; c<3; c++) smrow[0][col][c] = ipix[c] =
3481     (shrink[(row/4)*(m_Width/4)+col/4][c]*1485 + ipix[c]*6707 + 4096) >> 13;
3482 
3483   /* Then smooth left-to-right */
3484     ipix[0] = ipix[1] = ipix[2] = 0;
3485     for (col=0; col < (m_Width & ~3); col++)
3486       for (c=0; c<3; c++) smrow[1][col][c] = ipix[c] =
3487   (smrow[0][col][c]*1485 + ipix[c]*6707 + 4096) >> 13;
3488 
3489   /* Smooth top-to-bottom */
3490     if (row == 0)
3491       memcpy (smrow[2], smrow[1], sizeof **smrow * m_Width);
3492     else
3493       for (col=0; col < (m_Width & ~3); col++)
3494   for (c=0; c<3; c++) smrow[2][col][c] =
3495     (smrow[2][col][c]*6707 + smrow[1][col][c]*1485 + 4096) >> 13;
3496 
3497   /* Adjust the chroma toward the smooth values */
3498     for (col=0; col < (m_Width & ~3); col++) {
3499       for (i=j=30, c=0; c < 3; c++) {
3500   i += smrow[2][col][c];
3501   j += m_Image[row*m_Width+col][c];
3502       }
3503       j = (j << 16) / i;
3504       for (sum=c=0; c < 3; c++) {
3505   ipix[c] = foveon_apply_curve (l_curve[c+3],
3506     ((smrow[2][col][c] * j + 0x8000) >> 16) - m_Image[row*m_Width+col][c]);
3507   sum += ipix[c];
3508       }
3509       sum >>= 3;
3510       for (c=0; c<3; c++) {
3511   i = m_Image[row*m_Width+col][c] + ipix[c] - sum;
3512   if (i < 0) i = 0;
3513   m_Image[row*m_Width+col][c] = i;
3514       }
3515     }
3516   }
3517   FREE (shrink);
3518   FREE (smrow[6]);
3519   for (i=0; i < 8; i++)
3520     FREE (l_curve[i]);
3521 
3522   /* Trim off the black border */
3523   active[1] -= keep[1];
3524   active[3] -= 2;
3525   i = active[2] - active[0];
3526   for (row=0; row < active[3]-active[1]; row++)
3527     memcpy (m_Image[row*i], m_Image[(row+active[1])*m_Width+active[0]],
3528    i * sizeof *m_Image);
3529   m_Width = i;
3530   m_Height = row;
3531 #pragma GCC diagnostic pop
3532 }
3533 #undef m_Image
3534 
3535 /* RESTRICTED code ends here */
3536 
crop_masked_pixels()3537 void CLASS crop_masked_pixels()
3538 {
3539   int row, col;
3540   unsigned r, c, m, mm_BlackLevel[8], zero, val;
3541 
3542   if (m_LoadRawFunction == &CLASS phase_one_load_raw ||
3543       m_LoadRawFunction == &CLASS phase_one_load_raw_c)
3544     phase_one_correct();
3545   if (m_Fuji_Width) {
3546     for (row=0; row < m_RawHeight-m_TopMargin*2; row++) {
3547       for (col=0; col < m_Fuji_Width << !fuji_layout; col++) {
3548   if (fuji_layout) {
3549     r = m_Fuji_Width - 1 - col + (row >> 1);
3550     c = col + ((row+1) >> 1);
3551   } else {
3552     r = m_Fuji_Width - 1 + row - (col >> 1);
3553     c = row + ((col+1) >> 1);
3554   }
3555   if (r < m_Height && c < m_Width)
3556     BAYER(r,c) = RAW(row+m_TopMargin,col+m_LeftMargin);
3557       }
3558     }
3559   } else {
3560     for (row=0; row < m_Height; row++)
3561       for (col=0; col < m_Width; col++)
3562   BAYER2(row,col) = RAW(row+m_TopMargin,col+m_LeftMargin);
3563   }
3564   if (m_Mask[0][3]) goto mask_set;
3565   if (m_LoadRawFunction == &CLASS canon_load_raw ||
3566       m_LoadRawFunction == &CLASS lossless_jpeg_load_raw) {
3567     m_Mask[0][1] = m_Mask[1][1] = 2;
3568     m_Mask[0][3] = -2;
3569     goto sides;
3570   }
3571   if (m_LoadRawFunction == &CLASS canon_600_load_raw ||
3572       m_LoadRawFunction == &CLASS sony_load_raw ||
3573      (m_LoadRawFunction == &CLASS eight_bit_load_raw && strncmp(m_CameraModel,"DC2",3)) ||
3574       m_LoadRawFunction == &CLASS kodak_262_load_raw ||
3575      (m_LoadRawFunction == &CLASS packed_load_raw && (m_Load_Flags & 32))) {
3576 sides:
3577     m_Mask[0][0] = m_Mask[1][0] = m_TopMargin;
3578     m_Mask[0][2] = m_Mask[1][2] = m_TopMargin+m_Height;
3579     m_Mask[0][3] += m_LeftMargin;
3580     m_Mask[1][1] += m_LeftMargin+m_Width;
3581     m_Mask[1][3] += m_RawWidth;
3582   }
3583   if (m_LoadRawFunction == &CLASS nokia_load_raw) {
3584     m_Mask[0][2] = m_TopMargin;
3585     m_Mask[0][3] = m_Width;
3586   }
3587 mask_set:
3588   memset (mm_BlackLevel, 0, sizeof mm_BlackLevel);
3589   for (zero=m=0; m < 8; m++)
3590     for (row=m_Mask[m][0]; row < m_Mask[m][2]; row++)
3591       for (col=m_Mask[m][1]; col < m_Mask[m][3]; col++) {
3592   c = FC(row-m_TopMargin,col-m_LeftMargin);
3593   mm_BlackLevel[c] += val = RAW(row,col);
3594   mm_BlackLevel[4+c]++;
3595   zero += !val;
3596       }
3597   if (m_LoadRawFunction == &CLASS canon_600_load_raw && m_Width < m_RawWidth) {
3598     m_BlackLevel = (mm_BlackLevel[0]+mm_BlackLevel[1]+mm_BlackLevel[2]+mm_BlackLevel[3]) /
3599       (mm_BlackLevel[4]+mm_BlackLevel[5]+mm_BlackLevel[6]+mm_BlackLevel[7]) - 4;
3600     canon_600_correct();
3601   } else if (zero < mm_BlackLevel[4] && mm_BlackLevel[5] && mm_BlackLevel[6] && mm_BlackLevel[7])
3602     for (c=0; c<4; c++) m_CBlackLevel[c] = mm_BlackLevel[c] / mm_BlackLevel[4+c];
3603 }
3604 
remove_zeroes()3605 void CLASS remove_zeroes()
3606 {
3607   unsigned row, col, tot, n, r, c;
3608 
3609   for (row=0; row < m_Height; row++)
3610     for (col=0; col < m_Width; col++)
3611       if (BAYER(row,col) == 0) {
3612   tot = n = 0;
3613   for (r = row-2; r <= row+2; r++)
3614     for (c = col-2; c <= col+2; c++)
3615       if (r < m_Height && c < m_Width &&
3616     FC(r,c) == FC(row,col) && BAYER(r,c))
3617         tot += (n++,BAYER(r,c));
3618   if (n) BAYER(row,col) = tot/n;
3619       }
3620 }
3621 
3622 /*
3623    Seach from the current directory up to the root looking for
3624    a ".badpixels" file, and fix those pixels now.
3625  */
bad_pixels(const char * cfname)3626 void CLASS bad_pixels (const char *cfname)
3627 {
3628   FILE *fp=0;
3629   char *cp, line[128];
3630   int /* len, */ time, row, col, r, c, rad, tot, n;
3631 
3632   if (!m_Filters) return;
3633   if (cfname)
3634     fp = fopen (cfname, "r");
3635 /* MASK AWAY IN dcRaw
3636   else {
3637     for (len=32 ; ; len *= 2) {
3638       fname = (char *) MALLOC (len);
3639       if (!fname) return;
3640       if (getcwd (fname, len-16)) break;
3641       FREE (fname);
3642       if (errno != ERANGE) return;
3643     }
3644 #if defined(WIN32) || defined(DJGPP)
3645     if (fname[1] == ':')
3646       memmove (fname, fname+2, len-2);
3647     for (cp=fname; *cp; cp++)
3648       if (*cp == '\\') *cp = '/';
3649 #endif
3650     cp = fname + strlen(fname);
3651     if (cp[-1] == '/') cp--;
3652     while (*fname == '/') {
3653       strcpy (cp, "/.badpixels");
3654       if ((fp = fopen (fname, "r"))) break;
3655       if (cp == fname) break;
3656       while (*--cp != '/');
3657     }
3658     FREE (fname);
3659   }
3660 */
3661   if (!fp) return;
3662   while (fgets (line, 128, fp)) {
3663     cp = strchr (line, '#');
3664     if (cp) *cp = 0;
3665     if (sscanf (line, "%d %d %d", &col, &row, &time) != 3) continue;
3666     if ((unsigned) col >= m_Width || (unsigned) row >= m_Height) continue;
3667     if (time > m_TimeStamp) continue;
3668     for (tot=n=0, rad=1; rad < 3 && n==0; rad++)
3669       for (r = row-rad; r <= row+rad; r++)
3670   for (c = col-rad; c <= col+rad; c++)
3671     if ((unsigned) r < m_Height && (unsigned) c < m_Width &&
3672     (r != row || c != col) && fcol(r,c) == fcol(row,col)) {
3673       tot += BAYER2(r,c);
3674       n++;
3675     }
3676     BAYER2(row,col) = tot/n;
3677     TRACEKEYVALS("Fixed dead pixel at column","%d",col);
3678     TRACEKEYVALS("Fixed dead pixel at row","%d",row);
3679   }
3680   FCLOSE (fp);
3681 }
3682 
subtract(const char * fname)3683 void CLASS subtract (const char *fname)
3684 {
3685   FILE *fp;
3686   int dim[3]={0,0,0}, comment=0, number=0, error=0, nd=0, c, row, col;
3687   uint16_t *pixel;
3688 
3689   if (!(fp = fopen (fname, "rb"))) {
3690     perror (fname);  return;
3691   }
3692   if (fgetc(fp) != 'P' || fgetc(fp) != '5') error = 1;
3693   while (!error && nd < 3 && (c = fgetc(fp)) != EOF) {
3694     if (c == '#')  comment = 1;
3695     if (c == '\n') comment = 0;
3696     if (comment) continue;
3697     if (isdigit(c)) number = 1;
3698     if (number) {
3699       if (isdigit(c)) dim[nd] = dim[nd]*10 + c -'0';
3700       else if (isspace(c)) {
3701   number = 0;  nd++;
3702       } else error = 1;
3703     }
3704   }
3705   if (error || nd < 3) {
3706     fprintf (stderr,_("%s is not a valid PGM file!\n"), fname);
3707     FCLOSE (fp);  return;
3708   } else if (dim[0] != m_Width || dim[1] != m_Height || dim[2] != 65535) {
3709     fprintf (stderr,_("%s has the wrong dimensions!\n"), fname);
3710     FCLOSE (fp);  return;
3711   }
3712   pixel = (uint16_t*) CALLOC (m_Width, sizeof *pixel);
3713   merror (pixel, "subtract()");
3714   for (row=0; row < m_Height; row++) {
3715     ptfread (pixel, 2, m_Width, fp);
3716     for (col=0; col < m_Width; col++)
3717       BAYER(row,col) = MAX (BAYER(row,col) - ntohs(pixel[col]), 0);
3718   }
3719   FREE (pixel);
3720   FCLOSE (fp);
3721   memset (m_CBlackLevel, 0, sizeof m_CBlackLevel);
3722   m_BlackLevel = 0;
3723 }
3724 
gamma_curve(double pwr,double ts,int mode,int imax)3725 void CLASS gamma_curve (double pwr, double ts, int mode, int imax)
3726 {
3727   int i;
3728   double g[6], bnd[2]={0,0}, r;
3729 
3730   g[0] = pwr;
3731   g[1] = ts;
3732   g[2] = g[3] = g[4] = 0;
3733   bnd[g[1] >= 1] = 1;
3734   if (g[1] && (g[1]-1)*(g[0]-1) <= 0) {
3735     for (i=0; i < 48; i++) {
3736       g[2] = (bnd[0] + bnd[1])/2;
3737       if (g[0]) bnd[(pow(g[2]/g[1],-g[0]) - 1)/g[0] - 1/g[2] > -1] = g[2];
3738       else  bnd[g[2]/exp(1-1/g[2]) < g[1]] = g[2];
3739     }
3740     g[3] = g[2] / g[1];
3741     if (g[0]) g[4] = g[2] * (1/g[0] - 1);
3742   }
3743   if (g[0]) g[5] = 1 / (g[1]*SQR(g[3])/2 - g[4]*(1 - g[3]) +
3744     (1 - pow(g[3],1+g[0]))*(1 + g[4])/(1 + g[0])) - 1;
3745   else      g[5] = 1 / (g[1]*SQR(g[3])/2 + 1
3746     - g[2] - g[3] - g[2]*g[3]*(log(g[3]) - 1)) - 1;
3747   if (!mode--) {
3748     memcpy (m_Gamma, g, sizeof m_Gamma);
3749     return;
3750   }
3751   for (i=0; i < 0x10000; i++) {
3752     m_Curve[i] = 0xffff;
3753     if ((r = (double) i / imax) < 1)
3754       m_Curve[i] = 0x10000 * ( mode
3755   ? (r < g[3] ? r*g[1] : (g[0] ? pow( r,g[0])*(1+g[4])-g[4]    : log(r)*g[2]+1))
3756   : (r < g[2] ? r/g[1] : (g[0] ? pow((r+g[4])/(1+g[4]),1/g[0]) : exp((r-1)/g[2]))));
3757   }
3758 }
3759 
pseudoinverse(double (* in)[3],double (* out)[3],int size)3760 void CLASS pseudoinverse (double (*in)[3], double (*out)[3], int size)
3761 {
3762   double work[3][6], num;
3763   int i, j, k;
3764 
3765   for (i=0; i < 3; i++) {
3766     for (j=0; j < 6; j++)
3767       work[i][j] = j == i+3;
3768     for (j=0; j < 3; j++)
3769       for (k=0; k < size; k++)
3770   work[i][j] += in[k][i] * in[k][j];
3771   }
3772   for (i=0; i < 3; i++) {
3773     num = work[i][i];
3774     for (j=0; j < 6; j++)
3775       work[i][j] /= num;
3776     for (k=0; k < 3; k++) {
3777       if (k==i) continue;
3778       num = work[k][i];
3779       for (j=0; j < 6; j++)
3780   work[k][j] -= work[i][j] * num;
3781     }
3782   }
3783   for (i=0; i < size; i++)
3784     for (j=0; j < 3; j++)
3785       for (out[i][j]=k=0; k < 3; k++)
3786   out[i][j] += work[j][k+3] * in[i][k];
3787 }
3788 
cam_xyz_coeff(double MatrixXYZToCamRGB[4][3])3789 void CLASS cam_xyz_coeff (double MatrixXYZToCamRGB[4][3])
3790 {
3791   double MatrixSRGBToCamRGB[4][3], inverse[4][3], num;
3792   int i, j, k;
3793 
3794   for (i=0; i < m_Colors; i++)    /* Multiply out XYZ colorspace */
3795     for (j=0; j < 3; j++)
3796       for (MatrixSRGBToCamRGB[i][j] = k=0; k < 3; k++)
3797   MatrixSRGBToCamRGB[i][j] +=
3798           MatrixXYZToCamRGB[i][k] * MatrixRGBToXYZ[ptSpace_sRGB_D65][k][j];
3799 
3800   // Normalize MatrixSRGBToCamRGB such that
3801   // (1,1,1) in SRGB maps onto (1,1,1,1) in CamRGB.
3802   for (i=0; i < m_Colors; i++) {
3803     for (num=j=0; j < 3; j++)
3804       num += MatrixSRGBToCamRGB[i][j];
3805     for (j=0; j < 3; j++)
3806       MatrixSRGBToCamRGB[i][j] /= num;
3807 
3808     // TODO More profound explanation.
3809     // But somehow it is clear that the factors to bring
3810     // (1,1,1)=>(1,1,1,1) are the multipliers at the reference point D65.
3811     ASSIGN(m_D65Multipliers[i], 1 / num);
3812   }
3813 
3814   pseudoinverse (MatrixSRGBToCamRGB, inverse, m_Colors);
3815   m_RawColorPhotivo = m_RawColor;
3816   for (m_RawColor = i=0; i < 3; i++)
3817     for (j=0; j < m_Colors; j++)
3818       m_MatrixCamRGBToSRGB[i][j] = inverse[j][i];
3819 }
3820 
hat_transform(float * temp,float * base,int st,int size,int sc)3821 void CLASS hat_transform (float *temp, float *base, int st, int size, int sc)
3822 {
3823   int i;
3824   for (i=0; i < sc; i++)
3825     temp[i] = 2*base[st*i] + base[st*(sc-i)] + base[st*(i+sc)];
3826   for (; i+sc < size; i++)
3827     temp[i] = 2*base[st*i] + base[st*(i-sc)] + base[st*(i+sc)];
3828   for (; i < size; i++)
3829     temp[i] = 2*base[st*i] + base[st*(i-sc)] + base[st*(2*size-2-(i+sc))];
3830 }
3831 
3832 ////////////////////////////////////////////////////////////////////////////////
3833 //
3834 // ptAdjustMaximum
3835 // This is modelled after the adjust_maximum of libraw.
3836 // It's purpose is false color suppression in the highlights.
3837 // Typically "Threshold" should be between 0.75 and 1.
3838 //
3839 ////////////////////////////////////////////////////////////////////////////////
3840 
ptAdjustMaximum(double Threshold)3841 void CLASS ptAdjustMaximum(double Threshold) {
3842   m_WhiteLevel = LIM((int32_t)(Threshold*(double)m_WhiteLevel),0, 4095);
3843 }
3844 
3845 ////////////////////////////////////////////////////////////////////////////////
3846 //
3847 // ptScaleColors
3848 // Be aware : ptWaveletDenoising has as side effect that
3849 // m_Blacklevel and m_Whitelevel change.
3850 //
3851 ////////////////////////////////////////////////////////////////////////////////
3852 
ptScaleColors()3853 void CLASS ptScaleColors() {
3854   unsigned bottom, right, row, col, x, y, c, sum[8];
3855   int val;
3856   double dsum[8], dmin, dmax;
3857 
3858 
3859   // Use the UserSetting_Multipliers if they are defined.
3860   // Remark that they will be overwritten if we have a AutoWb on CameraWb on !
3861 
3862   if (m_UserSetting_Multiplier[0]) {
3863     TRACEKEYVALS("Setting PreMultipliers due to UserSetting","%s","");
3864     ASSIGN(m_PreMultipliers[0],m_UserSetting_Multiplier[0]);
3865     ASSIGN(m_PreMultipliers[1],m_UserSetting_Multiplier[1]);
3866     ASSIGN(m_PreMultipliers[2],m_UserSetting_Multiplier[2]);
3867     ASSIGN(m_PreMultipliers[3],m_UserSetting_Multiplier[3]);
3868   }
3869 
3870   // AutoWb calculation, also fallback if no CameraWb found and
3871   // CameraWb is on.
3872   // Also the GreyBox whitesetting is done here, so AutoWb should be on for
3873   // GreyBox calculation !
3874 
3875   if ( m_UserSetting_AutoWb ||
3876       (m_UserSetting_CameraWb && VALUE(m_CameraMultipliers[0]) == -1)) {
3877     memset (dsum, 0, sizeof dsum);
3878     bottom = MIN (m_UserSetting_GreyBox[1]+m_UserSetting_GreyBox[3], (int32_t)m_Height);
3879     right  = MIN (m_UserSetting_GreyBox[0]+m_UserSetting_GreyBox[2], (int32_t)m_Width);
3880     TRACEKEYVALS("AutoWB GreyBox[0]","%d",m_UserSetting_GreyBox[0]);
3881     TRACEKEYVALS("AutoWB GreyBox[1]","%d",m_UserSetting_GreyBox[1]);
3882     TRACEKEYVALS("AutoWB GreyBox[2]","%d",m_UserSetting_GreyBox[2]);
3883     TRACEKEYVALS("AutoWB GreyBox[3]","%d",m_UserSetting_GreyBox[3]);
3884     TRACEKEYVALS("AutoWB m_Width","%d",m_Width);
3885     TRACEKEYVALS("AutoWB m_Height","%d",m_Height);
3886     TRACEKEYVALS("AutoWB right","%d",right);
3887     TRACEKEYVALS("AutoWB bottom","%d",bottom);
3888     // Auto whitebalance done over the greybox but resulting
3889     // in the whole image if no greybox given.
3890     for (row=m_UserSetting_GreyBox[1]; row < bottom; row += 8)
3891       for (col=m_UserSetting_GreyBox[0]; col < right; col += 8) {
3892         // Apparently the image is scanned in 8*8 pixel blocks.
3893         memset (sum, 0, sizeof sum);
3894         for (y=row; y < row+8 && y < bottom; y++)
3895           for (x=col; x < col+8 && x < right; x++)
3896             for (c=0; c < 4; c++) {
3897               if (m_Filters) {
3898             c = fcol(y,x);
3899             val = BAYER2(y,x);
3900               } else
3901                 val = m_Image[y*m_Width+x][c];
3902               if ((unsigned) val > m_WhiteLevel-25) goto skip_block;
3903               if ((val -= m_CBlackLevel[c]) < 0) val = 0;
3904               sum[c] += val;
3905               sum[c+4]++;
3906               if (m_Filters) break;
3907             }
3908         for (c=0; c < 8; c++) dsum[c] += sum[c];
3909       skip_block: ;
3910       }
3911     // How intenser the blocks , how smaller the multipliers.
3912     // In terms of ratio's it means they will be close to each other
3913     // (neutral color balance) if the image has equally distributed RGB
3914     // (that's grey :))
3915     for (c=0; c < 4; c++) if (dsum[c]) ASSIGN(m_PreMultipliers[c], dsum[c+4] / dsum[c]);
3916     TRACEKEYVALS("Setting PreMultipliers due to AutoWB","%s","");
3917 
3918   }
3919 
3920   if (m_UserSetting_CameraWb && VALUE(m_CameraMultipliers[0]) != -1) {
3921     memset (sum, 0, sizeof sum);
3922     for (row=0; row < 8; row++)
3923       for (col=0; col < 8; col++) {
3924         c = FC(row,col);
3925         if ((val = white[row][col] - m_CBlackLevel[c]) > 0)
3926           sum[c] += val;
3927         sum[c+4]++;
3928       }
3929     if (sum[0] && sum[1] && sum[2] && sum[3]) {
3930       for (c=0; c < 4; c++) ASSIGN(m_PreMultipliers[c], (float) sum[c+4] / sum[c]);
3931       TRACEKEYVALS("Setting PreMultipliers due to CameraWB","%s","");
3932     }
3933     else if (VALUE(m_CameraMultipliers[0]) && VALUE(m_CameraMultipliers[2])) {
3934       ASSIGN(m_PreMultipliers[0],VALUE(m_CameraMultipliers[0]));
3935       ASSIGN(m_PreMultipliers[1],VALUE(m_CameraMultipliers[1]));
3936       ASSIGN(m_PreMultipliers[2],VALUE(m_CameraMultipliers[2]));
3937       ASSIGN(m_PreMultipliers[3],VALUE(m_CameraMultipliers[3]));
3938       TRACEKEYVALS("Setting PreMultipliers due to CameraMultipliers","%s","");
3939     }
3940     else
3941       fprintf (stderr,_("%s: Cannot use camera white balance.\n"), m_UserSetting_InputFileName);
3942   }
3943 
3944   if (VALUE(m_PreMultipliers[3]) == 0) {
3945     ASSIGN(m_PreMultipliers[3],
3946            (m_Colors < 4) ? VALUE(m_PreMultipliers[1]) : 1);
3947   }
3948 
3949   // Denoising before color scaling and interpolation.
3950   // Remark m_BlackLevel and m_WhiteLevel migth be changed.
3951   if (m_UserSetting_DenoiseThreshold) ptWaveletDenoise();
3952 
3953   for (dmin=DBL_MAX, dmax=c=0; c < 4; c++) {
3954     if (dmin > VALUE(m_PreMultipliers[c]))
3955       dmin = VALUE(m_PreMultipliers[c]);
3956     if (dmax < VALUE(m_PreMultipliers[c]))
3957       dmax = VALUE(m_PreMultipliers[c]);
3958   }
3959 
3960   TRACEKEYVALS("PreMult[0]","%f",VALUE(m_PreMultipliers[0]));
3961   TRACEKEYVALS("PreMult[1]","%f",VALUE(m_PreMultipliers[1]));
3962   TRACEKEYVALS("PreMult[2]","%f",VALUE(m_PreMultipliers[2]));
3963   TRACEKEYVALS("PreMult[3]","%f",VALUE(m_PreMultipliers[3]));
3964 #ifdef TRACE_ORIGIN
3965   TRACEKEYVALS("PreMult File","%s",m_PreMultipliers[0].File);
3966   TRACEKEYVALS("PreMult Line","%d",m_PreMultipliers[0].Line);
3967 #endif
3968 
3969   for (c=0;c<4;c++) {
3970     if (m_UserSetting_MaxMultiplier==0)
3971       ASSIGN(m_PreMultipliers[c],VALUE(m_PreMultipliers[c]) / dmax);
3972     else
3973       ASSIGN(m_PreMultipliers[c],VALUE(m_PreMultipliers[c]) / dmin);
3974     ASSIGN(m_Multipliers[c],
3975            VALUE(m_PreMultipliers[c])*0xffff/(m_WhiteLevel-m_CBlackLevel[c]));
3976   }
3977   if (m_UserSetting_MaxMultiplier==0)
3978     m_MinPreMulti = dmin/dmax; // And the maximum is per construction 1.0
3979   else
3980     m_MinPreMulti = 1.0; // TODO Mike: max is not 1.0 anymore...
3981 
3982   TRACEKEYVALS("dmax","%f",dmax);
3983   TRACEKEYVALS("dmin","%f",dmin);
3984   TRACEKEYVALS("m_MinPreMulti","%f",m_MinPreMulti);
3985   TRACEKEYVALS("PreMult[0]","%f",VALUE(m_PreMultipliers[0]));
3986   TRACEKEYVALS("PreMult[1]","%f",VALUE(m_PreMultipliers[1]));
3987   TRACEKEYVALS("PreMult[2]","%f",VALUE(m_PreMultipliers[2]));
3988   TRACEKEYVALS("PreMult[3]","%f",VALUE(m_PreMultipliers[3]));
3989 #ifdef TRACE_ORIGIN
3990   TRACEKEYVALS("PreMult File","%s",m_PreMultipliers[0].File);
3991   TRACEKEYVALS("PreMult Line","%d",m_PreMultipliers[0].Line);
3992 #endif
3993   TRACEKEYVALS("Mult[0]","%f",VALUE(m_Multipliers[0]));
3994   TRACEKEYVALS("Mult[1]","%f",VALUE(m_Multipliers[1]));
3995   TRACEKEYVALS("Mult[2]","%f",VALUE(m_Multipliers[2]));
3996   TRACEKEYVALS("Mult[3]","%f",VALUE(m_Multipliers[3]));
3997 #ifdef TRACE_ORIGIN
3998   TRACEKEYVALS("Mult File","%s",m_Multipliers[0].File);
3999   TRACEKEYVALS("Mult Line","%d",m_Multipliers[0].Line);
4000 #endif
4001 
4002   TRACEKEYVALS("Scaling colors","%s","");
4003 
4004   uint16_t LUT[0x10000][4];
4005 #pragma omp parallel for schedule(static)
4006   for (uint32_t i = 0; i < 0xffff; i++) {
4007     for (short c = 0; c < 4; c++) {
4008       LUT[i][c] = i>m_CBlackLevel[c]?
4009                     MIN((int32_t)((i - m_CBlackLevel[c])*VALUE(m_Multipliers[c])),0xffff):0;
4010     }
4011   }
4012 
4013   uint32_t Size = m_OutHeight*m_OutWidth;
4014 #pragma omp parallel for schedule(static)
4015   for (uint32_t i = 0; i < Size; i++) {
4016     for (short Color = 0; Color < 4; Color++) {
4017       m_Image[i][Color] = LUT[m_Image[i][Color]][Color];
4018     }
4019   }
4020 }
4021 
4022 ////////////////////////////////////////////////////////////////////////////////
4023 //
4024 // ptHighlight
4025 // Clipping is determined by Clip... FIXME
4026 //
4027 ////////////////////////////////////////////////////////////////////////////////
4028 
ptHighlight(const short ClipMode,const short ClipParameter)4029 void CLASS ptHighlight(const short  ClipMode,
4030                        const short  ClipParameter) {
4031 
4032   TRACEKEYVALS("ClipMode","%d",ClipMode);
4033   TRACEKEYVALS("ClipParameter","%d",ClipParameter);
4034 
4035   TRACEKEYVALS("m_Multi[0]","%f",VALUE(m_Multipliers[0]));
4036   TRACEKEYVALS("m_Multi[1]","%f",VALUE(m_Multipliers[1]));
4037   TRACEKEYVALS("m_Multi[2]","%f",VALUE(m_Multipliers[2]));
4038   TRACEKEYVALS("m_Multi[3]","%f",VALUE(m_Multipliers[3]));
4039 #ifdef TRACE_ORIGIN
4040   TRACEKEYVALS("Mult File","%s",m_Multipliers[0].File);
4041   TRACEKEYVALS("Mult Line","%d",m_Multipliers[0].Line);
4042 #endif
4043 
4044   TRACEKEYVALS("m_MinPreMulti","%f",m_MinPreMulti);
4045   short ColorRGB[4]={0,1,2,1};
4046 #pragma omp parallel for schedule(static) default(shared)
4047   for (uint16_t Row = 0; Row < m_OutHeight; Row++) {
4048     for (uint16_t Column = 0; Column < m_OutWidth; Column++) {
4049       uint32_t Pos = Row*m_OutWidth+Column;
4050 
4051       // Do take into account however that we scaled the image here
4052       // already !
4053 
4054       // Clip occurs if the sensor reached its max value. Full stop.
4055       // m_Image[Pos] stands for value after application of the
4056       // m_Multipliers, which are per construction so that the saturation
4057       // value of the sensor maps onto 0XFFFF. It is the unclipped pixel.
4058 
4059       short Clipped = 0;
4060       for (short Color = 0; Color < m_Colors; Color++) {
4061         if (m_Image[Pos][Color] >=
4062             (uint16_t)
4063                 ((m_WhiteLevel-m_CBlackLevel[ColorRGB[Color]])*VALUE(m_Multipliers[Color]))) {
4064           Clipped = 1;
4065         }
4066       }
4067 
4068       if (Clipped) {
4069         // Here it becomes fun. The sensor reached a clipped value.
4070 
4071         // 'ClippedPixel' stands for the pixel which is multiplied
4072         // by a value that guarantees the saturation value of the
4073         // least scaled channel maps onto 0XFFFF.
4074         // That value is obtained by observing that normally the
4075         // least scaled channel maps on saturation*minimum_multiplier
4076         // So since maximum_multipliers brings us per definition on 0XFFFF
4077         // upscaling with maximum_multiplier/minimum_multipier is that
4078         // value. Via the equivalence with the pre_multipliers where the
4079         // maximum is per construction 1 , it means that we have to upscale
4080         // with 1/m_MinPreMulti.
4081         // That way all saturated pixels are definitely mapped onto 0xFFFF
4082         uint16_t ClippedPixel[4];
4083         for (short Color = 0; Color < m_Colors; Color++) {
4084           // This ensures that the channel with the smallest multiplier
4085           // is clipped at its saturation level.
4086           ClippedPixel[Color] =
4087             MIN(0xFFFF,
4088                 (int32_t)(m_Image[Pos][Color]/m_MinPreMulti));
4089           // And now we correct it back for the increased exposure.
4090           // (but clipped stays clipped !)
4091           ClippedPixel[Color] = (uint16_t)(ClippedPixel[Color]* m_MinPreMulti);
4092         }
4093 
4094         // From here on there are now different strategies with respect
4095         // to clipping.
4096 
4097   // Try to remove purple highlights
4098   if (0)
4099     if (m_Image[Pos][2]>m_Image[Pos][1] && m_Image[Pos][0]==0xffff) m_Image[Pos][2]=m_Image[Pos][1];
4100 
4101         // Simply use the clipped value.
4102         if (ptClipMode_Clip == ClipMode) {
4103           for (short Color = 0; Color < m_Colors; Color++) {
4104             m_Image[Pos][Color] = ClippedPixel[Color];
4105           }
4106 
4107         // Or use a value starting from Unclipped->Clipped ,
4108         // defined by the ClipParameter.
4109         } else if (ptClipMode_NoClip == ClipMode) {
4110           for (short Color = 0; Color < m_Colors; Color++) {
4111             m_Image[Pos][Color] =
4112               m_Image[Pos][Color] +
4113                (uint16_t) (ClipParameter/100.0*
4114                            (ClippedPixel[Color]-m_Image[Pos][Color]));
4115           }
4116 
4117         // Or restore via Lab, which is basically the same as
4118         // used in ufraw (and a simplification of Cyril Guyots LCH blending.
4119         } else if (ptClipMode_Lab == ClipMode) {
4120           double ClippedLab[3];
4121           double UnclippedLab[3];
4122           double FinalLab[3];
4123           CamToLab(ClippedPixel,ClippedLab);
4124           CamToLab(m_Image[Pos],UnclippedLab);
4125           // FIXME / TODO : Clarify and explain.
4126           // This is a bit bizar in fact (but also in ufraw ...)
4127           // The result seems to be better when taking the clipped
4128           // alternatives for ab and unclipped for L.
4129           // Wouldn't we expect it the other way around ?
4130           FinalLab[0] = UnclippedLab[0] +
4131                         ClipParameter/100.0*
4132                         (ClippedLab[0]-UnclippedLab[0]);
4133           FinalLab[1] = ClippedLab[1];
4134           FinalLab[2] = ClippedLab[2];
4135           LabToCam(FinalLab,m_Image[Pos]);
4136 
4137         // Or restore via HSV, as in ufraw.
4138         } else if (ptClipMode_HSV == ClipMode) {
4139           // FIXME / TODO : can this not break in some 4 colour modes ?
4140           short MaxChannel,MidChannel,MinChannel;
4141           if (m_Image[Pos][0] > m_Image[Pos][1] &&
4142               m_Image[Pos][0] > m_Image[Pos][2]) {
4143             MaxChannel = 0;
4144       if (m_Image[Pos][1] > m_Image[Pos][2]) {
4145               MidChannel = 1;
4146               MinChannel = 2;
4147             } else {
4148               MidChannel = 2;
4149               MinChannel = 1;
4150             }
4151           } else if (m_Image[Pos][1] > m_Image[Pos][2]) {
4152             MaxChannel = 1;
4153       if (m_Image[Pos][0] > m_Image[Pos][2]) {
4154               MidChannel = 0;
4155               MinChannel = 2;
4156             } else {
4157               MidChannel = 2;
4158               MinChannel = 0;
4159             }
4160           } else {
4161             MaxChannel = 2;
4162       if (m_Image[Pos][0] > m_Image[Pos][1]) {
4163               MidChannel = 0;
4164               MinChannel = 1;
4165             } else {
4166               MidChannel = 1;
4167               MinChannel = 0;
4168             }
4169           }
4170 
4171           uint16_t UnclippedLuminance = m_Image[Pos][MaxChannel];
4172           uint16_t ClippedLuminance   = ClippedPixel[MaxChannel];
4173           double   ClippedSaturation;
4174           if ( ClippedPixel[MaxChannel]<ClippedPixel[MinChannel] ||
4175                ClippedPixel[MaxChannel]==0) {
4176             ClippedSaturation = 0;
4177     } else {
4178             ClippedSaturation =
4179               1.0 - (double)ClippedPixel[MinChannel] / ClippedPixel[MaxChannel];
4180           }
4181 //warning: variable 'ClippedHue' set but not used [-Wunused-but-set-variable]
4182 //          double ClippedHue;
4183 //    if ( ClippedPixel[MaxChannel]==ClippedPixel[MinChannel] ) {
4184 //            ClippedHue = 0;
4185 //    } else {
4186 //            ClippedHue =
4187 //              ((double)ClippedPixel[MidChannel]-ClippedPixel[MinChannel]) /
4188 //              ((double)ClippedPixel[MaxChannel]-ClippedPixel[MinChannel]);
4189 //          }
4190           double UnclippedHue;
4191     if ( m_Image[Pos][MaxChannel]==m_Image[Pos][MinChannel] ) {
4192             UnclippedHue = 0;
4193     } else {
4194             UnclippedHue =
4195               ((double)m_Image[Pos][MidChannel]-m_Image[Pos][MinChannel]) /
4196               ((double)m_Image[Pos][MaxChannel]-m_Image[Pos][MinChannel]);
4197           }
4198           uint16_t Luminance =
4199             UnclippedLuminance +
4200             (uint16_t)(ClipParameter/100.0 *
4201                        (ClippedLuminance-UnclippedLuminance));
4202           double Saturation = ClippedSaturation;
4203           double Hue = UnclippedHue;
4204     m_Image[Pos][MaxChannel] = Luminance;
4205     m_Image[Pos][MinChannel] = (uint16_t)(Luminance * (1-Saturation));
4206     m_Image[Pos][MidChannel] =
4207             (uint16_t)(Luminance * (1-Saturation + Saturation*Hue));
4208 
4209         } else if (ptClipMode_Blend == ClipMode) {
4210           // Do nothing at this stage, keep the unclipped image.
4211           ;
4212         } else if (ptClipMode_Rebuild == ClipMode) {
4213           // Do nothing at this stage, keep the unclipped image.
4214           ;
4215         } else {
4216           assert(0); // should not occur.
4217         }
4218       }
4219     }
4220   }
4221 
4222   if (ptClipMode_Rebuild == ClipMode) {
4223     ptRebuildHighlights(ClipParameter);
4224   }
4225   if (ptClipMode_Blend == ClipMode) {
4226     ptBlendHighlights();
4227   }
4228 }
4229 
pre_interpolate()4230 void CLASS pre_interpolate()
4231 {
4232   int row, col;
4233 
4234   TRACEKEYVALS("pre_interpolate","%s","");
4235 
4236   if (m_Shrink) {
4237     if (m_UserSetting_HalfSize) {
4238       // No interpolation will be needed as
4239       // m_Shrink has caused a 2X2 Bayer area mapped onto one pixel.
4240       m_Height = m_OutHeight;
4241       m_Width  = m_OutWidth;
4242     } else {
4243       // in photivo we assume that m_Shrink is only set due
4244       // to m_UserSetting_HalfSize.
4245       assert(0);
4246     }
4247   }
4248   if (m_Filters > 1000 && m_Colors == 3) {
4249     if (m_MixGreen) { // 4 color demosaicer will follow
4250       m_Colors++;
4251       // Change from dcraw 1.445 to 1.447 wanted "m_MixGreen = !m_UserSetting_HalfSize;"
4252       // but this doesn't work in Photivo, since we don't run the full pipe of dcraw,
4253       // since most of the time we start with phase2
4254     } else {
4255       // RG1BG2 -> RGB
4256 #pragma omp parallel for schedule(static) default(shared) private(row, col)
4257       for (row = FC(1,0) >> 1; row < m_Height; row+=2)
4258         for (col = FC(row,1) & 1; col < m_Width; col+=2)
4259           m_Image[row*m_Width+col][1] = m_Image[row*m_Width+col][3];
4260       m_Filters &= ~((m_Filters & 0x55555555) << 1);
4261     }
4262   }
4263 
4264   // If m_UserSetting_HalfSize is set no interpolation will
4265   // be needed. This is registered by m_Filters = 0.
4266   // (no Bayer array anymore, this means)
4267   if (m_UserSetting_HalfSize && m_Filters != 2) {
4268     m_Filters = 0;
4269   }
4270 }
4271 
border_interpolate(int border)4272 void CLASS border_interpolate (int border)
4273 {
4274   unsigned row, col, y, x, f, c, sum[8];
4275 
4276   for (row=0; row < m_Height; row++)
4277     for (col=0; col < m_Width; col++) {
4278       if (col==(unsigned) border && row >= (unsigned) border && row < (unsigned) (m_Height-border))
4279   col = m_Width-border;
4280       memset (sum, 0, sizeof sum);
4281       for (y=row-1; y != row+2; y++)
4282   for (x=col-1; x != col+2; x++)
4283     if (y < m_Height && x < m_Width) {
4284     f = fcol(y,x);
4285       sum[f] += m_Image[y*m_Width+x][f];
4286       sum[f+4]++;
4287     }
4288       f = fcol(row,col);
4289       for (c=0; c < (unsigned) m_Colors; c++) if (c != f && sum[c+4])
4290   m_Image[row*m_Width+col][c] = sum[c] / sum[c+4];
4291     }
4292 }
4293 
4294 
lin_interpolate()4295 void CLASS lin_interpolate()
4296 {
4297   int code[16][16][32], size=16, *ip, sum[4];
4298   int f, c, i, x, y, row, col, shift, color;
4299   uint16_t *pix;
4300 
4301   TRACEKEYVALS("Bilinear interpolation","%s","");
4302   if (m_Filters == 2) size = 6;
4303   border_interpolate(1);
4304   for (row=0; row < size; row++)
4305     for (col=0; col < size; col++) {
4306       ip = code[row][col]+1;
4307       f = fcol(row,col);
4308       memset (sum, 0, sizeof sum);
4309       for (y=-1; y <= 1; y++)
4310   for (x=-1; x <= 1; x++) {
4311     shift = (y==0) + (x==0);
4312     color = fcol(row+y,col+x);
4313     if (color == f) continue;
4314     *ip++ = (m_Width*y + x)*4 + color;
4315     *ip++ = shift;
4316     *ip++ = color;
4317     sum[color] += 1 << shift;
4318   }
4319       code[row][col][0] = (ip - code[row][col]) / 3;
4320       for (c=0; c < m_Colors; c++)
4321   if (c != f) {
4322     *ip++ = c;
4323     *ip++ = 256 / sum[c];
4324   }
4325     }
4326 #pragma omp parallel for schedule(static) default(shared) private(row,col,pix,ip,sum,i)
4327   for (row=1; row < m_Height-1; row++)
4328     for (col=1; col < m_Width-1; col++) {
4329       pix = m_Image[row*m_Width+col];
4330       ip = code[row % size][col % size];
4331       memset (sum, 0, sizeof sum);
4332       for (i=*ip++; i--; ip+=3)
4333   sum[ip[2]] += pix[ip[0]] << ip[1];
4334       for (i=m_Colors; --i; ip+=2)
4335   pix[ip[0]] = sum[ip[0]] * ip[1] >> 8;
4336     }
4337 }
4338 
4339 /*
4340    This algorithm is officially called:
4341 
4342    "Interpolation using a Threshold-based variable number of gradients"
4343 
4344    described in http://scien.stanford.edu/pages/labsite/1999/psych221/projects/99/tingchen/algodep/vargra.html
4345 
4346    I've extended the basic idea to work with non-Bayer filter arrays.
4347    Gradients are numbered clockwise from NW=0 to W=7.
4348  */
vng_interpolate()4349 void CLASS vng_interpolate()
4350 {
4351   static const int16_t *cp, terms[] = {
4352     -2,-2,+0,-1,0,0x01, -2,-2,+0,+0,1,0x01, -2,-1,-1,+0,0,0x01,
4353     -2,-1,+0,-1,0,0x02, -2,-1,+0,+0,0,0x03, -2,-1,+0,+1,1,0x01,
4354     -2,+0,+0,-1,0,0x06, -2,+0,+0,+0,1,0x02, -2,+0,+0,+1,0,0x03,
4355     -2,+1,-1,+0,0,0x04, -2,+1,+0,-1,1,0x04, -2,+1,+0,+0,0,0x06,
4356     -2,+1,+0,+1,0,0x02, -2,+2,+0,+0,1,0x04, -2,+2,+0,+1,0,0x04,
4357     -1,-2,-1,+0,0,0x80, -1,-2,+0,-1,0,0x01, -1,-2,+1,-1,0,0x01,
4358     -1,-2,+1,+0,1,0x01, -1,-1,-1,+1,0,0x88, -1,-1,+1,-2,0,0x40,
4359     -1,-1,+1,-1,0,0x22, -1,-1,+1,+0,0,0x33, -1,-1,+1,+1,1,0x11,
4360     -1,+0,-1,+2,0,0x08, -1,+0,+0,-1,0,0x44, -1,+0,+0,+1,0,0x11,
4361     -1,+0,+1,-2,1,0x40, -1,+0,+1,-1,0,0x66, -1,+0,+1,+0,1,0x22,
4362     -1,+0,+1,+1,0,0x33, -1,+0,+1,+2,1,0x10, -1,+1,+1,-1,1,0x44,
4363     -1,+1,+1,+0,0,0x66, -1,+1,+1,+1,0,0x22, -1,+1,+1,+2,0,0x10,
4364     -1,+2,+0,+1,0,0x04, -1,+2,+1,+0,1,0x04, -1,+2,+1,+1,0,0x04,
4365     +0,-2,+0,+0,1,0x80, +0,-1,+0,+1,1,0x88, +0,-1,+1,-2,0,0x40,
4366     +0,-1,+1,+0,0,0x11, +0,-1,+2,-2,0,0x40, +0,-1,+2,-1,0,0x20,
4367     +0,-1,+2,+0,0,0x30, +0,-1,+2,+1,1,0x10, +0,+0,+0,+2,1,0x08,
4368     +0,+0,+2,-2,1,0x40, +0,+0,+2,-1,0,0x60, +0,+0,+2,+0,1,0x20,
4369     +0,+0,+2,+1,0,0x30, +0,+0,+2,+2,1,0x10, +0,+1,+1,+0,0,0x44,
4370     +0,+1,+1,+2,0,0x10, +0,+1,+2,-1,1,0x40, +0,+1,+2,+0,0,0x60,
4371     +0,+1,+2,+1,0,0x20, +0,+1,+2,+2,0,0x10, +1,-2,+1,+0,0,0x80,
4372     +1,-1,+1,+1,0,0x88, +1,+0,+1,+2,0,0x08, +1,+0,+2,-1,0,0x40,
4373     +1,+0,+2,+1,0,0x10
4374   }, chood[] = { -1,-1, -1,0, -1,+1, 0,+1, +1,+1, +1,0, +1,-1, 0,-1 };
4375   uint16_t (*brow[5])[4], *pix;
4376   int prow=8, pcol=2, *ip, *code[16][16], gval[8], gmin, gmax, sum[4];
4377   int row, col, x, y, x1, x2, y1, y2, t, weight, grads, color, diag;
4378   int g, diff, thold, num, c;
4379 
4380   lin_interpolate();
4381 
4382   TRACEKEYVALS("VNG interpolation","%s","");
4383 
4384   if (m_Filters == 1) prow = pcol = 16;
4385   if (m_Filters == 2) prow = pcol =  6;
4386   ip = (int *) CALLOC (prow*pcol, 1280);
4387   merror (ip, "vng_interpolate()");
4388   for (row=0; row < prow; row++)		/* Precalculate for VNG */
4389     for (col=0; col < pcol; col++) {
4390       code[row][col] = ip;
4391       for (cp=terms, t=0; t < 64; t++) {
4392   y1 = *cp++;  x1 = *cp++;
4393   y2 = *cp++;  x2 = *cp++;
4394   weight = *cp++;
4395   grads = *cp++;
4396   color = fcol(row+y1,col+x1);
4397   if (fcol(row+y2,col+x2) != color) continue;
4398   diag = (fcol(row,col+1) == color && fcol(row+1,col) == color) ? 2:1;
4399   if (abs(y1-y2) == diag && abs(x1-x2) == diag) continue;
4400   *ip++ = (y1*m_Width + x1)*4 + color;
4401   *ip++ = (y2*m_Width + x2)*4 + color;
4402   *ip++ = weight;
4403   for (g=0; g < 8; g++)
4404     if (grads & 1<<g) *ip++ = g;
4405   *ip++ = -1;
4406       }
4407       *ip++ = INT_MAX;
4408       for (cp=chood, g=0; g < 8; g++) {
4409   y = *cp++;  x = *cp++;
4410   *ip++ = (y*m_Width + x) * 4;
4411   color = fcol(row,col);
4412   if (fcol(row+y,col+x) != color && fcol(row+y*2,col+x*2) == color)
4413     *ip++ = (y*m_Width + x) * 8 + color;
4414   else
4415     *ip++ = 0;
4416       }
4417     }
4418 
4419   brow[4] = (uint16_t (*)[4]) CALLOC (m_Width*3, sizeof **brow);
4420   merror (brow[4], "vng_interpolate()");
4421   for (row=0; row < 3; row++)
4422     brow[row] = brow[4] + row*m_Width;
4423 
4424   for (row=2; row < m_Height-2; row++) {    /* Do VNG interpolation */
4425     for (col=2; col < m_Width-2; col++) {
4426       pix = m_Image[row*m_Width+col];
4427       ip = code[row % prow][col % pcol];
4428       memset (gval, 0, sizeof gval);
4429       while ((g = ip[0]) != INT_MAX) {    /* Calculate gradients */
4430   diff = ABS(pix[g] - pix[ip[1]]) << ip[2];
4431   gval[ip[3]] += diff;
4432   ip += 5;
4433   if ((g = ip[-1]) == -1) continue;
4434   gval[g] += diff;
4435   while ((g = *ip++) != -1)
4436     gval[g] += diff;
4437       }
4438       ip++;
4439       gmin = gmax = gval[0];      /* Choose a threshold */
4440       for (g=1; g < 8; g++) {
4441   if (gmin > gval[g]) gmin = gval[g];
4442   if (gmax < gval[g]) gmax = gval[g];
4443       }
4444       if (gmax == 0) {
4445   memcpy (brow[2][col], pix, sizeof *m_Image);
4446   continue;
4447       }
4448       thold = gmin + (gmax >> 1);
4449       memset (sum, 0, sizeof sum);
4450       color = fcol(row,col);
4451       for (num=g=0; g < 8; g++,ip+=2) {   /* Average the neighbors */
4452   if (gval[g] <= thold) {
4453     for (c=0; c < m_Colors; c++)
4454       if (c == color && ip[1])
4455         sum[c] += (pix[c] + pix[ip[1]]) >> 1;
4456       else
4457         sum[c] += pix[ip[0] + c];
4458     num++;
4459   }
4460       }
4461       for (c=0; c < m_Colors; c++) {          /* Save to buffer */
4462   t = pix[color];
4463   if (c != color)
4464     t += (sum[c] - sum[color]) / num;
4465   brow[2][col][c] = CLIP(t);
4466       }
4467     }
4468     if (row > 3)        /* Write buffer to image */
4469       memcpy (m_Image[(row-2)*m_Width+2], brow[0]+2, (m_Width-4)*sizeof *m_Image);
4470     for (g=0; g < 4; g++)
4471       brow[(g-1) & 3] = brow[g];
4472   }
4473   memcpy (m_Image[(row-2)*m_Width+2], brow[0]+2, (m_Width-4)*sizeof *m_Image);
4474   memcpy (m_Image[(row-1)*m_Width+2], brow[1]+2, (m_Width-4)*sizeof *m_Image);
4475   FREE (brow[4]);
4476   FREE (code[0][0]);
4477 }
4478 
4479 /*
4480    Patterned Pixel Grouping Interpolation by Alain Desbiolles
4481 */
ppg_interpolate()4482 void CLASS ppg_interpolate()
4483 {
4484   const int dir[5] = { 1, m_Width, -1, -m_Width, 1 };
4485   int row, col, diff[2], guess[2], c, d, i;
4486   uint16_t (*pix)[4];
4487 
4488   border_interpolate(3);
4489 
4490   TRACEKEYVALS("PPG interpolation","%s","");
4491 
4492 #pragma omp parallel private(row,c,col,i,guess,diff,d,pix)
4493 /*  Fill in the green layer with gradients and pattern recognition: */
4494 #pragma omp for
4495   for (row=3; row < m_Height-3; row++)
4496     for (col=3+(FC(row,3) & 1), c=FC(row,col); col < m_Width-3; col+=2) {
4497       pix = m_Image + row*m_Width+col;
4498       for (i=0; i<2; i++) {
4499         d = dir[i];
4500   guess[i] = (pix[-d][1] + pix[0][c] + pix[d][1]) * 2
4501           - pix[-2*d][c] - pix[2*d][c];
4502   diff[i] = ( ABS(pix[-2*d][c] - pix[ 0][c]) +
4503         ABS(pix[ 2*d][c] - pix[ 0][c]) +
4504         ABS(pix[  -d][1] - pix[ d][1]) ) * 3 +
4505       ( ABS(pix[ 3*d][1] - pix[ d][1]) +
4506         ABS(pix[-3*d][1] - pix[-d][1]) ) * 2;
4507       }
4508       d = dir[i = diff[0] > diff[1]];
4509       pix[0][1] = ULIM(guess[i] >> 2, (int32_t)pix[d][1], (int32_t)pix[-d][1]);
4510     }
4511 /*  Calculate red and blue for each green pixel:    */
4512 #pragma omp for
4513   for (row=1; row < m_Height-1; row++)
4514     for (col=1+(FC(row,2) & 1), c=FC(row,col+1); col < m_Width-1; col+=2) {
4515       pix = m_Image + row*m_Width+col;
4516       for (i=0; (d=dir[i]) > 0; c=2-c, i++)
4517   pix[0][c] = CLIP((pix[-d][c] + pix[d][c] + 2*pix[0][1]
4518       - pix[-d][1] - pix[d][1]) >> 1);
4519     }
4520 /*  Calculate blue for red pixels and vice versa:   */
4521 #pragma omp for
4522   for (row=1; row < m_Height-1; row++)
4523     for (col=1+(FC(row,1) & 1), c=2-FC(row,col); col < m_Width-1; col+=2) {
4524       pix = m_Image + row*m_Width+col;
4525       for (i=0; i < 2; i++) {
4526         d = dir[i]+dir[i+1];
4527         diff[i] = ABS(pix[-d][c] - pix[d][c]) +
4528       ABS(pix[-d][1] - pix[0][1]) +
4529       ABS(pix[ d][1] - pix[0][1]);
4530   guess[i] = pix[-d][c] + pix[d][c] + 2*pix[0][1]
4531      - pix[-d][1] - pix[d][1];
4532       }
4533       if (diff[0] != diff[1])
4534   pix[0][c] = CLIP(guess[diff[0] > diff[1]] >> 1);
4535       else
4536   pix[0][c] = CLIP((guess[0]+guess[1]) >> 2);
4537     }
4538 }
4539 
4540 /*
4541    Adaptive Homogeneity-Directed interpolation is based on
4542    the work of Keigo Hirakawa, Thomas Parks, and Paul Lee.
4543  */
4544 #define TS 256    /* Tile Size */
4545 
ahd_interpolate()4546 void CLASS ahd_interpolate()
4547 {
4548   int i, j, k, top, left, row, col, tr, tc, c, d, val, hm[2];
4549   uint16_t (*pix)[4], (*rix)[3];
4550   static const int dir[4] = { -1, 1, -TS, TS };
4551   unsigned ldiff[2][4], abdiff[2][4], leps, abeps;
4552   float r, cbrt[0x10000], xyz[3], xyz_cam[3][4];
4553   uint16_t (*rgb)[TS][TS][3];
4554    short (*lab)[TS][TS][3], (*lix)[3];
4555    char (*homo)[TS][TS], *buffer;
4556 
4557   TRACEKEYVALS("AHD interpolation","%s","");
4558 
4559   for (i=0; i < 0x10000; i++) {
4560     r = i / 65535.0;
4561     cbrt[i] = r > 0.008856 ? pow(r,1/3.0) : 7.787*r + 16/116.0;
4562   }
4563   for (i=0; i < 3; i++)
4564     for (j=0; j < m_Colors; j++)
4565       for (xyz_cam[i][j] = k=0; k < 3; k++)
4566   xyz_cam[i][j] += MatrixRGBToXYZ[ptSpace_sRGB_D65][i][k] * m_MatrixCamRGBToSRGB[k][j] / D65Reference[i];
4567 
4568   border_interpolate(5);
4569 
4570 #pragma omp parallel private(buffer,rgb,lab,homo,top,left,row,c,col,pix,val,d,rix,xyz,lix,tc,tr,ldiff,abdiff,leps,abeps,hm,i,j) firstprivate(cbrt) shared(xyz_cam)
4571   {
4572       buffer = (char *) MALLOC (26*TS*TS);    /* 1664 kB */
4573       merror (buffer, "ahd_interpolate()");
4574       rgb  = (uint16_t(*)[TS][TS][3]) buffer;
4575       lab  = (short (*)[TS][TS][3])(buffer + 12*TS*TS);
4576       homo = (char  (*)[TS][TS])   (buffer + 24*TS*TS);
4577 
4578 #pragma omp for schedule(static)
4579       for (top=2; top < m_Height-5; top += TS-6)
4580           for (left=2; left < m_Width-5; left += TS-6) {
4581 
4582           /*  Interpolate green horizontally and vertically:    */
4583           for (row = top; row < top+TS && row < m_Height-2; row++) {
4584               col = left + (FC(row,left) & 1);
4585               for (c = FC(row,col); col < left+TS && col < m_Width-2; col+=2) {
4586                   pix = m_Image + row*m_Width+col;
4587                   val = ((pix[-1][1] + pix[0][c] + pix[1][1]) * 2
4588                          - pix[-2][c] - pix[2][c]) >> 2;
4589                   rgb[0][row-top][col-left][1] = ULIM(val,(int32_t)pix[-1][1],(int32_t)pix[1][1]);
4590                   val = ((pix[-m_Width][1] + pix[0][c] + pix[m_Width][1]) * 2
4591                          - pix[-2*m_Width][c] - pix[2*m_Width][c]) >> 2;
4592                   rgb[1][row-top][col-left][1] = ULIM(val,(int32_t)pix[-m_Width][1],(int32_t)pix[m_Width][1]);
4593               }
4594           }
4595           /*  Interpolate red and blue, and convert to CIELab:    */
4596           for (d=0; d < 2; d++)
4597               for (row=top+1; row < top+TS-1 && row < m_Height-3; row++)
4598                   for (col=left+1; col < left+TS-1 && col < m_Width-3; col++) {
4599               pix = m_Image + row*m_Width+col;
4600               rix = &rgb[d][row-top][col-left];
4601               lix = &lab[d][row-top][col-left];
4602               if ((c = 2 - FC(row,col)) == 1) {
4603                   c = FC(row+1,col);
4604                   val = pix[0][1] + (( pix[-1][2-c] + pix[1][2-c]
4605                                        - rix[-1][1] - rix[1][1] ) >> 1);
4606                   rix[0][2-c] = CLIP(val);
4607                   val = pix[0][1] + (( pix[-m_Width][c] + pix[m_Width][c]
4608                                        - rix[-TS][1] - rix[TS][1] ) >> 1);
4609               } else
4610                   val = rix[0][1] + (( pix[-m_Width-1][c] + pix[-m_Width+1][c]
4611                                        + pix[+m_Width-1][c] + pix[+m_Width+1][c]
4612                                        - rix[-TS-1][1] - rix[-TS+1][1]
4613                                        - rix[+TS-1][1] - rix[+TS+1][1] + 1) >> 2);
4614               rix[0][c] = CLIP(val);
4615               c = FC(row,col);
4616               rix[0][c] = pix[0][c];
4617               xyz[0] = xyz[1] = xyz[2] = 0.5;
4618               for (c=0; c < m_Colors; c++) {
4619                   xyz[0] += xyz_cam[0][c] * rix[0][c];
4620                   xyz[1] += xyz_cam[1][c] * rix[0][c];
4621                   xyz[2] += xyz_cam[2][c] * rix[0][c];
4622               }
4623               xyz[0] = cbrt[CLIP((int) xyz[0])];
4624               xyz[1] = cbrt[CLIP((int) xyz[1])];
4625               xyz[2] = cbrt[CLIP((int) xyz[2])];
4626               lix[0][0] = (short) (64 * (116 * xyz[1] - 16));
4627               lix[0][1] = (short) (64 * 500 * (xyz[0] - xyz[1]));
4628               lix[0][2] = (short) (64 * 200 * (xyz[1] - xyz[2]));
4629           }
4630           /*  Build homogeneity maps from the CIELab images:    */
4631           memset (homo, 0, 2*TS*TS);
4632           for (row=top+2; row < top+TS-2 && row < m_Height-4; row++) {
4633               tr = row-top;
4634               for (col=left+2; col < left+TS-2 && col < m_Width-4; col++) {
4635                   tc = col-left;
4636                   for (d=0; d < 2; d++) {
4637                       lix = &lab[d][tr][tc];
4638                       for (i=0; i < 4; i++) {
4639                           ldiff[d][i] = ABS(lix[0][0]-lix[dir[i]][0]);
4640                           abdiff[d][i] = SQR(lix[0][1]-lix[dir[i]][1])
4641                                          + SQR(lix[0][2]-lix[dir[i]][2]);
4642                       }
4643                   }
4644                   leps = MIN(MAX(ldiff[0][0],ldiff[0][1]),
4645                              MAX(ldiff[1][2],ldiff[1][3]));
4646                   abeps = MIN(MAX(abdiff[0][0],abdiff[0][1]),
4647                               MAX(abdiff[1][2],abdiff[1][3]));
4648                   for (d=0; d < 2; d++)
4649                       for (i=0; i < 4; i++)
4650                           if (ldiff[d][i] <= leps && abdiff[d][i] <= abeps)
4651                              homo[d][tr][tc]++;
4652               }
4653           }
4654           /*  Combine the most homogenous pixels for the final result:  */
4655           for (row=top+3; row < top+TS-3 && row < m_Height-5; row++) {
4656               tr = row-top;
4657               for (col=left+3; col < left+TS-3 && col < m_Width-5; col++) {
4658                   tc = col-left;
4659                   for (d=0; d < 2; d++)
4660                       for (hm[d]=0, i=tr-1; i <= tr+1; i++)
4661                           for (j=tc-1; j <= tc+1; j++)
4662                               hm[d] += homo[d][i][j];
4663                   if (hm[0] != hm[1])
4664                       for (c=0; c<3; c++) m_Image[row*m_Width+col][c] = rgb[hm[1] > hm[0]][tr][tc][c];
4665                   else
4666                       for (c=0; c<3; c++) m_Image[row*m_Width+col][c] =
4667                               (rgb[0][tr][tc][c] + rgb[1][tr][tc][c]) >> 1;
4668               }
4669           }
4670       }
4671       FREE (buffer);
4672   }
4673 }
4674 #undef TS
4675 
tiff_get(unsigned base,unsigned * tag,unsigned * type,unsigned * len,unsigned * save)4676 void CLASS tiff_get (unsigned base,
4677   unsigned *tag, unsigned *type, unsigned *len, unsigned *save)
4678 {
4679   *tag  = get2();
4680   *type = get2();
4681   *len  = get4();
4682   *save = ftell(m_InputFile) + 4;
4683   if (*len * ("11124811248488"[*type < 14 ? *type:0]-'0') > 4)
4684     fseek (m_InputFile, get4()+base, SEEK_SET);
4685 }
4686 
parse_thumb_note(int base,unsigned toff,unsigned tlen)4687 void CLASS parse_thumb_note (int base, unsigned toff, unsigned tlen)
4688 {
4689   unsigned entries, tag, type, len, save;
4690 
4691   entries = get2();
4692   while (entries--) {
4693     tiff_get (base, &tag, &type, &len, &save);
4694     if (tag == toff) m_ThumbOffset = get4()+base;
4695     if (tag == tlen) m_ThumbLength = get4();
4696     fseek (m_InputFile, save, SEEK_SET);
4697   }
4698 }
4699 
4700 //int CLASS parse_tiff_ifd (int base);
4701 
parse_makernote(int base,int uptag)4702 void CLASS parse_makernote (int base, int uptag)
4703 {
4704   static const uint8_t xlat[2][256] = {
4705   { 0xc1,0xbf,0x6d,0x0d,0x59,0xc5,0x13,0x9d,0x83,0x61,0x6b,0x4f,0xc7,0x7f,0x3d,0x3d,
4706     0x53,0x59,0xe3,0xc7,0xe9,0x2f,0x95,0xa7,0x95,0x1f,0xdf,0x7f,0x2b,0x29,0xc7,0x0d,
4707     0xdf,0x07,0xef,0x71,0x89,0x3d,0x13,0x3d,0x3b,0x13,0xfb,0x0d,0x89,0xc1,0x65,0x1f,
4708     0xb3,0x0d,0x6b,0x29,0xe3,0xfb,0xef,0xa3,0x6b,0x47,0x7f,0x95,0x35,0xa7,0x47,0x4f,
4709     0xc7,0xf1,0x59,0x95,0x35,0x11,0x29,0x61,0xf1,0x3d,0xb3,0x2b,0x0d,0x43,0x89,0xc1,
4710     0x9d,0x9d,0x89,0x65,0xf1,0xe9,0xdf,0xbf,0x3d,0x7f,0x53,0x97,0xe5,0xe9,0x95,0x17,
4711     0x1d,0x3d,0x8b,0xfb,0xc7,0xe3,0x67,0xa7,0x07,0xf1,0x71,0xa7,0x53,0xb5,0x29,0x89,
4712     0xe5,0x2b,0xa7,0x17,0x29,0xe9,0x4f,0xc5,0x65,0x6d,0x6b,0xef,0x0d,0x89,0x49,0x2f,
4713     0xb3,0x43,0x53,0x65,0x1d,0x49,0xa3,0x13,0x89,0x59,0xef,0x6b,0xef,0x65,0x1d,0x0b,
4714     0x59,0x13,0xe3,0x4f,0x9d,0xb3,0x29,0x43,0x2b,0x07,0x1d,0x95,0x59,0x59,0x47,0xfb,
4715     0xe5,0xe9,0x61,0x47,0x2f,0x35,0x7f,0x17,0x7f,0xef,0x7f,0x95,0x95,0x71,0xd3,0xa3,
4716     0x0b,0x71,0xa3,0xad,0x0b,0x3b,0xb5,0xfb,0xa3,0xbf,0x4f,0x83,0x1d,0xad,0xe9,0x2f,
4717     0x71,0x65,0xa3,0xe5,0x07,0x35,0x3d,0x0d,0xb5,0xe9,0xe5,0x47,0x3b,0x9d,0xef,0x35,
4718     0xa3,0xbf,0xb3,0xdf,0x53,0xd3,0x97,0x53,0x49,0x71,0x07,0x35,0x61,0x71,0x2f,0x43,
4719     0x2f,0x11,0xdf,0x17,0x97,0xfb,0x95,0x3b,0x7f,0x6b,0xd3,0x25,0xbf,0xad,0xc7,0xc5,
4720     0xc5,0xb5,0x8b,0xef,0x2f,0xd3,0x07,0x6b,0x25,0x49,0x95,0x25,0x49,0x6d,0x71,0xc7 },
4721   { 0xa7,0xbc,0xc9,0xad,0x91,0xdf,0x85,0xe5,0xd4,0x78,0xd5,0x17,0x46,0x7c,0x29,0x4c,
4722     0x4d,0x03,0xe9,0x25,0x68,0x11,0x86,0xb3,0xbd,0xf7,0x6f,0x61,0x22,0xa2,0x26,0x34,
4723     0x2a,0xbe,0x1e,0x46,0x14,0x68,0x9d,0x44,0x18,0xc2,0x40,0xf4,0x7e,0x5f,0x1b,0xad,
4724     0x0b,0x94,0xb6,0x67,0xb4,0x0b,0xe1,0xea,0x95,0x9c,0x66,0xdc,0xe7,0x5d,0x6c,0x05,
4725     0xda,0xd5,0xdf,0x7a,0xef,0xf6,0xdb,0x1f,0x82,0x4c,0xc0,0x68,0x47,0xa1,0xbd,0xee,
4726     0x39,0x50,0x56,0x4a,0xdd,0xdf,0xa5,0xf8,0xc6,0xda,0xca,0x90,0xca,0x01,0x42,0x9d,
4727     0x8b,0x0c,0x73,0x43,0x75,0x05,0x94,0xde,0x24,0xb3,0x80,0x34,0xe5,0x2c,0xdc,0x9b,
4728     0x3f,0xca,0x33,0x45,0xd0,0xdb,0x5f,0xf5,0x52,0xc3,0x21,0xda,0xe2,0x22,0x72,0x6b,
4729     0x3e,0xd0,0x5b,0xa8,0x87,0x8c,0x06,0x5d,0x0f,0xdd,0x09,0x19,0x93,0xd0,0xb9,0xfc,
4730     0x8b,0x0f,0x84,0x60,0x33,0x1c,0x9b,0x45,0xf1,0xf0,0xa3,0x94,0x3a,0x12,0x77,0x33,
4731     0x4d,0x44,0x78,0x28,0x3c,0x9e,0xfd,0x65,0x57,0x16,0x94,0x6b,0xfb,0x59,0xd0,0xc8,
4732     0x22,0x36,0xdb,0xd2,0x63,0x98,0x43,0xa1,0x04,0x87,0x86,0xf7,0xa6,0x26,0xbb,0xd6,
4733     0x59,0x4d,0xbf,0x6a,0x2e,0xaa,0x2b,0xef,0xe6,0x78,0xb6,0x4e,0xe0,0x2f,0xdc,0x7c,
4734     0xbe,0x57,0x19,0x32,0x7e,0x2a,0xd0,0xb8,0xba,0x29,0x00,0x3c,0x52,0x7d,0xa8,0x49,
4735     0x3b,0x2d,0xeb,0x25,0x49,0xfa,0xa3,0xaa,0x39,0xa7,0xc5,0xa7,0x50,0x11,0x36,0xfb,
4736     0xc6,0x67,0x4a,0xf5,0xa5,0x12,0x65,0x7e,0xb0,0xdf,0xaf,0x4e,0xb3,0x61,0x7f,0x2f } };
4737   unsigned offset=0, entries, tag, type, len, save, c;
4738   unsigned ver97=0, serial=0, i, wbi=0, wb[4]={0,0,0,0};
4739   uint8_t buf97[324], ci, cj, ck;
4740   short mm_ByteOrder, sm_ByteOrder=m_ByteOrder;
4741   char buf[10];
4742 /*
4743    The MakerNote might have its own TIFF header (possibly with
4744    its own byte-order!), or it might just be a table.
4745  */
4746   if (!strcmp(m_CameraMake,"Nokia")) return;
4747   ptfread (buf, 1, 10, m_InputFile);
4748   if (!strncmp (buf,"KDK" ,3) ||  /* these aren't TIFF tables */
4749       !strncmp (buf,"VER" ,3) ||
4750       !strncmp (buf,"IIII",4) ||
4751       !strncmp (buf,"MMMM",4)) return;
4752   if (!strncmp (buf,"KC"  ,2) ||  /* Konica KD-400Z, KD-510Z */
4753       !strncmp (buf,"MLY" ,3)) {  /* Minolta DiMAGE G series */
4754     m_ByteOrder = 0x4d4d;
4755     while ((i=ftell(m_InputFile)) < (unsigned) m_Data_Offset && i < (unsigned) 16384) {
4756       wb[0] = wb[2];  wb[2] = wb[1];  wb[1] = wb[3];
4757       wb[3] = get2();
4758       if (wb[1] == 256 && wb[3] == 256 &&
4759     wb[0] > 256 && wb[0] < 640 && wb[2] > 256 && wb[2] < 640)
4760   for (c=0; c < 4; c++) ASSIGN(m_CameraMultipliers[c], wb[c]);
4761     }
4762     goto quit;
4763   }
4764   if (!strcmp (buf,"Nikon")) {
4765       base = ftell(m_InputFile);
4766       m_ByteOrder = get2();
4767       if (get2() != 42) goto quit;
4768       offset = get4();
4769       fseek (m_InputFile, offset-8, SEEK_CUR);
4770     } else if (!strcmp (buf,"OLYMPUS")) {
4771       base = ftell(m_InputFile)-10;
4772       fseek (m_InputFile, -2, SEEK_CUR);
4773       m_ByteOrder = get2();  get2();
4774     } else if (!strncmp (buf,"SONY",4) ||
4775          !strcmp  (buf,"Panasonic")) {
4776       goto nf;
4777     } else if (!strncmp (buf,"FUJIFILM",8)) {
4778       base = ftell(m_InputFile)-10;
4779   nf: m_ByteOrder = 0x4949;
4780       fseek (m_InputFile,  2, SEEK_CUR);
4781     } else if (!strcmp (buf,"OLYMP") ||
4782          !strcmp (buf,"LEICA") ||
4783          !strcmp (buf,"Ricoh") ||
4784          !strcmp (buf,"EPSON"))
4785       fseek (m_InputFile, -2, SEEK_CUR);
4786     else if (!strcmp (buf,"AOC") ||
4787        !strcmp (buf,"QVC"))
4788       fseek (m_InputFile, -4, SEEK_CUR);
4789     else {
4790       fseek (m_InputFile, -10, SEEK_CUR);
4791       if (!strncmp(m_CameraMake,"SAMSUNG",7))
4792         base = ftell(m_InputFile);
4793     }
4794   entries = get2();
4795   if (entries > 1000) return;
4796   mm_ByteOrder = m_ByteOrder;
4797   while (entries--) {
4798     m_ByteOrder = mm_ByteOrder;
4799     tiff_get (base, &tag, &type, &len, &save);
4800     tag |= uptag << 16;
4801     if (tag == 2 && strstr(m_CameraMake,"NIKON") && !m_IsoSpeed)
4802       m_IsoSpeed = (get2(),get2());
4803     if (tag == 4 && len > 26 && len < 35) {
4804       if ((i=(get4(),get2())) != 0x7fff && !m_IsoSpeed)
4805         m_IsoSpeed =  50 * pow (2, i/32.0 - 4);
4806       if ((i=(get2(),get2())) != 0x7fff && !m_Aperture)
4807   m_Aperture = pow (2, i/64.0);
4808       if ((i=get2()) != 0xffff && !m_Shutter)
4809   m_Shutter = pow (2, (short) i/-32.0);
4810       wbi = (get2(),get2());
4811       m_ShotOrder = (get2(),get2());
4812     }
4813    if ((tag == 4 || tag == 0x114) && !strncmp(m_CameraMake,"KONICA",6)) {
4814       fseek (m_InputFile, tag == 4 ? 140:160, SEEK_CUR);
4815       switch (get2()) {
4816   case 72:  m_Flip = 0;  break;
4817   case 76:  m_Flip = 6;  break;
4818   case 82:  m_Flip = 5;  break;
4819       }
4820     }
4821     if (tag == 7 && type == 2 && len > 20)
4822       ptfgets (m_CameraModelBis, 64, m_InputFile);
4823     if (tag == 8 && type == 4)
4824       m_ShotOrder = get4();
4825     if (tag == 9 && !strcmp(m_CameraMake,"Canon"))
4826       ptfread (m_Artist, 64, 1, m_InputFile);
4827     if (tag == 0xc && len == 4) {
4828       ASSIGN(m_CameraMultipliers[0], getreal(type));
4829       ASSIGN(m_CameraMultipliers[2], getreal(type));
4830     }
4831     if (tag == 0xd && type == 7 && get2() == 0xaaaa) {
4832       for (c=i=2; (uint16_t) c != 0xbbbb && i < len; i++)
4833   c = c << 8 | fgetc(m_InputFile);
4834       while ((i+=4) < len-5)
4835   if (get4() == 257 && (i=len) && (c = (get4(),fgetc(m_InputFile))) < 3)
4836     m_Flip = "065"[c]-'0';
4837     }
4838     if (tag == 0x10 && type == 4)
4839       unique_id = get4();
4840     if (tag == 0x11 && m_IsRaw && !strncmp(m_CameraMake,"NIKON",5)) {
4841       fseek (m_InputFile, get4()+base, SEEK_SET);
4842       parse_tiff_ifd (base);
4843     }
4844     if (tag == 0x14 && type == 7) {
4845       if (len == 2560) {
4846         fseek (m_InputFile, 1248, SEEK_CUR);
4847         goto get2_256;
4848       }
4849       ptfread (buf, 1, 10, m_InputFile);
4850       if (!strncmp(buf,"NRW ",4)) {
4851         fseek (m_InputFile, strcmp(buf+4,"0100") ? 46:1546, SEEK_CUR);
4852         ASSIGN(m_CameraMultipliers[0], get4() << 2);
4853         ASSIGN(m_CameraMultipliers[1], get4() + get4());
4854         ASSIGN(m_CameraMultipliers[2], get4() << 2);
4855       }
4856     }
4857     if (tag == 0x15 && type == 2 && m_IsRaw)
4858       ptfread (m_CameraModel, 64, 1, m_InputFile);
4859     if (strstr(m_CameraMake,"PENTAX")) {
4860       if (tag == 0x1b) tag = 0x1018;
4861       if (tag == 0x1c) tag = 0x1017;
4862     }
4863     if (tag == 0x1d)
4864       while ((c = fgetc(m_InputFile)) && c != (unsigned) EOF)
4865   serial = serial*10 + (isdigit(c) ? c - '0' : c % 10);
4866     if (tag == 0x81 && type == 4) {
4867       m_Data_Offset = get4();
4868       fseek (m_InputFile, m_Data_Offset + 41, SEEK_SET);
4869       m_RawHeight = get2() * 2;
4870       m_RawWidth  = get2();
4871       m_Filters = 0x61616161;
4872     }
4873     if (tag == 0x29 && type == 1) {
4874       c = wbi < 18 ? "012347800000005896"[wbi]-'0' : 0;
4875       fseek (m_InputFile, 8 + c*32, SEEK_CUR);
4876       for (c=0; c < 4; c++) ASSIGN(m_CameraMultipliers[c ^ (c >> 1) ^ 1], get4());
4877     }
4878     if ((tag == 0x81  && type == 7) ||
4879   (tag == 0x100 && type == 7) ||
4880   (tag == 0x280 && type == 1)) {
4881       m_ThumbOffset = ftell(m_InputFile);
4882       m_ThumbLength = len;
4883     }
4884     if (tag == 0x88 && type == 4 && (m_ThumbOffset = get4()))
4885       m_ThumbOffset += base;
4886     if (tag == 0x89 && type == 4)
4887       m_ThumbLength = get4();
4888     if (tag == 0x8c || tag == 0x96)
4889       meta_offset = ftell(m_InputFile);
4890     if (tag == 0x97) {
4891       for (i=0; i < 4; i++)
4892   ver97 = ver97 * 10  + fgetc(m_InputFile)-'0';
4893       switch (ver97) {
4894   case 100:
4895     fseek (m_InputFile, 68, SEEK_CUR);
4896     for (c=0; c < 4; c++) ASSIGN(m_CameraMultipliers[(c >> 1) | ((c & 1) << 1)], get2());
4897     break;
4898   case 102:
4899     fseek (m_InputFile, 6, SEEK_CUR);
4900     goto get2_rggb;
4901   case 103:
4902     fseek (m_InputFile, 16, SEEK_CUR);
4903     for (c=0; c < 4; c++) ASSIGN(m_CameraMultipliers[c], get2());
4904       }
4905       if (ver97 >= 200) {
4906   if (ver97 != 205) fseek (m_InputFile, 280, SEEK_CUR);
4907   ptfread (buf97, 324, 1, m_InputFile);
4908       }
4909     }
4910     if (tag == 0xa1 && type == 7) {
4911       type = m_ByteOrder;
4912       m_ByteOrder = 0x4949;
4913       fseek (m_InputFile, 140, SEEK_CUR);
4914       for (c=0; c < 3; c++) ASSIGN(m_CameraMultipliers[c], get4());
4915       m_ByteOrder = type;
4916     }
4917     if (tag == 0xa4 && type == 3) {
4918       fseek (m_InputFile, wbi*48, SEEK_CUR);
4919       for (c=0; c<3; c++) ASSIGN(m_CameraMultipliers[c], get2());
4920     }
4921     if (tag == 0xa7 && (unsigned) (ver97-200) < 12 && !VALUE(m_CameraMultipliers[0])) {
4922       ci = xlat[0][serial & 0xff];
4923       cj = xlat[1][fgetc(m_InputFile)^fgetc(m_InputFile)^fgetc(m_InputFile)^fgetc(m_InputFile)];
4924       ck = 0x60;
4925       for (i=0; i < 324; i++)
4926   buf97[i] ^= (cj += ci * ck++);
4927       i = "66666>666;6A;:;55"[ver97-200] - '0';
4928       for (c=0; c < 4; c++)
4929         ASSIGN(m_CameraMultipliers[c ^ (c >> 1) ^ (i &1)],
4930                sget2 (buf97 + (i & -2) + c*2));
4931     }
4932     if (tag == 0x200 && len == 3)
4933       m_ShotOrder = (get4(),get4());
4934     if (tag == 0x200 && len == 4)
4935       for (c=0; c<4; c++) m_CBlackLevel[c ^ c >> 1] = get2();
4936     if (tag == 0x201 && len == 4)
4937       goto get2_rggb;
4938     if (tag == 0x220 && type == 7)
4939       meta_offset = ftell(m_InputFile);
4940     if (tag == 0x401 && type == 4 && len == 4) {
4941       for (c=0; c<4; c++) m_CBlackLevel[c ^ c >> 1] = get4();
4942     }
4943     if (tag == 0xe01) {   /* Nikon Capture Note */
4944       type = m_ByteOrder;
4945       m_ByteOrder = 0x4949;
4946       fseek (m_InputFile, 22, SEEK_CUR);
4947       for (offset=22; offset+22 < len; offset += 22+i) {
4948   tag = get4();
4949   fseek (m_InputFile, 14, SEEK_CUR);
4950   i = get4()-4;
4951   if (tag == 0x76a43207) m_Flip = get2();
4952   else fseek (m_InputFile, i, SEEK_CUR);
4953       }
4954       m_ByteOrder = type;
4955     }
4956     if (tag == 0xe80 && len == 256 && type == 7) {
4957       fseek (m_InputFile, 48, SEEK_CUR);
4958       ASSIGN(m_CameraMultipliers[0], get2() * 508 * 1.078 / 0x10000);
4959       ASSIGN(m_CameraMultipliers[2], get2() * 382 * 1.173 / 0x10000);
4960     }
4961     if (tag == 0xf00 && type == 7) {
4962       if (len == 614)
4963   fseek (m_InputFile, 176, SEEK_CUR);
4964       else if (len == 734 || len == 1502)
4965   fseek (m_InputFile, 148, SEEK_CUR);
4966       else goto next;
4967       goto get2_256;
4968     }
4969     if ((tag == 0x1011 && len == 9) || tag == 0x20400200)
4970       for (i=0; i < 3; i++)
4971   for (c=0; c<3; c++) m_cmatrix[i][c] = ((short) get2()) / 256.0;
4972     if ((tag == 0x1012 || tag == 0x20400600) && len == 4)
4973       for (c=0; c<4; c++) m_CBlackLevel[c ^ c >> 1] = get2();
4974     if (tag == 0x1017 || tag == 0x20400100)
4975       ASSIGN(m_CameraMultipliers[0], get2() / 256.0);
4976     if (tag == 0x1018 || tag == 0x20400100)
4977       ASSIGN(m_CameraMultipliers[2], get2() / 256.0);
4978     if (tag == 0x2011 && len == 2) {
4979 get2_256:
4980       m_ByteOrder = 0x4d4d;
4981       ASSIGN(m_CameraMultipliers[0], get2() / 256.0);
4982       ASSIGN(m_CameraMultipliers[2], get2() / 256.0);
4983     }
4984     if ((tag | 0x70) == 0x2070 && type == 4)
4985       fseek (m_InputFile, get4()+base, SEEK_SET);
4986     if (tag == 0x2010 && type != 7)
4987       m_LoadRawFunction = &CLASS olympus_load_raw;
4988     if (tag == 0x2020)
4989       parse_thumb_note (base, 257, 258);
4990     if (tag == 0x2040)
4991       parse_makernote (base, 0x2040);
4992     if (tag == 0xb028) {
4993       fseek (m_InputFile, get4()+base, SEEK_SET);
4994       parse_thumb_note (base, 136, 137);
4995     }
4996     if (tag == 0x4001 && len > 500) {
4997       i = len == 582 ? 50 : len == 653 ? 68 : len == 5120 ? 142 : 126;
4998       fseek (m_InputFile, i, SEEK_CUR);
4999 get2_rggb:
5000       for (c=0; c < 4; c++) ASSIGN(m_CameraMultipliers[c ^ (c >> 1)], get2());
5001       i = len >> 3 == 164 ? 112:22;
5002       fseek (m_InputFile, i, SEEK_CUR);
5003       for (c=0; c < 4; c++) sraw_mul[c ^ (c >> 1)] = get2();
5004     }
5005     if (tag == 0xa021)
5006       for (c=0; c<4; c++) ASSIGN(m_CameraMultipliers[c ^ (c >> 1)], get4());
5007     if (tag == 0xa028)
5008       for (c=0; c<4; c++) ASSIGN(m_CameraMultipliers[c ^ (c >> 1)], m_CameraMultipliers[c ^ (c >> 1)] - get4());
5009 next:
5010     fseek (m_InputFile, save, SEEK_SET);
5011   }
5012 quit:
5013   m_ByteOrder = sm_ByteOrder;
5014 }
5015 
5016 /*
5017    Since the TIFF DateTime string has no timezone information,
5018    assume that the camera's clock was set to Universal Time.
5019  */
get_timestamp(int reversed)5020 void CLASS get_timestamp (int reversed)
5021 {
5022   struct tm t;
5023   char str[20];
5024   int i;
5025 
5026   str[19] = 0;
5027   if (reversed)
5028     for (i=19; i--; ) str[i] = fgetc(m_InputFile);
5029   else
5030     ptfread (str, 19, 1, m_InputFile);
5031   memset (&t, 0, sizeof t);
5032   if (sscanf (str, "%d:%d:%d %d:%d:%d", &t.tm_year, &t.tm_mon,
5033   &t.tm_mday, &t.tm_hour, &t.tm_min, &t.tm_sec) != 6)
5034     return;
5035   t.tm_year -= 1900;
5036   t.tm_mon -= 1;
5037   t.tm_isdst = -1;
5038   if (mktime(&t) > 0)
5039     m_TimeStamp = mktime(&t);
5040 }
5041 
parse_exif(int base)5042 void CLASS parse_exif (int base)
5043 {
5044   unsigned kodak, entries, tag, type, len, save, c;
5045   double expo;
5046 
5047   kodak = !strncmp(m_CameraMake,"EASTMAN",7) && m_Tiff_NrIFDs < 3;
5048   entries = get2();
5049   while (entries--) {
5050     tiff_get (base, &tag, &type, &len, &save);
5051     switch (tag) {
5052       case 33434:  m_Shutter = getreal(type);   break;
5053       case 33437:  m_Aperture = getreal(type);    break;
5054       case 34855:  m_IsoSpeed = get2();     break;
5055       case 36867:
5056       case 36868:  get_timestamp(0);      break;
5057       case 37377:  if ((expo = -getreal(type)) < 128)
5058          m_Shutter = pow (2, expo);   break;
5059       case 37378:  m_Aperture = pow (2, getreal(type)/2); break;
5060       case 37386:  m_FocalLength = getreal(type);   break;
5061       case 37500:  parse_makernote (base, 0);   break;
5062       case 40962:  if (kodak) m_RawWidth  = get4(); break;
5063       case 40963:  if (kodak) m_RawHeight = get4(); break;
5064       case 41730:
5065   if (get4() == 0x20002)
5066     for (exif_cfa=c=0; c < 8; c+=2)
5067       exif_cfa |= fgetc(m_InputFile) * 0x01010101 << c;
5068     }
5069     fseek (m_InputFile, save, SEEK_SET);
5070   }
5071 }
5072 
romm_coeff(float romm_cam[3][3])5073 void CLASS romm_coeff (float romm_cam[3][3])
5074 {
5075   static const float rgb_romm[3][3] = /* ROMM == Kodak ProPhoto */
5076   { {  2.034193, -0.727420, -0.306766 },
5077     { -0.228811,  1.231729, -0.002922 },
5078     { -0.008565, -0.153273,  1.161839 } };
5079   int i, j, k;
5080 
5081   for (i=0; i < 3; i++)
5082     for (j=0; j < 3; j++)
5083       for (m_cmatrix[i][j] = k=0; k < 3; k++)
5084   m_cmatrix[i][j] += rgb_romm[i][k] * romm_cam[k][j];
5085 }
5086 
parse_mos(int offset)5087 void CLASS parse_mos (int offset)
5088 {
5089   char data[40];
5090   int skip, from, i, c, neut[4], planes=0, frot=0;
5091   static const char *mod[] =
5092   { "","DCB2","Volare","Cantare","CMost","Valeo 6","Valeo 11","Valeo 22",
5093     "Valeo 11p","Valeo 17","","Aptus 17","Aptus 22","Aptus 75","Aptus 65",
5094     "Aptus 54S","Aptus 65S","Aptus 75S","AFi 5","AFi 6","AFi 7",
5095         "","","","","","","","","","","","","","","","","","AFi-II 12" };
5096   float romm_cam[3][3];
5097 
5098   fseek (m_InputFile, offset, SEEK_SET);
5099   while (1) {
5100     if (get4() != 0x504b5453) break;
5101     get4();
5102     ptfread (data, 1, 40, m_InputFile);
5103     skip = get4();
5104     from = ftell(m_InputFile);
5105     if (!strcmp(data,"JPEG_preview_data")) {
5106       m_ThumbOffset = from;
5107       m_ThumbLength = skip;
5108     }
5109     if (!strcmp(data,"icc_camera_profile")) {
5110       m_ProfileOffset = from;
5111       m_ProfileLength = skip;
5112     }
5113     if (!strcmp(data,"ShootObj_back_type")) {
5114       ptfscanf (m_InputFile, "%d", &i);
5115       if ((unsigned) i < sizeof mod / sizeof (*mod))
5116   strcpy (m_CameraModel, mod[i]);
5117     }
5118     if (!strcmp(data,"icc_camera_to_tone_matrix")) {
5119       for (i=0; i < 9; i++)
5120   romm_cam[0][i] = int_to_float(get4());
5121       romm_coeff (romm_cam);
5122     }
5123     if (!strcmp(data,"CaptProf_color_matrix")) {
5124       for (i=0; i < 9; i++)
5125   ptfscanf (m_InputFile, "%f", &romm_cam[0][i]);
5126       romm_coeff (romm_cam);
5127     }
5128     if (!strcmp(data,"CaptProf_number_of_planes"))
5129       ptfscanf (m_InputFile, "%d", &planes);
5130     if (!strcmp(data,"CaptProf_raw_data_rotation"))
5131       ptfscanf (m_InputFile, "%d", &m_Flip);
5132     if (!strcmp(data,"CaptProf_mosaic_pattern"))
5133       for (c=0; c < 4; c++) {
5134   ptfscanf (m_InputFile, "%d", &i);
5135   if (i == 1) frot = c ^ (c >> 1);
5136       }
5137     if (!strcmp(data,"ImgProf_rotation_angle")) {
5138       ptfscanf (m_InputFile, "%d", &i);
5139       m_Flip = i - m_Flip;
5140     }
5141     if (!strcmp(data,"NeutObj_neutrals") && !VALUE(m_CameraMultipliers[0])) {
5142       for (c=0; c < 4; c++) ptfscanf (m_InputFile, "%d", neut+c);
5143       for (c=0; c<3; c++) ASSIGN(m_CameraMultipliers[c], (float) neut[0] / neut[c+1]);
5144     }
5145     if (!strcmp(data,"Rows_data"))
5146       m_Load_Flags = get4();
5147     parse_mos (from);
5148     fseek (m_InputFile, skip+from, SEEK_SET);
5149   }
5150   if (planes)
5151     m_Filters = (planes == 1) * 0x01010101 *
5152   (uint8_t) "\x94\x61\x16\x49"[(m_Flip/90 + frot) & 3];
5153 }
5154 
linear_table(unsigned len)5155 void CLASS linear_table (unsigned len)
5156 {
5157   int i;
5158   if (len > 0x1000) len = 0x1000;
5159   read_shorts (m_Curve, len);
5160   for (i=len; i < 0x1000; i++)
5161     m_Curve[i] = m_Curve[i-1];
5162   m_WhiteLevel = m_Curve[0xfff];
5163 }
5164 
parse_kodak_ifd(int base)5165 void CLASS parse_kodak_ifd (int base)
5166 {
5167   unsigned entries, tag, type, len, save;
5168   int i, c, wbi=-2, wbtemp=6500;
5169   float mul[3] = {1,1,1}, num = 0;
5170   static const int wbtag[] = { 64037,64040,64039,64041,-1,-1,64042 };
5171 
5172   entries = get2();
5173   if (entries > 1024) return;
5174   while (entries--) {
5175     tiff_get (base, &tag, &type, &len, &save);
5176     if (tag == 1020) wbi = getint(type);
5177     if (tag == 1021 && len == 72) {   /* WB set in software */
5178       fseek (m_InputFile, 40, SEEK_CUR);
5179       for (c=0; c<3; c++) ASSIGN(m_CameraMultipliers[c], 2048.0 / get2());
5180       wbi = -2;
5181     }
5182     if (tag == 2118) wbtemp = getint(type);
5183     if (tag == (unsigned)(2130 + wbi))
5184       for (c=0; c<3; c++) mul[c] = getreal(type);
5185     if (tag == (unsigned)(2140 + wbi) && wbi >= 0)
5186       for (c=0; c<3; c++) {
5187   for (num=i=0; i < 4; i++)
5188     num += getreal(type) * pow (wbtemp/100.0, i);
5189   ASSIGN(m_CameraMultipliers[c], 2048 / (num * mul[c]));
5190       }
5191     if (tag == 2317) linear_table (len);
5192     if (tag == 6020) m_IsoSpeed = getint(type);
5193     if (tag == 64013) wbi = fgetc(m_InputFile);
5194     if (wbi < 7 && (int) tag == wbtag[wbi])
5195       for(c=0;c<3;c++) ASSIGN(m_CameraMultipliers[c],get4());
5196     if (tag == 64019) m_Width = getint(type);
5197     if (tag == 64020) m_Height = (getint(type)+1) & -2;
5198 
5199     fseek (m_InputFile, save, SEEK_SET);
5200   }
5201 }
5202 
5203 //void CLASS parse_minolta (int base);
5204 
parse_tiff_ifd(int l_Base)5205 int CLASS parse_tiff_ifd (int l_Base) {
5206   unsigned    l_Entries;
5207   unsigned    l_Tag;
5208   unsigned    l_Type;
5209   unsigned    l_Length;
5210   unsigned    l_plen=16;
5211   unsigned    l_Save;
5212   int         l_ifd;
5213   int         l_use_cm=0;
5214   int         l_cfa;
5215   int         i, j, c;
5216   int         l_ImageLength=0;
5217   int blrr=1, blrc=1, dblack[] = { 0,0,0,0 };
5218   char        l_Software[64];
5219   char        *l_cbuf;
5220   char        *cp;
5221   uint8_t       l_cfa_pat[16];
5222   uint8_t       l_cfa_pc[] = { 0,1,2,3 };
5223   uint8_t       l_tab[256];
5224   double      l_cc[4][4];
5225   double      l_cm[4][3];
5226   double      l_cam_xyz[4][3];
5227   double      l_num;
5228   double      l_ab[]={ 1,1,1,1 };
5229   double      l_asn[] = { 0,0,0,0 };
5230   double      l_xyz[] = { 1,1,1 };
5231   unsigned    l_sony_curve[] = { 0,0,0,0,0,4095 };
5232   unsigned*   l_buf;
5233   unsigned    l_sony_offset=0;
5234   unsigned    l_sony_length=0;
5235   unsigned    l_sony_key=0;
5236   FILE*       l_sfp;
5237 
5238   struct jhead l_JHead;
5239 
5240   if (m_Tiff_NrIFDs >= sizeof m_Tiff_IFD / sizeof m_Tiff_IFD[0])
5241     return 1;
5242   l_ifd = m_Tiff_NrIFDs++;
5243   for (j=0; j < 4; j++)
5244     for (i=0; i < 4; i++)
5245       l_cc[j][i] = (i == j);
5246   l_Entries = get2();
5247   if (l_Entries > 512) return 1;
5248   while (l_Entries--) {
5249     tiff_get (l_Base, &l_Tag, &l_Type, &l_Length, &l_Save);
5250     switch (l_Tag) {
5251       case 5:   m_Width  = get2();  break;
5252       case 6:   m_Height = get2();  break;
5253       case 7:   m_Width += get2();  break;
5254       case 9:  m_Filters = get2();  break;
5255       case 14: case 15: case 16:
5256         m_WhiteLevel = get2();
5257         break;
5258       case 17: case 18:
5259   if (l_Type == 3 && l_Length == 1)
5260     ASSIGN(m_CameraMultipliers[(l_Tag-17)*2], get2() / 256.0);
5261   break;
5262       case 23:
5263   if (l_Type == 3) m_IsoSpeed = get2();
5264   break;
5265       case 36: case 37: case 38:
5266   ASSIGN(m_CameraMultipliers[l_Tag-0x24], get2());
5267   break;
5268       case 39:
5269   if (l_Length < 50 || VALUE(m_CameraMultipliers[0])) break;
5270   fseek (m_InputFile, 12, SEEK_CUR);
5271   for (c=0; c<3; c++) ASSIGN(m_CameraMultipliers[c], get2());
5272   break;
5273       case 46:
5274   if (l_Type != 7 || fgetc(m_InputFile) != 0xff || fgetc(m_InputFile) != 0xd8) break;
5275   m_ThumbOffset = ftell(m_InputFile) - 2;
5276   m_ThumbLength = l_Length;
5277   break;
5278       case 61440:     /* Fuji HS10 table */
5279   parse_tiff_ifd (l_Base);
5280   break;
5281       case 2: case 256: case 61441: /* ImageWidth */
5282   m_Tiff_IFD[l_ifd].width = getint(l_Type);
5283   break;
5284       case 3: case 257: case 61442: /* ImageHeight */
5285   m_Tiff_IFD[l_ifd].height = getint(l_Type);
5286   break;
5287       case 258:       /* BitsPerSample */
5288       case 61443:
5289   m_Tiff_IFD[l_ifd].samples = l_Length & 7;
5290   m_Tiff_IFD[l_ifd].bps = getint(l_Type);
5291   break;
5292       case 61446:
5293   m_RawHeight = 0;
5294   m_LoadRawFunction = &CLASS packed_load_raw;
5295   m_Load_Flags = get4() && (m_Filters=0x16161616) ? 24:80;
5296   break;
5297       case 259:       /* Compression */
5298   m_Tiff_IFD[l_ifd].comp = getint(l_Type);
5299   break;
5300       case 262:       /* PhotometricInterpretation */
5301   m_Tiff_IFD[l_ifd].phint = get2();
5302   break;
5303       case 270:       /* ImageDescription */
5304   ptfread (m_Description, 512, 1, m_InputFile);
5305   break;
5306       case 271:       /* Make */
5307   ptfgets (m_CameraMake, 64, m_InputFile);
5308   break;
5309       case 272:       /* Model */
5310   ptfgets (m_CameraModel, 64, m_InputFile);
5311   break;
5312       case 280:       /* Panasonic RW2 offset */
5313   if (l_Type != 4) break;
5314   m_LoadRawFunction = &CLASS panasonic_load_raw;
5315   m_Load_Flags = 0x2008;
5316 
5317       case 273:       /* StripOffset */
5318       case 513:       /* JpegIFOffset */
5319       case 61447:
5320   m_Tiff_IFD[l_ifd].offset = get4()+l_Base;
5321   if (!m_Tiff_IFD[l_ifd].bps && m_Tiff_IFD[l_ifd].offset > 0) {
5322     fseek (m_InputFile, m_Tiff_IFD[l_ifd].offset, SEEK_SET);
5323     if (ljpeg_start (&l_JHead, 1)) {
5324       m_Tiff_IFD[l_ifd].comp    = 6;
5325       m_Tiff_IFD[l_ifd].width   = l_JHead.wide;
5326       m_Tiff_IFD[l_ifd].height  = l_JHead.high;
5327       m_Tiff_IFD[l_ifd].bps     = l_JHead.bits;
5328       m_Tiff_IFD[l_ifd].samples = l_JHead.clrs;
5329       if (!(l_JHead.sraw || (l_JHead.clrs & 1)))
5330         m_Tiff_IFD[l_ifd].width *= l_JHead.clrs;
5331       i = m_ByteOrder;
5332       parse_tiff (m_Tiff_IFD[l_ifd].offset + 12);
5333       m_ByteOrder = i;
5334     }
5335   }
5336   break;
5337       case 274:       /* Orientation */
5338   m_Tiff_IFD[l_ifd].flip = "50132467"[get2() & 7]-'0';
5339   break;
5340       case 277:       /* SamplesPerPixel */
5341   m_Tiff_IFD[l_ifd].samples = getint(l_Type) & 7;
5342   break;
5343       case 279:       /* StripByteCounts */
5344       case 514:
5345       case 61448:
5346   m_Tiff_IFD[l_ifd].bytes = get4();
5347   break;
5348       case 61454:
5349   for (c=0; c < 3; c++) ASSIGN(m_CameraMultipliers[(4-c) % 3],getint(l_Type));
5350   break;
5351       case 305: case 11:    /* Software */
5352   ptfgets (l_Software, 64, m_InputFile);
5353   if (!strncmp(l_Software,"Adobe",5) ||
5354       !strncmp(l_Software,"dcraw",5) ||
5355       !strncmp(l_Software,"UFRaw",5) ||
5356       !strncmp(l_Software,"Bibble",6) ||
5357       !strncmp(l_Software,"Nikon Scan",10) ||
5358       !strcmp (l_Software,"Digital Photo Professional"))
5359     m_IsRaw = 0;
5360   break;
5361       case 306:       /* DateTime */
5362   get_timestamp(0);
5363   break;
5364       case 315:       /* Artist */
5365   ptfread (m_Artist, 64, 1, m_InputFile);
5366   break;
5367       case 322:       /* TileWidth */
5368   m_Tiff_IFD[l_ifd].tile_width = getint(l_Type);
5369   break;
5370       case 323:       /* TileLength */
5371   m_Tiff_IFD[l_ifd].tile_length = getint(l_Type);
5372   break;
5373       case 324:       /* TileOffsets */
5374   m_Tiff_IFD[l_ifd].offset = l_Length > 1 ? ftell(m_InputFile) : get4();
5375   if (l_Length == 4) {
5376     m_LoadRawFunction = &CLASS sinar_4shot_load_raw;
5377     m_IsRaw = 5;
5378   }
5379   break;
5380       case 330:       /* SubIFDs */
5381   if (!strcmp(m_CameraModel,"DSLR-A100") && m_Tiff_IFD[l_ifd].width == 3872) {
5382           m_LoadRawFunction = &CLASS sony_arw_load_raw;
5383     m_Data_Offset = get4()+l_Base;
5384     l_ifd++;  break;
5385   }
5386   while (l_Length--) {
5387     i = ftell(m_InputFile);
5388     fseek (m_InputFile, get4()+l_Base, SEEK_SET);
5389     if (parse_tiff_ifd (l_Base)) break;
5390     fseek (m_InputFile, i+4, SEEK_SET);
5391   }
5392   break;
5393       case 400:
5394   strcpy (m_CameraMake, "Sarnoff");
5395   m_WhiteLevel = 0xfff;
5396   break;
5397       case 28688:
5398   for (c=0; c < 4; c++) l_sony_curve[c+1] = get2() >> 2 & 0xfff;
5399   for (i=0; i < 5; i++)
5400     for (j = l_sony_curve[i]+1; (unsigned) j <= l_sony_curve[i+1]; j++)
5401       m_Curve[j] = m_Curve[j-1] + (1 << i);
5402   break;
5403       case 29184: l_sony_offset = get4();  break;
5404       case 29185: l_sony_length = get4();  break;
5405       case 29217: l_sony_key    = get4();  break;
5406       case 29264:
5407   parse_minolta (ftell(m_InputFile));
5408   m_RawWidth = 0;
5409   break;
5410       case 29443:
5411   for (c=0; c < 4; c++) ASSIGN(m_CameraMultipliers[c ^ (c < 2)], get2());
5412   break;
5413       case 29459:
5414   for (c=0; c < 4; c++) ASSIGN(m_CameraMultipliers[c], get2());
5415   i = (m_CameraMultipliers[1] == 1024 && m_CameraMultipliers[2] == 1024) << 1;
5416   SWAP (m_CameraMultipliers[i],m_CameraMultipliers[i+1])
5417   break;
5418       case 33405:     /* Model2 */
5419   ptfgets (m_CameraModelBis, 64, m_InputFile);
5420   break;
5421       case 33422:     /* CFAPattern */
5422       case 64777:     /* Kodak P-series */
5423   if ((l_plen=l_Length) > 16) l_plen = 16;
5424   ptfread (l_cfa_pat, 1, l_plen, m_InputFile);
5425   for (m_Colors=l_cfa=i=0; (unsigned) i < l_plen; i++) {
5426     m_Colors += !(l_cfa & (1 << l_cfa_pat[i]));
5427     l_cfa |= 1 << l_cfa_pat[i];
5428   }
5429   if (l_cfa == 070) memcpy (l_cfa_pc,"\003\004\005",3); /* CMY */
5430   if (l_cfa == 072) memcpy (l_cfa_pc,"\005\003\004\001",4); /* GMCY */
5431   goto guess_l_cfa_pc;
5432       case 33424:
5433       case 65024:
5434   fseek (m_InputFile, get4()+l_Base, SEEK_SET);
5435   parse_kodak_ifd (l_Base);
5436   break;
5437       case 33434:     /* ExposureTime */
5438   m_Shutter = getreal(l_Type);
5439   break;
5440       case 33437:     /* FNumber */
5441   m_Aperture = getreal(l_Type);
5442   break;
5443       case 34306:     /* Leaf white balance */
5444   for (c=0; c < 4; c++) ASSIGN(m_CameraMultipliers[c ^ 1], 4096.0 / get2());
5445   break;
5446       case 34307:     /* Leaf CatchLight color matrix */
5447   ptfread (l_Software, 1, 7, m_InputFile);
5448   if (strncmp(l_Software,"MATRIX",6)) break;
5449   m_Colors = 4;
5450   for (m_RawColor = i=0; i < 3; i++) {
5451     for (c=0; c < 4; c++) ptfscanf (m_InputFile, "%f", &m_MatrixCamRGBToSRGB[i][c^1]);
5452     if (!m_UserSetting_CameraWb) continue;
5453     l_num = 0;
5454     for (c=0; c < 4; c++) l_num += m_MatrixCamRGBToSRGB[i][c];
5455     for (c=0; c < 4; c++) m_MatrixCamRGBToSRGB[i][c] /= l_num;
5456   }
5457   break;
5458       case 34310:     /* Leaf metadata */
5459   parse_mos (ftell(m_InputFile));
5460       case 34303:
5461   strcpy (m_CameraMake, "Leaf");
5462   break;
5463       case 34665:     /* EXIF tag */
5464   fseek (m_InputFile, get4()+l_Base, SEEK_SET);
5465   parse_exif (l_Base);
5466   break;
5467       case 34675:     /* InterColorProfile */
5468       case 50831:     /* AsShotICCProfile */
5469   m_ProfileOffset = ftell(m_InputFile);
5470   m_ProfileLength = l_Length;
5471   break;
5472       case 37122:     /* CompressedBitsPerPixel */
5473   m_Kodak_cbpp = get4();
5474   break;
5475       case 37386:     /* FocalLength */
5476   m_FocalLength = getreal(l_Type);
5477   break;
5478       case 37393:     /* ImageNumber */
5479   m_ShotOrder = getint(l_Type);
5480   break;
5481       case 37400:     /* old Kodak KDC tag */
5482   for (m_RawColor = i=0; i < 3; i++) {
5483     getreal(l_Type);
5484     for (c=0; c<3; c++) m_MatrixCamRGBToSRGB[i][c] = getreal(l_Type);
5485   }
5486   break;
5487       case 46275:     /* Imacon tags */
5488   strcpy (m_CameraMake, "Imacon");
5489   m_Data_Offset = ftell(m_InputFile);
5490   l_ImageLength = l_Length;
5491   break;
5492       case 46279:
5493         if (l_ImageLength) break;
5494   fseek (m_InputFile, 38, SEEK_CUR);
5495       case 46274:
5496   fseek (m_InputFile, 40, SEEK_CUR);
5497   m_RawWidth  = get4();
5498   m_RawHeight = get4();
5499   m_LeftMargin = get4() & 7;
5500   m_Width = m_RawWidth - m_LeftMargin - (get4() & 7);
5501   m_TopMargin = get4() & 7;
5502   m_Height = m_RawHeight - m_TopMargin - (get4() & 7);
5503   if (m_RawWidth == 7262) {
5504     m_Height = 5444;
5505     m_Width  = 7244;
5506     m_LeftMargin = 7;
5507   }
5508   fseek (m_InputFile, 52, SEEK_CUR);
5509   for (c=0; c<3; c++) ASSIGN(m_CameraMultipliers[c], getreal(11));
5510   fseek (m_InputFile, 114, SEEK_CUR);
5511   m_Flip = (get2() >> 7) * 90;
5512   if (m_Width * m_Height * 6 == l_ImageLength) {
5513     if (m_Flip % 180 == 90) SWAP(m_Width,m_Height);
5514     m_RawWidth = m_Width;
5515     m_RawHeight = m_Height;
5516     m_LeftMargin = m_TopMargin = m_Filters = m_Flip = 0;
5517   }
5518   sprintf (m_CameraModel, "Ixpress %d-Mp", m_Height*m_Width/1000000);
5519   m_LoadRawFunction = &CLASS imacon_full_load_raw;
5520   if (m_Filters) {
5521     if (m_LeftMargin & 1) m_Filters = 0x61616161;
5522     m_LoadRawFunction = &CLASS unpacked_load_raw;
5523   }
5524   m_WhiteLevel = 0xffff;
5525   break;
5526       case 50454:     /* Sinar tag */
5527       case 50455:
5528   if (!(l_cbuf = (char *) MALLOC(l_Length))) break;
5529   ptfread (l_cbuf, 1, l_Length, m_InputFile);
5530   for (cp = l_cbuf-1; cp && cp < l_cbuf+l_Length; cp = strchr(cp,'\n'))
5531     if (!strncmp (++cp,"Neutral ",8))
5532       sscanf (cp+8, "%f %f %f",
5533                     &VALUE(m_CameraMultipliers[0]),
5534                     &VALUE(m_CameraMultipliers[1]),
5535                     &VALUE(m_CameraMultipliers[2]));
5536   FREE (l_cbuf);
5537   break;
5538       case 50458:
5539         if(!m_CameraMake[0]) strcpy(m_CameraMake,"Hasselblad");
5540         break;
5541       case 50459:     /* Hasselblad tag */
5542   i = m_ByteOrder;
5543   j = ftell(m_InputFile);
5544   c = m_Tiff_NrIFDs;
5545   m_ByteOrder = get2();
5546   fseek (m_InputFile, j+(get2(),get4()), SEEK_SET);
5547   parse_tiff_ifd (j);
5548   m_WhiteLevel = 0xffff;
5549   m_Tiff_NrIFDs = c;
5550   m_ByteOrder = i;
5551   break;
5552       case 50706:     /* DNGVersion */
5553   for (c=0; c < 4; c++) m_DNG_Version = (m_DNG_Version << 8) + fgetc(m_InputFile);
5554         if (!m_CameraMake[0]) strcpy (m_CameraMake,"DNG");
5555         m_IsRaw = 1;
5556   break;
5557       case 50710:     /* CFAPlaneColor */
5558   if (l_Length > 4) l_Length = 4;
5559   m_Colors = l_Length;
5560   ptfread (l_cfa_pc, 1, m_Colors, m_InputFile);
5561 guess_l_cfa_pc:
5562   for (c=0; c < m_Colors; c++) l_tab[l_cfa_pc[c]] = c;
5563   m_ColorDescriptor[c] = 0;
5564   for (i=16; i--; )
5565     m_Filters = m_Filters << 2 | l_tab[l_cfa_pat[i % l_plen]];
5566   break;
5567       case 50711:     /* CFALayout */
5568   if (get2() == 2) {
5569     m_Fuji_Width = 1;
5570     m_Filters = 0x49494949;
5571   }
5572   break;
5573       case 291:
5574       case 50712:     /* LinearizationTable */
5575   linear_table (l_Length);
5576   break;
5577         case 50713:     /* BlackLevelRepeatDim */
5578   blrr = get2();
5579   blrc = get2();
5580   break;
5581       case 61450:
5582   blrr = blrc = 2;
5583       case 50714:     /* BlackLevel */
5584   m_BlackLevel = getreal(l_Type);
5585   if (!m_Filters || !~m_Filters) break;
5586   dblack[0] = m_BlackLevel;
5587   dblack[1] = (blrc == 2) ? getreal(l_Type):dblack[0];
5588   dblack[2] = (blrr == 2) ? getreal(l_Type):dblack[0];
5589   dblack[3] = (blrc == 2 && blrr == 2) ? getreal(l_Type):dblack[1];
5590   if (m_Colors == 3)
5591     m_Filters |= ((m_Filters >> 2 & 0x22222222) |
5592           (m_Filters << 2 & 0x88888888)) & m_Filters << 1;
5593   for (c=0; c<4; c++) m_CBlackLevel[m_Filters >> (c << 1) & 3] = dblack[c];
5594   m_BlackLevel = 0;
5595   break;
5596       case 50715:     /* BlackLevelDeltaH */
5597       case 50716:     /* BlackLevelDeltaV */
5598   for (l_num=i=0; (unsigned)i < l_Length; i++)
5599     l_num += getreal(l_Type);
5600   m_BlackLevel += l_num/l_Length + 0.5;
5601   break;
5602       case 50717:     /* WhiteLevel */
5603   m_WhiteLevel = getint(l_Type);
5604   break;
5605       case 50718:     /* DefaultScale */
5606   m_PixelAspect  = getreal(l_Type);
5607   m_PixelAspect /= getreal(l_Type);
5608   break;
5609       case 50721:     /* ColorMatrix1 */
5610       case 50722:     /* ColorMatrix2 */
5611   for (c=0; c < m_Colors; c++) for (j=0; j < 3; j++)
5612     l_cm[c][j] = getreal(l_Type);
5613   l_use_cm = 1;
5614   break;
5615       case 50723:     /* CameraCalibration1 */
5616       case 50724:     /* CameraCalibration2 */
5617   for (i=0; i < m_Colors; i++)
5618     for (c=0; c < m_Colors; c++) l_cc[i][c] = getreal(l_Type);
5619   break;
5620       case 50727:     /* AnalogBalance */
5621   for (c=0; c < m_Colors; c++) l_ab[c] = getreal(l_Type);
5622   break;
5623       case 50728:     /* AsShotNeutral */
5624   for (c=0; c < m_Colors; c++) l_asn[c] = getreal(l_Type);
5625   break;
5626       case 50729:     /* AsShotWhiteXY */
5627   l_xyz[0] = getreal(l_Type);
5628   l_xyz[1] = getreal(l_Type);
5629   l_xyz[2] = 1 - l_xyz[0] - l_xyz[1];
5630   for (c=0; c<3; c++) l_xyz[c] /= D65Reference[c];
5631   break;
5632       case 50740:     /* DNGPrivateData */
5633   if (m_DNG_Version) break;
5634   parse_minolta (j = get4()+l_Base);
5635   fseek (m_InputFile, j, SEEK_SET);
5636   parse_tiff_ifd (l_Base);
5637   break;
5638       case 50752:
5639   read_shorts (cr2_slice, 3);
5640   break;
5641       case 50829:     /* ActiveArea */
5642   m_TopMargin = getint(l_Type);
5643   m_LeftMargin = getint(l_Type);
5644   m_Height = getint(l_Type) - m_TopMargin;
5645   m_Width = getint(l_Type) - m_LeftMargin;
5646   break;
5647       case 50830:			/* MaskedAreas */
5648         for (i=0; i < (int32_t)l_Length && i < 32; i++)
5649     m_Mask[0][i] = getint(l_Type);
5650   m_BlackLevel = 0;
5651   break;
5652       case 51009:			/* OpcodeList2 */
5653   meta_offset = ftell(m_InputFile);
5654   break;
5655       case 64772:     /* Kodak P-series */
5656         if (l_Length < 13) break;
5657   fseek (m_InputFile, 16, SEEK_CUR);
5658   m_Data_Offset = get4();
5659   fseek (m_InputFile, 28, SEEK_CUR);
5660   m_Data_Offset += get4();
5661   m_LoadRawFunction = &CLASS packed_load_raw;
5662         break;
5663       case 65026:
5664         if (l_Type == 2) ptfgets(m_CameraModelBis,64,m_InputFile);
5665     }
5666     fseek (m_InputFile, l_Save, SEEK_SET);
5667   }
5668   if (l_sony_length && (l_buf = (unsigned *) MALLOC(l_sony_length))) {
5669     fseek (m_InputFile, l_sony_offset, SEEK_SET);
5670     ptfread (l_buf, l_sony_length, 1, m_InputFile);
5671     sony_decrypt (l_buf, l_sony_length/4, 1, l_sony_key);
5672     l_sfp = m_InputFile;
5673     if ((m_InputFile = tmpfile())) {
5674       ptfwrite (l_buf, l_sony_length, 1, m_InputFile);
5675       fseek (m_InputFile, 0, SEEK_SET);
5676       parse_tiff_ifd (-l_sony_offset);
5677       FCLOSE (m_InputFile);
5678     }
5679     m_InputFile = l_sfp;
5680     FREE (l_buf);
5681   }
5682   for (i=0; i < m_Colors; i++)
5683     for (c=0; c < m_Colors; c++) l_cc[i][c] *= l_ab[i];
5684   if (l_use_cm) {
5685     for (c=0; c < m_Colors; c++) for (i=0; i < 3; i++)
5686       for (l_cam_xyz[c][i]=j=0; j < m_Colors; j++)
5687   l_cam_xyz[c][i] += l_cc[c][j] * l_cm[j][i] * l_xyz[i];
5688     cam_xyz_coeff (l_cam_xyz);
5689   }
5690   if (l_asn[0]) {
5691     ASSIGN(m_CameraMultipliers[3], 0);
5692     for (c=0; c < m_Colors; c++) ASSIGN(m_CameraMultipliers[c], 1 / l_asn[c]);
5693   }
5694 
5695   if (!l_use_cm)
5696     for (c=0; c < m_Colors; c++)
5697       ASSIGN(m_D65Multipliers[c],VALUE(m_D65Multipliers[c]) / l_cc[c][c]);
5698 
5699   return 0;
5700 }
5701 
5702 // To get out of the mess what is global and what is local
5703 // I started here with l_ tagging of the variables.
5704 // (but the most simple like i or c which are evidently , hopefully , local)
5705 // What remains must be a global.
5706 // (jpta) This is what my EOS400D would do.
5707 
parse_tiff(int l_Base)5708 int CLASS parse_tiff (int l_Base) {
5709   // Set to start of tiff
5710   fseek (m_InputFile, l_Base, SEEK_SET);
5711 
5712   // Check byte order and return if not OK
5713   m_ByteOrder = get2();
5714   if (m_ByteOrder != 0x4949 && m_ByteOrder != 0x4d4d) return 0;
5715 
5716   get2();
5717 
5718   int l_doff;
5719   while ((l_doff = get4())) {
5720     fseek (m_InputFile, l_doff+l_Base, SEEK_SET);
5721     if (parse_tiff_ifd (l_Base)) break;
5722   }
5723   return 1;
5724 }
5725 
apply_tiff()5726 void CLASS apply_tiff()
5727 {
5728   int l_MaxSample=0;
5729   int l_Raw=-1;
5730   int l_Thumb=-1;
5731   int i;
5732 
5733   struct jhead l_Jhead;
5734 
5735   m_ThumbMisc = 16;
5736   if (m_ThumbOffset) {
5737     fseek (m_InputFile,m_ThumbOffset,SEEK_SET);
5738     if (ljpeg_start (&l_Jhead, 1)) {
5739       m_ThumbMisc   = l_Jhead.bits;
5740       m_ThumbWidth  = l_Jhead.wide;
5741       m_ThumbHeight = l_Jhead.high;
5742     }
5743   }
5744 
5745   for (i=0; (unsigned) i < m_Tiff_NrIFDs; i++) {
5746     if (l_MaxSample < m_Tiff_IFD[i].samples)
5747   l_MaxSample = m_Tiff_IFD[i].samples;
5748     if (l_MaxSample > 3) l_MaxSample = 3;
5749     if ((m_Tiff_IFD[i].comp != 6 || m_Tiff_IFD[i].samples != 3) &&
5750         (m_Tiff_IFD[i].width | m_Tiff_IFD[i].height) < 0x10000 &&
5751          m_Tiff_IFD[i].width*m_Tiff_IFD[i].height > m_RawWidth*m_RawHeight) {
5752       m_RawWidth      = m_Tiff_IFD[i].width;
5753       m_RawHeight     = m_Tiff_IFD[i].height;
5754       m_Tiff_bps      = m_Tiff_IFD[i].bps;
5755       m_Tiff_Compress = m_Tiff_IFD[i].comp;
5756       m_Data_Offset   = m_Tiff_IFD[i].offset;
5757       m_Tiff_Flip     = m_Tiff_IFD[i].flip;
5758       m_Tiff_Samples  = m_Tiff_IFD[i].samples;
5759       m_TileWidth     = m_Tiff_IFD[i].tile_width;
5760       m_TileLength    = m_Tiff_IFD[i].tile_length;
5761       l_Raw           = i;
5762     }
5763   }
5764   if (!m_TileWidth ) m_TileWidth  = INT_MAX;
5765   if (!m_TileLength) m_TileLength = INT_MAX;
5766   for (i=m_Tiff_NrIFDs; i--; )
5767     if (m_Tiff_IFD[i].flip) m_Tiff_Flip = m_Tiff_IFD[i].flip;
5768 
5769   if (l_Raw >= 0 && !m_LoadRawFunction)
5770     switch (m_Tiff_Compress) {
5771       case 32767:
5772         if (m_Tiff_IFD[l_Raw].bytes == m_RawWidth*m_RawHeight) {
5773     m_Tiff_bps = 12;
5774     m_LoadRawFunction = &CLASS sony_arw2_load_raw;
5775     break;
5776   }
5777   if (m_Tiff_IFD[l_Raw].bytes*8U != m_RawWidth*m_RawHeight*m_Tiff_bps) {
5778     m_RawHeight += 8;
5779     m_LoadRawFunction = &CLASS sony_arw_load_raw;
5780     break;
5781   }
5782   m_Load_Flags = 79;
5783       case 32769:
5784         m_Load_Flags++;
5785       case 32770:
5786       case 32773: goto slr;
5787       case 0:  case 1:
5788   if (m_Tiff_IFD[l_Raw].bytes*5 == m_RawWidth*m_RawHeight*8) {
5789     m_Load_Flags = 81;
5790     m_Tiff_bps = 12;
5791   } slr:
5792   switch (m_Tiff_bps) {
5793     case  8: m_LoadRawFunction = &CLASS eight_bit_load_raw;	break;
5794     case 12: if (m_Tiff_IFD[l_Raw].phint == 2)
5795          m_Load_Flags = 6;
5796        m_LoadRawFunction = &CLASS packed_load_raw;		break;
5797     case 14: m_Load_Flags = 0;
5798     case 16: m_LoadRawFunction = &CLASS unpacked_load_raw;		break;
5799   }
5800   break;
5801       case 6:  case 7:  case 99:
5802   m_LoadRawFunction = &CLASS lossless_jpeg_load_raw;		break;
5803       case 262:
5804   m_LoadRawFunction = &CLASS kodak_262_load_raw;			break;
5805       case 34713:
5806 	if ((m_RawWidth+9)/10*16*m_RawHeight == m_Tiff_IFD[l_Raw].bytes) {
5807 	  m_LoadRawFunction = &CLASS packed_load_raw;
5808 	  m_Load_Flags = 1;
5809 	} else if (m_RawWidth*m_RawHeight*2 == m_Tiff_IFD[l_Raw].bytes) {
5810 	  m_LoadRawFunction = &CLASS unpacked_load_raw;
5811 	  m_Load_Flags = 4;
5812 	  m_ByteOrder = 0x4d4d;
5813 	} else
5814 	  m_LoadRawFunction = &CLASS nikon_load_raw;			break;
5815       case 34892:
5816   m_LoadRawFunction = &CLASS lossy_dng_load_raw;		break;
5817       case 65535:
5818   m_LoadRawFunction = &CLASS pentax_load_raw;
5819         break;
5820       case 65000:
5821   switch (m_Tiff_IFD[l_Raw].phint) {
5822     case 2: m_LoadRawFunction = &CLASS kodak_rgb_load_raw;
5823                   m_Filters = 0;
5824                   break;
5825     case 6: m_LoadRawFunction = &CLASS kodak_ycbcr_load_raw;
5826                   m_Filters = 0;
5827                   break;
5828     case 32803: m_LoadRawFunction = &CLASS kodak_65000_load_raw;
5829   }
5830       case 32867: break;
5831       default: m_IsRaw = 0;
5832     }
5833   if (!m_DNG_Version)
5834     if ( (m_Tiff_Samples == 3 && m_Tiff_IFD[l_Raw].bytes &&
5835 	  m_Tiff_bps != 14 && m_Tiff_bps != 2048 &&
5836 	  m_Tiff_Compress != 32769 && m_Tiff_Compress != 32770)
5837       || (m_Tiff_bps == 8 && !strstr(m_CameraMake,"KODAK") &&
5838           !strstr(m_CameraMake,"Kodak") &&
5839     !strstr(m_CameraModelBis,"DEBUG RAW")))
5840       m_IsRaw = 0;
5841 
5842   for (i=0; (unsigned) i < m_Tiff_NrIFDs; i++) {
5843     auto l_denom1 = SQR(m_Tiff_IFD[i].bps+1);
5844     auto l_denom2 = SQR(m_ThumbMisc+1);
5845     if (l_denom1 == 0 || l_denom2 == 0)
5846       continue;   // prevent divide by zero crash
5847 
5848     if (i != l_Raw &&
5849         m_Tiff_IFD[i].samples == l_MaxSample &&
5850         (unsigned)(m_Tiff_IFD[i].width * m_Tiff_IFD[i].height / l_denom1) >
5851             m_ThumbWidth * m_ThumbHeight / l_denom2 &&
5852         m_Tiff_IFD[i].comp != 34892)
5853     {
5854       m_ThumbWidth  = m_Tiff_IFD[i].width;
5855       m_ThumbHeight = m_Tiff_IFD[i].height;
5856       m_ThumbOffset = m_Tiff_IFD[i].offset;
5857       m_ThumbLength = m_Tiff_IFD[i].bytes;
5858       m_ThumbMisc   = m_Tiff_IFD[i].bps;
5859       l_Thumb = i;
5860     }
5861   }
5862 
5863   if (l_Thumb >= 0) {
5864     m_ThumbMisc |= m_Tiff_IFD[l_Thumb].samples << 5;
5865     switch (m_Tiff_IFD[l_Thumb].comp) {
5866       case 0:
5867   m_WriteThumb = &CLASS layer_thumb;
5868   break;
5869       case 1:
5870   if (m_Tiff_IFD[l_Thumb].bps <= 8)
5871     m_WriteThumb = &CLASS ppm_thumb;
5872   else if (!strcmp(m_CameraMake,"Imacon"))
5873     m_WriteThumb = &CLASS ppm16_thumb;
5874   else
5875     m_ThumbLoadRawFunction = &CLASS kodak_thumb_load_raw;
5876   break;
5877       case 65000:
5878   m_ThumbLoadRawFunction = m_Tiff_IFD[l_Thumb].phint == 6 ?
5879     &CLASS kodak_ycbcr_load_raw : &CLASS kodak_rgb_load_raw;
5880     }
5881   }
5882 }
5883 
parse_minolta(int base)5884 void CLASS parse_minolta (int base)
5885 {
5886   int save, tag, len, offset, high=0, wide=0, i, c;
5887   short sorder=m_ByteOrder;
5888 
5889   fseek (m_InputFile, base, SEEK_SET);
5890   if (fgetc(m_InputFile) || fgetc(m_InputFile)-'M' || fgetc(m_InputFile)-'R') return;
5891   m_ByteOrder = fgetc(m_InputFile) * 0x101;
5892   offset = base + get4() + 8;
5893   while ((save=ftell(m_InputFile)) < offset) {
5894     for (tag=i=0; i < 4; i++)
5895       tag = tag << 8 | fgetc(m_InputFile);
5896     len = get4();
5897     switch (tag) {
5898       case 0x505244:        /* PRD */
5899   fseek (m_InputFile, 8, SEEK_CUR);
5900   high = get2();
5901   wide = get2();
5902   break;
5903       case 0x574247:        /* WBG */
5904   get4();
5905   i = strcmp(m_CameraModel,"DiMAGE A200") ? 0:3;
5906   for (c=0; c < 4; c++) ASSIGN(m_CameraMultipliers[c ^ (c >> 1) ^ i], get2());
5907   break;
5908       case 0x545457:        /* TTW */
5909   parse_tiff (ftell(m_InputFile));
5910   m_Data_Offset = offset;
5911     }
5912     fseek (m_InputFile, save+len+8, SEEK_SET);
5913   }
5914   m_RawHeight = high;
5915   m_RawWidth  = wide;
5916   m_ByteOrder = sorder;
5917 }
5918 
5919 /*
5920    Many cameras have a "debug mode" that writes JPEG and raw
5921    at the same time.  The raw file has no header, so try to
5922    to open the matching JPEG file and read its metadata.
5923  */
parse_external_jpeg()5924 void CLASS parse_external_jpeg()
5925 {
5926   const char *file, *ext;
5927   char *jname, *jfile, *jext;
5928   FILE *save=m_InputFile;
5929 
5930   ext  = strrchr (m_UserSetting_InputFileName, '.');
5931   file = strrchr (m_UserSetting_InputFileName, '/');
5932   if (!file) file = strrchr (m_UserSetting_InputFileName, '\\');
5933   if (!file) file = m_UserSetting_InputFileName-1;
5934   file++;
5935   if (!ext || strlen(ext) != 4 || ext-file != 8) return;
5936   jname = (char *) MALLOC (strlen(m_UserSetting_InputFileName) + 1);
5937   merror (jname, "parse_external_jpeg()");
5938   strcpy (jname, m_UserSetting_InputFileName);
5939   jfile = file - m_UserSetting_InputFileName + jname;
5940   jext  = ext  - m_UserSetting_InputFileName + jname;
5941   if (strcasecmp (ext, ".jpg")) {
5942     strcpy (jext, isupper(ext[1]) ? ".JPG":".jpg");
5943     if (isdigit(*file)) {
5944       memcpy (jfile, file+4, 4);
5945       memcpy (jfile+4, file, 4);
5946     }
5947   } else
5948     while (isdigit(*--jext)) {
5949       if (*jext != '9') {
5950         (*jext)++;
5951   break;
5952       }
5953       *jext = '0';
5954     }
5955   if (strcmp (jname, m_UserSetting_InputFileName)) {
5956     if ((m_InputFile = fopen (jname, "rb"))) {
5957       TRACEKEYVALS("Reading metadata from","%s",jname);
5958       parse_tiff (12);
5959       m_ThumbOffset = 0;
5960       m_IsRaw = 1;
5961       FCLOSE (m_InputFile);
5962     }
5963   }
5964   if (!m_TimeStamp)
5965     fprintf (stderr,_("Failed to read metadata from %s\n"), jname);
5966   FREE (jname);
5967   m_InputFile = save;
5968 }
5969 
5970 /*
5971    CIFF block 0x1030 contains an 8x8 white sample.
5972    Load this into white[][] for use in scale_colors().
5973  */
ciff_block_1030()5974 void CLASS ciff_block_1030()
5975 {
5976   static const uint16_t key[] = { 0x410, 0x45f3 };
5977   int i, bpp, row, col, vbits=0;
5978   unsigned long bitbuf=0;
5979 
5980   if ((get2(),get4()) != 0x80008 || !get4()) return;
5981   bpp = get2();
5982   if (bpp != 10 && bpp != 12) return;
5983   for (i=row=0; row < 8; row++)
5984     for (col=0; col < 8; col++) {
5985       if (vbits < bpp) {
5986   bitbuf = bitbuf << 16 | (get2() ^ key[i++ & 1]);
5987   vbits += 16;
5988       }
5989       white[row][col] =
5990   bitbuf << (LONG_BIT - vbits) >> (LONG_BIT - bpp);
5991       vbits -= bpp;
5992     }
5993 }
5994 
5995 /*
5996    Parse a CIFF file, better known as Canon CRW format.
5997  */
parse_ciff(int offset,int length)5998 void CLASS parse_ciff (int offset, int length)
5999 {
6000   int tboff, nrecs, c, type, len, save, wbi=-1;
6001   uint16_t key[] = { 0x410, 0x45f3 };
6002 
6003   fseek (m_InputFile, offset+length-4, SEEK_SET);
6004   tboff = get4() + offset;
6005   fseek (m_InputFile, tboff, SEEK_SET);
6006   nrecs = get2();
6007   if (nrecs > 100) return;
6008   while (nrecs--) {
6009     type = get2();
6010     len  = get4();
6011     save = ftell(m_InputFile) + 4;
6012     fseek (m_InputFile, offset+get4(), SEEK_SET);
6013     if ((((type >> 8) + 8) | 8) == 0x38)
6014       parse_ciff (ftell(m_InputFile), len); /* Parse a sub-table */
6015 
6016     if (type == 0x0810)
6017       ptfread (m_Artist, 64, 1, m_InputFile);
6018     if (type == 0x080a) {
6019       ptfread (m_CameraMake, 64, 1, m_InputFile);
6020       fseek (m_InputFile, strlen(m_CameraMake) - 63, SEEK_CUR);
6021       ptfread (m_CameraModel, 64, 1, m_InputFile);
6022     }
6023     if (type == 0x1810) {
6024       fseek (m_InputFile, 12, SEEK_CUR);
6025       m_Flip = get4();
6026     }
6027     if (type == 0x1835)     /* Get the decoder table */
6028       m_Tiff_Compress = get4();
6029     if (type == 0x2007) {
6030       m_ThumbOffset = ftell(m_InputFile);
6031       m_ThumbLength = len;
6032     }
6033     if (type == 0x1818) {
6034       m_Shutter = pow (2, -int_to_float((get4(),get4())));
6035       m_Aperture = pow (2, int_to_float(get4())/2);
6036     }
6037     if (type == 0x102a) {
6038       m_IsoSpeed = pow (2, (get4(),get2())/32.0 - 4) * 50;
6039       m_Aperture  = pow (2, (get2(),(short)get2())/64.0);
6040       m_Shutter   = pow (2,-((short)get2())/32.0);
6041       wbi = (get2(),get2());
6042       if (wbi > 17) wbi = 0;
6043       fseek (m_InputFile, 32, SEEK_CUR);
6044       if (m_Shutter > 1e6) m_Shutter = get2()/10.0;
6045     }
6046     if (type == 0x102c) {
6047       if (get2() > 512) {   /* Pro90, G1 */
6048   fseek (m_InputFile, 118, SEEK_CUR);
6049   for (c=0; c < 4; c++) ASSIGN(m_CameraMultipliers[c ^ 2], get2());
6050       } else {        /* G2, S30, S40 */
6051   fseek (m_InputFile, 98, SEEK_CUR);
6052   for (c=0; c < 4; c++) ASSIGN(m_CameraMultipliers[c ^ (c >> 1) ^ 1], get2());
6053       }
6054     }
6055     if (type == 0x0032) {
6056       if (len == 768) {     /* EOS D30 */
6057   fseek (m_InputFile, 72, SEEK_CUR);
6058   for (c=0; c < 4; c++) ASSIGN(m_CameraMultipliers[c ^ (c >> 1)], 1024.0 / get2());
6059   if (!wbi) ASSIGN(m_CameraMultipliers[0], -1); /* use my auto white balance */
6060       } else if (!VALUE(m_CameraMultipliers[0])) {
6061   if (get2() == key[0])   /* Pro1, G6, S60, S70 */
6062     c = (strstr(m_CameraModel,"Pro1") ?
6063         "012346000000000000":"01345:000000006008")[wbi]-'0'+ 2;
6064   else {        /* G3, G5, S45, S50 */
6065     c = "023457000000006000"[wbi]-'0';
6066     key[0] = key[1] = 0;
6067   }
6068   fseek (m_InputFile, 78 + c*8, SEEK_CUR);
6069   for (c=0; c < 4; c++) ASSIGN(m_CameraMultipliers[c ^ (c >> 1) ^ 1], get2() ^ key[c & 1]);
6070   if (!wbi) ASSIGN(m_CameraMultipliers[0], -1);
6071       }
6072     }
6073     if (type == 0x10a9) {   /* D60, 10D, 300D, and clones */
6074       if (len > 66) wbi = "0134567028"[wbi]-'0';
6075       fseek (m_InputFile, 2 + wbi*8, SEEK_CUR);
6076       for (c=0; c < 4; c++) ASSIGN(m_CameraMultipliers[c ^ (c >> 1)], get2());
6077     }
6078     if (type == 0x1030 && (0x18040 >> wbi & 1))
6079       ciff_block_1030();    /* all that don't have 0x10a9 */
6080     if (type == 0x1031) {
6081       m_RawWidth = (get2(),get2());
6082       m_RawHeight = get2();
6083     }
6084     if (type == 0x5029) {
6085       m_FocalLength = len >> 16;
6086       if ((len & 0xffff) == 2) m_FocalLength /= 32;
6087     }
6088     if (type == 0x5813) flash_used = int_to_float(len);
6089     if (type == 0x5814) canon_ev   = int_to_float(len);
6090     if (type == 0x5817) m_ShotOrder = len;
6091     if (type == 0x5834) unique_id  = len;
6092     if (type == 0x580e) m_TimeStamp  = len;
6093     if (type == 0x180e) m_TimeStamp  = get4();
6094 #ifdef LOCALTIME
6095     if ((type | 0x4000) == 0x580e)
6096       m_TimeStamp = mktime (gmtime (&m_TimeStamp));
6097 #endif
6098     fseek (m_InputFile, save, SEEK_SET);
6099   }
6100 }
6101 
parse_rollei()6102 void CLASS parse_rollei()
6103 {
6104   char line[128], *val;
6105   struct tm t;
6106 
6107   fseek (m_InputFile, 0, SEEK_SET);
6108   memset (&t, 0, sizeof t);
6109   do {
6110     ptfgets (line, 128, m_InputFile);
6111     if ((val = strchr(line,'=')))
6112       *val++ = 0;
6113     else
6114       val = line + strlen(line);
6115     if (!strcmp(line,"DAT"))
6116       sscanf (val, "%d.%d.%d", &t.tm_mday, &t.tm_mon, &t.tm_year);
6117     if (!strcmp(line,"TIM"))
6118       sscanf (val, "%d:%d:%d", &t.tm_hour, &t.tm_min, &t.tm_sec);
6119     if (!strcmp(line,"HDR"))
6120       m_ThumbOffset = atoi(val);
6121     if (!strcmp(line,"X  "))
6122       m_RawWidth = atoi(val);
6123     if (!strcmp(line,"Y  "))
6124       m_RawHeight = atoi(val);
6125     if (!strcmp(line,"TX "))
6126       m_ThumbWidth = atoi(val);
6127     if (!strcmp(line,"TY "))
6128       m_ThumbHeight = atoi(val);
6129   } while (strncmp(line,"EOHD",4));
6130   m_Data_Offset = m_ThumbOffset + m_ThumbWidth * m_ThumbHeight * 2;
6131   t.tm_year -= 1900;
6132   t.tm_mon -= 1;
6133   if (mktime(&t) > 0)
6134     m_TimeStamp = mktime(&t);
6135   strcpy (m_CameraMake, "Rollei");
6136   strcpy (m_CameraModel,"d530flex");
6137   m_WriteThumb = &CLASS rollei_thumb;
6138 }
6139 
parse_sinar_ia()6140 void CLASS parse_sinar_ia()
6141 {
6142   int entries, off;
6143   char str[8], *cp;
6144 
6145   m_ByteOrder = 0x4949;
6146   fseek (m_InputFile, 4, SEEK_SET);
6147   entries = get4();
6148   fseek (m_InputFile, get4(), SEEK_SET);
6149   while (entries--) {
6150     off = get4(); get4();
6151     ptfread (str, 8, 1, m_InputFile);
6152     if (!strcmp(str,"META"))   meta_offset = off;
6153     if (!strcmp(str,"THUMB")) m_ThumbOffset = off;
6154     if (!strcmp(str,"RAW0"))   m_Data_Offset = off;
6155   }
6156   fseek (m_InputFile, meta_offset+20, SEEK_SET);
6157   ptfread (m_CameraMake, 64, 1, m_InputFile);
6158   m_CameraMake[63] = 0;
6159   if ((cp = strchr(m_CameraMake,' '))) {
6160     strcpy (m_CameraModel, cp+1);
6161     *cp = 0;
6162   }
6163   m_RawWidth  = get2();
6164   m_RawHeight = get2();
6165   m_LoadRawFunction = &CLASS unpacked_load_raw;
6166   m_ThumbWidth = (get4(),get2());
6167   m_ThumbHeight = get2();
6168   m_WriteThumb = &CLASS ppm_thumb;
6169   m_WhiteLevel = 0x3fff;
6170 }
6171 
parse_phase_one(int base)6172 void CLASS parse_phase_one (int base)
6173 {
6174 //warning: variable 'type' set but not used [-Wunused-but-set-variable]
6175   unsigned entries, tag, /*type,*/ len, data, save, i, c;
6176   float romm_cam[3][3];
6177   char *cp;
6178 
6179   memset (&ph1, 0, sizeof ph1);
6180   fseek (m_InputFile, base, SEEK_SET);
6181   m_ByteOrder = get4() & 0xffff;
6182   if (get4() >> 8 != 0x526177) return;    /* "Raw" */
6183   fseek (m_InputFile, get4()+base, SEEK_SET);
6184   entries = get4();
6185   get4();
6186   while (entries--) {
6187     tag  = get4();
6188 //    type = get4();
6189     len  = get4();
6190     data = get4();
6191     save = ftell(m_InputFile);
6192     fseek (m_InputFile, base+data, SEEK_SET);
6193     switch (tag) {
6194       case 0x100:  m_Flip = "0653"[data & 3]-'0';  break;
6195       case 0x106:
6196   for (i=0; i < 3; i++)
6197           for (short j=0; j<3; j++)
6198       romm_cam[i][j] = getreal(11);
6199   romm_coeff (romm_cam);
6200   break;
6201       case 0x107:
6202   for (c=0; c<3; c++) ASSIGN(m_CameraMultipliers[c], getreal(11));
6203   break;
6204       case 0x108:  m_RawWidth     = data; break;
6205       case 0x109:  m_RawHeight    = data; break;
6206       case 0x10a:  m_LeftMargin   = data; break;
6207       case 0x10b:  m_TopMargin    = data; break;
6208       case 0x10c:  m_Width         = data;  break;
6209       case 0x10d:  m_Height        = data;  break;
6210       case 0x10e:  ph1.format    = data;  break;
6211       case 0x10f:  m_Data_Offset   = data+base; break;
6212       case 0x110:  meta_offset   = data+base;
6213        m_MetaLength   = len;      break;
6214       case 0x112:  ph1.key_off   = save - 4;    break;
6215       case 0x210:  ph1.tag_210   = int_to_float(data);  break;
6216       case 0x21a:  ph1.tag_21a   = data;    break;
6217       case 0x21c:  strip_offset  = data+base;   break;
6218       case 0x21d:  ph1.black     = data;    break;
6219       case 0x222:  ph1.split_col = data;		break;
6220       case 0x223:  ph1.black_off = data+base;   break;
6221       case 0x301:
6222   m_CameraModel[63] = 0;
6223   ptfread (m_CameraModel, 1, 63, m_InputFile);
6224   if ((cp = strstr(m_CameraModel," camera"))) *cp = 0;
6225     }
6226     fseek (m_InputFile, save, SEEK_SET);
6227   }
6228   m_LoadRawFunction = ph1.format < 3 ?
6229   &CLASS phase_one_load_raw : &CLASS phase_one_load_raw_c;
6230   m_WhiteLevel = 0xffff;
6231   strcpy (m_CameraMake, "Phase One");
6232   if (m_CameraModel[0]) return;
6233   switch (m_RawHeight) {
6234     case 2060: strcpy (m_CameraModel,"LightPhase"); break;
6235     case 2682: strcpy (m_CameraModel,"H 10");   break;
6236     case 4128: strcpy (m_CameraModel,"H 20");   break;
6237     case 5488: strcpy (m_CameraModel,"H 25");   break;
6238   }
6239 }
6240 
parse_fuji(int offset)6241 void CLASS parse_fuji (int offset)
6242 {
6243   unsigned entries, tag, len, save, c;
6244 
6245   fseek (m_InputFile, offset, SEEK_SET);
6246   entries = get4();
6247   if (entries > 255) return;
6248   while (entries--) {
6249     tag = get2();
6250     len = get2();
6251     save = ftell(m_InputFile);
6252     if (tag == 0x100) {
6253       m_RawHeight = get2();
6254       m_RawWidth  = get2();
6255     } else if (tag == 0x121) {
6256       m_Height = get2();
6257       if ((m_Width = get2()) == 4284) m_Width += 3;
6258     } else if (tag == 0x130) {
6259       fuji_layout = fgetc(m_InputFile) >> 7;
6260       m_Fuji_Width = !(fgetc(m_InputFile) & 8);
6261     } else if (tag == 0x2ff0) {
6262       for (c=0; c<4; c++) m_CameraMultipliers[c ^ 1] = get2();
6263     } else if (tag == 0xc000) {
6264       c = m_ByteOrder;
6265       m_ByteOrder = 0x4949;
6266       if ((m_Width = get4()) > 10000) m_Width = get4();
6267       m_Height = get4();
6268       m_ByteOrder = c;
6269     }
6270     fseek (m_InputFile, save+len, SEEK_SET);
6271 
6272   }
6273   if (!m_RawHeight) {
6274     m_Filters = 0x16161616;
6275     m_LoadRawFunction = &CLASS packed_load_raw;
6276     m_Load_Flags = 24;
6277   }
6278   m_Height <<= fuji_layout;
6279   m_Width  >>= fuji_layout;
6280 }
6281 
parse_jpeg(int offset)6282 int CLASS parse_jpeg (int offset)
6283 {
6284   int len, save, hlen, mark;
6285 
6286   fseek (m_InputFile, offset, SEEK_SET);
6287   if (fgetc(m_InputFile) != 0xff || fgetc(m_InputFile) != 0xd8) return 0;
6288 
6289   while (fgetc(m_InputFile) == 0xff && (mark = fgetc(m_InputFile)) != 0xda) {
6290     m_ByteOrder = 0x4d4d;
6291     len   = get2() - 2;
6292     save  = ftell(m_InputFile);
6293     if (mark == 0xc0 || mark == 0xc3) {
6294       fgetc(m_InputFile);
6295       m_RawHeight = get2();
6296       m_RawWidth  = get2();
6297     }
6298     m_ByteOrder = get2();
6299     hlen  = get4();
6300     if (get4() == 0x48454150)   /* "HEAP" */
6301       parse_ciff (save+hlen, len-hlen);
6302     if (parse_tiff (save+6)) apply_tiff();
6303     fseek (m_InputFile, save+len, SEEK_SET);
6304   }
6305   return 1;
6306 }
6307 
parse_riff()6308 void CLASS parse_riff()
6309 {
6310   unsigned i, size, end;
6311   char tag[4], date[64], month[64];
6312   static const char mon[12][4] =
6313   { "Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec" };
6314   struct tm t;
6315 
6316   m_ByteOrder = 0x4949;
6317   ptfread (tag, 4, 1, m_InputFile);
6318   size = get4();
6319   end = ftell(m_InputFile) + size;
6320   if (!memcmp(tag,"RIFF",4) || !memcmp(tag,"LIST",4)) {
6321     get4();
6322     while (ftell(m_InputFile)+7 < (long) end)
6323       parse_riff();
6324   } else if (!memcmp(tag,"nctg",4)) {
6325     while ((unsigned) ftell(m_InputFile)+7 < end) {
6326       i = get2();
6327       size = get2();
6328       if ((i+1) >> 1 == 10 && size == 20)
6329   get_timestamp(0);
6330       else fseek (m_InputFile, size, SEEK_CUR);
6331     }
6332   } else if (!memcmp(tag,"IDIT",4) && size < 64) {
6333     ptfread (date, 64, 1, m_InputFile);
6334     date[size] = 0;
6335     memset (&t, 0, sizeof t);
6336     if (sscanf (date, "%*s %s %d %d:%d:%d %d", month, &t.tm_mday,
6337   &t.tm_hour, &t.tm_min, &t.tm_sec, &t.tm_year) == 6) {
6338       for (i=0; i < 12 && strcasecmp(mon[i],month); i++) {};
6339       t.tm_mon = i;
6340       t.tm_year -= 1900;
6341       if (mktime(&t) > 0)
6342   m_TimeStamp = mktime(&t);
6343     }
6344   } else
6345     fseek (m_InputFile, size, SEEK_CUR);
6346 }
6347 
parse_smal(int offset,int fsize)6348 void CLASS parse_smal (int offset, int fsize)
6349 {
6350   int ver;
6351 
6352   fseek (m_InputFile, offset+2, SEEK_SET);
6353   m_ByteOrder = 0x4949;
6354   ver = fgetc(m_InputFile);
6355   if (ver == 6)
6356     fseek (m_InputFile, 5, SEEK_CUR);
6357   if (get4() != (unsigned) fsize) return;
6358   if (ver > 6) m_Data_Offset = get4();
6359   m_RawHeight = m_Height = get2();
6360   m_RawWidth  = m_Width  = get2();
6361   strcpy (m_CameraMake, "SMaL");
6362   sprintf (m_CameraModel, "v%d %dx%d", ver, m_Width, m_Height);
6363   if (ver == 6) m_LoadRawFunction = &CLASS smal_v6_load_raw;
6364   if (ver == 9) m_LoadRawFunction = &CLASS smal_v9_load_raw;
6365 }
6366 
parse_cine()6367 void CLASS parse_cine()
6368 {
6369   unsigned off_head, off_setup, off_image, i;
6370 
6371   m_ByteOrder = 0x4949;
6372   fseek (m_InputFile, 4, SEEK_SET);
6373   m_IsRaw = get2() == 2;
6374   fseek (m_InputFile, 14, SEEK_CUR);
6375   m_IsRaw *= get4();
6376   off_head = get4();
6377   off_setup = get4();
6378   off_image = get4();
6379   m_TimeStamp = get4();
6380   if ((i = get4())) m_TimeStamp = i;
6381   fseek (m_InputFile, off_head+4, SEEK_SET);
6382   m_RawWidth = get4();
6383   m_RawHeight = get4();
6384   switch (get2(),get2()) {
6385     case  8:  m_LoadRawFunction = &CLASS eight_bit_load_raw;  break;
6386     case 16:  m_LoadRawFunction = &CLASS  unpacked_load_raw;
6387   }
6388   fseek (m_InputFile, off_setup+792, SEEK_SET);
6389   strcpy (m_CameraMake, "CINE");
6390   sprintf (m_CameraModel, "%d", get4());
6391   fseek (m_InputFile, 12, SEEK_CUR);
6392   switch ((i=get4()) & 0xffffff) {
6393     case  3:  m_Filters = 0x94949494;  break;
6394     case  4:  m_Filters = 0x49494949;  break;
6395     default:  m_IsRaw = 0;
6396   }
6397   fseek (m_InputFile, 72, SEEK_CUR);
6398   switch ((get4()+3600) % 360) {
6399     case 270:  m_Flip = 4;  break;
6400     case 180:  m_Flip = 1;  break;
6401     case  90:  m_Flip = 7;  break;
6402     case   0:  m_Flip = 2;
6403   }
6404   ASSIGN(m_CameraMultipliers[0], getreal(11));
6405   ASSIGN(m_CameraMultipliers[2], getreal(11));
6406   m_WhiteLevel = ~(-1 << get4());
6407   fseek (m_InputFile, 668, SEEK_CUR);
6408   m_Shutter = get4()/1000000000.0;
6409   fseek (m_InputFile, off_image, SEEK_SET);
6410   if (m_UserSetting_ShotSelect < m_IsRaw)
6411     fseek (m_InputFile, m_UserSetting_ShotSelect*8, SEEK_CUR);
6412   m_Data_Offset  = (int64_t) get4() + 8;
6413   m_Data_Offset += (int64_t) get4() << 32;
6414 }
6415 
parse_redcine()6416 void CLASS parse_redcine()
6417 {
6418   unsigned i, len, rdvo;
6419 
6420   m_ByteOrder = 0x4d4d;
6421   m_IsRaw = 0;
6422   fseek (m_InputFile, 52, SEEK_SET);
6423   m_Width  = get4();
6424   m_Height = get4();
6425   fseek (m_InputFile, 0, SEEK_END);
6426   fseek (m_InputFile, -(i = ftell(m_InputFile) & 511), SEEK_CUR);
6427   if (get4() != i || get4() != 0x52454f42) {
6428     fprintf (stderr,_("%s: Tail is missing, parsing from head...\n"), m_UserSetting_InputFileName);
6429     fseek (m_InputFile, 0, SEEK_SET);
6430     while ((int)(len = get4()) != EOF) {
6431       if (get4() == 0x52454456)
6432   if (m_IsRaw++ == m_UserSetting_ShotSelect)
6433     m_Data_Offset = ftell(m_InputFile) - 8;
6434       fseek (m_InputFile, len-8, SEEK_CUR);
6435     }
6436   } else {
6437     rdvo = get4();
6438     fseek (m_InputFile, 12, SEEK_CUR);
6439     m_IsRaw = get4();
6440     fseek (m_InputFile, rdvo+8 + m_UserSetting_ShotSelect*4, SEEK_SET);
6441     m_Data_Offset = get4();
6442   }
6443 }
6444 
foveon_gets(int offset,char * str,int len)6445 char * CLASS foveon_gets (int offset, char *str, int len)
6446 {
6447   int i;
6448   fseek (m_InputFile, offset, SEEK_SET);
6449   for (i=0; i < len-1; i++)
6450     if ((str[i] = get2()) == 0) break;
6451   str[i] = 0;
6452   return str;
6453 }
6454 
parse_foveon()6455 void CLASS parse_foveon()
6456 {
6457   int entries, img=0, off, len, tag, save, i, wide, high, pent, poff[256][2];
6458   char name[64], value[64];
6459 
6460   m_ByteOrder = 0x4949;     /* Little-endian */
6461   fseek (m_InputFile, 36, SEEK_SET);
6462   m_Flip = get4();
6463   fseek (m_InputFile, -4, SEEK_END);
6464   fseek (m_InputFile, get4(), SEEK_SET);
6465   if (get4() != 0x64434553) return; /* SECd */
6466   entries = (get4(),get4());
6467   while (entries--) {
6468     off = get4();
6469     len = get4();
6470     tag = get4();
6471     save = ftell(m_InputFile);
6472     fseek (m_InputFile, off, SEEK_SET);
6473     if (get4() != (unsigned)(0x20434553 | (tag << 24))) return;
6474     switch (tag) {
6475       case 0x47414d49:      /* IMAG */
6476       case 0x32414d49:      /* IMA2 */
6477   fseek (m_InputFile, 8, SEEK_CUR);
6478   pent = get4();
6479   wide = get4();
6480   high = get4();
6481   if (wide > m_RawWidth && high > m_RawHeight) {
6482     switch (pent) {
6483       case  5:  m_Load_Flags = 1;
6484       case  6:  m_LoadRawFunction = &CLASS foveon_sd_load_raw;  break;
6485       case 30:  m_LoadRawFunction = &CLASS foveon_dp_load_raw;  break;
6486       default:  m_LoadRawFunction = 0;
6487     }
6488     m_RawWidth  = wide;
6489     m_RawHeight = high;
6490     m_Data_Offset = off+28;
6491   }
6492   fseek (m_InputFile, off+28, SEEK_SET);
6493   if (fgetc(m_InputFile) == 0xff && fgetc(m_InputFile) == 0xd8
6494               && m_ThumbLength < (unsigned)(len-28)) {
6495     m_ThumbOffset = off+28;
6496     m_ThumbLength = len-28;
6497     m_WriteThumb = &CLASS jpeg_thumb;
6498   }
6499   if (++img == 2 && !m_ThumbLength) {
6500     m_ThumbOffset = off+24;
6501     m_ThumbWidth = wide;
6502     m_ThumbHeight = high;
6503     m_WriteThumb = &CLASS foveon_thumb;
6504   }
6505   break;
6506       case 0x464d4143:      /* CAMF */
6507   meta_offset = off+8;
6508   m_MetaLength = len-28;
6509   break;
6510       case 0x504f5250:      /* PROP */
6511   pent = (get4(),get4());
6512   fseek (m_InputFile, 12, SEEK_CUR);
6513   off += pent*8 + 24;
6514   if ((unsigned) pent > 256) pent=256;
6515   for (i=0; i < pent*2; i++)
6516     poff[0][i] = off + get4()*2;
6517   for (i=0; i < pent; i++) {
6518     foveon_gets (poff[i][0], name, 64);
6519     foveon_gets (poff[i][1], value, 64);
6520     if (!strcmp (name, "ISO"))
6521       m_IsoSpeed = atoi(value);
6522     if (!strcmp (name, "CAMMANUF"))
6523       strcpy (m_CameraMake, value);
6524     if (!strcmp (name, "CAMMODEL"))
6525       strcpy (m_CameraModel, value);
6526     if (!strcmp (name, "WB_DESC"))
6527       strcpy (m_CameraModelBis, value);
6528     if (!strcmp (name, "TIME"))
6529       m_TimeStamp = atoi(value);
6530     if (!strcmp (name, "EXPTIME"))
6531       m_Shutter = atoi(value) / 1000000.0;
6532     if (!strcmp (name, "APERTURE"))
6533       m_Aperture = atof(value);
6534     if (!strcmp (name, "FLENGTH"))
6535       m_FocalLength = atof(value);
6536   }
6537 #ifdef LOCALTIME
6538   m_TimeStamp = mktime (gmtime (&m_TimeStamp));
6539 #endif
6540     }
6541     fseek (m_InputFile, save, SEEK_SET);
6542   }
6543   m_IsFoveon = 1;
6544 }
6545 
6546 /*
6547   Thanks to Adobe for providing these excellent CAM -> XYZ matrices!
6548   All matrices are from Adobe DNG Converter unless otherwise noted.
6549 
6550  */
6551 
6552 #include "ptAdobeTable.h"
6553 
adobe_coeff(const char * make,const char * model)6554 void CLASS adobe_coeff (const char *make, const char *model) {
6555   double MatrixXYZToCamRGB[4][3];
6556   char name[130];
6557   unsigned i;
6558   sprintf (name, "%s %s", make , model);
6559   for (i=0; i < sizeof AdobeTable / sizeof *AdobeTable; i++)
6560     if (!strncmp (name,
6561                   AdobeTable[i].Identification,
6562                   strlen(AdobeTable[i].Identification))) {
6563       strcpy(m_CameraAdobeIdentification,AdobeTable[i].Identification);
6564       if (AdobeTable[i].Blackpoint)   {
6565         m_BlackLevel = (uint16_t) AdobeTable[i].Blackpoint;
6566       }
6567       if (AdobeTable[i].Whitepoint) {
6568         m_WhiteLevel = (uint16_t) AdobeTable[i].Whitepoint;
6569       }
6570       if (AdobeTable[i].XYZToCam[0]) {
6571         for (short j=0; j < 4; j++) {
6572           for (short k=0; k<3; k++) {
6573       MatrixXYZToCamRGB[j][k] = AdobeTable[i].XYZToCam[j*3+k] / 10000.0;
6574           }
6575         }
6576         cam_xyz_coeff (MatrixXYZToCamRGB);
6577       }
6578       break;
6579     }
6580 }
6581 
simple_coeff(int index)6582 void CLASS simple_coeff (int index)
6583 {
6584   static const float table[][12] = {
6585   /* index 0 -- all Foveon cameras */
6586   { 1.4032,-0.2231,-0.1016,-0.5263,1.4816,0.017,-0.0112,0.0183,0.9113 },
6587   /* index 1 -- Kodak DC20 and DC25 */
6588   { 2.25,0.75,-1.75,-0.25,-0.25,0.75,0.75,-0.25,-0.25,-1.75,0.75,2.25 },
6589   /* index 2 -- Logitech Fotoman Pixtura */
6590   { 1.893,-0.418,-0.476,-0.495,1.773,-0.278,-1.017,-0.655,2.672 },
6591   /* index 3 -- Nikon E880, E900, and E990 */
6592   { -1.936280,  1.800443, -1.448486,  2.584324,
6593      1.405365, -0.524955, -0.289090,  0.408680,
6594     -1.204965,  1.082304,  2.941367, -1.818705 }
6595   };
6596   int i, c;
6597 
6598   for (m_RawColor = i=0; i < 3; i++)
6599     for (c=0; c < m_Colors; c++) m_MatrixCamRGBToSRGB[i][c] = table[index][i*m_Colors+c];
6600 }
6601 
guess_byte_order(int words)6602 short CLASS guess_byte_order (int words)
6603 {
6604   uint8_t test[4][2];
6605   int t=2, msb;
6606   double diff, sum[2] = {0,0};
6607 
6608   ptfread (test[0], 2, 2, m_InputFile);
6609   for (words-=2; words--; ) {
6610     ptfread (test[t], 2, 1, m_InputFile);
6611     for (msb=0; msb < 2; msb++) {
6612       diff = (test[t^2][msb] << 8 | test[t^2][!msb])
6613      - (test[t  ][msb] << 8 | test[t  ][!msb]);
6614       sum[msb] += diff*diff;
6615     }
6616     t = (t+1) & 3;
6617   }
6618   return sum[0] < sum[1] ? 0x4d4d : 0x4949;
6619 }
6620 
find_green(int bps,int bite,int off0,int off1)6621 float CLASS find_green (int bps, int bite, int off0, int off1)
6622 {
6623   uint64_t bitbuf=0;
6624   int vbits, col, i, c;
6625   uint16_t img[2][2064];
6626   double sum[]={0,0};
6627 
6628   for (c=0;c<2;c++) {
6629     fseek (m_InputFile, c ? off1:off0, SEEK_SET);
6630     for (vbits=col=0; col < m_Width; col++) {
6631       for (vbits -= bps; vbits < 0; vbits += bite) {
6632   bitbuf <<= bite;
6633   for (i=0; i < bite; i+=8)
6634     bitbuf |= (unsigned) (fgetc(m_InputFile) << i);
6635       }
6636       img[c][col] = bitbuf << (64-bps-vbits) >> (64-bps);
6637     }
6638   }
6639   for (c=0;c<(m_Width-1);c++) {
6640     sum[ c & 1] += ABS(img[0][c]-img[1][c+1]);
6641     sum[~c & 1] += ABS(img[1][c]-img[0][c+1]);
6642   }
6643   return 100 * log(sum[0]/sum[1]);
6644 }
6645 
6646 /*
6647    Identify which camera created this file, and set global variables
6648    accordingly.
6649  */
6650 
identify()6651 void CLASS identify() {
6652   char         l_Head[32];
6653   char*        l_CharPointer;
6654   unsigned     l_HLen;
6655   unsigned     l_FLen;
6656   unsigned     l_FileSize;
6657   int          zero_fsize = 1;
6658   unsigned     l_IsCanon;
6659   struct jhead l_JHead;
6660   unsigned     i,c;
6661   short pana[][6] = {
6662     { 3130, 1743,  4,  0, -6,  0 },
6663     { 3130, 2055,  4,  0, -6,  0 },
6664     { 3130, 2319,  4,  0, -6,  0 },
6665     { 3170, 2103, 18,  0,-42, 20 },
6666     { 3170, 2367, 18, 13,-42,-21 },
6667     { 3177, 2367,  0,  0, -1,  0 },
6668     { 3304, 2458,  0,  0, -1,  0 },
6669     { 3330, 2463,  9,  0, -5,  0 },
6670     { 3330, 2479,  9,  0,-17,  4 },
6671     { 3370, 1899, 15,  0,-44, 20 },
6672     { 3370, 2235, 15,  0,-44, 20 },
6673     { 3370, 2511, 15, 10,-44,-21 },
6674     { 3690, 2751,  3,  0, -8, -3 },
6675     { 3710, 2751,  0,  0, -3,  0 },
6676     { 3724, 2450,  0,  0,  0, -2 },
6677     { 3770, 2487, 17,  0,-44, 19 },
6678     { 3770, 2799, 17, 15,-44,-19 },
6679     { 3880, 2170,  6,  0, -6,  0 },
6680     { 4060, 3018,  0,  0,  0, -2 },
6681     { 4290, 2391,  3,  0, -8, -1 },
6682     { 4330, 2439, 17, 15,-44,-19 },
6683     { 4508, 2962,  0,  0, -3, -4 },
6684     { 4508, 3330,  0,  0, -3, -6 } };
6685 
6686   static const struct {
6687     int fsize;
6688     char make[12], model[19], withjpeg;
6689   } l_Table[] = {
6690     {    62464, "Kodak",    "DC20"            ,0 },
6691     {   124928, "Kodak",    "DC20"            ,0 },
6692     {  1652736, "Kodak",    "DCS200"          ,0 },
6693     {  4159302, "Kodak",    "C330"            ,0 },
6694     {  4162462, "Kodak",    "C330"            ,0 },
6695     {   460800, "Kodak",    "C603v"           ,0 },
6696     {   614400, "Kodak",    "C603v"           ,0 },
6697     {  6163328, "Kodak",    "C603"            ,0 },
6698     {  6166488, "Kodak",    "C603"            ,0 },
6699     {  9116448, "Kodak",    "C603y"           ,0 },
6700     {   311696, "ST Micro", "STV680 VGA"      ,0 },  /* SPYz */
6701     {   787456, "Creative", "PC-CAM 600"      ,0 },
6702     {  1138688, "Minolta",  "RD175"           ,0 },
6703     {  3840000, "Foculus",  "531C"            ,0 },
6704     {   307200, "Generic",  "640x480"         ,0 },
6705     {   786432, "AVT",      "F-080C"          ,0 },
6706     {  1447680, "AVT",      "F-145C"          ,0 },
6707     {  1920000, "AVT",      "F-201C"          ,0 },
6708     {  5067304, "AVT",      "F-510C"          ,0 },
6709     {  5067316, "AVT",      "F-510C"          ,0 },
6710     { 10134608, "AVT",      "F-510C"          ,0 },
6711     { 10134620, "AVT",      "F-510C"          ,0 },
6712     { 16157136, "AVT",      "F-810C"          ,0 },
6713     {  1409024, "Sony",     "XCD-SX910CR"     ,0 },
6714     {  2818048, "Sony",     "XCD-SX910CR"     ,0 },
6715     {  3884928, "Micron",   "2010"            ,0 },
6716     {  6624000, "Pixelink", "A782"            ,0 },
6717     { 13248000, "Pixelink", "A782"            ,0 },
6718     {  6291456, "RoverShot","3320AF"          ,0 },
6719     {  6553440, "Canon",    "PowerShot A460"  ,0 },
6720     {  6653280, "Canon",    "PowerShot A530"  ,0 },
6721     {  6573120, "Canon",    "PowerShot A610"  ,0 },
6722     {  9219600, "Canon",    "PowerShot A620"  ,0 },
6723     {  9243240, "Canon",    "PowerShot A470"  ,0 },
6724     { 10341600, "Canon",    "PowerShot A720 IS"  ,0 },
6725     { 10383120, "Canon",    "PowerShot A630"  ,0 },
6726     { 12945240, "Canon",    "PowerShot A640"  ,0 },
6727     { 15636240, "Canon",    "PowerShot A650"  ,0 },
6728     {  5298000, "Canon",    "PowerShot SD300" ,0 },
6729     {  7710960, "Canon",    "PowerShot S3 IS" ,0 },
6730     { 15467760, "Canon",    "PowerShot SX110 IS",0 },
6731     { 15534576, "Canon",    "PowerShot SX120 IS",0 },
6732     { 18653760, "Canon",    "PowerShot SX20 IS",0 },
6733     { 19131120, "Canon",    "PowerShot SX220 HS",0 },
6734     { 21936096, "Canon",    "PowerShot SX30 IS",0 },
6735     {  5939200, "OLYMPUS",  "C770UZ"          ,0 },
6736     {  1581060, "NIKON",    "E900"            ,1 },  /* or E900s,E910 */
6737     {  2465792, "NIKON",    "E950"            ,1 },  /* or E800,E700 */
6738     {  2940928, "NIKON",    "E2100"           ,1 },  /* or E2500 */
6739     {  4771840, "NIKON",    "E990"            ,1 },  /* or E995, Oly C3030Z */
6740     {  4775936, "NIKON",    "E3700"           ,1 },  /* or Optio 33WR */
6741     {  5869568, "NIKON",    "E4300"           ,1 },  /* or DiMAGE Z2 */
6742     {  5865472, "NIKON",    "E4500"           ,1 },
6743     {  7438336, "NIKON",    "E5000"           ,1 },  /* or E5700 */
6744     {  8998912, "NIKON",    "COOLPIX S6"      ,1 },
6745     {  1976352, "CASIO",    "QV-2000UX"       ,1 },
6746     {  3217760, "CASIO",    "QV-3*00EX"       ,1 },
6747     {  6218368, "CASIO",    "QV-5700"         ,1 },
6748     {  6054400, "CASIO",    "QV-R41"          ,1 },
6749     {  7530816, "CASIO",    "QV-R51"          ,1 },
6750     {  7684000, "CASIO",    "QV-4000"         ,1 },
6751     {  2937856, "CASIO",    "EX-S20"          ,1 },
6752     {  4948608, "CASIO",    "EX-S100"         ,1 },
6753     {  7542528, "CASIO",    "EX-Z50"          ,1 },
6754     {  7562048, "CASIO",    "EX-Z500"         ,1 },
6755     {  7753344, "CASIO",    "EX-Z55"          ,1 },
6756     {  7816704, "CASIO",    "EX-Z60"          ,1 },
6757     { 10843712, "CASIO",    "EX-Z75"          ,1 },
6758     { 10834368, "CASIO",    "EX-Z750"         ,1 },
6759     { 12310144, "CASIO",    "EX-Z850"         ,1 },
6760     { 12489984, "CASIO",    "EX-Z8"           ,1 },
6761     { 15499264, "CASIO",    "EX-Z1050"        ,1 },
6762     { 18702336, "CASIO",    "EX-ZR100"        ,1 },
6763     {  7426656, "CASIO",    "EX-P505"         ,1 },
6764     {  9313536, "CASIO",    "EX-P600"         ,1 },
6765     { 10979200, "CASIO",    "EX-P700"         ,1 },
6766     {  3178560, "PENTAX",   "Optio S"         ,1 },
6767     {  4841984, "PENTAX",   "Optio S"         ,1 },
6768     {  6114240, "PENTAX",   "Optio S4"        ,1 },  /* or S4i, CASIO EX-Z4 */
6769     { 10702848, "PENTAX",   "Optio 750Z"      ,1 },
6770     { 15980544, "AGFAPHOTO","DC-833m"         ,1 },
6771     { 16098048, "SAMSUNG",  "S85"             ,1 },
6772     { 16215552, "SAMSUNG",  "S85"             ,1 },
6773     { 20487168, "SAMSUNG",  "WB550"           ,1 },
6774     { 24000000, "SAMSUNG",  "WB550"           ,1 },
6775     { 12582980, "Sinar",    ""                ,0 },
6776     { 33292868, "Sinar",    ""                ,0 },
6777     { 44390468, "Sinar",    ""                ,0 } };
6778 
6779   static const char *l_Corporation[] =
6780     { "Canon", "NIKON", "EPSON", "KODAK", "Kodak", "OLYMPUS", "PENTAX",
6781       "MINOLTA", "Minolta", "Konica", "CASIO", "Sinar", "Phase One",
6782       "SAMSUNG", "Mamiya", "MOTOROLA", "LEICA" };
6783 
6784   // Byte order of input file.
6785   memset (m_Mask, 0, sizeof m_Mask);
6786   m_ByteOrder = get2();
6787 
6788   // Length of header.
6789   l_HLen = get4();
6790 
6791 /*  m_BlackLevel = 0;
6792   for (int k=0; k<4; k++) m_CBlackLevel[k]=0; TODO Mike */
6793 
6794   // Length of file.
6795   fseek (m_InputFile, 0, SEEK_SET);
6796   ptfread (l_Head, 1, 32, m_InputFile);
6797   fseek (m_InputFile, 0, SEEK_END);
6798   l_FLen = l_FileSize = ftell(m_InputFile);
6799 
6800 #pragma GCC diagnostic push
6801 #pragma GCC diagnostic ignored "-Wwrite-strings"
6802   if ((l_CharPointer = (char *) memmem (l_Head, 32, "MMMM", 4)) ||
6803       (l_CharPointer = (char *) memmem (l_Head, 32, "IIII", 4))) {
6804 #pragma GCC diagnostic pop
6805     parse_phase_one (l_CharPointer-l_Head);
6806     if ((l_CharPointer-l_Head) && parse_tiff(0)) apply_tiff();
6807   } else if (m_ByteOrder == 0x4949 || m_ByteOrder == 0x4d4d) {
6808     if (!memcmp (l_Head+6,"HEAPCCDR",8)) {
6809       m_Data_Offset = l_HLen;
6810       parse_ciff (l_HLen, l_FLen - l_HLen);
6811     } else if (parse_tiff(0)) apply_tiff();
6812   } else if (!memcmp (l_Head,"\xff\xd8\xff\xe1",4) &&
6813        !memcmp (l_Head+6,"Exif",4)) {
6814     fseek (m_InputFile, 4, SEEK_SET);
6815     m_Data_Offset = 4 + get2();
6816     fseek (m_InputFile, m_Data_Offset, SEEK_SET);
6817     if (fgetc(m_InputFile) != 0xff)
6818       parse_tiff(12);
6819     m_ThumbOffset = 0;
6820   } else if (!memcmp (l_Head+25,"ARECOYK",7)) {
6821     strcpy (m_CameraMake, "Contax");
6822     strcpy (m_CameraModel,"N Digital");
6823     fseek (m_InputFile, 33, SEEK_SET);
6824     get_timestamp(1);
6825     fseek (m_InputFile, 60, SEEK_SET);
6826     for (c=0; c < 4; c++) ASSIGN(m_CameraMultipliers[c ^ (c >> 1)], get4());
6827   } else if (!strcmp (l_Head, "PXN")) {
6828     strcpy (m_CameraMake, "Logitech");
6829     strcpy (m_CameraModel,"Fotoman Pixtura");
6830   } else if (!strcmp (l_Head, "qktk")) {
6831     strcpy (m_CameraMake, "Apple");
6832     strcpy (m_CameraModel,"QuickTake 100");
6833     m_LoadRawFunction = &CLASS quicktake_100_load_raw;
6834   } else if (!strcmp (l_Head, "qktn")) {
6835     strcpy (m_CameraMake, "Apple");
6836     strcpy (m_CameraModel,"QuickTake 150");
6837     m_LoadRawFunction = &CLASS kodak_radc_load_raw;
6838   } else if (!memcmp (l_Head,"FUJIFILM",8)) {
6839     fseek (m_InputFile, 84, SEEK_SET);
6840     m_ThumbOffset = get4();
6841     m_ThumbLength = get4();
6842     fseek (m_InputFile, 92, SEEK_SET);
6843     parse_fuji (get4());
6844     if (m_ThumbOffset > 120) {
6845       fseek (m_InputFile, 120, SEEK_SET);
6846       m_IsRaw += (i = get4());
6847       if (m_IsRaw == 2 && m_UserSetting_ShotSelect)
6848   parse_fuji (i);
6849     }
6850     m_LoadRawFunction = &CLASS unpacked_load_raw;
6851     fseek (m_InputFile, 100+28*(m_UserSetting_ShotSelect > 0), SEEK_SET);
6852     parse_tiff (m_Data_Offset = get4());
6853     parse_tiff (m_ThumbOffset+12);
6854     apply_tiff();
6855   } else if (!memcmp (l_Head,"RIFF",4)) {
6856     fseek (m_InputFile, 0, SEEK_SET);
6857     parse_riff();
6858   } else if (!memcmp (l_Head,"\0\001\0\001\0@",6)) {
6859     fseek (m_InputFile, 6, SEEK_SET);
6860     ptfread (m_CameraMake, 1, 8, m_InputFile);
6861     ptfread (m_CameraModel, 1, 8, m_InputFile);
6862     ptfread (m_CameraModelBis, 1, 16, m_InputFile);
6863     m_Data_Offset = get2();
6864     get2();
6865     m_RawWidth = get2();
6866     m_RawHeight = get2();
6867     m_LoadRawFunction = &CLASS nokia_load_raw;
6868     m_Filters = 0x61616161;
6869   } else if (!memcmp (l_Head,"NOKIARAW",8)) {
6870     strcpy (m_CameraMake, "NOKIA");
6871     strcpy (m_CameraModel, "X2");
6872     m_ByteOrder = 0x4949;
6873     fseek (m_InputFile, 300, SEEK_SET);
6874     m_Data_Offset = get4();
6875     i = get4();
6876     m_Width = get2();
6877     m_Height = get2();
6878     m_Data_Offset += i - m_Width * 5 / 4 * m_Height;
6879     m_LoadRawFunction = &CLASS nokia_load_raw;
6880     m_Filters = 0x61616161;
6881   } else if (!memcmp (l_Head,"ARRI",4)) {
6882     m_ByteOrder = 0x4949;
6883     fseek (m_InputFile, 20, SEEK_SET);
6884     m_Width = get4();
6885     m_Height = get4();
6886     strcpy (m_CameraMake, "ARRI");
6887     fseek (m_InputFile, 668, SEEK_SET);
6888     ptfread (m_CameraModel, 1, 64, m_InputFile);
6889     m_Data_Offset = 4096;
6890     m_LoadRawFunction = &CLASS packed_load_raw;
6891     m_Load_Flags = 88;
6892     m_Filters = 0x61616161;
6893   } else if (!memcmp (l_Head+4,"RED1",4)) {
6894     strcpy (m_CameraMake, "RED");
6895     strcpy (m_CameraModel,"ONE");
6896     parse_redcine();
6897     m_LoadRawFunction = &CLASS redcine_load_raw;
6898     gamma_curve (1/2.4, 12.92, 1, 4095);
6899     m_Filters = 0x49494949;
6900   } else if (!memcmp (l_Head,"DSC-Image",9))
6901     parse_rollei();
6902   else if (!memcmp (l_Head,"PWAD",4))
6903     parse_sinar_ia();
6904   else if (!memcmp (l_Head,"\0MRM",4))
6905     parse_minolta(0);
6906   else if (!memcmp (l_Head,"FOVb",4))
6907     parse_foveon();
6908   else if (!memcmp (l_Head,"CI",2))
6909     parse_cine();
6910   else {
6911     for (zero_fsize=i=0; i < sizeof l_Table / sizeof *l_Table; i++)
6912       if (l_FileSize == (unsigned) l_Table[i].fsize) {
6913   strcpy (m_CameraMake,  l_Table[i].make );
6914   strcpy (m_CameraModel, l_Table[i].model);
6915   if (l_Table[i].withjpeg)
6916     parse_external_jpeg();
6917       }
6918   }
6919   if (zero_fsize) l_FileSize = 0;
6920   if (m_CameraMake[0] == 0) parse_smal (0, l_FLen);
6921   if (m_CameraMake[0] == 0) parse_jpeg (m_IsRaw = 0);
6922 
6923   for (i=0; i < sizeof l_Corporation / sizeof *l_Corporation; i++)
6924     if (strstr (m_CameraMake, l_Corporation[i])) /* Simplify company names */
6925   strcpy (m_CameraMake, l_Corporation[i]);
6926   if (!strncmp (m_CameraMake,"KODAK",5) &&
6927   ((l_CharPointer = strstr(m_CameraModel," DIGITAL CAMERA")) ||
6928    (l_CharPointer = strstr(m_CameraModel," Digital Camera")) ||
6929    (l_CharPointer = strstr(m_CameraModel,"FILE VERSION"))))
6930      *l_CharPointer = 0;
6931   l_CharPointer = m_CameraMake + strlen(m_CameraMake);  /* Remove trailing spaces */
6932   while (*--l_CharPointer == ' ') *l_CharPointer = 0;
6933   l_CharPointer = m_CameraModel + strlen(m_CameraModel);
6934   while (*--l_CharPointer == ' ') *l_CharPointer = 0;
6935   i = strlen(m_CameraMake);     /* Remove make from model */
6936   if (!strncasecmp (m_CameraModel, m_CameraMake, i) && m_CameraModel[i++] == ' ')
6937     memmove (m_CameraModel, m_CameraModel+i, 64-i);
6938   if (!strncmp (m_CameraModel,"FinePix ",8))
6939     strcpy (m_CameraModel, m_CameraModel+8);
6940   if (!strncmp (m_CameraModel,"Digital Camera ",15))
6941     strcpy (m_CameraModel, m_CameraModel+15);
6942 
6943   m_Description[511] = m_Artist[63] = m_CameraMake[63] = m_CameraModel[63] = m_CameraModelBis[63] = 0;
6944 
6945   if (!m_IsRaw) goto notraw;
6946 
6947   if (!m_Height) m_Height = m_RawHeight;
6948   if (!m_Width)  m_Width  = m_RawWidth;
6949   if (m_Height == 2624 && m_Width == 3936) /* Pentax K10D and Samsung GX10 */
6950     { m_Height  = 2616;   m_Width  = 3896; }
6951   if (m_Height == 3136 && m_Width == 4864)  /* Pentax K20D and Samsung GX20 */
6952     { m_Height  = 3124;   m_Width  = 4688; m_Filters = 0x16161616; }
6953   if (m_Width == 4352 && (!strcmp(m_CameraModel,"K-r") || !strcmp(m_CameraModel,"K-x")))
6954     { m_Width  = 4309; m_Filters = 0x16161616; }
6955   if (m_Width >= 4960 && !strncmp(m_CameraModel,"K-5",3))
6956     { m_LeftMargin = 10; m_Width  = 4950; m_Filters = 0x16161616; }
6957   if (m_Width == 4736 && !strcmp(m_CameraModel,"K-7"))
6958     { m_Height  = 3122;   m_Width  = 4684; m_Filters = 0x16161616; m_TopMargin = 2; }
6959   if (m_Width == 7424 && !strcmp(m_CameraModel,"645D"))
6960     { m_Height  = 5502;   m_Width  = 7328; m_Filters = 0x61616161; m_TopMargin = 29;
6961       m_LeftMargin = 48; }
6962   if (m_Height == 3014 && m_Width == 4096)  /* Ricoh GX200 */
6963       m_Width  = 4014;
6964   if (m_DNG_Version) {
6965     if (m_Filters == UINT_MAX) m_Filters = 0;
6966     if (m_Filters) m_IsRaw = m_Tiff_Samples;
6967     else   m_Colors = m_Tiff_Samples;
6968     if (m_Tiff_Compress == 1)
6969       m_LoadRawFunction = &CLASS packed_dng_load_raw;
6970     if (m_Tiff_Compress == 7)
6971       m_LoadRawFunction = &CLASS lossless_dng_load_raw;
6972     goto dng_skip;
6973   }
6974   if ((l_IsCanon = !strcmp(m_CameraMake,"Canon"))) {
6975     m_LoadRawFunction = memcmp (l_Head+6,"HEAPCCDR",8) ?
6976   &CLASS lossless_jpeg_load_raw : &CLASS canon_load_raw;
6977   }
6978   if (!strcmp(m_CameraMake,"NIKON")) {
6979     if (!m_LoadRawFunction)
6980       m_LoadRawFunction = &CLASS packed_load_raw;
6981     if (m_CameraModel[0] == 'E')
6982       m_Load_Flags |= !m_Data_Offset << 2 | 2;
6983   }
6984   if (!strcmp(m_CameraMake,"CASIO")) {
6985     m_LoadRawFunction = &CLASS packed_load_raw;
6986     m_WhiteLevel = 0xf7f;
6987   }
6988 
6989 /* Set parameters based on camera name (for non-DNG files). */
6990 
6991   if (m_IsFoveon) {
6992     if (m_Height*2 < m_Width) m_PixelAspect = 0.5;
6993     if (m_Height   > m_Width) m_PixelAspect = 2;
6994     m_Filters = 0;
6995     simple_coeff(0);
6996   } else if (l_IsCanon && m_Tiff_bps == 15) {
6997     switch (m_Width) {
6998       case 3344: m_Width -= 66;
6999       case 3872: m_Width -= 6;
7000     }
7001     if (m_Height > m_Width) SWAP(m_Height,m_Width);
7002     m_Filters = 0;
7003     m_LoadRawFunction = &CLASS canon_sraw_load_raw;
7004   } else if (!strcmp(m_CameraModel,"PowerShot 600")) {
7005     m_Height = 613;
7006     m_Width  = 854;
7007     m_RawWidth = 896;
7008     m_PixelAspect = 607/628.0;
7009     m_Colors = 4;
7010     m_Filters = 0xe1e4e1e4;
7011     m_LoadRawFunction = &CLASS canon_600_load_raw;
7012   } else if (!strcmp(m_CameraModel,"PowerShot A5") ||
7013        !strcmp(m_CameraModel,"PowerShot A5 Zoom")) {
7014     m_Height = 773;
7015     m_Width  = 960;
7016     m_RawWidth = 992;
7017     m_PixelAspect = 256/235.0;
7018     m_Colors = 4;
7019     m_Filters = 0x1e4e1e4e;
7020     goto canon_a5;
7021   } else if (!strcmp(m_CameraModel,"PowerShot A50")) {
7022     m_Height =  968;
7023     m_Width  = 1290;
7024     m_RawWidth = 1320;
7025     m_Colors = 4;
7026     m_Filters = 0x1b4e4b1e;
7027     goto canon_a5;
7028   } else if (!strcmp(m_CameraModel,"PowerShot Pro70")) {
7029     m_Height = 1024;
7030     m_Width  = 1552;
7031     m_Colors = 4;
7032     m_Filters = 0x1e4b4e1b;
7033     goto canon_a5;
7034   } else if (!strcmp(m_CameraModel,"PowerShot SD300")) {
7035     m_Height = 1752;
7036     m_Width  = 2344;
7037     m_RawHeight = 1766;
7038     m_RawWidth  = 2400;
7039     m_TopMargin  = 12;
7040     m_LeftMargin = 12;
7041     goto canon_a5;
7042   } else if (!strcmp(m_CameraModel,"PowerShot A460")) {
7043     m_Height = 1960;
7044     m_Width  = 2616;
7045     m_RawHeight = 1968;
7046     m_RawWidth  = 2664;
7047     m_TopMargin  = 4;
7048     m_LeftMargin = 4;
7049     goto canon_a5;
7050   } else if (!strcmp(m_CameraModel,"PowerShot A530")) {
7051     m_Height = 1984;
7052     m_Width  = 2620;
7053     m_RawHeight = 1992;
7054     m_RawWidth  = 2672;
7055     m_TopMargin  = 6;
7056     m_LeftMargin = 10;
7057     goto canon_a5;
7058   } else if (!strcmp(m_CameraModel,"PowerShot A610")) {
7059     if (canon_s2is()) strcpy (m_CameraModel+10, "S2 IS");
7060     m_Height = 1960;
7061     m_Width  = 2616;
7062     m_RawHeight = 1968;
7063     m_RawWidth  = 2672;
7064     m_TopMargin  = 8;
7065     m_LeftMargin = 12;
7066     goto canon_a5;
7067   } else if (!strcmp(m_CameraModel,"PowerShot A620")) {
7068     m_Height = 2328;
7069     m_Width  = 3112;
7070     m_RawHeight = 2340;
7071     m_RawWidth  = 3152;
7072     m_TopMargin  = 12;
7073     m_LeftMargin = 36;
7074     goto canon_a5;
7075   } else if (!strcmp(m_CameraModel,"PowerShot A470")) {
7076     m_Height = 2328;
7077     m_Width  = 3096;
7078     m_RawHeight = 2346;
7079     m_RawWidth  = 3152;
7080     m_TopMargin  = 6;
7081     m_LeftMargin = 12;
7082     goto canon_a5;
7083   } else if (!strcmp(m_CameraModel,"PowerShot A720 IS")) {
7084     m_Height = 2472;
7085     m_Width  = 3298;
7086     m_RawHeight = 2480;
7087     m_RawWidth  = 3336;
7088     m_TopMargin  = 5;
7089     m_LeftMargin = 6;
7090     goto canon_a5;
7091   } else if (!strcmp(m_CameraModel,"PowerShot A630")) {
7092     m_Height = 2472;
7093     m_Width  = 3288;
7094     m_RawHeight = 2484;
7095     m_RawWidth  = 3344;
7096     m_TopMargin  = 6;
7097     m_LeftMargin = 12;
7098     goto canon_a5;
7099   } else if (!strcmp(m_CameraModel,"PowerShot A640")) {
7100     m_Height = 2760;
7101     m_Width  = 3672;
7102     m_RawHeight = 2772;
7103     m_RawWidth  = 3736;
7104     m_TopMargin  = 6;
7105     m_LeftMargin = 12;
7106     goto canon_a5;
7107  } else if (!strcmp(m_CameraModel,"PowerShot A650")) {
7108     m_Height = 3024;
7109     m_Width  = 4032;
7110     m_RawHeight = 3048;
7111     m_RawWidth  = 4104;
7112     m_TopMargin  = 12;
7113     m_LeftMargin = 48;
7114     goto canon_a5;
7115   } else if (!strcmp(m_CameraModel,"PowerShot S3 IS")) {
7116     m_Height = 2128;
7117     m_Width  = 2840;
7118     m_RawHeight = 2136;
7119     m_RawWidth  = 2888;
7120     m_TopMargin  = 8;
7121     m_LeftMargin = 44;
7122 canon_a5:
7123     m_Tiff_bps = 10;
7124     m_LoadRawFunction = &CLASS packed_load_raw;
7125     m_Load_Flags = 40;
7126     if (m_RawWidth > 1600) m_ZeroIsBad = 1;
7127   } else if (!strcmp(m_CameraModel,"PowerShot SX110 IS")) {
7128     m_Height = 2760;
7129     m_Width  = 3684;
7130     m_RawHeight = 2772;
7131     m_RawWidth  = 3720;
7132     m_TopMargin  = 12;
7133     m_LeftMargin = 6;
7134     m_LoadRawFunction = &CLASS packed_load_raw;
7135     m_Load_Flags = 40;
7136     m_ZeroIsBad = 1;
7137   } else if (!strcmp(m_CameraModel,"PowerShot SX120 IS")) {
7138     m_Height = 2742;
7139     m_Width  = 3664;
7140     m_RawHeight = 2778;
7141     m_RawWidth  = 3728;
7142     m_TopMargin  = 18;
7143     m_LeftMargin = 16;
7144     m_Filters = 0x49494949;
7145     m_LoadRawFunction = &CLASS packed_load_raw;
7146     m_Load_Flags = 40;
7147     m_ZeroIsBad = 1;
7148   } else if (!strcmp(m_CameraModel,"PowerShot SX20 IS")) {
7149     m_Height = 3024;
7150     m_Width  = 4032;
7151     m_RawHeight = 3048;
7152     m_RawWidth  = 4080;
7153     m_TopMargin  = 12;
7154     m_LeftMargin = 24;
7155     m_LoadRawFunction = &CLASS packed_load_raw;
7156     m_Load_Flags = 40;
7157     m_ZeroIsBad = 1;
7158   } else if (!strcmp(m_CameraModel,"PowerShot SX220 HS")) {
7159     m_Height = 3043;
7160     m_Width  = 4072;
7161     m_RawHeight = 3060;
7162     m_RawWidth  = 4168;
7163     m_Mask[0][0] = m_TopMargin = 16;
7164     m_Mask[0][2] = m_TopMargin + m_Height;
7165     m_Mask[0][3] = m_LeftMargin = 92;
7166     m_LoadRawFunction = &CLASS packed_load_raw;
7167     m_Load_Flags = 8;
7168     m_ZeroIsBad = 1;
7169   } else if (!strcmp(m_CameraModel,"PowerShot SX30 IS")) {
7170     m_Height = 3254;
7171     m_Width  = 4366;
7172     m_RawHeight = 3276;
7173     m_RawWidth  = 4464;
7174     m_TopMargin  = 10;
7175     m_LeftMargin = 25;
7176     m_Filters = 0x16161616;
7177     m_LoadRawFunction = &CLASS packed_load_raw;
7178     m_Load_Flags = 40;
7179     m_ZeroIsBad = 1;
7180   } else if (!strcmp(m_CameraModel,"PowerShot Pro90 IS")) {
7181     m_Width  = 1896;
7182     m_Colors = 4;
7183     m_Filters = 0xb4b4b4b4;
7184   } else if (l_IsCanon && m_RawWidth == 2144) {
7185     m_Height = 1550;
7186     m_Width  = 2088;
7187     m_TopMargin  = 8;
7188     m_LeftMargin = 4;
7189     if (!strcmp(m_CameraModel,"PowerShot G1")) {
7190       m_Colors = 4;
7191       m_Filters = 0xb4b4b4b4;
7192     }
7193   } else if (l_IsCanon && m_RawWidth == 2224) {
7194     m_Height = 1448;
7195     m_Width  = 2176;
7196     m_TopMargin  = 6;
7197     m_LeftMargin = 48;
7198   } else if (l_IsCanon && m_RawWidth == 2376) {
7199     m_Height = 1720;
7200     m_Width  = 2312;
7201     m_TopMargin  = 6;
7202     m_LeftMargin = 12;
7203   } else if (l_IsCanon && m_RawWidth == 2672) {
7204     m_Height = 1960;
7205     m_Width  = 2616;
7206     m_TopMargin  = 6;
7207     m_LeftMargin = 12;
7208   } else if (l_IsCanon && m_RawWidth == 3152) {
7209     m_Height = 2056;
7210     m_Width  = 3088;
7211     m_TopMargin  = 12;
7212     m_LeftMargin = 64;
7213     if (unique_id == 0x80000170)
7214       adobe_coeff ("Canon","EOS 300D");
7215   } else if (l_IsCanon && m_RawWidth == 3160) {
7216     m_Height = 2328;
7217     m_Width  = 3112;
7218     m_TopMargin  = 12;
7219     m_LeftMargin = 44;
7220   } else if (l_IsCanon && m_RawWidth == 3344) {
7221     m_Height = 2472;
7222     m_Width  = 3288;
7223     m_TopMargin  = 6;
7224     m_LeftMargin = 4;
7225   } else if (!strcmp(m_CameraModel,"EOS D2000C")) {
7226     m_Filters = 0x61616161;
7227     m_BlackLevel = m_Curve[200];
7228   } else if (l_IsCanon && m_RawWidth == 3516) {
7229     m_TopMargin  = 14;
7230     m_LeftMargin = 42;
7231     if (unique_id == 0x80000189)
7232       adobe_coeff ("Canon","EOS 350D");
7233     goto canon_cr2;
7234   } else if (l_IsCanon && m_RawWidth == 3596) {
7235     m_TopMargin  = 12;
7236     m_LeftMargin = 74;
7237     goto canon_cr2;
7238   } else if (l_IsCanon && m_RawWidth == 3744) {
7239     m_Height = 2760;
7240     m_Width  = 3684;
7241     m_TopMargin  = 16;
7242     m_LeftMargin = 8;
7243     if (unique_id > 0x2720000) {
7244       m_TopMargin  = 12;
7245       m_LeftMargin = 52;
7246     }
7247   } else if (l_IsCanon && m_RawWidth == 3944) {
7248     m_Height = 2602;
7249     m_Width  = 3908;
7250     m_TopMargin  = 18;
7251     m_LeftMargin = 30;
7252   } else if (l_IsCanon && m_RawWidth == 3948) {
7253     m_TopMargin  = 18;
7254     m_LeftMargin = 42;
7255     m_Height -= 2;
7256     if (unique_id == 0x80000236)
7257       adobe_coeff ("Canon","EOS 400D");
7258     if (unique_id == 0x80000254)
7259       adobe_coeff ("Canon","EOS 1000D");
7260     goto canon_cr2;
7261   } else if (l_IsCanon && m_RawWidth == 3984) {
7262     m_TopMargin  = 20;
7263     m_LeftMargin = 76;
7264     m_Height -= 2;
7265     goto canon_cr2;
7266   } else if (l_IsCanon && m_RawWidth == 4104) {
7267     m_Height = 3024;
7268     m_Width  = 4032;
7269     m_TopMargin  = 12;
7270     m_LeftMargin = 48;
7271  } else if (l_IsCanon && m_RawWidth == 4152) {
7272     m_TopMargin  = 12;
7273     m_LeftMargin = 192;
7274     goto canon_cr2;
7275   } else if (l_IsCanon && m_RawWidth == 4160) {
7276     m_Height = 3048;
7277     m_Width  = 4048;
7278     m_TopMargin  = 11;
7279     m_LeftMargin = 104;
7280   } else if (l_IsCanon && m_RawWidth == 4176) {
7281     m_Height = 3045;
7282     m_Width  = 4072;
7283     m_LeftMargin = 96;
7284     m_Mask[0][0] = m_TopMargin = 17;
7285     m_Mask[0][2] = m_RawHeight;
7286     m_Mask[0][3] = 80;
7287     m_Filters = 0x49494949;
7288   } else if (l_IsCanon && m_RawWidth == 4312) {
7289     m_TopMargin  = 18;
7290     m_LeftMargin = 22;
7291     m_Height -= 2;
7292     if (unique_id == 0x80000176)
7293       adobe_coeff ("Canon","EOS 450D");
7294     goto canon_cr2;
7295   } else if (l_IsCanon && m_RawWidth == 4352) {
7296     m_TopMargin  = 18;
7297     m_LeftMargin = 62;
7298     if (unique_id == 0x80000288)
7299       adobe_coeff ("Canon","EOS 1100D");
7300     goto canon_cr2;
7301   } else if (l_IsCanon && m_RawWidth == 4476) {
7302     m_TopMargin  = 34;
7303     m_LeftMargin = 90;
7304     goto canon_cr2;
7305   } else if (l_IsCanon && m_RawWidth == 4480) {
7306     m_Height = 3326;
7307     m_Width  = 4432;
7308     m_TopMargin  = 10;
7309     m_LeftMargin = 12;
7310     m_Filters = 0x49494949;
7311   } else if (l_IsCanon && m_RawWidth == 4496) {
7312     m_Height = 3316;
7313     m_Width  = 4404;
7314     m_TopMargin  = 50;
7315     m_LeftMargin = 80;
7316   } else if (l_IsCanon && m_RawWidth == 4832) {
7317     m_TopMargin = unique_id == 0x80000261 ? 51:26;
7318     m_LeftMargin = 62;
7319     if (unique_id == 0x80000252)
7320       adobe_coeff ("Canon","EOS 500D");
7321     goto canon_cr2;
7322   } else if (l_IsCanon && m_RawWidth == 5108) {
7323     m_TopMargin  = 13;
7324     m_LeftMargin = 98;
7325     goto canon_cr2;
7326   } else if (l_IsCanon && m_RawWidth == 5120) {
7327     m_Height -= m_TopMargin = 45;
7328     m_LeftMargin = 142;
7329     m_Width = 4916;
7330   } else if (l_IsCanon && m_RawWidth == 5280) {
7331     m_TopMargin  = 52;
7332     m_LeftMargin = 72;
7333     if (unique_id == 0x80000301)
7334       adobe_coeff ("Canon","EOS 650D");
7335     goto canon_cr2;
7336   } else if (l_IsCanon && m_RawWidth == 5344) {
7337     m_TopMargin = 51;
7338     m_LeftMargin = 142;
7339     if (unique_id == 0x80000269) {
7340       m_TopMargin = 100;
7341       m_LeftMargin = 126;
7342       m_Height -= 2;
7343       adobe_coeff ("Canon","EOS-1D X");
7344     }
7345     if (unique_id == 0x80000270)
7346       adobe_coeff ("Canon","EOS 550D");
7347     if (unique_id == 0x80000286)
7348       adobe_coeff ("Canon","EOS 600D");
7349     goto canon_cr2;
7350   } else if (l_IsCanon && m_RawWidth == 5360) {
7351     m_TopMargin = 51;
7352     m_LeftMargin = 158;
7353     goto canon_cr2;
7354   } else if (l_IsCanon && m_RawWidth == 5568) {
7355     m_TopMargin = 38;
7356     m_LeftMargin = 72;
7357     goto canon_cr2;
7358   } else if (l_IsCanon && m_RawWidth == 5712) {
7359     m_Height = 3752;
7360     m_Width  = 5640;
7361     m_TopMargin  = 20;
7362     m_LeftMargin = 62;
7363   } else if (l_IsCanon && m_RawWidth == 5792) {
7364     m_TopMargin  = 51;
7365     m_LeftMargin = 158;
7366 canon_cr2:
7367     m_Height -= m_TopMargin;
7368     m_Width  -= m_LeftMargin;
7369   } else if (l_IsCanon && m_RawWidth == 5920) {
7370     m_Height = 3870;
7371     m_Width  = 5796;
7372     m_TopMargin  = 80;
7373     m_LeftMargin = 122;
7374   } else if (!strcmp(m_CameraModel,"D1")) {
7375     ASSIGN(m_CameraMultipliers[0],VALUE(m_CameraMultipliers[0]) * 256/527.0);
7376     ASSIGN(m_CameraMultipliers[2],VALUE(m_CameraMultipliers[2]) * 256/317.0);
7377   } else if (!strcmp(m_CameraModel,"D1X")) {
7378     m_Width -= 4;
7379     m_PixelAspect = 0.5;
7380   } else if (!strcmp(m_CameraModel,"D40X") ||
7381        !strcmp(m_CameraModel,"D60")  ||
7382        !strcmp(m_CameraModel,"D80")  ||
7383        !strcmp(m_CameraModel,"D3000")) {
7384     m_Height -= 3;
7385     m_Width  -= 4;
7386   } else if (!strcmp(m_CameraModel,"D3")   ||
7387        !strcmp(m_CameraModel,"D3S") ||
7388        !strcmp(m_CameraModel,"D700")) {
7389     m_Width -= 4;
7390     m_LeftMargin = 2;
7391   } else if (!strcmp(m_CameraModel,"D3100")) {
7392     m_Width -= 28;
7393     m_LeftMargin = 6;
7394   } else if (!strcmp(m_CameraModel,"D5000") ||
7395        !strcmp(m_CameraModel,"D90")) {
7396     m_Width -= 42;
7397   } else if (!strcmp(m_CameraModel,"D5100") ||
7398        !strcmp(m_CameraModel,"D7000")) {
7399     m_Width -= 44;
7400   } else if (!strcmp(m_CameraModel,"D3200") ||
7401 	     !strcmp(m_CameraModel,"D600")  ||
7402        !strcmp(m_CameraModel,"D800")) {
7403     m_Width -= 46;
7404   } else if (!strcmp(m_CameraModel,"D4")) {
7405     m_Width -= 52;
7406     m_LeftMargin = 2;
7407   } else if (!strncmp(m_CameraModel,"D40",3) ||
7408        !strncmp(m_CameraModel,"D50",3) ||
7409        !strncmp(m_CameraModel,"D70",3)) {
7410     m_Width--;
7411   } else if (!strcmp(m_CameraModel,"D100")) {
7412     if (m_Load_Flags)
7413       m_RawWidth = (m_Width += 3) + 3;
7414   } else if (!strcmp(m_CameraModel,"D200")) {
7415     m_LeftMargin = 1;
7416     m_Width -= 4;
7417     m_Filters = 0x94949494;
7418   } else if (!strncmp(m_CameraModel,"D2H",3)) {
7419     m_LeftMargin = 6;
7420     m_Width -= 14;
7421   } else if (!strncmp(m_CameraModel,"D2X",3)) {
7422     if (m_Width == 3264) m_Width -= 32;
7423     else m_Width -= 8;
7424   } else if (!strncmp(m_CameraModel,"D300",4)) {
7425     m_Width -= 32;
7426   } else if (!strcmp(m_CameraMake,"NIKON") && m_RawWidth == 4032) {
7427     adobe_coeff ("NIKON","COOLPIX P7700");
7428   } else if (!strncmp(m_CameraModel,"COOLPIX P",9)) {
7429     m_Load_Flags = 24;
7430     m_Filters = 0x94949494;
7431     if (m_CameraModel[9] == '7' && m_IsoSpeed >= 400)
7432       m_BlackLevel = 255;
7433   } else if (!strncmp(m_CameraModel,"1 ",2)) {
7434     m_Height -= 2;
7435   } else if (l_FileSize == 1581060) {
7436     m_Height = 963;
7437     m_Width = 1287;
7438     m_RawWidth = 1632;
7439     m_WhiteLevel = 0x3f4;
7440     m_Colors = 4;
7441     m_Filters = 0x1e1e1e1e;
7442     simple_coeff(3);
7443     ASSIGN(m_D65Multipliers[0], 1.2085);
7444     ASSIGN(m_D65Multipliers[1], 1.0943);
7445     ASSIGN(m_D65Multipliers[3], 1.1103);
7446     goto e900;
7447   } else if (l_FileSize == 2465792) {
7448     m_Height = 1203;
7449     m_Width  = 1616;
7450     m_RawWidth = 2048;
7451     m_Colors = 4;
7452     m_Filters = 0x4b4b4b4b;
7453     adobe_coeff ("NIKON","E950");
7454 e900:
7455     m_Tiff_bps = 10;
7456     m_LoadRawFunction = &CLASS packed_load_raw;
7457     m_Load_Flags = 6;
7458   } else if (l_FileSize == 4771840) {
7459     m_Height = 1540;
7460     m_Width  = 2064;
7461     m_Colors = 4;
7462     m_Filters = 0xe1e1e1e1;
7463     m_LoadRawFunction = &CLASS packed_load_raw;
7464     m_Load_Flags = 6;
7465     if (!m_TimeStamp && nikon_e995())
7466       strcpy (m_CameraModel, "E995");
7467     if (strcmp(m_CameraModel,"E995")) {
7468       m_Filters = 0xb4b4b4b4;
7469       simple_coeff(3);
7470       ASSIGN(m_D65Multipliers[0], 1.196);
7471       ASSIGN(m_D65Multipliers[1], 1.246);
7472       ASSIGN(m_D65Multipliers[2], 1.018);
7473     }
7474   } else if (!strcmp(m_CameraModel,"E2100")) {
7475     if (!m_TimeStamp && !nikon_e2100()) goto cp_e2500;
7476     m_Height = 1206;
7477     m_Width  = 1616;
7478     m_Load_Flags = 30;
7479   } else if (!strcmp(m_CameraModel,"E2500")) {
7480 cp_e2500:
7481     strcpy (m_CameraModel, "E2500");
7482     m_Height = 1204;
7483     m_Width  = 1616;
7484     m_Colors = 4;
7485     m_Filters = 0x4b4b4b4b;
7486   } else if (l_FileSize == 4775936) {
7487     m_Height = 1542;
7488     m_Width  = 2064;
7489     m_LoadRawFunction = &CLASS packed_load_raw;
7490     m_Load_Flags = 30;
7491     if (!m_TimeStamp) nikon_3700();
7492     if (m_CameraModel[0] == 'E' && atoi(m_CameraModel+1) < 3700)
7493       m_Filters = 0x49494949;
7494     if (!strcmp(m_CameraModel,"Optio 33WR")) {
7495       m_Flip = 1;
7496       m_Filters = 0x16161616;
7497     }
7498      if (m_CameraMake[0] == 'O') {
7499       int li = find_green (12, 32, 1188864, 3576832);
7500       int lc = find_green (12, 32, 2383920, 2387016);
7501       if (abs(li) < abs(lc)) {
7502   SWAP(li,lc);
7503   m_Load_Flags = 24;
7504       }
7505       if (li < 0) m_Filters = 0x61616161;
7506     }
7507   } else if (l_FileSize == 5869568) {
7508     m_Height = 1710;
7509     m_Width  = 2288;
7510     m_Filters = 0x16161616;
7511     if (!m_TimeStamp && minolta_z2()) {
7512       strcpy (m_CameraMake, "Minolta");
7513       strcpy (m_CameraModel,"DiMAGE Z2");
7514     }
7515     m_LoadRawFunction = &CLASS packed_load_raw;
7516     m_Load_Flags = 6 + 24 * (m_CameraMake[0] == 'M');
7517   } else if (!strcmp(m_CameraModel,"E4500")) {
7518     m_Height = 1708;
7519     m_Width  = 2288;
7520     m_Colors = 4;
7521     m_Filters = 0xb4b4b4b4;
7522   } else if (l_FileSize == 7438336) {
7523     m_Height = 1924;
7524     m_Width  = 2576;
7525     m_Colors = 4;
7526     m_Filters = 0xb4b4b4b4;
7527   } else if (l_FileSize == 8998912) {
7528     m_Height = 2118;
7529     m_Width  = 2832;
7530     m_WhiteLevel = 0xf83;
7531     m_LoadRawFunction = &CLASS packed_load_raw;
7532     m_Load_Flags = 30;
7533  } else if (!strcmp(m_CameraMake,"FUJIFILM")) {
7534     if (!strcmp(m_CameraModel+7,"S2Pro")) {
7535       strcpy (m_CameraModel,"S2Pro");
7536       m_Height = 2144;
7537       m_Width  = 2880;
7538       m_Flip = 6;
7539     } else if (m_LoadRawFunction != &CLASS packed_load_raw)
7540       m_WhiteLevel = (m_IsRaw == 2 && m_UserSetting_ShotSelect) ? 0x2f00 : 0x3e00;
7541     m_TopMargin = (m_RawHeight - m_Height) >> 2 << 1;
7542     m_LeftMargin = (m_RawWidth - m_Width ) >> 2 << 1;
7543     if (m_Width == 2848) m_Filters = 0x16161616;
7544     if (m_Width == 3328) {
7545       m_Width = 3262;
7546       m_LeftMargin = 34;
7547     }
7548     if (m_Width == 4952) {
7549       m_LeftMargin = 0;
7550       m_Filters = 2;
7551     }
7552     if (fuji_layout) m_RawWidth *= m_IsRaw;
7553   } else if (!strcmp(m_CameraModel,"RD175")) {
7554     m_Height = 986;
7555     m_Width = 1534;
7556     m_Data_Offset = 513;
7557     m_Filters = 0x61616161;
7558     m_LoadRawFunction = &CLASS minolta_rd175_load_raw;
7559   } else if (!strcmp(m_CameraModel,"KD-400Z")) {
7560     m_Height = 1712;
7561     m_Width  = 2312;
7562     m_RawWidth = 2336;
7563     goto konica_400z;
7564   } else if (!strcmp(m_CameraModel,"KD-510Z")) {
7565     goto konica_510z;
7566   } else if (!strcasecmp(m_CameraMake,"MINOLTA")) {
7567     m_LoadRawFunction = &CLASS unpacked_load_raw;
7568     m_WhiteLevel = 0xfff;
7569     if (!strncmp(m_CameraModel,"DiMAGE A",8)) {
7570       if (!strcmp(m_CameraModel,"DiMAGE A200"))
7571   m_Filters = 0x49494949;
7572       m_Tiff_bps = 12;
7573       m_LoadRawFunction = &CLASS packed_load_raw;
7574     } else if (!strncmp(m_CameraModel,"ALPHA",5) ||
7575          !strncmp(m_CameraModel,"DYNAX",5) ||
7576          !strncmp(m_CameraModel,"MAXXUM",6)) {
7577       sprintf (m_CameraModel+20, "DYNAX %-10s", m_CameraModel+6+(m_CameraModel[0]=='M'));
7578       adobe_coeff (m_CameraMake, m_CameraModel+20);
7579       m_LoadRawFunction = &CLASS packed_load_raw;
7580     } else if (!strncmp(m_CameraModel,"DiMAGE G",8)) {
7581       if (m_CameraModel[8] == '4') {
7582   m_Height = 1716;
7583   m_Width  = 2304;
7584       } else if (m_CameraModel[8] == '5') {
7585 konica_510z:
7586   m_Height = 1956;
7587   m_Width  = 2607;
7588   m_RawWidth = 2624;
7589       } else if (m_CameraModel[8] == '6') {
7590   m_Height = 2136;
7591   m_Width  = 2848;
7592       }
7593       m_Data_Offset += 14;
7594       m_Filters = 0x61616161;
7595 konica_400z:
7596       m_LoadRawFunction = &CLASS unpacked_load_raw;
7597       m_WhiteLevel = 0x3df;
7598       m_ByteOrder = 0x4d4d;
7599     }
7600   } else if (!strcmp(m_CameraModel,"*ist D")) {
7601     m_LoadRawFunction = &CLASS unpacked_load_raw;
7602     data_error = -1;
7603   } else if (!strcmp(m_CameraModel,"*ist DS")) {
7604     m_Height -= 2;
7605   } else if (!strcmp(m_CameraModel,"K-x")) {
7606     m_Width = 4309;
7607     m_Filters = 0x16161616;
7608   } else if (!strcmp(m_CameraModel,"Optio S")) {
7609     if (l_FileSize == 3178560) {
7610       m_Height = 1540;
7611       m_Width  = 2064;
7612       m_LoadRawFunction = &CLASS eight_bit_load_raw;
7613       ASSIGN(m_CameraMultipliers[0],VALUE(m_CameraMultipliers[0]) * 4);
7614       ASSIGN(m_CameraMultipliers[2],VALUE(m_CameraMultipliers[2]) * 4);
7615     } else {
7616       m_Height = 1544;
7617       m_Width  = 2068;
7618       m_RawWidth = 3136;
7619       m_LoadRawFunction = &CLASS packed_load_raw;
7620       m_WhiteLevel = 0xf7c;
7621     }
7622   } else if (l_FileSize == 6114240) {
7623     m_Height = 1737;
7624     m_Width  = 2324;
7625     m_RawWidth = 3520;
7626     m_LoadRawFunction = &CLASS packed_load_raw;
7627     m_WhiteLevel = 0xf7a;
7628   } else if (!strcmp(m_CameraModel,"Optio 750Z")) {
7629     m_Height = 2302;
7630     m_Width  = 3072;
7631     m_LoadRawFunction = &CLASS packed_load_raw;
7632     m_Load_Flags = 30;
7633   } else if (!strcmp(m_CameraModel,"DC-833m")) {
7634     m_Height = 2448;
7635     m_Width  = 3264;
7636     m_ByteOrder = 0x4949;
7637     m_Filters = 0x61616161;
7638     m_LoadRawFunction = &CLASS unpacked_load_raw;
7639     m_WhiteLevel = 0xfc00;
7640   } else if (!strncmp(m_CameraModel,"S85",3)) {
7641     m_Height = 2448;
7642     m_Width  = 3264;
7643     m_RawWidth = l_FileSize/m_Height/2;
7644     m_ByteOrder = 0x4d4d;
7645     m_LoadRawFunction = &CLASS unpacked_load_raw;
7646   } else if (!strcmp(m_CameraMake,"SAMSUNG") && m_RawWidth == 4704) {
7647     m_Height -= m_TopMargin = 8;
7648     m_Width -= 2 * (m_LeftMargin = 8);
7649     m_Load_Flags = 32;
7650   } else if (!strcmp(m_CameraMake,"SAMSUNG") && m_RawWidth == 5632) {
7651     m_ByteOrder = 0x4949;
7652     m_Height = 3694;
7653     m_TopMargin = 2;
7654     m_Width  = 5574 - (m_LeftMargin = 32 + m_Tiff_bps);
7655     if (m_Tiff_bps == 12) m_Load_Flags = 80;
7656   } else if (!strcmp(m_CameraModel,"EX1")) {
7657     m_ByteOrder = 0x4949;
7658     m_Height -= 20;
7659     m_TopMargin = 2;
7660     if ((m_Width -= 6) > 3682) {
7661       m_Height -= 10;
7662       m_Width  -= 46;
7663       m_TopMargin = 8;
7664     }
7665   } else if (!strcmp(m_CameraModel,"WB2000")) {
7666     m_ByteOrder = 0x4949;
7667     m_Height -= 3;
7668     m_TopMargin = 2;
7669     if ((m_Width -= 10) > 3718) {
7670       m_Height -= 28;
7671       m_Width  -= 56;
7672       m_TopMargin = 8;
7673     }
7674   } else if (l_FileSize == 20487168) {
7675     m_Height = 2808;
7676     m_Width  = 3648;
7677     goto wb550;
7678   } else if (l_FileSize == 24000000) {
7679     m_Height = 3000;
7680     m_Width  = 4000;
7681 wb550:
7682     strcpy (m_CameraModel, "WB550");
7683     m_ByteOrder = 0x4d4d;
7684     m_LoadRawFunction = &CLASS unpacked_load_raw;
7685     m_Load_Flags = 6;
7686     m_WhiteLevel = 0x3df;
7687   } else if (!strcmp(m_CameraModel,"EX2F")) {
7688     m_Height = 3045;
7689     m_Width  = 4070;
7690     m_TopMargin = 3;
7691     m_ByteOrder = 0x4949;
7692     m_Filters = 0x49494949;
7693     m_LoadRawFunction = &CLASS unpacked_load_raw;
7694   } else if (!strcmp(m_CameraModel,"STV680 VGA")) {
7695     m_Height = 484;
7696     m_Width  = 644;
7697     m_LoadRawFunction = &CLASS eight_bit_load_raw;
7698     m_Flip = 2;
7699     m_Filters = 0x16161616;
7700     m_BlackLevel = 16;
7701   } else if (!strcmp(m_CameraModel,"N95")) {
7702     m_TopMargin = 2;
7703     m_Height = m_RawHeight - m_TopMargin;
7704   } else if (!strcmp(m_CameraModel,"531C")) {
7705     m_Height = 1200;
7706     m_Width  = 1600;
7707     m_LoadRawFunction = &CLASS unpacked_load_raw;
7708     m_Filters = 0x49494949;
7709   } else if (!strcmp(m_CameraModel,"640x480")) {
7710     m_Height = 480;
7711     m_Width  = 640;
7712     m_LoadRawFunction = &CLASS eight_bit_load_raw;
7713     gamma_curve (0.45, 4.5, 1, 255);
7714   } else if (!strcmp(m_CameraModel,"F-080C")) {
7715     m_Height = 768;
7716     m_Width  = 1024;
7717     m_LoadRawFunction = &CLASS eight_bit_load_raw;
7718   } else if (!strcmp(m_CameraModel,"F-145C")) {
7719     m_Height = 1040;
7720     m_Width  = 1392;
7721     m_LoadRawFunction = &CLASS eight_bit_load_raw;
7722   } else if (!strcmp(m_CameraModel,"F-201C")) {
7723     m_Height = 1200;
7724     m_Width  = 1600;
7725     m_LoadRawFunction = &CLASS eight_bit_load_raw;
7726   } else if (!strcmp(m_CameraModel,"F-510C")) {
7727     m_Height = 1958;
7728     m_Width  = 2588;
7729     m_LoadRawFunction = l_FileSize < 7500000 ?
7730   &CLASS eight_bit_load_raw : &CLASS unpacked_load_raw;
7731     m_Data_Offset = l_FileSize - m_Width*m_Height*(l_FileSize >> 22);
7732     m_WhiteLevel = 0xfff0;
7733   } else if (!strcmp(m_CameraModel,"F-810C")) {
7734     m_Height = 2469;
7735     m_Width  = 3272;
7736     m_LoadRawFunction = &CLASS unpacked_load_raw;
7737     m_WhiteLevel = 0xfff0;
7738   } else if (!strcmp(m_CameraModel,"XCD-SX910CR")) {
7739     m_Height = 1024;
7740     m_Width  = 1375;
7741     m_RawWidth = 1376;
7742     m_Filters = 0x49494949;
7743     m_WhiteLevel = 0x3ff;
7744     m_LoadRawFunction = l_FileSize < 2000000 ?
7745   &CLASS eight_bit_load_raw : &CLASS unpacked_load_raw;
7746   } else if (!strcmp(m_CameraModel,"2010")) {
7747     m_Height = 1207;
7748     m_Width  = 1608;
7749     m_ByteOrder = 0x4949;
7750     m_Filters = 0x16161616;
7751     m_Data_Offset = 3212;
7752     m_WhiteLevel = 0x3ff;
7753     m_LoadRawFunction = &CLASS unpacked_load_raw;
7754   } else if (!strcmp(m_CameraModel,"A782")) {
7755     m_Height = 3000;
7756     m_Width  = 2208;
7757     m_Filters = 0x61616161;
7758     m_LoadRawFunction = l_FileSize < 10000000 ?
7759   &CLASS eight_bit_load_raw : &CLASS unpacked_load_raw;
7760     m_WhiteLevel = 0xffc0;
7761   } else if (!strcmp(m_CameraModel,"3320AF")) {
7762     m_Height = 1536;
7763     m_RawWidth = m_Width = 2048;
7764     m_Filters = 0x61616161;
7765     m_LoadRawFunction = &CLASS unpacked_load_raw;
7766     m_WhiteLevel = 0x3ff;
7767     fseek (m_InputFile, 0x300000, SEEK_SET);
7768     if ((m_ByteOrder = guess_byte_order(0x10000)) == 0x4d4d) {
7769       m_Height -= (m_TopMargin = 16);
7770       m_Width -= (m_LeftMargin = 28);
7771       m_WhiteLevel = 0xf5c0;
7772       strcpy (m_CameraMake, "ISG");
7773       m_CameraModel[0] = 0;
7774     }
7775   } else if (!strcmp(m_CameraMake,"Hasselblad")) {
7776     if (m_LoadRawFunction == &CLASS lossless_jpeg_load_raw)
7777       m_LoadRawFunction = &CLASS hasselblad_load_raw;
7778     if (m_RawWidth == 7262) {
7779       m_Height = 5444;
7780       m_Width  = 7248;
7781       m_TopMargin  = 4;
7782       m_LeftMargin = 7;
7783       m_Filters = 0x61616161;
7784     } else if (m_RawWidth == 7410) {
7785       m_Height = 5502;
7786       m_Width  = 7328;
7787       m_TopMargin  = 4;
7788       m_LeftMargin = 41;
7789       m_Filters = 0x61616161;
7790     } else if (m_RawWidth == 9044) {
7791       m_Height = 6716;
7792       m_Width  = 8964;
7793       m_TopMargin  = 8;
7794       m_LeftMargin = 40;
7795       m_BlackLevel += m_Load_Flags = 256;
7796       m_WhiteLevel = 0x8101;
7797     } else if (m_RawWidth == 4090) {
7798       strcpy (m_CameraModel, "V96C");
7799       m_Height -= (m_TopMargin = 6);
7800       m_Width -= (m_LeftMargin = 3) + 7;
7801       m_Filters = 0x61616161;
7802     }
7803   } else if (!strcmp(m_CameraMake,"Sinar")) {
7804     if (!memcmp(l_Head,"8BPS",4)) {
7805       fseek (m_InputFile, 14, SEEK_SET);
7806       m_Height = get4();
7807       m_Width  = get4();
7808       m_Filters = 0x61616161;
7809       m_Data_Offset = 68;
7810     }
7811     if (!m_LoadRawFunction) m_LoadRawFunction = &CLASS unpacked_load_raw;
7812     m_WhiteLevel = 0x3fff;
7813   } else if (!strcmp(m_CameraMake,"Leaf")) {
7814     m_WhiteLevel = 0x3fff;
7815     fseek (m_InputFile, m_Data_Offset, SEEK_SET);
7816     if (ljpeg_start (&l_JHead, 1) && l_JHead.bits == 15)
7817       m_WhiteLevel = 0x1fff;
7818     if (m_Tiff_Samples > 1) m_Filters = 0;
7819     if (m_Tiff_Samples > 1 || m_TileLength < m_RawHeight) {
7820       m_LoadRawFunction = &CLASS leaf_hdr_load_raw;
7821       m_RawWidth = m_TileWidth;
7822     }
7823     if ((m_Width | m_Height) == 2048) {
7824       if (m_Tiff_Samples == 1) {
7825   m_Filters = 1;
7826   strcpy (m_ColorDescriptor, "RBTG");
7827   strcpy (m_CameraModel, "CatchLight");
7828   m_TopMargin =  8; m_LeftMargin = 18; m_Height = 2032; m_Width = 2016;
7829       } else {
7830   strcpy (m_CameraModel, "DCB2");
7831   m_TopMargin = 10; m_LeftMargin = 16; m_Height = 2028; m_Width = 2022;
7832       }
7833     } else if (m_Width+m_Height == 3144+2060) {
7834       if (!m_CameraModel[0]) strcpy (m_CameraModel, "Cantare");
7835       if (m_Width > m_Height) {
7836    m_TopMargin = 6; m_LeftMargin = 32; m_Height = 2048;  m_Width = 3072;
7837   m_Filters = 0x61616161;
7838       } else {
7839   m_LeftMargin = 6;  m_TopMargin = 32;  m_Width = 2048; m_Height = 3072;
7840   m_Filters = 0x16161616;
7841       }
7842       if (!VALUE(m_CameraMultipliers[0]) || m_CameraModel[0] == 'V') m_Filters = 0;
7843       else m_IsRaw = m_Tiff_Samples;
7844     } else if (m_Width == 2116) {
7845       strcpy (m_CameraModel, "Valeo 6");
7846       m_Height -= 2 * (m_TopMargin = 30);
7847       m_Width -= 2 * (m_LeftMargin = 55);
7848       m_Filters = 0x49494949;
7849     } else if (m_Width == 3171) {
7850       strcpy (m_CameraModel, "Valeo 6");
7851       m_Height -= 2 * (m_TopMargin = 24);
7852       m_Width -= 2 * (m_LeftMargin = 24);
7853       m_Filters = 0x16161616;
7854     }
7855   } else if (!strcmp(m_CameraMake,"LEICA") || !strcmp(m_CameraMake,"Panasonic")) {
7856     if ((l_FLen-m_Data_Offset) / (m_RawWidth*8/7) == m_RawHeight)
7857       m_LoadRawFunction = &CLASS panasonic_load_raw;
7858     if (!m_LoadRawFunction) {
7859       m_LoadRawFunction = &CLASS unpacked_load_raw;
7860       m_Load_Flags = 4;
7861     }
7862     m_ZeroIsBad = 1;
7863     if ((m_Height += 12) > m_RawHeight) m_Height = m_RawHeight;
7864     for (i=0; i < sizeof pana / sizeof *pana; i++)
7865       if (m_RawWidth == pana[i][0] && m_RawHeight == pana[i][1]) {
7866         m_LeftMargin = pana[i][2];
7867         m_TopMargin = pana[i][3];
7868         m_Width += pana[i][4];
7869         m_Height += pana[i][5];
7870       }
7871     m_Filters = 0x01010101 * (unsigned char) "\x94\x61\x49\x16"
7872       [((m_Filters-1) ^ (m_LeftMargin & 1) ^ (m_TopMargin << 1)) & 3];
7873   } else if (!strcmp(m_CameraModel,"C770UZ")) {
7874     m_Height = 1718;
7875     m_Width  = 2304;
7876     m_Filters = 0x16161616;
7877     m_LoadRawFunction = &CLASS packed_load_raw;
7878     m_Load_Flags = 30;
7879   } else if (!strcmp(m_CameraMake,"OLYMPUS")) {
7880     m_Height += m_Height & 1;
7881     m_Filters = exif_cfa;
7882     if (m_Width == 4100) m_Width -= 4;
7883     if (m_Width == 4080) m_Width -= 24;
7884     if (m_LoadRawFunction == &CLASS unpacked_load_raw)
7885       m_Load_Flags = 4;
7886     m_Tiff_bps = 12;
7887     if (!strcmp(m_CameraModel,"E-300") ||
7888       !strcmp(m_CameraModel,"E-500")) {
7889       m_Width -= 20;
7890       if (m_LoadRawFunction == &CLASS unpacked_load_raw) {
7891   m_WhiteLevel = 0xfc3;
7892   memset (m_CBlackLevel, 0, sizeof m_CBlackLevel);
7893       }
7894     } else if (!strcmp(m_CameraModel,"E-330")) {
7895       m_Width -= 30;
7896       if (m_LoadRawFunction == &CLASS unpacked_load_raw)
7897   m_WhiteLevel = 0xf79;
7898     } else if (!strcmp(m_CameraModel,"SP550UZ")) {
7899       m_ThumbLength = l_FLen - (m_ThumbOffset = 0xa39800);
7900       m_ThumbHeight = 480;
7901       m_ThumbWidth  = 640;
7902     } else if (!strcmp(m_CameraModel,"XZ-2")) {
7903       m_LoadRawFunction = &CLASS packed_load_raw;
7904       m_Load_Flags = 24;
7905     }
7906   } else if (!strcmp(m_CameraModel,"N Digital")) {
7907     m_Height = 2047;
7908     m_Width  = 3072;
7909     m_Filters = 0x61616161;
7910     m_Data_Offset = 0x1a00;
7911     m_LoadRawFunction = &CLASS packed_load_raw;
7912   } else if (!strcmp(m_CameraModel,"DSC-F828")) {
7913     m_Width = 3288;
7914     m_LeftMargin = 5;
7915     m_Mask[1][3] = -17;
7916     m_Data_Offset = 862144;
7917     m_LoadRawFunction = &CLASS sony_load_raw;
7918     m_Filters = 0x9c9c9c9c;
7919     m_Colors = 4;
7920     strcpy (m_ColorDescriptor, "RGBE");
7921   } else if (!strcmp(m_CameraModel,"DSC-V3")) {
7922     m_Width = 3109;
7923     m_LeftMargin = 59;
7924     m_Mask[0][1] = 9;
7925     m_Data_Offset = 787392;
7926     m_LoadRawFunction = &CLASS sony_load_raw;
7927   } else if (!strcmp(m_CameraMake,"SONY") && m_RawWidth == 3984) {
7928     adobe_coeff ("SONY","DSC-R1");
7929     m_Width = 3925;
7930     m_ByteOrder = 0x4d4d;
7931   } else if (!strcmp(m_CameraMake,"SONY") && m_RawWidth == 5504) {
7932     m_Width -= 8;
7933   } else if (!strcmp(m_CameraMake,"SONY") && m_RawWidth == 6048) {
7934     m_Width -= 24;
7935   } else if (!strcmp(m_CameraModel,"DSLR-A100")) {
7936     if (m_Width == 3880) {
7937       m_Height--;
7938       m_Width = ++m_RawWidth;
7939     } else {
7940       m_ByteOrder = 0x4d4d;
7941       m_Load_Flags = 2;
7942     }
7943     m_Filters = 0x61616161;
7944   } else if (!strcmp(m_CameraModel,"DSLR-A350")) {
7945     m_Height -= 4;
7946   } else if (!strcmp(m_CameraModel,"PIXL")) {
7947     m_Height -= m_TopMargin = 4;
7948     m_Width -= m_LeftMargin = 32;
7949     gamma_curve (0, 7, 1, 255);
7950   } else if (!strcmp(m_CameraModel,"C603v")) {
7951     m_Height = 480;
7952     m_Width  = 640;
7953     if (l_FileSize < 614400 || find_green (16, 16, 3840, 5120) < 25) goto c603v;
7954     strcpy (m_CameraModel,"KAI-0340");
7955     m_Height -= 3;
7956     m_Data_Offset = 3840;
7957     m_ByteOrder = 0x4949;
7958     m_LoadRawFunction = &CLASS unpacked_load_raw;
7959   } else if (!strcmp(m_CameraModel,"C603y")) {
7960     m_Height = 2134;
7961     m_Width  = 2848;
7962 c603v:
7963     m_Filters = 0;
7964     m_LoadRawFunction = &CLASS kodak_yrgb_load_raw;
7965     gamma_curve (0, 3.875, 1, 255);
7966   } else if (!strcmp(m_CameraModel,"C603")) {
7967     m_RawHeight = m_Height = 2152;
7968     m_RawWidth  = m_Width  = 2864;
7969     goto c603;
7970   } else if (!strcmp(m_CameraModel,"C330")) {
7971     m_Height = 1744;
7972     m_Width  = 2336;
7973     m_RawHeight = 1779;
7974     m_RawWidth  = 2338;
7975     m_TopMargin = 33;
7976     m_LeftMargin = 1;
7977 c603:
7978     m_ByteOrder = 0x4949;
7979     if ((m_Data_Offset = l_FileSize - m_RawHeight*m_RawWidth)) {
7980       fseek (m_InputFile, 168, SEEK_SET);
7981       read_shorts (m_Curve, 256);
7982     } else gamma_curve (0, 3.875, 1, 255);
7983     m_LoadRawFunction = &CLASS eight_bit_load_raw;
7984   } else if (!strncasecmp(m_CameraMake,"EasyShare",9)) {
7985     m_Data_Offset = m_Data_Offset < 0x15000 ? 0x15000 : 0x17000;
7986     m_LoadRawFunction = &CLASS packed_load_raw;
7987   } else if (!strcasecmp(m_CameraMake,"KODAK")) {
7988     if (m_Filters == UINT_MAX) m_Filters = 0x61616161;
7989     if (!strncmp(m_CameraModel,"NC2000",6)) {
7990       m_Width -= 4;
7991       m_LeftMargin = 2;
7992     } else if (!strcmp(m_CameraModel,"EOSDCS3B")) {
7993       m_Width -= 4;
7994       m_LeftMargin = 2;
7995     } else if (!strcmp(m_CameraModel,"EOSDCS1")) {
7996       m_Width -= 4;
7997       m_LeftMargin = 2;
7998     } else if (!strcmp(m_CameraModel,"DCS420")) {
7999       m_Width -= 4;
8000       m_LeftMargin = 2;
8001     } else if (!strncmp(m_CameraModel,"DCS460",7)) {
8002       m_CameraModel[6]=0;
8003       m_Width -= 4;
8004       m_LeftMargin = 2;
8005     } else if (!strcmp(m_CameraModel,"DCS460A")) {
8006       m_Width -= 4;
8007       m_LeftMargin = 2;
8008       m_Colors = 1;
8009       m_Filters = 0;
8010     } else if (!strcmp(m_CameraModel,"DCS660M")) {
8011       m_BlackLevel = 214;
8012       m_Colors = 1;
8013       m_Filters = 0;
8014     } else if (!strcmp(m_CameraModel,"DCS760M")) {
8015       m_Colors = 1;
8016       m_Filters = 0;
8017     }
8018     if (!strcmp(m_CameraModel+4,"20X"))
8019       strcpy (m_ColorDescriptor, "MYCY");
8020     if (strstr(m_CameraModel,"DC25")) {
8021       strcpy (m_CameraModel, "DC25");
8022       m_Data_Offset = 15424;
8023     }
8024     if (!strncmp(m_CameraModel,"DC2",3)) {
8025       m_RawHeight = m_Height = 242;
8026       if (l_FLen < 100000) {
8027   m_RawWidth = 256; m_Width = 249;
8028   m_PixelAspect = (4.0*m_Height) / (3.0*m_Width);
8029       } else {
8030   m_RawWidth = 512; m_Width = 501;
8031   m_PixelAspect = (493.0*m_Height) / (373.0*m_Width);
8032       }
8033       m_Data_Offset += m_RawWidth + 1;
8034       m_Colors = 4;
8035       m_Filters = 0x8d8d8d8d;
8036       simple_coeff(1);
8037       ASSIGN(m_D65Multipliers[1], 1.179);
8038       ASSIGN(m_D65Multipliers[2], 1.209);
8039       ASSIGN(m_D65Multipliers[3], 1.036);
8040       m_LoadRawFunction = &CLASS eight_bit_load_raw;
8041     } else if (!strcmp(m_CameraModel,"40")) {
8042       strcpy (m_CameraModel, "DC40");
8043       m_Height = 512;
8044       m_Width  = 768;
8045       m_Data_Offset = 1152;
8046       m_LoadRawFunction = &CLASS kodak_radc_load_raw;
8047     } else if (strstr(m_CameraModel,"DC50")) {
8048       strcpy (m_CameraModel, "DC50");
8049       m_Height = 512;
8050       m_Width  = 768;
8051       m_Data_Offset = 19712;
8052       m_LoadRawFunction = &CLASS kodak_radc_load_raw;
8053     } else if (strstr(m_CameraModel,"DC120")) {
8054       strcpy (m_CameraModel, "DC120");
8055       m_Height = 976;
8056       m_Width  = 848;
8057       m_PixelAspect = m_Height/0.75/m_Width;
8058       m_LoadRawFunction = m_Tiff_Compress == 7 ?
8059   &CLASS kodak_jpeg_load_raw : &CLASS kodak_dc120_load_raw;
8060     } else if (!strcmp(m_CameraModel,"DCS200")) {
8061       m_ThumbHeight = 128;
8062       m_ThumbWidth  = 192;
8063       m_ThumbOffset = 6144;
8064       m_ThumbMisc   = 360;
8065       m_WriteThumb = &CLASS layer_thumb;
8066       m_Height = 1024;
8067       m_Width  = 1536;
8068       m_Data_Offset = 79872;
8069       m_LoadRawFunction = &CLASS eight_bit_load_raw;
8070       m_BlackLevel = 17;
8071     }
8072   } else if (!strcmp(m_CameraModel,"Fotoman Pixtura")) {
8073     m_Height = 512;
8074     m_Width  = 768;
8075     m_Data_Offset = 3632;
8076     m_LoadRawFunction = &CLASS kodak_radc_load_raw;
8077     m_Filters = 0x61616161;
8078     simple_coeff(2);
8079   } else if (!strncmp(m_CameraModel,"QuickTake",9)) {
8080     if (l_Head[5]) strcpy (m_CameraModel+10, "200");
8081     fseek (m_InputFile, 544, SEEK_SET);
8082     m_Height = get2();
8083     m_Width  = get2();
8084     m_Data_Offset = (get4(),get2()) == 30 ? 738:736;
8085     if (m_Height > m_Width) {
8086       SWAP(m_Height,m_Width);
8087       fseek (m_InputFile, m_Data_Offset-6, SEEK_SET);
8088       m_Flip = ~get2() & 3 ? 5:6;
8089     }
8090     m_Filters = 0x61616161;
8091   } else if (!strcmp(m_CameraMake,"Rollei") && !m_LoadRawFunction) {
8092     switch (m_RawWidth) {
8093       case 1316:
8094   m_Height = 1030;
8095   m_Width  = 1300;
8096   m_TopMargin  = 1;
8097   m_LeftMargin = 6;
8098   break;
8099       case 2568:
8100   m_Height = 1960;
8101   m_Width  = 2560;
8102   m_TopMargin  = 2;
8103   m_LeftMargin = 8;
8104     }
8105     m_Filters = 0x16161616;
8106     m_LoadRawFunction = &CLASS rollei_load_raw;
8107   } else if (!strcmp(m_CameraModel,"PC-CAM 600")) {
8108     m_Height = 768;
8109     m_Data_Offset = m_Width = 1024;
8110     m_Filters = 0x49494949;
8111     m_LoadRawFunction = &CLASS eight_bit_load_raw;
8112   } else if (!strcmp(m_CameraModel,"QV-2000UX")) {
8113     m_Height = 1208;
8114     m_Width  = 1632;
8115     m_Data_Offset = m_Width * 2;
8116     m_LoadRawFunction = &CLASS eight_bit_load_raw;
8117   } else if (l_FileSize == 3217760) {
8118     m_Height = 1546;
8119     m_Width  = 2070;
8120     m_RawWidth = 2080;
8121     m_LoadRawFunction = &CLASS eight_bit_load_raw;
8122   } else if (!strcmp(m_CameraModel,"QV-4000")) {
8123     m_Height = 1700;
8124     m_Width  = 2260;
8125     m_LoadRawFunction = &CLASS unpacked_load_raw;
8126     m_WhiteLevel = 0xffff;
8127   } else if (!strcmp(m_CameraModel,"QV-5700")) {
8128     m_Height = 1924;
8129     m_Width  = 2576;
8130     m_RawWidth = 3232;
8131     m_Tiff_bps = 10;
8132   } else if (!strcmp(m_CameraModel,"QV-R41")) {
8133     m_Height = 1720;
8134     m_Width  = 2312;
8135     m_RawWidth = 3520;
8136     m_LeftMargin = 2;
8137   } else if (!strcmp(m_CameraModel,"QV-R51")) {
8138     m_Height = 1926;
8139     m_Width  = 2580;
8140     m_RawWidth = 3904;
8141   } else if (!strcmp(m_CameraModel,"EX-S20")) {
8142     m_Height = 1208;
8143     m_Width  = 1620;
8144     m_RawWidth = 2432;
8145     m_Flip = 3;
8146   } else if (!strcmp(m_CameraModel,"EX-S100")) {
8147     m_Height = 1544;
8148     m_Width  = 2058;
8149     m_RawWidth = 3136;
8150   } else if (!strcmp(m_CameraModel,"EX-Z50")) {
8151     m_Height = 1931;
8152     m_Width  = 2570;
8153     m_RawWidth = 3904;
8154   } else if (!strcmp(m_CameraModel,"EX-Z500")) {
8155     m_Height = 1937;
8156     m_Width  = 2577;
8157     m_RawWidth = 3904;
8158     m_Filters = 0x16161616;
8159   } else if (!strcmp(m_CameraModel,"EX-Z55")) {
8160     m_Height = 1960;
8161     m_Width  = 2570;
8162     m_RawWidth = 3904;
8163  } else if (!strcmp(m_CameraModel,"EX-Z60")) {
8164     m_Height = 2145;
8165     m_Width  = 2833;
8166     m_RawWidth = 3584;
8167     m_Filters = 0x16161616;
8168     m_Tiff_bps = 10;
8169   } else if (!strcmp(m_CameraModel,"EX-Z75")) {
8170     m_Height = 2321;
8171     m_Width  = 3089;
8172     m_RawWidth = 4672;
8173     m_WhiteLevel = 0xfff;
8174   } else if (!strcmp(m_CameraModel,"EX-Z750")) {
8175     m_Height = 2319;
8176     m_Width  = 3087;
8177     m_RawWidth = 4672;
8178     m_WhiteLevel = 0xfff;
8179   } else if (!strcmp(m_CameraModel,"EX-Z850")) {
8180     m_Height = 2468;
8181     m_Width  = 3279;
8182     m_RawWidth = 4928;
8183     m_WhiteLevel = 0xfff;
8184   } else if (!strcmp(m_CameraModel,"EX-Z8")) {
8185     m_Height = 2467;
8186     m_Width  = 3281;
8187     m_RawHeight = 2502;
8188     m_RawWidth  = 4992;
8189     m_WhiteLevel = 0xfff;
8190   } else if (l_FileSize == 15499264) {	/* EX-Z1050 or EX-Z1080 */
8191     m_Height = 2752;
8192     m_Width  = 3672;
8193     m_RawWidth = 5632;
8194   } else if (!strcmp(m_CameraModel,"EX-ZR100")) {
8195     m_Height = 3044;
8196     m_Width  = 4072;
8197     m_RawWidth = 4096;
8198     m_Load_Flags = 80;
8199   } else if (!strcmp(m_CameraModel,"EX-P505")) {
8200     m_Height = 1928;
8201     m_Width  = 2568;
8202     m_RawWidth = 3852;
8203     m_WhiteLevel = 0xfff;
8204   } else if (l_FileSize == 9313536) { /* EX-P600 or QV-R61 */
8205     m_Height = 2142;
8206     m_Width  = 2844;
8207     m_RawWidth = 4288;
8208   } else if (!strcmp(m_CameraModel,"EX-P700")) {
8209     m_Height = 2318;
8210     m_Width  = 3082;
8211     m_RawWidth = 4672;
8212   }
8213   if (!m_CameraModel[0])
8214     sprintf (m_CameraModel, "%dx%d", m_Width, m_Height);
8215   if (m_Filters == UINT_MAX) m_Filters = 0x94949494;
8216   if (m_RawColor) adobe_coeff (m_CameraMake, m_CameraModel);
8217   if (m_LoadRawFunction == &CLASS kodak_radc_load_raw)
8218     if (m_RawColor) adobe_coeff ("Apple","Quicktake");
8219   if (m_ThumbOffset && !m_ThumbHeight) {
8220     fseek (m_InputFile, m_ThumbOffset, SEEK_SET);
8221     if (ljpeg_start (&l_JHead, 1)) {
8222       m_ThumbWidth  = l_JHead.wide;
8223       m_ThumbHeight = l_JHead.high;
8224     }
8225   }
8226 dng_skip:
8227   if (m_Fuji_Width) {
8228     m_Fuji_Width = m_Width >> !fuji_layout;
8229     if (~m_Fuji_Width & 1) m_Filters = 0x49494949;
8230     m_Width = (m_Height >> fuji_layout) + m_Fuji_Width;
8231     m_Height = m_Width - 1;
8232     m_PixelAspect = 1;
8233   } else {
8234     if (m_RawHeight < m_Height) m_RawHeight = m_Height;
8235     if (m_RawWidth  < m_Width ) m_RawWidth  = m_Width;
8236   }
8237   if (!m_Tiff_bps) m_Tiff_bps = 12;
8238   if (!m_WhiteLevel) m_WhiteLevel = (1 << m_Tiff_bps) - 1;
8239   if (!m_LoadRawFunction || m_Height < 22) m_IsRaw = 0;
8240 #ifdef NO_JASPER
8241   if (m_LoadRawFunction == &CLASS redcine_load_raw) {
8242     fprintf (stderr,_("%s: You must link dcraw with %s!\n"),
8243         m_UserSetting_InputFileName, "libjasper");
8244     m_IsRaw = 0;
8245   }
8246 #endif
8247 #ifdef NO_JPEG
8248   if (m_LoadRawFunction == &CLASS kodak_jpeg_load_raw ||
8249       m_LoadRawFunction == &CLASS lossy_dng_load_raw) {
8250         fprintf (stderr,_("%s: You must link dcraw with %s!\n"),
8251         m_UserSetting_InputFileName, "libjpeg");
8252     m_IsRaw = 0;
8253   }
8254 #endif
8255   if (!m_ColorDescriptor[0])
8256     strcpy (m_ColorDescriptor, m_Colors == 3 ? "RGBG":"GMCY");
8257   if (!m_RawHeight) m_RawHeight = m_Height;
8258   if (!m_RawWidth ) m_RawWidth  = m_Width;
8259   if (m_Filters && m_Colors == 3)
8260     m_Filters |= ((m_Filters >> 2 & 0x22222222) |
8261       (m_Filters << 2 & 0x88888888)) & m_Filters << 1;
8262 notraw:
8263   // Somehow Nikon D90 files give a corrupt value here... although they shouldn't.
8264   if (m_Flip == -1) m_Flip = m_Tiff_Flip;
8265   if (m_Flip == -1) m_Flip = 0;
8266 }
8267 
fuji_rotate()8268 void CLASS fuji_rotate() {
8269   int i, row, col;
8270   double step;
8271   float r, c, fr, fc;
8272   unsigned ur, uc;
8273   uint16_t wide, high, (*img)[4], (*pix)[4];
8274 
8275   if (!m_Fuji_Width) return;
8276   TRACEKEYVALS("Rotating image 45 degrees","%s","");
8277   TRACEKEYVALS("m_Fuji_Width","%d",m_Fuji_Width);
8278   TRACEKEYVALS("m_Shrink","%d",m_Shrink);
8279   TRACEKEYVALS("m_UserSetting_HalfSize","%d",m_UserSetting_HalfSize);
8280   // XXX JDLA : Was : m_Fuji_Width = (m_Fuji_Width - 1 + m_Shrink) >> m_Shrink;
8281   m_Fuji_Width =
8282     (m_Fuji_Width - 1 + m_UserSetting_HalfSize) >> m_UserSetting_HalfSize;
8283   TRACEKEYVALS("m_Fuji_Width","%d",m_Fuji_Width);
8284   step = sqrt(0.5);
8285   wide = (uint16_t) (m_Fuji_Width / step);
8286   high = (uint16_t) ((m_Height - m_Fuji_Width) / step);
8287   img = (uint16_t (*)[4]) CALLOC (wide*high, sizeof *img);
8288   TRACEKEYVALS("m_Width","%d",m_Width);
8289   TRACEKEYVALS("m_Height","%d",m_Height);
8290   TRACEKEYVALS("wide","%d",wide);
8291   TRACEKEYVALS("high","%d",high);
8292   merror (img, "fuji_rotate()");
8293 
8294   for (row=0; row < high; row++)
8295     for (col=0; col < wide; col++) {
8296       ur = (unsigned) (r = m_Fuji_Width + (row-col)*step);
8297       uc = (unsigned) (c = (row+col)*step);
8298       if (ur > (unsigned)(m_Height-2) || uc > (unsigned)(m_Width-2)) continue;
8299       fr = r - ur;
8300       fc = c - uc;
8301       pix = m_Image + ur*m_Width + uc;
8302       for (i=0; i < m_Colors; i++)
8303   img[row*wide+col][i] = (uint16_t) (
8304     (pix[    0][i]*(1-fc) + pix[      1][i]*fc) * (1-fr) +
8305     (pix[m_Width][i]*(1-fc) + pix[m_Width+1][i]*fc) * fr);
8306     }
8307   FREE (m_Image);
8308   m_OutWidth  = m_Width  = wide;
8309   m_OutHeight = m_Height = high;
8310   m_Image  = img;
8311   m_Fuji_Width = 0; // this prevents image rotation when only phase 2 is called
8312 
8313   TRACEKEYVALS("m_Width","%d",m_Width);
8314   TRACEKEYVALS("m_Height","%d",m_Height);
8315   TRACEKEYVALS("m_OutWidth","%d",m_OutWidth);
8316   TRACEKEYVALS("m_OutHeight","%d",m_OutHeight);
8317 }
8318 
stretch()8319 void CLASS stretch()
8320 {
8321   uint16_t newdim, (*img)[4], *pix0, *pix1;
8322   int row, col, c;
8323   double rc, frac;
8324 
8325   if (m_PixelAspect == 1) return;
8326   TRACEKEYVALS("Stretching the image","%s","");
8327   TRACEKEYVALS("m_PixelAspect","%f",m_PixelAspect);
8328   if (m_PixelAspect < 1) {
8329     newdim = (uint16_t) (m_Height / m_PixelAspect + 0.5);
8330     img = (uint16_t (*)[4]) CALLOC (m_Width*newdim, sizeof *img);
8331     merror (img, "stretch()");
8332     for (rc=row=0; row < newdim; row++, rc+=m_PixelAspect) {
8333       frac = rc - (c = (int) rc);
8334       pix0 = pix1 = m_Image[c*m_Width];
8335       if (c+1 < m_Height) pix1 += m_Width*4;
8336       for (col=0; col < m_Width; col++, pix0+=4, pix1+=4)
8337   for (c=0; c < m_Colors; c++) img[row*m_Width+col][c] =
8338           (uint16_t)(pix0[c]*(1-frac) + pix1[c]*frac + 0.5);
8339     }
8340     m_OutHeight = m_Height = newdim;
8341   } else {
8342     newdim = (uint16_t) (m_Width * m_PixelAspect + 0.5);
8343     img = (uint16_t (*)[4]) CALLOC (m_Height*newdim, sizeof *img);
8344     merror (img, "stretch()");
8345     for (rc=col=0; col < newdim; col++, rc+=1/m_PixelAspect) {
8346       frac = rc - (c = (int) rc);
8347       pix0 = pix1 = m_Image[c];
8348       if (c+1 < m_Width) pix1 += 4;
8349       for (row=0; row < m_Height; row++, pix0+=m_Width*4, pix1+=m_Width*4)
8350   for (c=0; c < m_Colors; c++) img[row*newdim+col][c] =
8351          (uint16_t) (pix0[c]*(1-frac) + pix1[c]*frac + 0.5);
8352     }
8353     m_OutWidth = m_Width = newdim;
8354   }
8355   FREE (m_Image);
8356   m_Image = img;
8357 
8358   TRACEKEYVALS("m_Width","%d",m_Width);
8359   TRACEKEYVALS("m_Height","%d",m_Height);
8360   TRACEKEYVALS("m_OutWidth","%d",m_OutWidth);
8361   TRACEKEYVALS("m_OutHeight","%d",m_OutHeight);
8362 }
8363 
flip_index(int row,int col)8364 int CLASS flip_index (int row, int col)
8365 {
8366   if (m_Flip & 4) SWAP(row,col);
8367   if (m_Flip & 2) row = m_OutHeight - 1 - row;
8368   if (m_Flip & 1) col = m_OutWidth  - 1 - col;
8369   return row * m_OutWidth + col;
8370 }
8371 
8372 struct tiff_tag {
8373   uint16_t tag, type;
8374   int count;
8375   union { char c[4]; short s[2]; int i; } val;
8376 };
8377 
8378 struct tiff_hdr {
8379   uint16_t order, magic;
8380   int ifd;
8381   uint16_t pad, ntag;
8382   struct tiff_tag tag[23];
8383   int nextifd;
8384   uint16_t pad2, nexif;
8385   struct tiff_tag exif[4];
8386   uint16_t pad3, ngps;
8387   struct tiff_tag gpst[10];
8388   short bps[4];
8389   int rat[10];
8390   unsigned gps[26];
8391   char desc[512], make[64], model[64], soft[32], date[20], artist[64];
8392 };
8393 
tiff_set(uint16_t * ntag,uint16_t tag,uint16_t type,int count,int val)8394 void CLASS tiff_set (uint16_t *ntag,
8395   uint16_t tag, uint16_t type, int count, int val)
8396 {
8397   struct tiff_tag *tt;
8398   int c;
8399 
8400   tt = (struct tiff_tag *)(ntag+1) + (*ntag)++;
8401   tt->tag = tag;
8402   tt->type = type;
8403   tt->count = count;
8404   if (type < 3 && count <= 4)
8405     for(c=0;c<4;c++) tt->val.c[c] = val >> (c << 3);
8406   else if (type == 3 && count <= 2)
8407     for(c=0;c<2;c++) tt->val.s[c] = val >> (c << 4);
8408   else tt->val.i = val;
8409 }
8410 
8411 #define TOFF(ptr) ((char *)(&(ptr)) - (char *)th)
8412 
tiff_head(struct tiff_hdr * th)8413 void CLASS tiff_head (struct tiff_hdr *th)
8414 {
8415   int psize=0;
8416   struct tm *t;
8417 
8418   memset (th, 0, sizeof *th);
8419   th->order = htonl(0x4d4d4949) >> 16;
8420   th->magic = 42;
8421   th->ifd = 10;
8422   tiff_set (&th->ntag, 270, 2, 512, TOFF(th->desc));
8423   tiff_set (&th->ntag, 271, 2, 64, TOFF(th->make));
8424   tiff_set (&th->ntag, 272, 2, 64, TOFF(th->model));
8425   tiff_set (&th->ntag, 274, 3, 1, "12435867"[m_Flip]-'0');
8426   tiff_set (&th->ntag, 282, 5, 1, TOFF(th->rat[0]));
8427   tiff_set (&th->ntag, 283, 5, 1, TOFF(th->rat[2]));
8428   tiff_set (&th->ntag, 284, 3, 1, 1);
8429   tiff_set (&th->ntag, 296, 3, 1, 2);
8430   tiff_set (&th->ntag, 305, 2, 32, TOFF(th->soft));
8431   tiff_set (&th->ntag, 306, 2, 20, TOFF(th->date));
8432   tiff_set (&th->ntag, 315, 2, 64, TOFF(th->artist));
8433   tiff_set (&th->ntag, 34665, 4, 1, TOFF(th->nexif));
8434   if (psize) tiff_set (&th->ntag, 34675, 7, psize, sizeof *th);
8435   tiff_set (&th->nexif, 33434, 5, 1, TOFF(th->rat[4]));
8436   tiff_set (&th->nexif, 33437, 5, 1, TOFF(th->rat[6]));
8437   tiff_set (&th->nexif, 34855, 3, 1, (int) m_IsoSpeed);
8438   tiff_set (&th->nexif, 37386, 5, 1, TOFF(th->rat[8]));
8439   strncpy (th->desc, m_Description, 512);
8440   strncpy (th->make, m_CameraMake, 64);
8441   strncpy (th->model, m_CameraModel, 64);
8442   strcpy (th->soft, DCRAW_VERSION);
8443   t = localtime (&m_TimeStamp);
8444   sprintf (th->date, "%04d:%02d:%02d %02d:%02d:%02d",
8445       t->tm_year+1900,t->tm_mon+1,t->tm_mday,t->tm_hour,t->tm_min,t->tm_sec);
8446   strncpy (th->artist, m_Artist, 64);
8447 }
8448 
jpeg_thumb()8449 void CLASS jpeg_thumb ()
8450 /* Remember: This function is modified to write the raw’s thumbnail to the
8451    m_Thumb instead of a file on disk. Always access thumbnails via DcRaw::thumbnail()!
8452 */
8453 {
8454   char *thumb;
8455   uint16_t exif[5];
8456   struct tiff_hdr th;
8457 
8458   thumb = (char *) MALLOC (m_ThumbLength);
8459   merror (thumb, "jpeg_thumb()");
8460   ptfread (thumb, 1, m_ThumbLength, m_InputFile);
8461 //  fputc (0xff, m_OutputFile);
8462 //  fputc (0xd8, m_OutputFile);
8463   m_Thumb.push_back('\xff');
8464   m_Thumb.push_back('\xd8');
8465 
8466   if (strcmp (thumb+6, "Exif")) {
8467     memcpy (exif, "\xff\xe1  Exif\0\0", 10);
8468     exif[1] = htons (8 + sizeof th);
8469     //ptfwrite (exif, 1, sizeof exif, m_OutputFile);
8470     VAppend(m_Thumb, (char*)&exif[0], sizeof(exif));
8471     tiff_head (&th);
8472     //ptfwrite (&th, 1, sizeof th, m_OutputFile);
8473     VAppend(m_Thumb, (char*)&th, sizeof(th));
8474   }
8475   //ptfwrite (thumb+2, 1, m_ThumbLength-2, m_OutputFile);
8476   VAppend(m_Thumb, thumb+2, m_ThumbLength-2);
8477 
8478   FREE (thumb);
8479 }
8480 
8481 ////////////////////////////////////////////////////////////////////////////////
8482 //
8483 // Identify
8484 //
8485 // First method to be called when in an photivo application.
8486 // Hereafter camera, model, and a number of other picture and camera
8487 // parameters are identified.
8488 // Returns 0 on success.
8489 //
8490 ////////////////////////////////////////////////////////////////////////////////
8491 
Identify(const QString NewInputFile)8492 short CLASS Identify(const QString NewInputFile) {
8493 
8494   // This is here to support multiple calls.
8495   ResetNonUserSettings();
8496   FCLOSE(m_InputFile);
8497 
8498   if (NewInputFile != "") {
8499     FREE(m_UserSetting_InputFileName);
8500     m_UserSetting_InputFileName = (char*) MALLOC(1 + strlen(NewInputFile.toLocal8Bit().data()));
8501     ptMemoryError(m_UserSetting_InputFileName,__FILE__,__LINE__);
8502     strcpy(m_UserSetting_InputFileName, NewInputFile.toLocal8Bit().data());
8503   }
8504 
8505   if (!(m_InputFile = fopen (m_UserSetting_InputFileName, "rb"))) {
8506     perror (m_UserSetting_InputFileName);
8507     return -1;
8508   }
8509 
8510   identify();
8511 
8512   if (!m_IsRaw) {
8513     FCLOSE(m_InputFile);
8514   }
8515   return !m_IsRaw;
8516 }
8517 
8518 ////////////////////////////////////////////////////////////////////////////////
8519 //
8520 // RunDcRaw_Phase1
8521 //
8522 // Settings are given via the m_UserSetting* members.
8523 // It will end there where the raw image is loaded.
8524 // Badpixels and darkframes subtracted.
8525 // But before colorscaling and the like so that we can
8526 // intervene in the whitebalances etc.
8527 // Returns 0 on success.
8528 //
8529 ////////////////////////////////////////////////////////////////////////////////
8530 
RunDcRaw_Phase1()8531 short CLASS RunDcRaw_Phase1() {
8532 
8533   // TODO foveon for the moment not in. Need study material
8534   // to have this +/- right.
8535   assert (!m_IsFoveon);
8536 
8537   TRACEKEYVALS("PreMult[0]","%f",VALUE(m_PreMultipliers[0]));
8538   TRACEKEYVALS("PreMult[1]","%f",VALUE(m_PreMultipliers[1]));
8539   TRACEKEYVALS("PreMult[2]","%f",VALUE(m_PreMultipliers[2]));
8540   TRACEKEYVALS("PreMult[3]","%f",VALUE(m_PreMultipliers[3]));
8541 #ifdef TRACE_ORIGIN
8542   TRACEKEYVALS("PreMult File","%s",m_PreMultipliers[0].File);
8543   TRACEKEYVALS("PreMult Line","%d",m_PreMultipliers[0].Line);
8544 #endif
8545   TRACEKEYVALS("D65Mult[0]","%f",VALUE(m_D65Multipliers[0]));
8546   TRACEKEYVALS("D65Mult[1]","%f",VALUE(m_D65Multipliers[1]));
8547   TRACEKEYVALS("D65Mult[2]","%f",VALUE(m_D65Multipliers[2]));
8548   TRACEKEYVALS("D65Mult[3]","%f",VALUE(m_D65Multipliers[3]));
8549 #ifdef TRACE_ORIGIN
8550   TRACEKEYVALS("D65Mult File","%s",m_D65Multipliers[0].File);
8551   TRACEKEYVALS("D65Mult Line","%d",m_D65Multipliers[0].Line);
8552 #endif
8553 
8554   TRACEKEYVALS("RawWidth","%d",m_RawWidth);
8555   TRACEKEYVALS("RawHeight","%d",m_RawHeight);
8556   TRACEKEYVALS("TopMargin","%d",m_TopMargin);
8557   TRACEKEYVALS("LeftMargin","%d",m_LeftMargin);
8558   TRACEKEYVALS("BlackLevel","%d",m_BlackLevel);
8559 
8560   // OK for second entry.
8561   if (m_LoadRawFunction == &CLASS kodak_ycbcr_load_raw) {
8562     m_Height += m_Height & 1;
8563     m_Width  += m_Width  & 1;
8564   }
8565 
8566   m_OutHeight = m_Height;
8567   m_OutWidth  = m_Width;
8568 
8569   TRACEKEYVALS("OutWidth","%d",m_OutWidth);
8570   TRACEKEYVALS("Width","%d",m_Width);
8571 
8572   // Also some reshuffling for second entry problem.
8573   // not sure how c_matrix comes into play here ...
8574   int l_CameraMatrix = (m_UserSetting_CameraMatrix < 0) ?
8575      m_UserSetting_CameraWb : m_UserSetting_CameraMatrix;
8576   TRACEKEYVALS("US_CameraWB","%d",m_UserSetting_CameraWb);
8577   TRACEKEYVALS("US_CameraMatr","%d",m_UserSetting_CameraMatrix);
8578   TRACEKEYVALS("CameraMatrix","%d",l_CameraMatrix);
8579   TRACEKEYVALS("m_cmatrix[0][0","%f",m_cmatrix[0][0]);
8580   if (l_CameraMatrix && m_cmatrix[0][0] > 0.25) {
8581     TRACEKEYVALS("Using CamMatr","%s","Yes");
8582     memcpy (m_MatrixCamRGBToSRGB, m_cmatrix, sizeof m_cmatrix);
8583     m_RawColor = 0;
8584   }
8585 
8586   // Allocation is depending on m_Raw_Image below.
8587   FREE(m_Image);
8588 
8589   if (m_MetaLength) {
8590     FREE(m_MetaData);
8591     m_MetaData = (char *) MALLOC (m_MetaLength);
8592     merror (m_MetaData, "main()");
8593   }
8594   if (m_Filters || m_Colors == 1) {
8595     m_Raw_Image = (uint16_t *) CALLOC ((m_RawHeight+7)*m_RawWidth, 2);
8596     merror (m_Raw_Image, "main().m_Raw_Image");
8597   } else {
8598     // Basic image memory allocation @ 4 int per pixel happens here.
8599     m_Image = (uint16_t (*)[4]) CALLOC (m_OutHeight*m_OutWidth, sizeof *m_Image);
8600     merror (m_Image, "main()");
8601   }
8602 
8603   TRACEKEYVALS("CameraMake","%s",m_CameraMake);
8604   TRACEKEYVALS("CameraModel","%s",m_CameraModel);
8605   TRACEKEYVALS("InputFile","%s",m_UserSetting_InputFileName);
8606   TRACEKEYVALS("Filters","%x",m_Filters);
8607   TRACEKEYVALS("Flip","%x",m_Flip);
8608 
8609   fseek (m_InputFile, m_Data_Offset, SEEK_SET);
8610 
8611   // Basic loading operation.
8612   // That's the hook into the real workhorse.
8613 
8614   (*this.*m_LoadRawFunction)();
8615 
8616   if (m_Raw_Image) {
8617     // Basic image memory allocation @ 4 int per pixel happens here.
8618     m_Image = (uint16_t (*)[4]) CALLOC (m_OutHeight*m_OutWidth, sizeof *m_Image);
8619     merror (m_Image, "main()");
8620     crop_masked_pixels();
8621     FREE (m_Raw_Image);
8622   }
8623 
8624   if (m_ZeroIsBad) remove_zeroes();
8625   bad_pixels (m_UserSetting_BadPixelsFileName);
8626   if (m_UserSetting_DarkFrameFileName)
8627     subtract (m_UserSetting_DarkFrameFileName);
8628 
8629   // photivo extra.
8630   // Calculation of the inverse m_MatrixCamRGBToSRGB
8631   double rgb_cam_transpose[4][3];
8632   for (short i=0; i<4; i++) for (short j=0; j<3; j++)
8633     rgb_cam_transpose[i][j] = m_MatrixCamRGBToSRGB[j][i];
8634   pseudoinverse(rgb_cam_transpose,m_MatrixSRGBToCamRGB,m_Colors);
8635 
8636   // ReportedWidth & Height correct for fuji_rotate stuff and pixelaspects.
8637   m_ReportedWidth  = m_Width;
8638   m_ReportedHeight = m_Height;
8639   if (m_Fuji_Width) {
8640     m_IsFuji = m_Fuji_Width;
8641     m_ReportedWidth  = (m_Fuji_Width-1) / sqrt(0.5);
8642     m_ReportedHeight = (m_Height-m_Fuji_Width+1)/sqrt(0.5);
8643   }
8644   if (m_PixelAspect<1)
8645     m_ReportedHeight = (uint16_t) (m_Height / m_PixelAspect + 0.5);
8646   if (m_PixelAspect>1)
8647     m_ReportedWidth = (uint16_t) (m_Width * m_PixelAspect + 0.5);
8648 
8649   // TODO Mike: m_ReportedH/W is never set back to m_H/W, CHECK!
8650 
8651   TRACEKEYVALS("m_Width","%d",m_Width);
8652   TRACEKEYVALS("m_Height","%d",m_Height);
8653   TRACEKEYVALS("m_ReportedWidth","%d",m_ReportedWidth);
8654   TRACEKEYVALS("m_ReportedHeight","%d",m_ReportedHeight);
8655 
8656   TRACEKEYVALS("PreMult[0]","%f",VALUE(m_PreMultipliers[0]));
8657   TRACEKEYVALS("PreMult[1]","%f",VALUE(m_PreMultipliers[1]));
8658   TRACEKEYVALS("PreMult[2]","%f",VALUE(m_PreMultipliers[2]));
8659   TRACEKEYVALS("PreMult[3]","%f",VALUE(m_PreMultipliers[3]));
8660 #ifdef TRACE_ORIGIN
8661   TRACEKEYVALS("PreMult File","%s",m_PreMultipliers[0].File);
8662   TRACEKEYVALS("PreMult Line","%d",m_PreMultipliers[0].Line);
8663 #endif
8664   TRACEKEYVALS("D65Mult[0]","%f",VALUE(m_D65Multipliers[0]));
8665   TRACEKEYVALS("D65Mult[1]","%f",VALUE(m_D65Multipliers[1]));
8666   TRACEKEYVALS("D65Mult[2]","%f",VALUE(m_D65Multipliers[2]));
8667   TRACEKEYVALS("D65Mult[3]","%f",VALUE(m_D65Multipliers[3]));
8668 #ifdef TRACE_ORIGIN
8669   TRACEKEYVALS("D65Mult File","%s",m_D65Multipliers[0].File);
8670   TRACEKEYVALS("D65Mult Line","%d",m_D65Multipliers[0].Line);
8671 #endif
8672   TRACEKEYVALS("Colors","%d",m_Colors);
8673   TRACEKEYVALS("Filters","%x",m_Filters);
8674   TRACEKEYVALS("Flip","%x",m_Flip);
8675 
8676   // Cache the image after Phase1.
8677   FREE(m_Image_AfterPhase1);
8678   m_Image_AfterPhase1 =
8679     (uint16_t (*)[4]) CALLOC (m_OutHeight*m_OutWidth, sizeof *m_Image);
8680   merror (m_Image_AfterPhase1, "main()");
8681   memcpy(m_Image_AfterPhase1,m_Image,m_OutHeight*m_OutWidth*sizeof(*m_Image));
8682   // Some other stuff to cache.
8683   m_Filters_AfterPhase1 = m_Filters;
8684   m_BlackLevel_AfterPhase1 = m_BlackLevel;
8685   for (int k=0; k<8; k++) m_CBlackLevel_AfterPhase1[k] = m_CBlackLevel[k];
8686   m_WhiteLevel_AfterPhase1 = m_WhiteLevel;
8687   m_Width_AfterPhase1 = m_Width;
8688   m_Height_AfterPhase1 = m_Height;
8689   m_OutWidth_AfterPhase1 = m_OutWidth;
8690   m_OutHeight_AfterPhase1 = m_OutHeight;
8691 
8692   return 0;
8693 }
8694 
8695 ////////////////////////////////////////////////////////////////////////////////
8696 //
8697 // RunDcRaw_Phase2
8698 //
8699 // Color scaling.
8700 // Interpolation.
8701 // Green mixing.
8702 //
8703 ////////////////////////////////////////////////////////////////////////////////
8704 
RunDcRaw_Phase2(const short NoCache)8705 short CLASS RunDcRaw_Phase2(const short NoCache) {
8706 
8707   // Make sure we are starting from the right image.
8708   if (NoCache) {
8709     FREE(m_Image_AfterPhase1);
8710   } else {
8711     FREE(m_Image);
8712     m_Width = m_Width_AfterPhase1;
8713     m_Height = m_Height_AfterPhase1;
8714     m_OutWidth = m_OutWidth_AfterPhase1;
8715     m_OutHeight = m_OutHeight_AfterPhase1;
8716     m_Image =
8717       (uint16_t (*)[4]) CALLOC (m_OutHeight*m_OutWidth, sizeof *m_Image);
8718     merror (m_Image, "main()");
8719     memcpy(m_Image,m_Image_AfterPhase1,m_OutHeight*m_OutWidth*sizeof(*m_Image));
8720     // Restore some other cached values.
8721     m_Filters    = m_Filters_AfterPhase1;
8722     m_BlackLevel = m_BlackLevel_AfterPhase1;
8723     for (int k=0; k<8; k++) m_CBlackLevel[k] = m_CBlackLevel_AfterPhase1[k];
8724     m_WhiteLevel = m_WhiteLevel_AfterPhase1;
8725   }
8726   m_Fuji_Width = m_IsFuji;
8727   unsigned i = m_CBlackLevel[3];
8728   for (int c=0; c<3; c++) if (i > m_CBlackLevel[c]) i = m_CBlackLevel[c];
8729   for (int c=0; c<4; c++) m_CBlackLevel[c] -= i;
8730   m_BlackLevel += i;
8731   if (m_UserSetting_BlackPoint >= 0) m_BlackLevel = m_UserSetting_BlackPoint;
8732   for (int c=0; c<4; c++) m_CBlackLevel[c] += m_BlackLevel;
8733   if (m_UserSetting_Saturation > 0)  m_WhiteLevel = m_UserSetting_Saturation;
8734 
8735   // If m_UserSetting_HalfSize then the BAYER(row,col) macro
8736   // will map 2X2 pixels of the Bayer array, directly onto one
8737   // pixel of the image (and the correct color channel) foregoing
8738   // the need for interpolation and much faster !
8739   m_Shrink = m_Filters && m_UserSetting_HalfSize;
8740 
8741   TRACEKEYVALS("Shrink","%d",m_Shrink);
8742 
8743   TRACEKEYVALS("BlackLevel","%d",m_BlackLevel);
8744   TRACEKEYVALS("WhiteLevel","%d",m_WhiteLevel);
8745   TRACEKEYVALS("Colors","%d",m_Colors);
8746 
8747   TRACEKEYVALS("Phase2 begin Width","%d",m_Width);
8748   TRACEKEYVALS("Phase2 begin Height","%d",m_Height);
8749   TRACEKEYVALS("Phase2 begin OutWidth","%d",m_OutWidth);
8750   TRACEKEYVALS("Phase2 begin OutHeight","%d",m_OutHeight);
8751 
8752   // Crop for detail view
8753   if (m_UserSetting_DetailView == 1 &&
8754       m_IsFuji == 0 &&
8755       m_PixelAspect == 1.0f) {
8756     ptCrop();
8757   }
8758 
8759   // Copied from earlier to here also.
8760   // Enables Phase3 to reenter with a different FourColorRGB setting.
8761   if ((m_UserSetting_Quality == ptInterpolation_VNG4 || m_UserSetting_HalfSize)
8762       && m_Filters != 0) { // m_Filters==0 <-> 3 channel RAWs
8763     m_MixGreen = 1;
8764   } else {
8765     m_MixGreen = 0;
8766   }
8767 
8768   if (!m_IsFoveon && m_UserSetting_AdjustMaximum > 0) {
8769     ptAdjustMaximum(1-m_UserSetting_AdjustMaximum);
8770   }
8771 
8772   assert (!m_IsFoveon);
8773   // if (m_IsFoveon ) foveon_interpolate();
8774 
8775   if (m_UserSetting_GreenEquil) {
8776     TRACEKEYVALS("Green equilibration","%s","");
8777     green_equilibrate((float)m_UserSetting_GreenEquil/100.0f);
8778   }
8779 
8780   if (m_UserSetting_HotpixelReduction) {
8781     TRACEKEYVALS("Hotpixel reduction on bayer","%s","");
8782     ptHotpixelReductionBayer();
8783   }
8784 
8785   if (m_UserSetting_CfaLineDn !=0) {
8786     TRACEKEYVALS("Cfa line denoise","%s","");
8787     cfa_linedn(0.00002*(float)m_UserSetting_CfaLineDn);
8788   }
8789 
8790   if (!m_IsFoveon) {
8791     ptScaleColors();
8792   }
8793 
8794   if (m_UserSetting_CaCorrect !=0) {
8795     TRACEKEYVALS("CA correction","%s","");
8796     CA_correct(m_UserSetting_CaRed,m_UserSetting_CaBlue);
8797   }
8798 
8799   TRACEKEYVALS("Colors","%d",m_Colors);
8800 
8801   // not 1:1 pipe, use FC marco instead of interpolation
8802   uint16_t    (*TempImage)[4];
8803   if (m_Shrink && m_Filters != 2) { // -> preinterpolate will set m_Filters = 0 if != 2
8804     m_OutHeight = (m_Height + 1) / 2;
8805     m_OutWidth  = (m_Width + 1) / 2;
8806     TempImage = (uint16_t (*)[4]) CALLOC (m_OutHeight*m_OutWidth, sizeof *TempImage);
8807     merror (TempImage, "main()");
8808 #pragma omp parallel for schedule(static)
8809     for (uint16_t row=0; row < m_Height; row++) {
8810       for (uint16_t col=0; col < m_Width; col++) {
8811         TempImage[((row) >> m_Shrink)*m_OutWidth + ((col) >> m_Shrink)][FC(row,col)] =
8812           m_Image[(row)*m_Width + (col)][FC(row,col)];
8813       }
8814     }
8815     FREE(m_Image);
8816     m_Image = TempImage;
8817   }
8818 
8819   // RG1BG2 -> RGB (if not 4 colors needed later on)
8820   pre_interpolate();
8821 
8822   TRACEKEYVALS("Colors","%d",m_Colors);
8823 
8824 
8825   // Interpolation/demosaicing according to one of the algorithms.
8826   if (m_Filters) {
8827     if (m_UserSetting_BayerDenoise && !m_UserSetting_HalfSize) {
8828       if (m_UserSetting_BayerDenoise==1) fbdd(0);
8829       else if (m_UserSetting_BayerDenoise==2) fbdd(1);
8830     }
8831     if (m_Filters == 2) // for 3x3 pattern we fix to VNG
8832       vng_interpolate();
8833     else if (m_UserSetting_Quality == ptInterpolation_Linear)
8834       lin_interpolate();
8835     else if (m_UserSetting_Quality == ptInterpolation_VNG ||
8836              m_UserSetting_Quality == ptInterpolation_VNG4)
8837       vng_interpolate();
8838     else if (m_UserSetting_Quality == ptInterpolation_PPG)
8839       ppg_interpolate();
8840     else if (m_UserSetting_Quality == ptInterpolation_DCB)
8841       dcb(m_UserSetting_InterpolationPasses, 1);
8842     else if (m_UserSetting_Quality == ptInterpolation_DCBSoft)
8843       dcb_interpolate_soft_old(m_UserSetting_InterpolationPasses, 1);
8844     else if (m_UserSetting_Quality == ptInterpolation_DCBSharp)
8845       dcb_interpolate_sharp_old(m_UserSetting_InterpolationPasses, 1);
8846     else if (m_UserSetting_Quality == ptInterpolation_AHD)
8847       ahd_interpolate();
8848     else if (m_UserSetting_Quality == ptInterpolation_AHD_mod)
8849       ahd_interpolate_mod();
8850     else if (m_UserSetting_Quality == ptInterpolation_VCD)
8851       vcd_interpolate(12);
8852     else if (m_UserSetting_Quality == ptInterpolation_LMMSE)
8853       lmmse_interpolate(1);
8854     else if (m_UserSetting_Quality == ptInterpolation_AMaZE)
8855       amaze_demosaic();
8856   } else {
8857     if (m_UserSetting_HotpixelReduction && m_UserSetting_HalfSize) {
8858       TRACEKEYVALS("Hotpixel reduction on RGB","%s","");
8859       ptHotpixelReduction();
8860     }
8861     if (m_UserSetting_BayerDenoise && !m_UserSetting_HalfSize) {
8862       if (m_UserSetting_BayerDenoise==1) fbdd(0);
8863       else if (m_UserSetting_BayerDenoise==2) fbdd(1);
8864     }
8865   }
8866   // If 1:1 and no interpolation is chosen show the Bayer pattern.
8867 
8868   TRACEKEYVALS("Interpolation type","%d",m_UserSetting_Quality);
8869 
8870   // Additional photivo stuff. Other halvings on request.
8871   if (m_UserSetting_HalfSize > 1                      ||
8872       (m_UserSetting_HalfSize == 1 && m_Shrink  == 0) || // 3 channel RAWs
8873       (m_UserSetting_HalfSize == 1 && m_Filters == 2)) { // 3x3 pattern
8874     short Factor = m_UserSetting_HalfSize - 1;
8875     if (m_Shrink == 0 || m_Filters == 2) Factor += 1;
8876 
8877     uint16_t NewHeight = m_Height >> Factor;
8878     uint16_t NewWidth = m_Width >> Factor;
8879 
8880     short Step = 1 << Factor;
8881     int Average = 2 * Factor;
8882 
8883     uint16_t (*NewImage)[4] =
8884       (uint16_t (*)[4]) CALLOC(NewWidth*NewHeight,sizeof(*m_Image));
8885     ptMemoryError(NewImage,__FILE__,__LINE__);
8886 
8887 #pragma omp parallel for schedule(static)
8888     for (uint16_t Row=0; Row < NewHeight*Step; Row+=Step) {
8889       for (uint16_t Col=0; Col < NewWidth*Step; Col+=Step) {
8890         uint32_t  PixelValue[4] = {0,0,0,0};
8891         for (uint8_t sRow=0; sRow < Step; sRow++) {
8892           for (uint8_t sCol=0; sCol < Step; sCol++) {
8893             int32_t index = (Row+sRow)*m_Width+Col+sCol;
8894             for (short c=0; c < 4; c++) {
8895               PixelValue[c] += m_Image[index][c];
8896             }
8897           }
8898         }
8899         for (short c=0; c < 4; c++) {
8900           NewImage[Row/Step*NewWidth+Col/Step][c]
8901             = PixelValue[c] >> Average;
8902         }
8903       }
8904     }
8905 
8906     FREE(m_Image);
8907     m_Height = m_OutHeight = NewHeight;
8908     m_Width = m_OutWidth = NewWidth;
8909     m_Image = NewImage;
8910   }
8911 
8912   // Green mixing
8913   if (m_MixGreen && m_Colors != 3) {
8914 #pragma omp parallel for schedule(static) default(shared)
8915     for (uint32_t i=0; i < (uint32_t) m_Height*m_Width; i++)
8916       m_Image[i][1] = (m_Image[i][1] + m_Image[i][3]) >> 1;
8917     m_Colors = 3;
8918   }
8919 
8920   // Median filter.
8921   if (!m_IsFoveon && m_Colors == 3) {
8922     if (m_UserSetting_MedianPasses > 0)  median_filter_new();
8923     if (m_UserSetting_ESMedianPasses > 0 && !m_UserSetting_HalfSize) es_median_filter();
8924     if (m_UserSetting_EeciRefine == 1)  refinement();
8925   }
8926 
8927   // Additional cleaning with hotpixel reduction
8928   if (m_UserSetting_HotpixelReduction && m_UserSetting_Quality != ptInterpolation_Bayer) {
8929     ptHotpixelReduction();
8930   }
8931 
8932   // XXX JDLA Additional steps for Fuji
8933   // And they don't hurt for others as they are early stopped.
8934   fuji_rotate();
8935   stretch();
8936 
8937   // Crop for detail view
8938   if (m_UserSetting_DetailView == 1 &&
8939       (m_IsFuji != 0 ||
8940        m_PixelAspect != 1.0f)) {
8941     ptCrop();
8942   }
8943 
8944   // Cache the image after Phase2.
8945   FREE(m_Image_AfterPhase2);
8946   m_Image_AfterPhase2 =
8947     (uint16_t (*)[4]) CALLOC (m_OutHeight*m_OutWidth, sizeof *m_Image);
8948   merror (m_Image_AfterPhase2, "main()");
8949   memcpy(m_Image_AfterPhase2,m_Image,m_OutHeight*m_OutWidth*sizeof(*m_Image));
8950   // Some other stuff to cache.
8951   m_Filters_AfterPhase2 = m_Filters;
8952 
8953   TRACEKEYVALS("BlackLevel","%d",m_BlackLevel);
8954   TRACEKEYVALS("WhiteLevel","%d",m_WhiteLevel);
8955   TRACEKEYVALS("Colors","%d",m_Colors);
8956   TRACEKEYVALS("Filters","%x",m_Filters);
8957 
8958   TRACEKEYVALS("Phase2 end Width","%d",m_Width);
8959   TRACEKEYVALS("Phase2 end Height","%d",m_Height);
8960   TRACEKEYVALS("Phase2 end OutWidth","%d",m_OutWidth);
8961   TRACEKEYVALS("Phase2 end OutHeight","%d",m_OutHeight);
8962 
8963   return 0;
8964 }
8965 
8966 ////////////////////////////////////////////////////////////////////////////////
8967 //
8968 // RunDcRaw_Phase3
8969 //
8970 // Highlights
8971 //
8972 ////////////////////////////////////////////////////////////////////////////////
8973 
RunDcRaw_Phase3(const short NoCache)8974 short CLASS RunDcRaw_Phase3(const short NoCache) {
8975 
8976   // Make sure we are starting from the right image.
8977   if (NoCache) {
8978     FREE(m_Image_AfterPhase2);
8979   } else {
8980     FREE(m_Image);
8981     m_Image =
8982       (uint16_t (*)[4]) CALLOC (m_OutHeight*m_OutWidth, sizeof *m_Image);
8983     merror (m_Image, "main()");
8984     memcpy(m_Image,m_Image_AfterPhase2,m_OutHeight*m_OutWidth*sizeof(*m_Image));
8985     // Restore some other cached values.
8986     m_Filters    = m_Filters_AfterPhase2;
8987   }
8988 
8989   TRACEKEYVALS("CamMult[0]","%f",VALUE(m_CameraMultipliers[0]));
8990   TRACEKEYVALS("CamMult[1]","%f",VALUE(m_CameraMultipliers[1]));
8991   TRACEKEYVALS("CamMult[2]","%f",VALUE(m_CameraMultipliers[2]));
8992   TRACEKEYVALS("CamMult[3]","%f",VALUE(m_CameraMultipliers[3]));
8993 #ifdef TRACE_ORIGIN
8994   TRACEKEYVALS("CamMult File","%s",m_CameraMultipliers[0].File);
8995   TRACEKEYVALS("CamMult Line","%d",m_CameraMultipliers[0].Line);
8996 #endif
8997 
8998   ptHighlight(m_UserSetting_photivo_ClipMode,
8999               m_UserSetting_photivo_ClipParameter);
9000 
9001   // Cache the image after Phase3.
9002   FREE(m_Image_AfterPhase3);
9003   m_Image_AfterPhase3 =
9004     (uint16_t (*)[4]) CALLOC (m_OutHeight*m_OutWidth, sizeof *m_Image);
9005   merror (m_Image_AfterPhase3, "main()");
9006   memcpy(m_Image_AfterPhase3,m_Image,m_OutHeight*m_OutWidth*sizeof(*m_Image));
9007   // Some other stuff to cache.
9008   m_Filters_AfterPhase3 = m_Filters;
9009 
9010   return 0;
9011 }
9012 
9013 ////////////////////////////////////////////////////////////////////////////////
9014 //
9015 // BlendHighlights
9016 // (original from dcraw TODO Refine and analyse)
9017 //
9018 ////////////////////////////////////////////////////////////////////////////////
9019 
ptBlendHighlights()9020 void CLASS ptBlendHighlights() {
9021 
9022   int ClipLevel=INT_MAX;
9023   int i;
9024   int j;
9025 
9026   static const float trans[2][4][4] =
9027   { { { 1,1,1 }, { 1.7320508,-1.7320508,0 }, { -1,-1,2 } },
9028     { { 1,1,1,1 }, { 1,-1,1,-1 }, { 1,1,-1,-1 }, { 1,-1,-1,1 } } };
9029   static const float itrans[2][4][4] =
9030   { { { 1,0.8660254,-0.5 }, { 1,-0.8660254,-0.5 }, { 1,0,1 } },
9031     { { 1,1,1,1 }, { 1,-1,1,-1 }, { 1,1,-1,-1 }, { 1,-1,-1,1 } } };
9032   float Cam[2][4], lab[2][4], Sum[2], chratio;
9033 
9034   const int transIdx = m_Colors - 3;
9035   assert(transIdx > -1);
9036   if (transIdx > 1) return;
9037 
9038   // to shut up gcc warnings...
9039   const int localColors = ptMin(static_cast<int>(m_Colors), 4);
9040 
9041   for (short c=0; c<m_Colors; c++) {
9042     if (ClipLevel > (i = (int)(0xFFFF*VALUE(m_PreMultipliers[c])))) {
9043       ClipLevel = i;
9044     }
9045   }
9046 
9047   for (uint16_t Row=0; Row < m_Height; Row++) {
9048     for (uint16_t Column=0; Column < m_Width; Column++) {
9049       short c;
9050       for (c=0; c<m_Colors; c++) {
9051         if (m_Image[Row*m_Width+Column][c] > ClipLevel) break;
9052       }
9053       if (c == m_Colors) continue; // No clip
9054       for (c=0; c<m_Colors; c++) {
9055   Cam[0][c] = m_Image[Row*m_Width+Column][c];
9056   Cam[1][c] = MIN(Cam[0][c],(float)ClipLevel);
9057       }
9058       for (i=0; i < 2; i++) {
9059   for (c=0; c<m_Colors; c++) {
9060           for (lab[i][c]=j=0; j < m_Colors; j++) {
9061       lab[i][c] += trans[transIdx][c][j] * Cam[i][j];
9062           }
9063         }
9064   for (Sum[i]=0,c=1; c < m_Colors; c++) {
9065     Sum[i] += SQR(lab[i][c]);
9066         }
9067       }
9068       chratio = sqrt(Sum[1]/Sum[0]);
9069       for (c = 1; c < m_Colors; c++) {
9070         lab[0][c] *= chratio;
9071       }
9072       for (c = 0; (c < localColors); c++) {
9073         for (Cam[0][c]=j=0; (j < localColors); j++) {
9074           Cam[0][c] += itrans[transIdx][c][j] * lab[0][j];
9075         }
9076       }
9077       for (c = 0; c < m_Colors; c++) {
9078         m_Image[Row*m_Width+Column][c] = (uint16_t)(Cam[0][c] / m_Colors);
9079       }
9080     }
9081   }
9082 }
9083 
9084 ////////////////////////////////////////////////////////////////////////////////
9085 //
9086 // Hotpixel reduction
9087 //
9088 ////////////////////////////////////////////////////////////////////////////////
9089 
9090 
ptHotpixelReduction()9091 void CLASS ptHotpixelReduction() {
9092   uint16_t HotpixelThreshold = 0x00ff;
9093   uint16_t Threshold = (int32_t) ((1.0-m_UserSetting_HotpixelReduction)*0x2fff);
9094   uint16_t Width = m_OutWidth;
9095   uint16_t Height = m_OutHeight;
9096   // bei 1:2 oder kleiner m_Image hat in jedem Punkt RGBG
9097   // bei 1:1 m_Image hat Bayer Pattern
9098   // Länge und Breite OutWidth und OutHeight
9099   // unterschieptiche pixel in unterschieptichen ebenen ansprechen und werte zur luminanz skalieren
9100 #pragma omp parallel for schedule(static) default(shared)
9101   for (uint16_t Row=0; Row<Height; Row++) {
9102     for (uint16_t Col=0; Col<Width; Col++) {
9103       uint16_t TempValue = 0;
9104       for (int c=0; c<4; c++) {
9105         if (m_Image[Row*Width+Col][c] > HotpixelThreshold) {
9106           if (Row > 1) TempValue = MAX(m_Image[(Row-1)*Width+Col][c],TempValue);
9107           if (Row < Height-1) TempValue = MAX(m_Image[(Row+1)*Width+Col][c],TempValue);
9108           if (Col > 1) TempValue = MAX(m_Image[Row*Width+Col-1][c],TempValue);
9109           if (Col < Width-1) TempValue = MAX(m_Image[Row*Width+Col+1][c],TempValue);
9110           if (TempValue+Threshold<m_Image[Row*Width+Col][c])
9111             m_Image[Row*Width+Col][c] = TempValue;
9112         }
9113         if (m_Image[Row*Width+Col][c] < 10*HotpixelThreshold) {
9114           TempValue = 0xffff;
9115           if (Row > 1) TempValue = MIN(m_Image[(Row-1)*Width+Col][c],TempValue);
9116           if (Row < Height-1) TempValue = MIN(m_Image[(Row+1)*Width+Col][c],TempValue);
9117           if (Col > 1) TempValue = MIN(m_Image[Row*Width+Col-1][c],TempValue);
9118           if (Col < Width-1) TempValue = MIN(m_Image[Row*Width+Col+1][c],TempValue);
9119           if (TempValue-Threshold>m_Image[Row*Width+Col][c])
9120             m_Image[Row*Width+Col][c] = TempValue;
9121         }
9122       }
9123     }
9124   }
9125 }
9126 
ptHotpixelReductionBayer()9127 void CLASS ptHotpixelReductionBayer() {
9128   uint16_t HotpixelThreshold = 0x00ff;
9129   uint16_t Threshold = (int32_t) ((1.0-m_UserSetting_HotpixelReduction)*0x2fff);
9130   uint16_t Width = m_OutWidth;
9131   uint16_t Height = m_OutHeight;
9132 
9133 #pragma omp parallel for schedule(static)
9134   for (uint16_t Row=0; Row<Height; Row++) {
9135     for (uint16_t Col=0; Col<Width; Col++) {
9136       uint16_t TempValue = 0;
9137       for (int Channel=0; Channel<4; Channel++) {
9138         if (m_Image[Row*Width+Col][Channel] > HotpixelThreshold) {
9139           if (Row > 2) TempValue = MAX(m_Image[(Row-2)*Width+Col][Channel],TempValue);
9140           if (Row < Height-2) TempValue = MAX(m_Image[(Row+2)*Width+Col][Channel],TempValue);
9141           if (Col > 2) TempValue = MAX(m_Image[Row*Width+Col-2][Channel],TempValue);
9142           if (Col < Width-2) TempValue = MAX(m_Image[Row*Width+Col+2][Channel],TempValue);
9143           if (TempValue+Threshold<m_Image[Row*Width+Col][Channel]) {
9144             for (int c=0; c<4; c++) {
9145               if (Row > 1) {
9146                 TempValue = MAX(m_Image[(Row-1)*Width+Col][c],TempValue);
9147                 if (Col > 1) TempValue = MAX(m_Image[(Row-1)*Width+Col-1][c],TempValue);
9148                 if (Col < Width-1) TempValue = MAX(m_Image[(Row-1)*Width+Col+1][c],TempValue);
9149               }
9150               if (Row < Height-1) {
9151                 TempValue = MAX(m_Image[(Row+1)*Width+Col][c],TempValue);
9152                 if (Col > 1) TempValue = MAX(m_Image[(Row+1)*Width+Col-1][c],TempValue);
9153                 if (Col < Width-1) TempValue = MAX(m_Image[(Row+1)*Width+Col+1][c],TempValue);
9154               }
9155               if (Col > 1) TempValue = MAX(m_Image[Row*Width+Col-1][c],TempValue);
9156               if (Col < Width-1) TempValue = MAX(m_Image[Row*Width+Col+1][c],TempValue);
9157             }
9158             if (TempValue+Threshold<m_Image[Row*Width+Col][Channel])
9159               m_Image[Row*Width+Col][Channel] = TempValue;
9160           }
9161         }
9162       }
9163       for (int Channel=0; Channel<4; Channel++) {
9164         if (m_Image[Row*Width+Col][Channel] < 10*HotpixelThreshold) {
9165           TempValue = 0xffff;
9166           if (Row > 2) TempValue = MIN(m_Image[(Row-2)*Width+Col][Channel],TempValue);
9167           if (Row < Height-2) TempValue = MIN(m_Image[(Row+2)*Width+Col][Channel],TempValue);
9168           if (Col > 2) TempValue = MIN(m_Image[Row*Width+Col-2][Channel],TempValue);
9169           if (Col < Width-2) TempValue = MIN(m_Image[Row*Width+Col+2][Channel],TempValue);
9170           if (TempValue-Threshold>m_Image[Row*Width+Col][Channel]) {
9171             for (int c=0; c<4; c++) {
9172               if (Row > 1) {
9173                 TempValue = MIN(m_Image[(Row-1)*Width+Col][c],TempValue);
9174                 if (Col > 1) TempValue = MIN(m_Image[(Row-1)*Width+Col-1][c],TempValue);
9175                 if (Col < Width-1) TempValue = MIN(m_Image[(Row-1)*Width+Col+1][c],TempValue);
9176               }
9177               if (Row < Height-1) {
9178                 TempValue = MIN(m_Image[(Row+1)*Width+Col][c],TempValue);
9179                 if (Col > 1) TempValue = MIN(m_Image[(Row+1)*Width+Col-1][c],TempValue);
9180                 if (Col < Width-1) TempValue = MIN(m_Image[(Row+1)*Width+Col+1][c],TempValue);
9181               }
9182               if (Col > 1) TempValue = MIN(m_Image[Row*Width+Col-1][c],TempValue);
9183               if (Col < Width-1) TempValue = MIN(m_Image[Row*Width+Col+1][c],TempValue);
9184             }
9185             if (TempValue-Threshold>m_Image[Row*Width+Col][Channel])
9186               m_Image[Row*Width+Col][Channel] = TempValue;
9187           }
9188         }
9189       }
9190     }
9191   }
9192 }
9193 
9194 ////////////////////////////////////////////////////////////////////////////////
9195 //
9196 // Crop for detail view
9197 //
9198 ////////////////////////////////////////////////////////////////////////////////
9199 
MultOf6(uint16_t AValue)9200 inline uint16_t MultOf6(uint16_t AValue) {
9201   return ptMax(AValue - (AValue % 6), 0);
9202 }
9203 
ptCrop()9204 void CLASS ptCrop() {
9205   assert (m_UserSetting_HalfSize == 0);
9206 
9207   uint16_t (*TempImage)[4];
9208   uint16_t CropW = m_UserSetting_DetailViewCropW;
9209   uint16_t CropH = m_UserSetting_DetailViewCropH;
9210   uint16_t CropX = m_UserSetting_DetailViewCropX;
9211   uint16_t CropY = m_UserSetting_DetailViewCropY;
9212 
9213   if (m_Filters == 2) { // for 3x3 pattern
9214     CropW = MultOf6(CropW);
9215     CropH = MultOf6(CropH);
9216     CropX = MultOf6(CropX);
9217     CropY = MultOf6(CropY);
9218   }
9219 
9220   if (m_Flip & 2) {
9221     CropX = m_Height - CropX - CropW;
9222   }
9223   if (m_Flip & 1) {
9224     CropY = m_Width - CropY - CropH;
9225   }
9226   if (m_Flip & 4) {
9227     SWAP(CropW, CropH);
9228     SWAP(CropX, CropY);
9229   }
9230   m_OutHeight = CropH;
9231   m_OutWidth  = CropW;
9232   TempImage = (uint16_t (*)[4]) CALLOC (m_OutHeight*m_OutWidth, sizeof *TempImage);
9233   merror (TempImage, "Temp for detail view");
9234 
9235 #pragma omp parallel for schedule(static)
9236   for (uint16_t row=0; row < m_OutHeight; row++) {
9237     for (uint16_t col=0; col < m_OutWidth; col++) {
9238       for (short c=0; c<4; c++) {
9239         TempImage[row *m_OutWidth + col][c] =
9240           m_Image[(row+CropY)*m_Width + (col+CropX)][c];
9241       }
9242     }
9243   }
9244 
9245   m_Width = m_OutWidth;
9246   m_Height = m_OutHeight;
9247   FREE(m_Image);
9248   m_Image = TempImage;
9249   TRACEKEYVALS("Phase2 detail view Width","%d",m_Width);
9250   TRACEKEYVALS("Phase2 detail view Height","%d",m_Height);
9251   TRACEKEYVALS("Phase2 detail view OutWidth","%d",m_OutWidth);
9252   TRACEKEYVALS("Phase2 detail view OutHeight","%d",m_OutHeight);
9253 }
9254 
9255 ////////////////////////////////////////////////////////////////////////////////
9256 //
9257 // MedianFilter
9258 // Repeatepty 3x3 median filter on R-G and B-G channels
9259 // Repeat : m_UserSetting_MedianPasses
9260 //
9261 ////////////////////////////////////////////////////////////////////////////////
9262 
ptMedianFilter()9263 void CLASS ptMedianFilter() {
9264 
9265   int      Median[9];
9266   static const uint8_t opt[] =  /* Optimal 9-element median search */
9267   { 1,2, 4,5, 7,8, 0,1, 3,4, 6,7, 1,2, 4,5, 7,8,
9268     0,3, 5,8, 4,7, 3,6, 1,4, 2,5, 4,7, 4,2, 6,4, 4,2 };
9269 
9270   for (short Pass=1; Pass <= m_UserSetting_MedianPasses; Pass++) {
9271     for (short c=0; c < 3; c+=2) {
9272 #pragma omp parallel for schedule(static) default(shared)
9273       for (int32_t i = 0; i< (int32_t)m_Width*m_Height; i++) {
9274         m_Image[i][3] = m_Image[i][c];
9275       }
9276 #pragma omp parallel for schedule(static) default(shared) private(Median)
9277       for (int32_t n=m_Width; n<m_Width*(m_Height-1); n++) {
9278         if ((n+1) % m_Width < 2) continue;
9279         short k=0;
9280         for (int32_t i = -m_Width; i <= m_Width; i += m_Width) {
9281           for (int32_t j = i-1; j <= i+1; j++) {
9282             Median[k++] = m_Image[n+j][3] - m_Image[n+j][1];
9283           }
9284         }
9285         for (unsigned short i=0; i < sizeof opt; i+=2) {
9286           if (Median[opt[i]] > Median[opt[i+1]]) {
9287             SWAP (Median[opt[i]] , Median[opt[i+1]]);
9288           }
9289         }
9290         m_Image[n][c] = CLIP(Median[4] + m_Image[n][1]);
9291       }
9292     }
9293   }
9294 }
9295 
9296 ////////////////////////////////////////////////////////////////////////////////
9297 //
9298 // WaveletDenoise
9299 // (original from dcraw TODO Refine and analyse)
9300 // Be aware :
9301 //   Changes m_WhiteLevel
9302 //   Changes m_Blacklevel
9303 //
9304 ////////////////////////////////////////////////////////////////////////////////
9305 
ptWaveletDenoise()9306 void CLASS ptWaveletDenoise() {
9307   static const float Noise[] =
9308   { 0.8002,0.2735,0.1202,0.0585,0.0291,0.0152,0.0080,0.0044 };
9309 
9310   int Scale=1;
9311   int lev, hpass, lpass, wlast, blk[2];
9312 
9313   TRACEKEYVALS("BlackLevel","%d",m_BlackLevel);
9314   TRACEKEYVALS("WhiteLevel","%d",m_WhiteLevel);
9315 
9316   while (m_WhiteLevel << Scale < 0x10000) Scale++;
9317   m_WhiteLevel <<= --Scale;
9318   m_BlackLevel <<= Scale;
9319   for (int c=0; c<4; c++) m_CBlackLevel[c] <<= Scale;
9320 
9321   TRACEKEYVALS("Scale(denoise)","%d",Scale);
9322   TRACEKEYVALS("BlackLevel","%d",m_BlackLevel);
9323   TRACEKEYVALS("WhiteLevel","%d",m_WhiteLevel);
9324 
9325   uint32_t Size = m_OutHeight*m_OutWidth;
9326   float *fImage = (float*)
9327     MALLOC((Size*3 +m_OutHeight+ m_OutWidth)* sizeof(*fImage));
9328   merror(fImage,"WaveletDenoise()");
9329 
9330   float* fTemp = fImage + Size*3;
9331   short NrColors = m_Colors;
9332   if (NrColors == 3 && m_Filters) NrColors++;
9333   for (short c=0; c<NrColors; c++) {  /* deNoise R,G1,B,G3 individually */
9334     for (uint32_t i=0; i < Size; i++) {
9335       fImage[i] = 256 * sqrt((unsigned) (m_Image[i][c] << Scale));
9336     }
9337     for (hpass=lev=0; lev < 5; lev++) {
9338       lpass = Size*((lev & 1)+1);
9339       for (uint16_t Row=0; Row < m_OutHeight; Row++) {
9340         hat_transform(fTemp,fImage+hpass+Row*m_OutWidth,1,m_OutWidth,1<<lev);
9341   for (uint16_t Col=0; Col < m_OutWidth; Col++) {
9342           fImage[lpass + Row*m_OutWidth + Col] = fTemp[Col] * 0.25;
9343         }
9344       }
9345       for (uint16_t Col=0; Col < m_OutWidth; Col++) {
9346         hat_transform(fTemp,fImage+lpass+Col,m_OutWidth,m_OutHeight,1<<lev);
9347         for (uint16_t Row=0; Row < m_OutHeight; Row++) {
9348           fImage[lpass + Row*m_OutWidth + Col] = fTemp[Row] * 0.25;
9349         }
9350       }
9351       float Threshold = m_UserSetting_DenoiseThreshold * Noise[lev];
9352       for (uint32_t i=0; i < Size; i++) {
9353         fImage[hpass+i] -= fImage[lpass+i];
9354         if (fImage[hpass+i] < -Threshold) {
9355           fImage[hpass+i] += Threshold;
9356         } else if (fImage[hpass+i] >  Threshold) {
9357           fImage[hpass+i] -= Threshold;
9358         } else {
9359           fImage[hpass+i] = 0;
9360         }
9361         if (hpass) {
9362           fImage[i] += fImage[hpass+i];
9363         }
9364       }
9365       hpass = lpass;
9366     }
9367     for (uint32_t i=0; i < Size; i++) {
9368       m_Image[i][c] = CLIP((int32_t)(SQR(fImage[i]+fImage[lpass+i])/0x10000));
9369     }
9370   }
9371   if (m_Filters && m_Colors == 3) {  /* pull G1 and G3 closer together */
9372     float Multiplier[2];
9373     for (uint16_t Row=0; Row < 2; Row++) {
9374       Multiplier[Row] = 0.125 *
9375         VALUE(m_PreMultipliers[FC(Row+1,0) | 1]) /
9376         VALUE(m_PreMultipliers[FC(Row,0) | 1]);
9377       blk[Row] = m_CBlackLevel[FC(Row,0) | 1];
9378     }
9379     uint16_t* Window[4];
9380     for (short i=0; i < 4; i++) {
9381       Window[i] = (uint16_t *) fImage + m_Width*i;
9382     }
9383     wlast = -1;
9384     for (uint16_t Row=1; Row < m_Height-1; Row++) {
9385       while (wlast < Row+1) {
9386         wlast++;
9387   for (short i=0; i < 4; i++) {
9388     Window[(i+3) & 3] = Window[i];
9389         }
9390   for (uint16_t Col = FC(wlast,1) & 1; Col < m_Width; Col+=2) {
9391     Window[2][Col] = BAYER(wlast,Col);
9392         }
9393       }
9394       float Threshold = m_UserSetting_DenoiseThreshold/512;
9395       float Average;
9396       float Difference;
9397       for (uint16_t Col = (FC(Row,0) & 1)+1; Col < m_Width-1; Col+=2) {
9398   Average = ( Window[0][Col-1] + Window[0][Col+1] +
9399         Window[2][Col-1] + Window[2][Col+1] - blk[~Row & 1]*4 )
9400           * Multiplier[Row & 1]
9401           + (Window[1][Col] + blk[Row & 1]) * 0.5;
9402   Average = Average < 0 ? 0 : sqrt(Average);
9403   Difference = sqrt(BAYER(Row,Col)) - Average;
9404   if (Difference < -Threshold) {
9405           Difference += Threshold;
9406   } else if (Difference >  Threshold) {
9407           Difference -= Threshold;
9408   } else {
9409           Difference = 0;
9410         }
9411   BAYER(Row,Col) = CLIP((int32_t)(SQR(Average+Difference) + 0.5));
9412       }
9413     }
9414   }
9415   FREE(fImage);
9416 }
9417 
9418 ////////////////////////////////////////////////////////////////////////////////
9419 //
9420 // RebuildHighlights
9421 // (original from dcraw TODO Refine and analyse)
9422 //
9423 ////////////////////////////////////////////////////////////////////////////////
9424 
9425 #define SCALE (4 >> m_Shrink)
ptRebuildHighlights(const short highlight)9426 void CLASS ptRebuildHighlights(const short highlight) {
9427   float *map, sum, wgt, grow;
9428   int hsat[4], count, spread, change, val, i;
9429   unsigned high, wide, mrow, mcol, row, col, d, y, x;
9430   uint16_t *pixel;
9431   static const signed char dir[8][2] =
9432     { {-1,-1}, {-1,0}, {-1,1}, {0,1}, {1,1}, {1,0}, {1,-1}, {0,-1} };
9433 
9434   grow = pow (2, 1-highlight);
9435   for (short c=0;c<m_Colors;c++)  hsat[c] = (int)(32000 * VALUE(m_PreMultipliers[c]));
9436   short kc = 0;
9437   for (short c=1; c < m_Colors; c++)
9438     if (VALUE(m_PreMultipliers[kc]) < VALUE(m_PreMultipliers[c])) kc = c;
9439   high = m_Height / SCALE;
9440   wide =  m_Width / SCALE;
9441   map = (float *) CALLOC (high*wide, sizeof *map);
9442   merror (map, "recover_highlights()");
9443   for (short c=0;c<m_Colors;c++) {
9444     if (c != kc) {
9445       memset (map, 0, high*wide*sizeof *map);
9446 #pragma omp parallel for schedule(static) private(mrow, mcol, sum, wgt, count, pixel, row, col)
9447       for (mrow=0; mrow < high; mrow++) {
9448         for (mcol=0; mcol < wide; mcol++) {
9449           sum = wgt = count = 0;
9450           for (row = mrow*SCALE; row < (mrow+1)*SCALE; row++) {
9451             for (col = mcol*SCALE; col < (mcol+1)*SCALE; col++) {
9452               pixel = m_Image[row*m_Width+col];
9453               if (pixel[c] / hsat[c] == 1 && pixel[kc] > 24000) {
9454                 sum += pixel[c];
9455                 wgt += pixel[kc];
9456                 count++;
9457               }
9458             }
9459             if (count == SCALE*SCALE) map[mrow*wide+mcol] = sum / wgt;
9460           }
9461         }
9462       }
9463       for (spread = (int)(32/grow); spread--; ) {
9464 #pragma omp parallel for schedule(static) private(mrow, mcol, sum, count, x, y, d)
9465         for (mrow=0; mrow < high; mrow++) {
9466           for (mcol=0; mcol < wide; mcol++) {
9467             if (map[mrow*wide+mcol]) continue;
9468             sum = count = 0;
9469             for (d=0; d < 8; d++) {
9470               y = mrow + dir[d][0];
9471               x = mcol + dir[d][1];
9472               if (y < high && x < wide && map[y*wide+x] > 0) {
9473                 sum  += (1 + (d & 1)) * map[y*wide+x];
9474                 count += 1 + (d & 1);
9475               }
9476             }
9477             if (count > 3)
9478               map[mrow*wide+mcol] = - (sum+grow) / (count+grow);
9479           }
9480         }
9481         change = 0;
9482 #pragma omp parallel for schedule(static) private(i) reduction(||:change)
9483         for (i=0; i < (int)(high*wide); i++) {
9484           if (map[i] < 0) {
9485             map[i] = -map[i];
9486             change = 1;
9487           }
9488         }
9489         if (!change) break;
9490       }
9491 #pragma omp parallel for schedule(static) private(i)
9492       for (i=0; i < (int)(high*wide); i++) {
9493         if (map[i] == 0) map[i] = 1;
9494       }
9495 #pragma omp parallel for schedule(static) private(mrow, mcol, row, col, pixel, val)
9496       for (mrow=0; mrow < high; mrow++) {
9497         for (mcol=0; mcol < wide; mcol++) {
9498           for (row = mrow*SCALE; row < (mrow+1)*SCALE; row++) {
9499             for (col = mcol*SCALE; col < (mcol+1)*SCALE; col++) {
9500               pixel = m_Image[row*m_Width+col];
9501               if (pixel[c] / hsat[c] > 1) {
9502                 val = (int)(pixel[kc] * map[mrow*wide+mcol]);
9503                 if (pixel[c] < val) pixel[c] = CLIP(val);
9504               }
9505             }
9506           }
9507         }
9508       }
9509     }
9510   }
9511   FREE (map);
9512 }
9513 #undef SCALE
9514 
9515 ////////////////////////////////////////////////////////////////////////////////
9516 //
9517 // LabToCam helper function.
9518 //
9519 // FIXME
9520 // At this moment this is verbatim copies of ptImage.cpp. Room for improvement.
9521 //
9522 ////////////////////////////////////////////////////////////////////////////////
9523 
9524 
LabToCam(double Lab[3],uint16_t Cam[4])9525 void CLASS LabToCam(double Lab[3],uint16_t Cam[4]) {
9526 
9527   if(!ToCamFunctionInited) {
9528     for(short i=0;i<m_Colors;i++) {
9529       for (short j=0;j<3;j++) {
9530         MatrixXYZToCam[i][j] = 0.0;
9531         for (short k=0;k<3;k++) {
9532           MatrixXYZToCam[i][j] +=
9533             m_MatrixSRGBToCamRGB[i][k] * MatrixXYZToRGB[ptSpace_sRGB_D65][k][j];
9534         }
9535       }
9536     }
9537   ToCamFunctionInited = 1;
9538   }
9539 
9540   double xyz[3];
9541   double fx,fy,fz;
9542   double xr,yr,zr;
9543   const double epsilon = 216.0/24389.0;
9544   const double kappa   = 24389.0/27.0;
9545 
9546   const double L = Lab[0];
9547   const double a = Lab[1];
9548   const double b = Lab[2];
9549 
9550   const double Tmp1 = (L+16.0)/116.0;
9551 
9552   yr = (L<=kappa*epsilon)?
9553        (L/kappa):(Tmp1*Tmp1*Tmp1);
9554   fy = (yr<=epsilon) ? ((kappa*yr+16.0)/116.0) : Tmp1;
9555   fz = fy - b/200.0;
9556   fx = a/500.0 + fy;
9557   const double fz3 = fz*fz*fz;
9558   const double fx3 = fx*fx*fx;
9559   zr = (fz3<=epsilon) ? ((116.0*fz-16.0)/kappa) : fz3;
9560   xr = (fx3<=epsilon) ? ((116.0*fx-16.0)/kappa) : fx3;
9561 
9562   xyz[0] = xr*D65Reference[0]*65535.0 - 0.5;
9563   xyz[1] = yr*D65Reference[1]*65535.0 - 0.5;
9564   xyz[2] = zr*D65Reference[2]*65535.0 - 0.5;
9565 
9566   // And finally to RGB via the matrix.
9567   for (short c=0; c<m_Colors; c++) {
9568     double Value = 0;
9569     Value += MatrixXYZToCam[c][0] * xyz[0];
9570     Value += MatrixXYZToCam[c][1] * xyz[1];
9571     Value += MatrixXYZToCam[c][2] * xyz[2];
9572     Cam[c] = (uint16_t) CLIP((int32_t)(Value));
9573   }
9574 }
9575 
9576 ////////////////////////////////////////////////////////////////////////////////
9577 //
9578 // CamToLab helper function.
9579 //
9580 ////////////////////////////////////////////////////////////////////////////////
9581 
9582 
CamToLab(uint16_t Cam[4],double Lab[3])9583 void CLASS CamToLab(uint16_t Cam[4], double Lab[3]) {
9584 
9585   // Initialize the lookup table for the RGB->LAB function
9586   // if this would be the first time.
9587   if (!ToLABFunctionInited) {
9588     // Remark : we extend the table well beyond r>1.0 for numerical
9589     // stability purposes. XYZ>1.0 occurs sometimes and this way
9590     // it stays stable (srgb->lab->srgb correct within 0.02%)
9591     for (uint32_t i=0; i<0x20000; i++) {
9592       double r = (double)(i) / 0xffff;
9593       ToLABFunctionTable[i] = r > 216.0/24389.0 ?
9594                               pow(r,1/3.0) :
9595                               (24389.0/27.0*r + 16.0)/116.0;
9596     }
9597     for(short i=0;i<3;i++) {
9598       for (short j=0;j<m_Colors;j++) {
9599         MatrixCamToXYZ[i][j] = 0.0;
9600         for (short k=0;k<3;k++) {
9601           MatrixCamToXYZ[i][j] +=
9602             MatrixRGBToXYZ[ptSpace_sRGB_D65][i][k] * m_MatrixCamRGBToSRGB[k][j];
9603         }
9604       }
9605     }
9606   ToLABFunctionInited = 1;
9607   }
9608 
9609   // First go to XYZ
9610   double xyz[3] = {0.5,0.5,0.5};
9611   for (short Color = 0; Color < m_Colors; Color++) {
9612     xyz[0] += MatrixCamToXYZ[0][Color] * Cam[Color];
9613     xyz[1] += MatrixCamToXYZ[1][Color] * Cam[Color];
9614     xyz[2] += MatrixCamToXYZ[2][Color] * Cam[Color];
9615   }
9616 
9617   // Reference White
9618   xyz[0] /= D65Reference[0];
9619   xyz[1] /= D65Reference[1];
9620   xyz[2] /= D65Reference[2];
9621 
9622   // Then to Lab
9623   xyz[0] = ToLABFunctionTable[ (int32_t) MAX(0.0,xyz[0]) ];
9624   xyz[1] = ToLABFunctionTable[ (int32_t) MAX(0.0,xyz[1]) ];
9625   xyz[2] = ToLABFunctionTable[ (int32_t) MAX(0.0,xyz[2]) ];
9626 
9627   // L in 0 , a in 1, b in 2
9628   Lab[0] = 116.0 * xyz[1] - 16.0;
9629   Lab[1] = 500.0*(xyz[0]-xyz[1]);
9630   Lab[2] = 200.0*(xyz[1]-xyz[2]);
9631 }
9632 
9633 //==============================================================================
9634 
thumbnail()9635 TImage8RawData ptDcRaw::thumbnail() {
9636   m_Thumb.clear();
9637 
9638   if(m_InputFile && m_LoadRawFunction) {
9639     fseek (m_InputFile, m_ThumbOffset, SEEK_SET);
9640     (this->*m_WriteThumb)();
9641   }
9642 
9643   return m_Thumb;
9644 }
9645 
9646