Commit message: adopted dcraw 9.20
CVE: CVE-2018-5816
Vulnerability description: An integer overflow error within the "identify()" function (internal/dcraw_common.cpp) in LibRaw versions prior to 0.18.12 can be exploited to trigger a division by zero via specially crafted NOKIARAW file (Note: This vulnerability is caused due to an incomplete fix of CVE-2018-5804).

Project: LibRaw

void CLASS kodak_rgb_load_raw()
{
  short buf[768], *bp;
  int row, col, len, c, i, rgb[3];
  ushort *ip=image[0];

  for (row=0; row < height; row++)
  {
#ifdef LIBRAW_LIBRARY_BUILD
    checkCancel();
#endif
    for (col=0; col < width; col+=256) {
      len = MIN (256, width-col);
      kodak_65000_decode (buf, len*3);
      memset (rgb, 0, sizeof rgb);
      for (bp=buf, i=0; i < len; i++, ip+=4)
	FORC3 if ((ip[c] = rgb[c] += *bp++) >> 12) derror();
    }
  }
}

Project: LibRaw

int LibRaw::get_decoder_info(libraw_decoder_info_t* d_info)
{
  if(!d_info)   return LIBRAW_UNSPECIFIED_ERROR;
  if(!load_raw) return LIBRAW_OUT_OF_ORDER_CALL;
  
  d_info->decoder_flags = LIBRAW_DECODER_NOTSET;
  int rawdata = (imgdata.idata.filters || P1.colors == 1);
  // dcraw.c names order
  if (load_raw == &LibRaw::canon_600_load_raw) 
    {
      d_info->decoder_name = "canon_600_load_raw()";   
      d_info->decoder_flags = LIBRAW_DECODER_FLATFIELD; // WB set within decoder, no need to load raw
    }
  else if (load_raw == &LibRaw::canon_load_raw)
    {
      d_info->decoder_name = "canon_load_raw()"; 
      d_info->decoder_flags = LIBRAW_DECODER_FLATFIELD;
    }
  else if (load_raw == &LibRaw::lossless_jpeg_load_raw)
    {
      // Check rbayer
      d_info->decoder_name = "lossless_jpeg_load_raw()"; 
      d_info->decoder_flags = LIBRAW_DECODER_FLATFIELD | LIBRAW_DECODER_HASCURVE | LIBRAW_DECODER_TRYRAWSPEED;
    }
  else if (load_raw == &LibRaw::canon_sraw_load_raw) 
    {
      d_info->decoder_name = "canon_sraw_load_raw()";
      d_info->decoder_flags = LIBRAW_DECODER_LEGACY | LIBRAW_DECODER_TRYRAWSPEED; 
    }
  else if (load_raw == &LibRaw::lossless_dng_load_raw) 
    {
      // Check rbayer
      d_info->decoder_name = "lossless_dng_load_raw()"; 
      d_info->decoder_flags = rawdata? LIBRAW_DECODER_FLATFIELD : LIBRAW_DECODER_LEGACY ;
      d_info->decoder_flags |= LIBRAW_DECODER_HASCURVE;
      d_info->decoder_flags |= LIBRAW_DECODER_TRYRAWSPEED;
    }
  else if (load_raw == &LibRaw::packed_dng_load_raw)
    {
      // Check rbayer
      d_info->decoder_name = "packed_dng_load_raw()"; 
      d_info->decoder_flags = rawdata ? LIBRAW_DECODER_FLATFIELD : LIBRAW_DECODER_LEGACY;
      d_info->decoder_flags |= LIBRAW_DECODER_HASCURVE;
      d_info->decoder_flags |= LIBRAW_DECODER_TRYRAWSPEED;
    }
  else if (load_raw == &LibRaw::pentax_load_raw )
    {
      d_info->decoder_name = "pentax_load_raw()"; 
      d_info->decoder_flags = LIBRAW_DECODER_FLATFIELD  | LIBRAW_DECODER_TRYRAWSPEED;
    }
  else if (load_raw == &LibRaw::nikon_load_raw)
    {
      // Check rbayer
      d_info->decoder_name = "nikon_load_raw()";
      d_info->decoder_flags = LIBRAW_DECODER_FLATFIELD | LIBRAW_DECODER_TRYRAWSPEED;
    }
  else if (load_raw == &LibRaw::rollei_load_raw )
    {
      // UNTESTED
      d_info->decoder_name = "rollei_load_raw()"; 
      d_info->decoder_flags = LIBRAW_DECODER_FLATFIELD;
    }
  else if (load_raw == &LibRaw::phase_one_load_raw )
    {
      d_info->decoder_name = "phase_one_load_raw()"; 
      d_info->decoder_flags = LIBRAW_DECODER_FLATFIELD;
    }
  else if (load_raw == &LibRaw::phase_one_load_raw_c )
    {
      d_info->decoder_name = "phase_one_load_raw_c()"; 
      d_info->decoder_flags = LIBRAW_DECODER_FLATFIELD;
    }
  else if (load_raw == &LibRaw::hasselblad_load_raw )
    {
      d_info->decoder_name = "hasselblad_load_raw()"; 
      d_info->decoder_flags = LIBRAW_DECODER_FLATFIELD;
    }
  else if (load_raw == &LibRaw::leaf_hdr_load_raw )
    {
      d_info->decoder_name = "leaf_hdr_load_raw()"; 
      d_info->decoder_flags = imgdata.idata.filters? LIBRAW_DECODER_FLATFIELD:LIBRAW_DECODER_LEGACY;
    }
  else if (load_raw == &LibRaw::unpacked_load_raw )
    {
      d_info->decoder_name = "unpacked_load_raw()"; 
      d_info->decoder_flags = LIBRAW_DECODER_FLATFIELD | LIBRAW_DECODER_USEBAYER2;
    }
  else if (load_raw == &LibRaw::sinar_4shot_load_raw )
    {
      // UNTESTED
      d_info->decoder_name = "sinar_4shot_load_raw()";
      d_info->decoder_flags = (O.shot_select|| O.half_size)?LIBRAW_DECODER_FLATFIELD:LIBRAW_DECODER_LEGACY;
    }
  else if (load_raw == &LibRaw::imacon_full_load_raw )
    {
      d_info->decoder_name = "imacon_full_load_raw()"; 
      d_info->decoder_flags = LIBRAW_DECODER_LEGACY; 
    }
  else if (load_raw == &LibRaw::hasselblad_full_load_raw )
    {
      d_info->decoder_name = "hasselblad_full_load_raw()"; 
      d_info->decoder_flags = LIBRAW_DECODER_LEGACY; 
    }
  else if (load_raw == &LibRaw::packed_load_raw )
    {
      d_info->decoder_name = "packed_load_raw()";
      d_info->decoder_flags = LIBRAW_DECODER_FLATFIELD;
      d_info->decoder_flags |= LIBRAW_DECODER_TRYRAWSPEED;
    }
  else if (load_raw == &LibRaw::nokia_load_raw )
    {
      // UNTESTED
      d_info->decoder_name = "nokia_load_raw()";
      d_info->decoder_flags = LIBRAW_DECODER_FLATFIELD;
    }
  else if (load_raw == &LibRaw::canon_rmf_load_raw )
    {
      // UNTESTED
      d_info->decoder_name = "canon_rmf_load_raw()";
      d_info->decoder_flags = LIBRAW_DECODER_FLATFIELD;
    }
  else if (load_raw == &LibRaw::panasonic_load_raw )
    {
      d_info->decoder_name = "panasonic_load_raw()";
      d_info->decoder_flags = LIBRAW_DECODER_FLATFIELD  | LIBRAW_DECODER_TRYRAWSPEED;
    }
  else if (load_raw == &LibRaw::olympus_load_raw )
    {
      d_info->decoder_name = "olympus_load_raw()"; 
      d_info->decoder_flags = LIBRAW_DECODER_FLATFIELD | LIBRAW_DECODER_TRYRAWSPEED;
    }
  else if (load_raw == &LibRaw::minolta_rd175_load_raw ) 
    {  
      // UNTESTED
      d_info->decoder_name = "minolta_rd175_load_raw()"; 
      d_info->decoder_flags = LIBRAW_DECODER_FLATFIELD;
    }
  else if (load_raw == &LibRaw::quicktake_100_load_raw )
    {
      // UNTESTED
      d_info->decoder_name = "quicktake_100_load_raw()";
      d_info->decoder_flags = LIBRAW_DECODER_FLATFIELD;
    }
  else if (load_raw == &LibRaw::kodak_radc_load_raw )
    {
      d_info->decoder_name = "kodak_radc_load_raw()"; 
      d_info->decoder_flags = LIBRAW_DECODER_FLATFIELD;
    }
  else if (load_raw == &LibRaw::kodak_jpeg_load_raw )
    {
      // UNTESTED + RBAYER
      d_info->decoder_name = "kodak_jpeg_load_raw()"; 
      d_info->decoder_flags = LIBRAW_DECODER_FLATFIELD;
    }
  else if (load_raw == &LibRaw::lossy_dng_load_raw)
    {
      // Check rbayer
      d_info->decoder_name = "lossy_dng_load_raw()"; 
      d_info->decoder_flags = LIBRAW_DECODER_LEGACY | LIBRAW_DECODER_TRYRAWSPEED;
      d_info->decoder_flags |= LIBRAW_DECODER_HASCURVE;
    }
  else if (load_raw == &LibRaw::kodak_dc120_load_raw )
    {
      d_info->decoder_name = "kodak_dc120_load_raw()"; 
      d_info->decoder_flags = LIBRAW_DECODER_FLATFIELD;
    }
  else if (load_raw == &LibRaw::eight_bit_load_raw )
    {
      d_info->decoder_name = "eight_bit_load_raw()";
      d_info->decoder_flags = LIBRAW_DECODER_FLATFIELD;
      d_info->decoder_flags |= LIBRAW_DECODER_HASCURVE;
    }
  else if (load_raw == &LibRaw::kodak_yrgb_load_raw )    
    {
      d_info->decoder_name = "kodak_yrgb_load_raw()"; 
      d_info->decoder_flags = LIBRAW_DECODER_LEGACY;
      d_info->decoder_flags |= LIBRAW_DECODER_HASCURVE;
    }
  else if (load_raw == &LibRaw::kodak_262_load_raw )
    {
      d_info->decoder_name = "kodak_262_load_raw()"; // UNTESTED!
      d_info->decoder_flags = LIBRAW_DECODER_FLATFIELD;
      d_info->decoder_flags |= LIBRAW_DECODER_HASCURVE;
    }
  else if (load_raw == &LibRaw::kodak_65000_load_raw )
    {
      d_info->decoder_name = "kodak_65000_load_raw()";
      d_info->decoder_flags = LIBRAW_DECODER_FLATFIELD;
      d_info->decoder_flags |= LIBRAW_DECODER_HASCURVE;
    }
  else if (load_raw == &LibRaw::kodak_ycbcr_load_raw )
    {
      // UNTESTED
      d_info->decoder_name = "kodak_ycbcr_load_raw()"; 
      d_info->decoder_flags = LIBRAW_DECODER_LEGACY;
      d_info->decoder_flags |= LIBRAW_DECODER_HASCURVE;
    }
  else if (load_raw == &LibRaw::kodak_rgb_load_raw ) 
    {
      // UNTESTED
      d_info->decoder_name = "kodak_rgb_load_raw()"; 
      d_info->decoder_flags = LIBRAW_DECODER_LEGACY;
    }
  else if (load_raw == &LibRaw::sony_load_raw )
    {
      d_info->decoder_name = "sony_load_raw()"; 
      d_info->decoder_flags = LIBRAW_DECODER_FLATFIELD;
    }
  else if (load_raw == &LibRaw::sony_arw_load_raw )
    {
      d_info->decoder_name = "sony_arw_load_raw()";
      d_info->decoder_flags = LIBRAW_DECODER_FLATFIELD;
      d_info->decoder_flags |= LIBRAW_DECODER_TRYRAWSPEED;

    }
  else if (load_raw == &LibRaw::sony_arw2_load_raw )
    {
      d_info->decoder_name = "sony_arw2_load_raw()";
      d_info->decoder_flags = LIBRAW_DECODER_FLATFIELD;
      d_info->decoder_flags |= LIBRAW_DECODER_HASCURVE;
      d_info->decoder_flags |= LIBRAW_DECODER_TRYRAWSPEED;
      d_info->decoder_flags |= LIBRAW_DECODER_ITSASONY;
    }
  else if (load_raw == &LibRaw::samsung_load_raw )
    {
      d_info->decoder_name = "samsung_load_raw()";
      d_info->decoder_flags = LIBRAW_DECODER_FLATFIELD;
      d_info->decoder_flags |= LIBRAW_DECODER_TRYRAWSPEED;
    }
  else if (load_raw == &LibRaw::smal_v6_load_raw )
    {
      // UNTESTED
      d_info->decoder_name = "smal_v6_load_raw()";
      d_info->decoder_flags = LIBRAW_DECODER_FLATFIELD;
    }
  else if (load_raw == &LibRaw::smal_v9_load_raw )
    {
      // UNTESTED
      d_info->decoder_name = "smal_v9_load_raw()";
      d_info->decoder_flags = LIBRAW_DECODER_FLATFIELD;
    }
  else  if (load_raw == &LibRaw::redcine_load_raw)
    {
      d_info->decoder_name = "redcine_load_raw()";
      d_info->decoder_flags = LIBRAW_DECODER_FLATFIELD; 
      d_info->decoder_flags |= LIBRAW_DECODER_HASCURVE;
    }
  else if (load_raw == &LibRaw::x3f_load_raw )
    {
      d_info->decoder_name = "x3f_load_raw()";
      d_info->decoder_flags = LIBRAW_DECODER_LEGACY | LIBRAW_DECODER_OWNALLOC; 
    }
#ifdef LIBRAW_DEMOSAIC_PACK_GPL2
  else if (load_raw == &LibRaw::foveon_sd_load_raw )
    {
      d_info->decoder_name = "foveon_sd_load_raw()";
      d_info->decoder_flags = LIBRAW_DECODER_LEGACY; 
    }
  else if (load_raw == &LibRaw::foveon_dp_load_raw )
    {
      d_info->decoder_name = "foveon_dp_load_raw()";
      d_info->decoder_flags = LIBRAW_DECODER_LEGACY; 
    }
#endif
  else
    {
      d_info->decoder_name = "Unknown unpack function";
      d_info->decoder_flags = LIBRAW_DECODER_NOTSET;
    }
  return LIBRAW_SUCCESS;
}

Project: LibRaw

void LibRaw::x3f_load_raw()
{
  int raise_error=0;
  x3f_t *x3f = (x3f_t*)_x3f_data;
  if(!x3f) return; // No data pointer set
  if(X3F_OK == x3f_load_data(x3f, x3f_get_raw(x3f)))
    {
      x3f_directory_entry_t *DE = x3f_get_raw(x3f);
      x3f_directory_entry_header_t *DEH = &DE->header;
      x3f_image_data_t *ID = &DEH->data_subsection.image_data;
      x3f_huffman_t *HUF = ID->huffman;
      x3f_true_t *TRU = ID->tru;
      uint16_t *data = NULL;
      if(ID->rows != S.raw_height || ID->columns != S.raw_width)
        {
          raise_error = 1;
          goto end;
        }
      if (HUF != NULL)
        data = HUF->x3rgb16.element;
      if (TRU != NULL)
        data = TRU->x3rgb16.element;
      if (data == NULL) 
        {
          raise_error = 1;
          goto end;
        }
      imgdata.rawdata.color3_image = (ushort (*)[3])data;
    }
  else
    raise_error = 1;
end:
  if(raise_error)
    throw LIBRAW_EXCEPTION_IO_CORRUPT;
}

Project: LibRaw

void CLASS adobe_coeff (const char *t_make, const char *t_model)
{
  static const struct {
    const char *prefix;
    short t_black, t_maximum, trans[12];
  } table[] = {
    { "AgfaPhoto DC-833m", 0, 0,	/* DJC */
	{ 11438,-3762,-1115,-2409,9914,2497,-1227,2295,5300 } },
    { "Apple QuickTake", 0, 0,		/* DJC */
	{ 21392,-5653,-3353,2406,8010,-415,7166,1427,2078 } },
    { "Canon EOS D2000", 0, 0,
	{ 24542,-10860,-3401,-1490,11370,-297,2858,-605,3225 } },
    { "Canon EOS D6000", 0, 0,
	{ 20482,-7172,-3125,-1033,10410,-285,2542,226,3136 } },
    { "Canon EOS D30", 0, 0,
	{ 9805,-2689,-1312,-5803,13064,3068,-2438,3075,8775 } },
    { "Canon EOS D60", 0, 0xfa0,
	{ 6188,-1341,-890,-7168,14489,2937,-2640,3228,8483 } },
    { "Canon EOS 5D Mark III", 0, 0x3c80,
	{ 6722,-635,-963,-4287,12460,2028,-908,2162,5668 } },
    { "Canon EOS 5D Mark II", 0, 0x3cf0,
	{ 4716,603,-830,-7798,15474,2480,-1496,1937,6651 } },
    { "Canon EOS 5D", 0, 0xe6c,
	{ 6347,-479,-972,-8297,15954,2480,-1968,2131,7649 } },
    { "Canon EOS 6D", 0, 0x3c82,
	{ 7034,-804,-1014,-4420,12564,2058,-851,1994,5758 } },
    { "Canon EOS 7D", 0, 0x3510,
	{ 6844,-996,-856,-3876,11761,2396,-593,1772,6198 } },
    { "Canon EOS 10D", 0, 0xfa0,
	{ 8197,-2000,-1118,-6714,14335,2592,-2536,3178,8266 } },
    { "Canon EOS 20Da", 0, 0,
	{ 14155,-5065,-1382,-6550,14633,2039,-1623,1824,6561 } },
    { "Canon EOS 20D", 0, 0xfff,
	{ 6599,-537,-891,-8071,15783,2424,-1983,2234,7462 } },
    { "Canon EOS 30D", 0, 0,
	{ 6257,-303,-1000,-7880,15621,2396,-1714,1904,7046 } },
    { "Canon EOS 40D", 0, 0x3f60,
	{ 6071,-747,-856,-7653,15365,2441,-2025,2553,7315 } },
    { "Canon EOS 50D", 0, 0x3d93,
	{ 4920,616,-593,-6493,13964,2784,-1774,3178,7005 } },
    { "Canon EOS 60D", 0, 0x2ff7,
	{ 6719,-994,-925,-4408,12426,2211,-887,2129,6051 } },
    { "Canon EOS 70D", 0, 0x3bc7,
	{ 7034,-804,-1014,-4420,12564,2058,-851,1994,5758 } },
    { "Canon EOS 100D", 0, 0x350f,
	{ 6602,-841,-939,-4472,12458,2247,-975,2039,6148 } },
    { "Canon EOS 300D", 0, 0xfa0,
	{ 8197,-2000,-1118,-6714,14335,2592,-2536,3178,8266 } },
    { "Canon EOS 350D", 0, 0xfff,
	{ 6018,-617,-965,-8645,15881,2975,-1530,1719,7642 } },
    { "Canon EOS 400D", 0, 0xe8e,
	{ 7054,-1501,-990,-8156,15544,2812,-1278,1414,7796 } },
    { "Canon EOS 450D", 0, 0x390d,
	{ 5784,-262,-821,-7539,15064,2672,-1982,2681,7427 } },
    { "Canon EOS 500D", 0, 0x3479,
	{ 4763,712,-646,-6821,14399,2640,-1921,3276,6561 } },
    { "Canon EOS 550D", 0, 0x3dd7,
	{ 6941,-1164,-857,-3825,11597,2534,-416,1540,6039 } },
    { "Canon EOS 600D", 0, 0x3510,
	{ 6461,-907,-882,-4300,12184,2378,-819,1944,5931 } },
    { "Canon EOS 650D", 0, 0x354d,
	{ 6602,-841,-939,-4472,12458,2247,-975,2039,6148 } },
    { "Canon EOS 700D", 0, 0x3c00,
	{ 6602,-841,-939,-4472,12458,2247,-975,2039,6148 } },
    { "Canon EOS 1000D", 0, 0xe43,
	{ 6771,-1139,-977,-7818,15123,2928,-1244,1437,7533 } },
    { "Canon EOS 1100D", 0, 0x3510,
	{ 6444,-904,-893,-4563,12308,2535,-903,2016,6728 } },
    { "Canon EOS M", 0, 0,
	{ 6602,-841,-939,-4472,12458,2247,-975,2039,6148 } },
    { "Canon EOS-1Ds Mark III", 0, 0x3bb0,
	{ 5859,-211,-930,-8255,16017,2353,-1732,1887,7448 } },
    { "Canon EOS-1Ds Mark II", 0, 0xe80,
	{ 6517,-602,-867,-8180,15926,2378,-1618,1771,7633 } },
    { "Canon EOS-1D Mark IV", 0, 0x3bb0,
	{ 6014,-220,-795,-4109,12014,2361,-561,1824,5787 } },
    { "Canon EOS-1D Mark III", 0, 0x3bb0,
	{ 6291,-540,-976,-8350,16145,2311,-1714,1858,7326 } },
    { "Canon EOS-1D Mark II N", 0, 0xe80,
	{ 6240,-466,-822,-8180,15825,2500,-1801,1938,8042 } },
    { "Canon EOS-1D Mark II", 0, 0xe80,
	{ 6264,-582,-724,-8312,15948,2504,-1744,1919,8664 } },
    { "Canon EOS-1DS", 0, 0xe20,
	{ 4374,3631,-1743,-7520,15212,2472,-2892,3632,8161 } },
    { "Canon EOS-1D C", 0, 0x3c4e,
	{ 6847,-614,-1014,-4669,12737,2139,-1197,2488,6846 } },
    { "Canon EOS-1D X", 0, 0x3c4e,
	{ 6847,-614,-1014,-4669,12737,2139,-1197,2488,6846 } },
    { "Canon EOS-1D", 0, 0xe20,
	{ 6806,-179,-1020,-8097,16415,1687,-3267,4236,7690 } },
    { "Canon EOS C500", 853, 0,		/* DJC */
	{ 17851,-10604,922,-7425,16662,763,-3660,3636,22278 } },
    { "Canon PowerShot A530", 0, 0,
	{ 0 } },	/* don't want the A5 matrix */
    { "Canon PowerShot A50", 0, 0,
	{ -5300,9846,1776,3436,684,3939,-5540,9879,6200,-1404,11175,217 } },
    { "Canon PowerShot A5", 0, 0,
	{ -4801,9475,1952,2926,1611,4094,-5259,10164,5947,-1554,10883,547 } },
    { "Canon PowerShot G10", 0, 0,
	{ 11093,-3906,-1028,-5047,12492,2879,-1003,1750,5561 } },
    { "Canon PowerShot G11", 0, 0,
	{ 12177,-4817,-1069,-1612,9864,2049,-98,850,4471 } },
    { "Canon PowerShot G12", 0, 0,
	{ 13244,-5501,-1248,-1508,9858,1935,-270,1083,4366 } },
    { "Canon PowerShot G15", 0, 0,
	{ 7474,-2301,-567,-4056,11456,2975,-222,716,4181 } },
    { "Canon PowerShot G16", 0, 0,
        { 14130,-8071,127,2199,6528,1551,3402,-1721,4960 } },
    { "Canon PowerShot G1 X", 0, 0,
	{ 7378,-1255,-1043,-4088,12251,2048,-876,1946,5805 } },
    { "Canon PowerShot G1", 0, 0,
	{ -4778,9467,2172,4743,-1141,4344,-5146,9908,6077,-1566,11051,557 } },
    { "Canon PowerShot G2", 0, 0,
	{ 9087,-2693,-1049,-6715,14382,2537,-2291,2819,7790 } },
    { "Canon PowerShot G3", 0, 0,
	{ 9212,-2781,-1073,-6573,14189,2605,-2300,2844,7664 } },
    { "Canon PowerShot G5", 0, 0,
	{ 9757,-2872,-933,-5972,13861,2301,-1622,2328,7212 } },
    { "Canon PowerShot G6", 0, 0,
	{ 9877,-3775,-871,-7613,14807,3072,-1448,1305,7485 } },
    { "Canon PowerShot G9", 0, 0,
	{ 7368,-2141,-598,-5621,13254,2625,-1418,1696,5743 } },
    { "Canon PowerShot Pro1", 0, 0,
	{ 10062,-3522,-999,-7643,15117,2730,-765,817,7323 } },
    { "Canon PowerShot Pro70", 34, 0,
	{ -4155,9818,1529,3939,-25,4522,-5521,9870,6610,-2238,10873,1342 } },
    { "Canon PowerShot Pro90", 0, 0,
	{ -4963,9896,2235,4642,-987,4294,-5162,10011,5859,-1770,11230,577 } },
    { "Canon PowerShot S30", 0, 0,
	{ 10566,-3652,-1129,-6552,14662,2006,-2197,2581,7670 } },
    { "Canon PowerShot S40", 0, 0,
	{ 8510,-2487,-940,-6869,14231,2900,-2318,2829,9013 } },
    { "Canon PowerShot S45", 0, 0,
	{ 8163,-2333,-955,-6682,14174,2751,-2077,2597,8041 } },
    { "Canon PowerShot S50", 0, 0,
	{ 8882,-2571,-863,-6348,14234,2288,-1516,2172,6569 } },
    { "Canon PowerShot S60", 0, 0,
	{ 8795,-2482,-797,-7804,15403,2573,-1422,1996,7082 } },
    { "Canon PowerShot S70", 0, 0,
	{ 9976,-3810,-832,-7115,14463,2906,-901,989,7889 } },
    { "Canon PowerShot S90", 0, 0,
	{ 12374,-5016,-1049,-1677,9902,2078,-83,852,4683 } },
    { "Canon PowerShot S95", 0, 0,
	{ 13440,-5896,-1279,-1236,9598,1931,-180,1001,4651 } },
    { "Canon PowerShot S120", 0, 0, /* LibRaw */
      { 10800,-4782,-628,-2057,10783,1176,-802,2091,4739 } },
    { "Canon PowerShot S110", 0, 0,
	{ 8039,-2643,-654,-3783,11230,2930,-206,690,4194 } },
    { "Canon PowerShot S100", 0, 0,
	{ 7968,-2565,-636,-2873,10697,2513,180,667,4211 } },
    { "Canon PowerShot SX1 IS", 0, 0,
	{ 6578,-259,-502,-5974,13030,3309,-308,1058,4970 } },
    { "Canon PowerShot SX50 HS", 0, 0,
	{ 12432,-4753,-1247,-2110,10691,1629,-412,1623,4926 } },
    { "Canon PowerShot A3300", 0, 0,	/* DJC */
	{ 10826,-3654,-1023,-3215,11310,1906,0,999,4960 } },
    { "Canon PowerShot A470", 0, 0,	/* DJC */
	{ 12513,-4407,-1242,-2680,10276,2405,-878,2215,4734 } },
    { "Canon PowerShot A610", 0, 0,	/* DJC */
	{ 15591,-6402,-1592,-5365,13198,2168,-1300,1824,5075 } },
    { "Canon PowerShot A620", 0, 0,	/* DJC */
	{ 15265,-6193,-1558,-4125,12116,2010,-888,1639,5220 } },
    { "Canon PowerShot A630", 0, 0,	/* DJC */
	{ 14201,-5308,-1757,-6087,14472,1617,-2191,3105,5348 } },
    { "Canon PowerShot A640", 0, 0,	/* DJC */
	{ 13124,-5329,-1390,-3602,11658,1944,-1612,2863,4885 } },
    { "Canon PowerShot A650", 0, 0,	/* DJC */
	{ 9427,-3036,-959,-2581,10671,1911,-1039,1982,4430 } },
    { "Canon PowerShot A720", 0, 0,	/* DJC */
	{ 14573,-5482,-1546,-1266,9799,1468,-1040,1912,3810 } },
    { "Canon PowerShot S3 IS", 0, 0,	/* DJC */
	{ 14062,-5199,-1446,-4712,12470,2243,-1286,2028,4836 } },
    { "Canon PowerShot SX110 IS", 0, 0,	/* DJC */
	{ 14134,-5576,-1527,-1991,10719,1273,-1158,1929,3581 } },
    { "Canon PowerShot SX220", 0, 0,	/* DJC */
	{ 13898,-5076,-1447,-1405,10109,1297,-244,1860,3687 } },
    { "Casio EX-S20", 0, 0,		/* DJC */
	{ 11634,-3924,-1128,-4968,12954,2015,-1588,2648,7206 } },
    { "Casio EX-Z750", 0, 0,		/* DJC */
	{ 10819,-3873,-1099,-4903,13730,1175,-1755,3751,4632 } },
    { "Casio EX-Z10", 128, 0xfff,	/* DJC */
	{ 9790,-3338,-603,-2321,10222,2099,-344,1273,4799 } },
    { "CINE 650", 0, 0,
	{ 3390,480,-500,-800,3610,340,-550,2336,1192 } },
    { "CINE 660", 0, 0,
	{ 3390,480,-500,-800,3610,340,-550,2336,1192 } },
    { "CINE", 0, 0,
	{ 20183,-4295,-423,-3940,15330,3985,-280,4870,9800 } },
    { "Contax N Digital", 0, 0xf1e,
	{ 7777,1285,-1053,-9280,16543,2916,-3677,5679,7060 } },
    { "Epson R-D1", 0, 0,
	{ 6827,-1878,-732,-8429,16012,2564,-704,592,7145 } },
    { "Fujifilm E550", 0, 0,
	{ 11044,-3888,-1120,-7248,15168,2208,-1531,2277,8069 } },
    { "Fujifilm E900", 0, 0,
	{ 9183,-2526,-1078,-7461,15071,2574,-2022,2440,8639 } },
    { "Fujifilm F5", 0, 0,
	{ 13690,-5358,-1474,-3369,11600,1998,-132,1554,4395 } },
    { "Fujifilm F6", 0, 0,
	{ 13690,-5358,-1474,-3369,11600,1998,-132,1554,4395 } },
    { "Fujifilm F77", 0, 0xfe9,
	{ 13690,-5358,-1474,-3369,11600,1998,-132,1554,4395 } },
    { "Fujifilm F7", 0, 0,
	{ 10004,-3219,-1201,-7036,15047,2107,-1863,2565,7736 } },
    { "Fujifilm F8", 0, 0,
	{ 13690,-5358,-1474,-3369,11600,1998,-132,1554,4395 } },
    { "Fujifilm S100FS", 514, 0,
	{ 11521,-4355,-1065,-6524,13767,3058,-1466,1984,6045 } },
    { "Fujifilm S20Pro", 0, 0,
	{ 10004,-3219,-1201,-7036,15047,2107,-1863,2565,7736 } },
    { "Fujifilm S20", 512, 0x3fff,
	{ 11401,-4498,-1312,-5088,12751,2613,-838,1568,5941 } },
    { "Fujifilm S2Pro", 128, 0,
	{ 12492,-4690,-1402,-7033,15423,1647,-1507,2111,7697 } },
    { "Fujifilm S3Pro", 0, 0,
	{ 11807,-4612,-1294,-8927,16968,1988,-2120,2741,8006 } },
    { "Fujifilm S5Pro", 0, 0,
	{ 12300,-5110,-1304,-9117,17143,1998,-1947,2448,8100 } },
    { "Fujifilm S5000", 0, 0,
	{ 8754,-2732,-1019,-7204,15069,2276,-1702,2334,6982 } },
    { "Fujifilm S5100", 0, 0,
	{ 11940,-4431,-1255,-6766,14428,2542,-993,1165,7421 } },
    { "Fujifilm S5500", 0, 0,
	{ 11940,-4431,-1255,-6766,14428,2542,-993,1165,7421 } },
    { "Fujifilm S5200", 0, 0,
	{ 9636,-2804,-988,-7442,15040,2589,-1803,2311,8621 } },
    { "Fujifilm S5600", 0, 0,
	{ 9636,-2804,-988,-7442,15040,2589,-1803,2311,8621 } },
    { "Fujifilm S6", 0, 0,
	{ 12628,-4887,-1401,-6861,14996,1962,-2198,2782,7091 } },
    { "Fujifilm S7000", 0, 0,
	{ 10190,-3506,-1312,-7153,15051,2238,-2003,2399,7505 } },
    { "Fujifilm S9000", 0, 0,
	{ 10491,-3423,-1145,-7385,15027,2538,-1809,2275,8692 } },
    { "Fujifilm S9500", 0, 0,
	{ 10491,-3423,-1145,-7385,15027,2538,-1809,2275,8692 } },
    { "Fujifilm S9100", 0, 0,
	{ 12343,-4515,-1285,-7165,14899,2435,-1895,2496,8800 } },
    { "Fujifilm S9600", 0, 0,
	{ 12343,-4515,-1285,-7165,14899,2435,-1895,2496,8800 } },
    { "Fujifilm SL1000", 0, 0,
	{ 11705,-4262,-1107,-2282,10791,1709,-555,1713,4945 } },
    { "Fujifilm IS-1", 0, 0,
	{ 21461,-10807,-1441,-2332,10599,1999,289,875,7703 } },
    { "Fujifilm IS Pro", 0, 0,
	{ 12300,-5110,-1304,-9117,17143,1998,-1947,2448,8100 } },
    { "Fujifilm HS10 HS11", 0, 0xf68,
	{ 12440,-3954,-1183,-1123,9674,1708,-83,1614,4086 } },
    { "Fujifilm HS2", 0, 0,
	{ 13690,-5358,-1474,-3369,11600,1998,-132,1554,4395 } },
    { "Fujifilm HS3", 0, 0,
	{ 13690,-5358,-1474,-3369,11600,1998,-132,1554,4395 } },
    { "Fujifilm HS50EXR", 0, 0,
	{ 12085,-4727,-953,-3257,11489,2002,-511,2046,4592 } },
    { "Fujifilm F900EXR", 0, 0,
	{ 12085,-4727,-953,-3257,11489,2002,-511,2046,4592 } },
    { "Fujifilm X100S", 0, 0,
	{ 10592,-4262,-1008,-3514,11355,2465,-870,2025,6386 } },
    { "Fujifilm X100", 0, 0,
	{ 12161,-4457,-1069,-5034,12874,2400,-795,1724,6904 } },
    { "Fujifilm X10", 0, 0,
	{ 13509,-6199,-1254,-4430,12733,1865,-331,1441,5022 } },
    { "Fujifilm X20", 0, 0,
	{ 11768,-4971,-1133,-4904,12927,2183,-480,1723,4605 } },
    { "Fujifilm X-Pro1", 0, 0,
	{ 10413,-3996,-993,-3721,11640,2361,-733,1540,6011 } },
    { "Fujifilm X-A1", 0, 0,
        { 10413,-3996,-993,-3721,11640,2361,-733,1540,6011 } },
    { "Fujifilm X-E1", 0, 0,
	{ 10413,-3996,-993,-3721,11640,2361,-733,1540,6011 } },
    { "Fujifilm X-E2", 0, 0,
      { 12066,-5927,-367,-1969,9878,1503,-721,2034,5453 } },
    { "Fujifilm XF1", 0, 0,
	{ 13509,-6199,-1254,-4430,12733,1865,-331,1441,5022 } },
    { "Fujifilm X-M1", 0, 0,
      { 13193,-6685,-425,-2229,10458,1534,-878,1763,5217 } },
    { "Fujifilm X-S1", 0, 0,
	{ 13509,-6199,-1254,-4430,12733,1865,-331,1441,5022 } },
    { "Fujifilm XQ1", 0, 0,
      { 14305,-7365,-687,-3117,12383,432,-287,1660,4361 } },
    { "Hasselblad Lunar", 128, 0,
	{ 5491,-1192,-363,-4951,12342,2948,-911,1722,7192 } },
    { "Hasselblad Stellar", 200, 0,
	{ 8651,-2754,-1057,-3464,12207,1373,-568,1398,4434 } },
    { "Imacon Ixpress", 0, 0,		/* DJC */
	{ 7025,-1415,-704,-5188,13765,1424,-1248,2742,6038 } },
    { "Kodak NC2000", 0, 0,
	{ 13891,-6055,-803,-465,9919,642,2121,82,1291 } },
    { "Kodak DCS315C", 8, 0,
	{ 17523,-4827,-2510,756,8546,-137,6113,1649,2250 } },
    { "Kodak DCS330C", 8, 0,
	{ 20620,-7572,-2801,-103,10073,-396,3551,-233,2220 } },
    { "Kodak DCS420", 0, 0,
	{ 10868,-1852,-644,-1537,11083,484,2343,628,2216 } },
    { "Kodak DCS460", 0, 0,
	{ 10592,-2206,-967,-1944,11685,230,2206,670,1273 } },
    { "Kodak EOSDCS1", 0, 0,
	{ 10592,-2206,-967,-1944,11685,230,2206,670,1273 } },
    { "Kodak EOSDCS3B", 0, 0,
	{ 9898,-2700,-940,-2478,12219,206,1985,634,1031 } },
    { "Kodak DCS520C", 178, 0,
	{ 24542,-10860,-3401,-1490,11370,-297,2858,-605,3225 } },
    { "Kodak DCS560C", 177, 0,
	{ 20482,-7172,-3125,-1033,10410,-285,2542,226,3136 } },
    { "Kodak DCS620C", 177, 0,
	{ 23617,-10175,-3149,-2054,11749,-272,2586,-489,3453 } },
    { "Kodak DCS620X", 176, 0,
	{ 13095,-6231,154,12221,-21,-2137,895,4602,2258 } },
    { "Kodak DCS660C", 173, 0,
	{ 18244,-6351,-2739,-791,11193,-521,3711,-129,2802 } },
    { "Kodak DCS720X", 0, 0,
	{ 11775,-5884,950,9556,1846,-1286,-1019,6221,2728 } },
    { "Kodak DCS760C", 0, 0,
	{ 16623,-6309,-1411,-4344,13923,323,2285,274,2926 } },
    { "Kodak DCS Pro SLR", 0, 0,
	{ 5494,2393,-232,-6427,13850,2846,-1876,3997,5445 } },
    { "Kodak DCS Pro 14nx", 0, 0,
	{ 5494,2393,-232,-6427,13850,2846,-1876,3997,5445 } },
    { "Kodak DCS Pro 14", 0, 0,
	{ 7791,3128,-776,-8588,16458,2039,-2455,4006,6198 } },
    { "Kodak ProBack645", 0, 0,
	{ 16414,-6060,-1470,-3555,13037,473,2545,122,4948 } },
    { "Kodak ProBack", 0, 0,
	{ 21179,-8316,-2918,-915,11019,-165,3477,-180,4210 } },
    { "Kodak P712", 0, 0,
	{ 9658,-3314,-823,-5163,12695,2768,-1342,1843,6044 } },
    { "Kodak P850", 0, 0xf7c,
	{ 10511,-3836,-1102,-6946,14587,2558,-1481,1792,6246 } },
    { "Kodak P880", 0, 0xfff,
	{ 12805,-4662,-1376,-7480,15267,2360,-1626,2194,7904 } },
    { "Kodak EasyShare Z980", 0, 0,
	{ 11313,-3559,-1101,-3893,11891,2257,-1214,2398,4908 } },
    { "Kodak EasyShare Z981", 0, 0,
	{ 12729,-4717,-1188,-1367,9187,2582,274,860,4411 } },
    { "Kodak EasyShare Z990", 0, 0xfed,
	{ 11749,-4048,-1309,-1867,10572,1489,-138,1449,4522 } },
    { "Kodak EASYSHARE Z1015", 0, 0xef1,
	{ 11265,-4286,-992,-4694,12343,2647,-1090,1523,5447 } },
    { "Leaf CMost", 0, 0,
	{ 3952,2189,449,-6701,14585,2275,-4536,7349,6536 } },
    { "Leaf Valeo 6", 0, 0,
	{ 3952,2189,449,-6701,14585,2275,-4536,7349,6536 } },
    { "Leaf Aptus 54S", 0, 0,
	{ 8236,1746,-1314,-8251,15953,2428,-3673,5786,5771 } },
    { "Leaf Aptus 65", 0, 0,
	{ 7914,1414,-1190,-8777,16582,2280,-2811,4605,5562 } },
    { "Leaf Aptus 75", 0, 0,
	{ 7914,1414,-1190,-8777,16582,2280,-2811,4605,5562 } },
    { "Leaf", 0, 0,
	{ 8236,1746,-1314,-8251,15953,2428,-3673,5786,5771 } },
    { "Mamiya ZD", 0, 0,
	{ 7645,2579,-1363,-8689,16717,2015,-3712,5941,5961 } },
    { "Micron 2010", 110, 0,		/* DJC */
	{ 16695,-3761,-2151,155,9682,163,3433,951,4904 } },
    { "Minolta DiMAGE 5", 0, 0xf7d,
	{ 8983,-2942,-963,-6556,14476,2237,-2426,2887,8014 } },
    { "Minolta DiMAGE 7Hi", 0, 0xf7d,
	{ 11368,-3894,-1242,-6521,14358,2339,-2475,3056,7285 } },
    { "Minolta DiMAGE 7", 0, 0xf7d,
	{ 9144,-2777,-998,-6676,14556,2281,-2470,3019,7744 } },
    { "Minolta DiMAGE A1", 0, 0xf8b,
	{ 9274,-2547,-1167,-8220,16323,1943,-2273,2720,8340 } },
    { "Minolta DiMAGE A200", 0, 0,
	{ 8560,-2487,-986,-8112,15535,2771,-1209,1324,7743 } },
    { "Minolta DiMAGE A2", 0, 0xf8f,
	{ 9097,-2726,-1053,-8073,15506,2762,-966,981,7763 } },
    { "Minolta DiMAGE Z2", 0, 0,	/* DJC */
	{ 11280,-3564,-1370,-4655,12374,2282,-1423,2168,5396 } },
    { "Minolta DYNAX 5", 0, 0xffb,
	{ 10284,-3283,-1086,-7957,15762,2316,-829,882,6644 } },
    { "Minolta DYNAX 7", 0, 0xffb,
	{ 10239,-3104,-1099,-8037,15727,2451,-927,925,6871 } },
    { "Motorola PIXL", 0, 0,		/* DJC */
	{ 8898,-989,-1033,-3292,11619,1674,-661,3178,5216 } },
    { "Nikon D100", 0, 0,
	{ 5902,-933,-782,-8983,16719,2354,-1402,1455,6464 } },
    { "Nikon D1H", 0, 0,
	{ 7577,-2166,-926,-7454,15592,1934,-2377,2808,8606 } },
    { "Nikon D1X", 0, 0,
	{ 7702,-2245,-975,-9114,17242,1875,-2679,3055,8521 } },
    { "Nikon D1", 0, 0, /* multiplied by 2.218750, 1.0, 1.148438 */
	{ 16772,-4726,-2141,-7611,15713,1972,-2846,3494,9521 } },
    { "Nikon D200", 0, 0xfbc,
	{ 8367,-2248,-763,-8758,16447,2422,-1527,1550,8053 } },
    { "Nikon D2H", 0, 0,
	{ 5710,-901,-615,-8594,16617,2024,-2975,4120,6830 } },
    { "Nikon D2X", 0, 0,
	{ 10231,-2769,-1255,-8301,15900,2552,-797,680,7148 } },
    { "Nikon D3000", 0, 0,
	{ 8736,-2458,-935,-9075,16894,2251,-1354,1242,8263 } },
    { "Nikon D3100", 0, 0,
	{ 7911,-2167,-813,-5327,13150,2408,-1288,2483,7968 } },
    { "Nikon D3200", 0, 0xfb9,
	{ 7013,-1408,-635,-5268,12902,2640,-1470,2801,7379 } },
    { "Nikon D300", 0, 0,
	{ 9030,-1992,-715,-8465,16302,2255,-2689,3217,8069 } },
    { "Nikon D3X", 0, 0,
	{ 7171,-1986,-648,-8085,15555,2718,-2170,2512,7457 } },
    { "Nikon D3S", 0, 0,
	{ 8828,-2406,-694,-4874,12603,2541,-660,1509,7587 } },
    { "Nikon D3", 0, 0,
	{ 8139,-2171,-663,-8747,16541,2295,-1925,2008,8093 } },
    { "Nikon D40X", 0, 0,
	{ 8819,-2543,-911,-9025,16928,2151,-1329,1213,8449 } },
    { "Nikon D40", 0, 0,
	{ 6992,-1668,-806,-8138,15748,2543,-874,850,7897 } },
    { "Nikon D4", 0, 0,
        { 10076,-4135,-659,-4586,13006,746,-1189,2107,6185 } },
    { "Nikon D5000", 0, 0xf00,
	{ 7309,-1403,-519,-8474,16008,2622,-2433,2826,8064 } },
    { "Nikon D5100", 0, 0x3de6,
	{ 8198,-2239,-724,-4871,12389,2798,-1043,2050,7181 } },
    { "Nikon D5200", 0, 0,
	{ 8322,-3112,-1047,-6367,14342,2179,-988,1638,6394 } },
    {"Nikon D5300",0, 0,
       { 10645,-5086,-698,-4938,13608,761,-1107,1874,5312 } },
    { "Nikon D50", 0, 0,
	{ 7732,-2422,-789,-8238,15884,2498,-859,783,7330 } },
    { "Nikon D600", 0, 0x3e07,
	{ 8178,-2245,-609,-4857,12394,2776,-1207,2086,7298 } },
    {"Nikon D610",0, 0,
        { 10426,-4005,-444,-3565,11764,1403,-1206,2266,6549 } },
    { "Nikon D60", 0, 0,
	{ 8736,-2458,-935,-9075,16894,2251,-1354,1242,8263 } },
    { "Nikon D7000", 0, 0,
	{ 8198,-2239,-724,-4871,12389,2798,-1043,2050,7181 } },
    { "Nikon D7100", 0, 0,
	{ 8322,-3112,-1047,-6367,14342,2179,-988,1638,6394 } },
    { "Nikon D700", 0, 0,
	{ 8139,-2171,-663,-8747,16541,2295,-1925,2008,8093 } },
    { "Nikon D70", 0, 0,
	{ 7732,-2422,-789,-8238,15884,2498,-859,783,7330 } },
    { "Nikon D800", 0, 0,
	{ 7866,-2108,-555,-4869,12483,2681,-1176,2069,7501 } },
    { "Nikon D80", 0, 0,
	{ 8629,-2410,-883,-9055,16940,2171,-1490,1363,8520 } },
    { "Nikon D90", 0, 0xf00,
	{ 7309,-1403,-519,-8474,16008,2622,-2434,2826,8064 } },
    {"Nikon Df",0, 0,
        { 10076,-4135,-659,-4586,13006,746,-1189,2107,6185 } },
    { "Nikon E700", 0, 0x3dd,		/* DJC */
	{ -3746,10611,1665,9621,-1734,2114,-2389,7082,3064,3406,6116,-244 } },
    { "Nikon E800", 0, 0x3dd,		/* DJC */
	{ -3746,10611,1665,9621,-1734,2114,-2389,7082,3064,3406,6116,-244 } },
    { "Nikon E950", 0, 0x3dd,		/* DJC */
	{ -3746,10611,1665,9621,-1734,2114,-2389,7082,3064,3406,6116,-244 } },
    { "Nikon E995", 0, 0,	/* copied from E5000 */
	{ -5547,11762,2189,5814,-558,3342,-4924,9840,5949,688,9083,96 } },
    { "Nikon E2100", 0, 0,	/* copied from Z2, new white balance */
	{ 13142,-4152,-1596,-4655,12374,2282,-1769,2696,6711} },
    { "Nikon E2500", 0, 0,
	{ -5547,11762,2189,5814,-558,3342,-4924,9840,5949,688,9083,96 } },
    { "Nikon E3200", 0, 0,		/* DJC */
	{ 9846,-2085,-1019,-3278,11109,2170,-774,2134,5745 } },
    { "Nikon E4300", 0, 0,	/* copied from Minolta DiMAGE Z2 */
	{ 11280,-3564,-1370,-4655,12374,2282,-1423,2168,5396 } },
    { "Nikon E4500", 0, 0,
	{ -5547,11762,2189,5814,-558,3342,-4924,9840,5949,688,9083,96 } },
    { "Nikon E5000", 0, 0,
	{ -5547,11762,2189,5814,-558,3342,-4924,9840,5949,688,9083,96 } },
    { "Nikon E5400", 0, 0,
	{ 9349,-2987,-1001,-7919,15766,2266,-2098,2680,6839 } },
    { "Nikon E5700", 0, 0,
	{ -5368,11478,2368,5537,-113,3148,-4969,10021,5782,778,9028,211 } },
    { "Nikon E8400", 0, 0,
	{ 7842,-2320,-992,-8154,15718,2599,-1098,1342,7560 } },
    { "Nikon E8700", 0, 0,
	{ 8489,-2583,-1036,-8051,15583,2643,-1307,1407,7354 } },
    { "Nikon E8800", 0, 0,
	{ 7971,-2314,-913,-8451,15762,2894,-1442,1520,7610 } },
    { "Nikon COOLPIX A", 0, 0,
	{ 8198,-2239,-724,-4871,12389,2798,-1043,2050,7181 } },
    { "Nikon COOLPIX P330", 0, 0,
	{ 10321,-3920,-931,-2750,11146,1824,-442,1545,5539 } },
    { "Nikon COOLPIX P6000", 0, 0,
	{ 9698,-3367,-914,-4706,12584,2368,-837,968,5801 } },
    { "Nikon COOLPIX P7000", 0, 0,
	{ 11432,-3679,-1111,-3169,11239,2202,-791,1380,4455 } },
    { "Nikon COOLPIX P7100", 0, 0,
	{ 11053,-4269,-1024,-1976,10182,2088,-526,1263,4469 } },
    { "Nikon COOLPIX P7700", 200, 0,
	{ 10321,-3920,-931,-2750,11146,1824,-442,1545,5539 } },
    { "Nikon COOLPIX P7800", 200, 0,
      { 13443,-6418,-673,-1309,10025,1131,-462,1827,4782 } },
    { "Nikon 1 V2", 0, 0,
	{ 6588,-1305,-693,-3277,10987,2634,-355,2016,5106 } },
    { "Nikon 1 J3", 0, 0,
      { 8144,-2671,-473,-1740,9834,1601,-58,1971,4296 } },
    { "Nikon 1 AW1", 0, 0,
      { 8144,-2671,-473,-1740,9834,1601,-58,1971,4296 } },
    { "Nikon 1 ", 0, 0,
	{ 8994,-2667,-865,-4594,12324,2552,-699,1786,6260 } },
    { "Olympus C5050", 0, 0,
	{ 10508,-3124,-1273,-6079,14294,1901,-1653,2306,6237 } },
    { "Olympus C5060", 0, 0,
	{ 10445,-3362,-1307,-7662,15690,2058,-1135,1176,7602 } },
    { "Olympus C7070", 0, 0,
	{ 10252,-3531,-1095,-7114,14850,2436,-1451,1723,6365 } },
    { "Olympus C70", 0, 0,
	{ 10793,-3791,-1146,-7498,15177,2488,-1390,1577,7321 } },
    { "Olympus C80", 0, 0,
	{ 8606,-2509,-1014,-8238,15714,2703,-942,979,7760 } },
    { "Olympus E-10", 0, 0xffc,
	{ 12745,-4500,-1416,-6062,14542,1580,-1934,2256,6603 } },
    { "Olympus E-1", 0, 0,
	{ 11846,-4767,-945,-7027,15878,1089,-2699,4122,8311 } },
    { "Olympus E-20", 0, 0xffc,
	{ 13173,-4732,-1499,-5807,14036,1895,-2045,2452,7142 } },
    { "Olympus E-300", 0, 0,
	{ 7828,-1761,-348,-5788,14071,1830,-2853,4518,6557 } },
    { "Olympus E-330", 0, 0,
	{ 8961,-2473,-1084,-7979,15990,2067,-2319,3035,8249 } },
    { "Olympus E-30", 0, 0xfbc,
	{ 8144,-1861,-1111,-7763,15894,1929,-1865,2542,7607 } },
    { "Olympus E-3", 0, 0xf99,
	{ 9487,-2875,-1115,-7533,15606,2010,-1618,2100,7389 } },
    { "Olympus E-400", 0, 0,
	{ 6169,-1483,-21,-7107,14761,2536,-2904,3580,8568 } },
    { "Olympus E-410", 0, 0xf6a,
	{ 8856,-2582,-1026,-7761,15766,2082,-2009,2575,7469 } },
    { "Olympus E-420", 0, 0xfd7,
	{ 8746,-2425,-1095,-7594,15612,2073,-1780,2309,7416 } },
    { "Olympus E-450", 0, 0xfd2,
	{ 8745,-2425,-1095,-7594,15613,2073,-1780,2309,7416 } },
    { "Olympus E-500", 0, 0,
	{ 8136,-1968,-299,-5481,13742,1871,-2556,4205,6630 } },
    { "Olympus E-510", 0, 0xf6a,
	{ 8785,-2529,-1033,-7639,15624,2112,-1783,2300,7817 } },
    { "Olympus E-520", 0, 0xfd2,
	{ 8344,-2322,-1020,-7596,15635,2048,-1748,2269,7287 } },
    { "Olympus E-5", 0, 0xeec,
	{ 11200,-3783,-1325,-4576,12593,2206,-695,1742,7504 } },
    { "Olympus E-600", 0, 0xfaf,
	{ 8453,-2198,-1092,-7609,15681,2008,-1725,2337,7824 } },
    { "Olympus E-620", 0, 0xfaf,
	{ 8453,-2198,-1092,-7609,15681,2008,-1725,2337,7824 } },
    { "Olympus E-P1", 0, 0xffd,
	{ 8343,-2050,-1021,-7715,15705,2103,-1831,2380,8235 } },
    { "Olympus E-P2", 0, 0xffd,
	{ 8343,-2050,-1021,-7715,15705,2103,-1831,2380,8235 } },
    { "Olympus E-P3", 0, 0,
	{ 7575,-2159,-571,-3722,11341,2725,-1434,2819,6271 } },
    { "Olympus E-P5", 0, 0,
	{ 8380,-2630,-639,-2887,10725,2496,-627,1427,5438 } },
    { "Olympus E-PL1s", 0, 0,
	{ 11409,-3872,-1393,-4572,12757,2003,-709,1810,7415 } },
    { "Olympus E-PL1", 0, 0,
	{ 11408,-4289,-1215,-4286,12385,2118,-387,1467,7787 } },
    { "Olympus E-PL2", 0, 0xcf3,
	{ 15030,-5552,-1806,-3987,12387,1767,-592,1670,7023 } },
    { "Olympus E-PL3", 0, 0,
	{ 7575,-2159,-571,-3722,11341,2725,-1434,2819,6271 } },
    { "Olympus E-PL5", 0, 0xfcb,
	{ 8380,-2630,-639,-2887,10725,2496,-627,1427,5438 } },
    { "Olympus E-PL6", 0, 0,
	{ 8380,-2630,-639,-2887,10725,2496,-627,1427,5438 } },
    { "Olympus E-PM1", 0, 0,
	{ 7575,-2159,-571,-3722,11341,2725,-1434,2819,6271 } },
    { "Olympus E-PM2", 0, 0,
	{ 8380,-2630,-639,-2887,10725,2496,-627,1427,5438 } },
    {"Olympus E-M1", 0, 0,
        { 11663,-5527,-419,-1683,9915,1389,-582,1933,5016 } },
    { "Olympus E-M5", 0, 0xfe1,
	{ 8380,-2630,-639,-2887,10725,2496,-627,1427,5438 } },
    { "Olympus SP350", 0, 0,
	{ 12078,-4836,-1069,-6671,14306,2578,-786,939,7418 } },
    { "Olympus SP3", 0, 0,
	{ 11766,-4445,-1067,-6901,14421,2707,-1029,1217,7572 } },
    { "Olympus SP500UZ", 0, 0xfff,
	{ 9493,-3415,-666,-5211,12334,3260,-1548,2262,6482 } },
    { "Olympus SP510UZ", 0, 0xffe,
	{ 10593,-3607,-1010,-5881,13127,3084,-1200,1805,6721 } },
    { "Olympus SP550UZ", 0, 0xffe,
	{ 11597,-4006,-1049,-5432,12799,2957,-1029,1750,6516 } },
    { "Olympus SP560UZ", 0, 0xff9,
	{ 10915,-3677,-982,-5587,12986,2911,-1168,1968,6223 } },
    { "Olympus SP570UZ", 0, 0,
	{ 11522,-4044,-1146,-4736,12172,2904,-988,1829,6039 } },
    {"Olympus STYLUS1",0, 0,
        { 11976,-5518,-545,-1419,10472,846,-475,1766,4524 } },
    { "Olympus XZ-10", 0, 0,
	{ 9777,-3483,-925,-2886,11297,1800,-602,1663,5134 } },
    { "Olympus XZ-1", 0, 0,
	{ 10901,-4095,-1074,-1141,9208,2293,-62,1417,5158 } },
    { "Olympus XZ-2", 0, 0,
	{ 9777,-3483,-925,-2886,11297,1800,-602,1663,5134 } },
    { "OmniVision ov5647", 0, 0,	/* DJC */
	{ 12782,-4059,-379,-478,9066,1413,1340,1513,5176 } },
    { "Pentax *ist DL2", 0, 0,
	{ 10504,-2438,-1189,-8603,16207,2531,-1022,863,12242 } },
    { "Pentax *ist DL", 0, 0,
	{ 10829,-2838,-1115,-8339,15817,2696,-837,680,11939 } },
    { "Pentax *ist DS2", 0, 0,
	{ 10504,-2438,-1189,-8603,16207,2531,-1022,863,12242 } },
    { "Pentax *ist DS", 0, 0,
	{ 10371,-2333,-1206,-8688,16231,2602,-1230,1116,11282 } },
    { "Pentax *ist D", 0, 0,
	{ 9651,-2059,-1189,-8881,16512,2487,-1460,1345,10687 } },
    { "Pentax K10D", 0, 0,
	{ 9566,-2863,-803,-7170,15172,2112,-818,803,9705 } },
    { "Pentax K1", 0, 0,
	{ 11095,-3157,-1324,-8377,15834,2720,-1108,947,11688 } },
    { "Pentax K20D", 0, 0,
	{ 9427,-2714,-868,-7493,16092,1373,-2199,3264,7180 } },
    { "Pentax K200D", 0, 0,
	{ 9186,-2678,-907,-8693,16517,2260,-1129,1094,8524 } },
    { "Pentax K2000", 0, 0,
	{ 11057,-3604,-1155,-5152,13046,2329,-282,375,8104 } },
    { "Pentax K-m", 0, 0,
	{ 11057,-3604,-1155,-5152,13046,2329,-282,375,8104 } },
    { "Pentax K-x", 0, 0,
	{ 8843,-2837,-625,-5025,12644,2668,-411,1234,7410 } },
    { "Pentax K-r", 0, 0,
	{ 9895,-3077,-850,-5304,13035,2521,-883,1768,6936 } },
    { "Pentax K-3", 0, 0,
	{ 7415,-2052,-721,-5186,12788,2682,-1446,2157,6773 } },
    { "Pentax K-5 II", 0, 0,
	{ 8170,-2725,-639,-4440,12017,2744,-771,1465,6599 } },
    { "Pentax K-5", 0, 0,
	{ 8713,-2833,-743,-4342,11900,2772,-722,1543,6247 } },
    { "Pentax K-7", 0, 0,
	{ 9142,-2947,-678,-8648,16967,1663,-2224,2898,8615 } },
    { "Pentax MX-1", 0, 0,
	{ 8804,-2523,-1238,-2423,11627,860,-682,1774,4753 } },
    { "Pentax Q10", 0, 0,
	{ 12995,-5593,-1107,-1879,10139,2027,-64,1233,4919 } },
    { "Pentax 645D", 0, 0x3e00,
	{ 10646,-3593,-1158,-3329,11699,1831,-667,2874,6287 } },
    { "Panasonic DMC-FZ8", 0, 0xf7f,
	{ 8986,-2755,-802,-6341,13575,3077,-1476,2144,6379 } },
    { "Panasonic DMC-FZ18", 0, 0,
	{ 9932,-3060,-935,-5809,13331,2753,-1267,2155,5575 } },
    { "Panasonic DMC-FZ28", 15, 0xf96,
	{ 10109,-3488,-993,-5412,12812,2916,-1305,2140,5543 } },
    { "Panasonic DMC-FZ30", 0, 0xf94,
	{ 10976,-4029,-1141,-7918,15491,2600,-1670,2071,8246 } },
    { "Panasonic DMC-FZ3", 143, 0,
	{ 9938,-2780,-890,-4604,12393,2480,-1117,2304,4620 } },
    { "Panasonic DMC-FZ4", 143, 0,
	{ 13639,-5535,-1371,-1698,9633,2430,316,1152,4108 } },
    { "Panasonic DMC-FZ50", 0, 0,
	{ 7906,-2709,-594,-6231,13351,3220,-1922,2631,6537 } },
    { "Panasonic DMC-FZ7", 144, 0,
	{ 11532,-4324,-1066,-2375,10847,1749,-564,1699,4351 } },
    { "Leica V-LUX1", 0, 0,
	{ 7906,-2709,-594,-6231,13351,3220,-1922,2631,6537 } },
    { "Panasonic DMC-L10", 15, 0xf96,
	{ 8025,-1942,-1050,-7920,15904,2100,-2456,3005,7039 } },
    { "Panasonic DMC-L1", 0, 0xf7f,
	{ 8054,-1885,-1025,-8349,16367,2040,-2805,3542,7629 } },
    { "Leica DIGILUX 3", 0, 0xf7f,
	{ 8054,-1885,-1025,-8349,16367,2040,-2805,3542,7629 } },
    { "Panasonic DMC-LC1", 0, 0,
	{ 11340,-4069,-1275,-7555,15266,2448,-2960,3426,7685 } },
    { "Leica DIGILUX 2", 0, 0,
	{ 11340,-4069,-1275,-7555,15266,2448,-2960,3426,7685 } },
    { "Panasonic DMC-LF1", 143, 0,
	{ 9379,-3267,-816,-3227,11560,1881,-926,1928,5340 } },
    { "Leica C (Typ 112)", 143, 0,
	{ 9379,-3267,-816,-3227,11560,1881,-926,1928,5340 } },
    { "Panasonic DMC-LX1", 0, 0xf7f,
	{ 10704,-4187,-1230,-8314,15952,2501,-920,945,8927 } },
    { "Leica D-LUX2", 0, 0xf7f,
	{ 10704,-4187,-1230,-8314,15952,2501,-920,945,8927 } },
    { "Panasonic DMC-LX2", 0, 0,
	{ 8048,-2810,-623,-6450,13519,3272,-1700,2146,7049 } },
    { "Leica D-LUX3", 0, 0,
	{ 8048,-2810,-623,-6450,13519,3272,-1700,2146,7049 } },
    { "Panasonic DMC-LX3", 15, 0,
	{ 8128,-2668,-655,-6134,13307,3161,-1782,2568,6083 } },
    { "Leica D-LUX 4", 15, 0,
	{ 8128,-2668,-655,-6134,13307,3161,-1782,2568,6083 } },
    { "Panasonic DMC-LX5", 143, 0,
	{ 10909,-4295,-948,-1333,9306,2399,22,1738,4582 } },
    { "Leica D-LUX 5", 143, 0,
	{ 10909,-4295,-948,-1333,9306,2399,22,1738,4582 } },
    { "Panasonic DMC-LX7", 143, 0,
	{ 10148,-3743,-991,-2837,11366,1659,-701,1893,4899 } },
    { "Leica D-LUX 6", 143, 0,
	{ 10148,-3743,-991,-2837,11366,1659,-701,1893,4899 } },
    { "Panasonic DMC-FZ100", 143, 0xfff,
	{ 16197,-6146,-1761,-2393,10765,1869,366,2238,5248 } },
    { "Leica V-LUX 2", 143, 0xfff,
	{ 16197,-6146,-1761,-2393,10765,1869,366,2238,5248 } },
    { "Panasonic DMC-FZ150", 143, 0xfff,
	{ 11904,-4541,-1189,-2355,10899,1662,-296,1586,4289 } },
    { "Leica V-LUX 3", 143, 0xfff,
	{ 11904,-4541,-1189,-2355,10899,1662,-296,1586,4289 } },
    { "Panasonic DMC-FZ200", 143, 0xfff,
	{ 8112,-2563,-740,-3730,11784,2197,-941,2075,4933 } },
    { "Leica V-LUX 4", 143, 0xfff,
	{ 8112,-2563,-740,-3730,11784,2197,-941,2075,4933 } },
    { "Panasonic DMC-FX150", 15, 0xfff,
	{ 9082,-2907,-925,-6119,13377,3058,-1797,2641,5609 } },
    { "Panasonic DMC-G10", 0, 0,
	{ 10113,-3400,-1114,-4765,12683,2317,-377,1437,6710 } },
    { "Panasonic DMC-G1", 15, 0xf94,
	{ 8199,-2065,-1056,-8124,16156,2033,-2458,3022,7220 } },
    { "Panasonic DMC-G2", 15, 0xf3c,
	{ 10113,-3400,-1114,-4765,12683,2317,-377,1437,6710 } },
    { "Panasonic DMC-G3", 143, 0xfff,
	{ 6763,-1919,-863,-3868,11515,2684,-1216,2387,5879 } },
    { "Panasonic DMC-G5", 143, 0xfff,
	{ 7798,-2562,-740,-3879,11584,2613,-1055,2248,5434 } },
    { "Panasonic DMC-G6", 142, 0xfff,
	{ 8294,-2891,-651,-3869,11590,2595,-1183,2267,5352 } },
    { "Panasonic DMC-GF1", 15, 0xf92,
	{ 7888,-1902,-1011,-8106,16085,2099,-2353,2866,7330 } },
    { "Panasonic DMC-GF2", 143, 0xfff,
	{ 7888,-1902,-1011,-8106,16085,2099,-2353,2866,7330 } },
    { "Panasonic DMC-GF3", 143, 0xfff,
	{ 9051,-2468,-1204,-5212,13276,2121,-1197,2510,6890 } },
    { "Panasonic DMC-GF5", 143, 0xfff,
	{ 8228,-2945,-660,-3938,11792,2430,-1094,2278,5793 } },
    { "Panasonic DMC-GF6", 143, 0,
	{ 8130,-2801,-946,-3520,11289,2552,-1314,2511,5791 } },
    { "Panasonic DMC-GH1", 15, 0xf92,
	{ 6299,-1466,-532,-6535,13852,2969,-2331,3112,5984 } },
    { "Panasonic DMC-GH2", 15, 0xf95,
	{ 7780,-2410,-806,-3913,11724,2484,-1018,2390,5298 } },
    { "Panasonic DMC-GH3", 144, 0,
	{ 6559,-1752,-491,-3672,11407,2586,-962,1875,5130 } },
    { "Panasonic DMC-GM1", 143, 0,
        { 8977,-3976,-425,-3050,11095,1117,-1217,2563,4750 } },
    { "Panasonic DMC-GX1", 143, 0,
	{ 6763,-1919,-863,-3868,11515,2684,-1216,2387,5879 } },
    {"Panasonic DMC-GX7",143,0,
        {7541,-2355,-591,-3163,10598,1894,-933,2109,5006}},
    { "Phase One H 20", 0, 0,		/* DJC */
	{ 1313,1855,-109,-6715,15908,808,-327,1840,6020 } },
    { "Phase One H 25", 0, 0,
	{ 2905,732,-237,-8134,16626,1476,-3038,4253,7517 } },
    { "Phase One P 2", 0, 0,
	{ 2905,732,-237,-8134,16626,1476,-3038,4253,7517 } },
    { "Phase One P 30", 0, 0,
	{ 4516,-245,-37,-7020,14976,2173,-3206,4671,7087 } },
    { "Phase One P 45", 0, 0,
	{ 5053,-24,-117,-5684,14076,1702,-2619,4492,5849 } },
    { "Phase One P40", 0, 0,
	{ 8035,435,-962,-6001,13872,2320,-1159,3065,5434 } },
    { "Phase One P65", 0, 0,
	{ 8035,435,-962,-6001,13872,2320,-1159,3065,5434 } },
    { "Red One", 704, 0xffff,		/* DJC */
	{ 21014,-7891,-2613,-3056,12201,856,-2203,5125,8042 } },
    { "Samsung EK-GN120", 0, 0, /* Adobe; Galaxy NX */
        { 7557,-2522,-739,-4679,12949,1894,-840,1777,5311 } },
    { "Samsung EX1", 0, 0x3e00,
	{ 8898,-2498,-994,-3144,11328,2066,-760,1381,4576 } },
    { "Samsung EX2F", 0, 0x7ff,
	{ 10648,-3897,-1055,-2022,10573,1668,-492,1611,4742 } },
    { "Samsung EK-GN120", 0, 0,
	{ 7557,-2522,-739,-4679,12949,1894,-840,1777,5311 } },
    { "Samsung NX300", 0, 0,
        { 8873,-3984,-372,-3759,12305,1013,-994,1981,4788 } },
    { "Samsung NX2000", 0, 0,
	{ 7557,-2522,-739,-4679,12949,1894,-840,1777,5311 } },
    { "Samsung NX2", 0, 0xfff,	/* NX20, NX200, NX210 */
	{ 6933,-2268,-753,-4921,13387,1647,-803,1641,6096 } },
    { "Samsung NX1000", 0, 0,
	{ 6933,-2268,-753,-4921,13387,1647,-803,1641,6096 } },
    { "Samsung NX1100", 0, 0,
	{ 6933,-2268,-753,-4921,13387,1647,-803,1641,6096 } },
    { "Samsung NX", 0, 0,	/* NX5, NX10, NX11, NX100 */
	{ 10332,-3234,-1168,-6111,14639,1520,-1352,2647,8331 } },
    { "Samsung WB2000", 0, 0xfff,
	{ 12093,-3557,-1155,-1000,9534,1733,-22,1787,4576 } },
    { "Samsung GX-1", 0, 0,
	{ 10504,-2438,-1189,-8603,16207,2531,-1022,863,12242 } },
    { "Samsung GX20", 0, 0,	/* copied from Pentax K20D */
	{ 9427,-2714,-868,-7493,16092,1373,-2199,3264,7180 } },
    { "Samsung S85", 0, 0,		/* DJC */
	{ 11885,-3968,-1473,-4214,12299,1916,-835,1655,5549 } },
     // Foveon: LibRaw color data
    { "Sigma SD9", 15, 4095,			/* LibRaw */
      { 14082,-2201,-1056,-5243,14788,167,-121,196,8881 } },
    //{ 7401,-1169,-567,2059,3769,1510,664,3367,5328 } },
    { "Sigma SD10", 15, 16383,			/* LibRaw */
      { 14082,-2201,-1056,-5243,14788,167,-121,196,8881 } },
    //{ 7401,-1169,-567,2059,3769,1510,664,3367,5328 } },
    { "Sigma SD14", 15, 16383,			/* LibRaw */
      { 14082,-2201,-1056,-5243,14788,167,-121,196,8881 } },
    //{ 7401,-1169,-567,2059,3769,1510,664,3367,5328 } },
    { "Sigma SD15", 15, 4095,			/* LibRaw */
      { 14082,-2201,-1056,-5243,14788,167,-121,196,8881 } },
    //{ 7401,-1169,-567,2059,3769,1510,664,3367,5328 } },
    // Merills + SD1
    { "Sigma SD1", 31, 4095,			/* LibRaw */
      { 5133,-1895,-353,4978,744,144,3837,3069,2777 } },
    { "Sigma DP1 Merrill", 31, 4095,			/* LibRaw */
      { 5133,-1895,-353,4978,744,144,3837,3069,2777 } },
    { "Sigma DP2 Merrill", 31, 4095,			/* LibRaw */
      { 5133,-1895,-353,4978,744,144,3837,3069,2777 } },
    { "Sigma DP3 Merrill", 31, 4095,			/* LibRaw */
      { 5133,-1895,-353,4978,744,144,3837,3069,2777 } },
    // Sigma DP (non-Merill Versions)
    { "Sigma DP", 0, 4095,			/* LibRaw */
      //  { 7401,-1169,-567,2059,3769,1510,664,3367,5328 } },
      { 13100,-3638,-847,6855,2369,580,2723,3218,3251 } },
    { "Sinar", 0, 0,			/* DJC */
	{ 16442,-2956,-2422,-2877,12128,750,-1136,6066,4559 } },
    { "Sony DSC-F828", 0, 0,
	{ 7924,-1910,-777,-8226,15459,2998,-1517,2199,6818,-7242,11401,3481 } },
    { "Sony DSC-R1", -512, 0,
	{ 8512,-2641,-694,-8042,15670,2526,-1821,2117,7414 } },
    { "Sony DSC-V3", 0, 0,
	{ 7511,-2571,-692,-7894,15088,3060,-948,1111,8128 } },
    { "Sony DSC-RX100M2", -200, 0,
	{ 8651,-2754,-1057,-3464,12207,1373,-568,1398,4434 } },
    { "Sony DSC-RX100", -200, 0,
	{ 8651,-2754,-1057,-3464,12207,1373,-568,1398,4434 } },
    {"Sony DSC-RX10",0, 0,
        { 8562,-3595,-385,-2715,11089,1128,-1023,2081,4400 } },
    { "Sony DSC-RX1R", -128, 0,
        { 8195,-2800,-422,-4261,12273,1709,-1505,2400,5624 } },
    { "Sony DSC-RX1", -128, 0,
	{ 6344,-1612,-462,-4863,12477,2681,-865,1786,6899 } },
    { "Sony DSLR-A100", 0, 0xfeb,
	{ 9437,-2811,-774,-8405,16215,2290,-710,596,7181 } },
    { "Sony DSLR-A290", 0, 0,
	{ 6038,-1484,-579,-9145,16746,2512,-875,746,7218 } },
    { "Sony DSLR-A2", 0, 0,
	{ 9847,-3091,-928,-8485,16345,2225,-715,595,7103 } },
    { "Sony DSLR-A300", 0, 0,
	{ 9847,-3091,-928,-8485,16345,2225,-715,595,7103 } },
    { "Sony DSLR-A330", 0, 0,
	{ 9847,-3091,-929,-8485,16346,2225,-714,595,7103 } },
    { "Sony DSLR-A350", 0, 0xffc,
	{ 6038,-1484,-578,-9146,16746,2513,-875,746,7217 } },
    { "Sony DSLR-A380", 0, 0,
	{ 6038,-1484,-579,-9145,16746,2512,-875,746,7218 } },
    { "Sony DSLR-A390", 0, 0,
	{ 6038,-1484,-579,-9145,16746,2512,-875,746,7218 } },
    { "Sony DSLR-A450", -128, 0xfeb,
	{ 4950,-580,-103,-5228,12542,3029,-709,1435,7371 } },
    { "Sony DSLR-A580", -128, 0xfeb,
	{ 5932,-1492,-411,-4813,12285,2856,-741,1524,6739 } },
    { "Sony DSLR-A5", -128, 0xfeb,
	{ 4950,-580,-103,-5228,12542,3029,-709,1435,7371 } },
    { "Sony DSLR-A700", -128, 0,
	{ 5775,-805,-359,-8574,16295,2391,-1943,2341,7249 } },
    { "Sony DSLR-A850", -128, 0,
	{ 5413,-1162,-365,-5665,13098,2866,-608,1179,8440 } },
    { "Sony DSLR-A900", -128, 0,
	{ 5209,-1072,-397,-8845,16120,2919,-1618,1803,8654 } },
    {"Sony ILCE-3000",-128, 0,
        { 14009,-8208,729,3738,4752,2932,5743,-3800,6494 } },    
    {"Sony ILCE-A7R",-128, 0,
        { 8592,-3219,-348,-3846,12042,1475,-1079,2166,5893 } },
    {"Sony ILCE-A7",-128, 0,
        { 8592,-3219,-348,-3846,12042,1475,-1079,2166,5893 } },
    { "Sony NEX-5T", -128, 0,
        { 7623,-2693,-347,-4060,11875,1928,-1363,2329,5752 } },
    { "Sony NEX-5N", -128, 0,
	{ 5991,-1456,-455,-4764,12135,2980,-707,1425,6701 } },
    { "Sony NEX-5R", -128, 0,
	{ 6129,-1545,-418,-4930,12490,2743,-977,1693,6615 } },
    { "Sony NEX-3N", -128, 0,
	{ 6129,-1545,-418,-4930,12490,2743,-977,1693,6615 } },
    { "Sony NEX-3", -128, 0,		/* Adobe */
	{ 6549,-1550,-436,-4880,12435,2753,-854,1868,6976 } },
    { "Sony NEX-5", -128, 0,		/* Adobe */
	{ 6549,-1550,-436,-4880,12435,2753,-854,1868,6976 } },
    { "Sony NEX-6", -128, 0,
	{ 6129,-1545,-418,-4930,12490,2743,-977,1693,6615 } },
    { "Sony NEX-7", -128, 0,
	{ 5491,-1192,-363,-4951,12342,2948,-911,1722,7192 } },
    { "Sony NEX", -128, 0,	/* NEX-C3, NEX-F3 */
	{ 5991,-1456,-455,-4764,12135,2980,-707,1425,6701 } },
    { "Sony SLT-A33", -128, 0,
	{ 6069,-1221,-366,-5221,12779,2734,-1024,2066,6834 } },
    { "Sony SLT-A35", -128, 0,
	{ 5986,-1618,-415,-4557,11820,3120,-681,1404,6971 } },
    { "Sony SLT-A37", -128, 0,
	{ 5991,-1456,-455,-4764,12135,2980,-707,1425,6701 } },
    { "Sony SLT-A55", -128, 0,
	{ 5932,-1492,-411,-4813,12285,2856,-741,1524,6739 } },
    { "Sony SLT-A57", -128, 0,
	{ 5991,-1456,-455,-4764,12135,2980,-707,1425,6701 } },
    { "Sony SLT-A58", -128, 0,
	{ 5991,-1456,-455,-4764,12135,2980,-707,1425,6701 } },
    { "Sony SLT-A65", -128, 0,
	{ 5491,-1192,-363,-4951,12342,2948,-911,1722,7192 } },
    { "Sony SLT-A77", -128, 0,
	{ 5491,-1192,-363,-4951,12342,2948,-911,1722,7192 } },
    { "Sony SLT-A99", -128, 0,
	{ 6344,-1612,-462,-4863,12477,2681,-865,1786,6899 } },
  };
  double cam_xyz[4][3];
  char name[130];
  int i, j;

  sprintf (name, "%s %s", t_make, t_model);
  for (i=0; i < sizeof table / sizeof *table; i++)
    if (!strncasecmp(name, table[i].prefix, strlen(table[i].prefix))) {
      if (table[i].t_black>0)   black   = (ushort) table[i].t_black;
      else if(table[i].t_black <0 && black == 0 )  black   = (ushort) (-table[i].t_black);
      if (table[i].t_maximum) maximum = (ushort) table[i].t_maximum;
      if (table[i].trans[0]) {
	for (raw_color = j=0; j < 12; j++)
#ifdef LIBRAW_LIBRARY_BUILD
          imgdata.color.cam_xyz[0][j] = 
#endif
	  cam_xyz[0][j] = table[i].trans[j] / 10000.0;
	cam_xyz_coeff (rgb_cam, cam_xyz);
      }
      break;
    }
}

Project: LibRaw
File: libraw_cxx.cpp

int LibRaw::copy_mem_image(void* scan0, int stride, int bgr)

{
    // the image memory pointed to by scan0 is assumed to be in the format returned by get_mem_image_format
    if((imgdata.progress_flags & LIBRAW_PROGRESS_THUMB_MASK) < LIBRAW_PROGRESS_PRE_INTERPOLATE)
        return LIBRAW_OUT_OF_ORDER_CALL;

    if(libraw_internal_data.output_data.histogram)
      {
        int perc, val, total, t_white=0x2000,c;
        perc = S.width * S.height * 0.01;        /* 99th percentile white level */
        if (IO.fuji_width) perc /= 2;
        if (!((O.highlight & ~2) || O.no_auto_bright))
          for (t_white=c=0; c < P1.colors; c++) {
            for (val=0x2000, total=0; --val > 32; )
              if ((total += libraw_internal_data.output_data.histogram[c][val]) > perc) break;
            if (t_white < val) t_white = val;
          }
        gamma_curve (O.gamm[0], O.gamm[1], 2, (t_white << 3)/O.bright);
      }
    
    int s_iheight = S.iheight;
    int s_iwidth = S.iwidth;
    int s_width = S.width;
    int s_hwight = S.height;

    S.iheight = S.height;
    S.iwidth  = S.width;

    if (S.flip & 4) SWAP(S.height,S.width);
    uchar *ppm;
    ushort *ppm2;
    int c, row, col, soff, rstep, cstep;

    soff  = flip_index (0, 0);
    cstep = flip_index (0, 1) - soff;
    rstep = flip_index (1, 0) - flip_index (0, S.width);

    for (row=0; row < S.height; row++, soff += rstep) 
      {
        uchar *bufp = ((uchar*)scan0)+row*stride;
        ppm2 = (ushort*) (ppm = bufp);
        // keep trivial decisions in the outer loop for speed
        if (bgr) {
          if (O.output_bps == 8) {
            for (col=0; col < S.width; col++, soff += cstep) 
              FORBGR *ppm++ = imgdata.color.curve[imgdata.image[soff][c]]>>8;
          }
          else {
            for (col=0; col < S.width; col++, soff += cstep) 
              FORBGR *ppm2++ = imgdata.color.curve[imgdata.image[soff][c]];
          }
        }
        else {
          if (O.output_bps == 8) {
            for (col=0; col < S.width; col++, soff += cstep) 
              FORRGB *ppm++ = imgdata.color.curve[imgdata.image[soff][c]]>>8;
          }
          else {
            for (col=0; col < S.width; col++, soff += cstep) 
              FORRGB *ppm2++ = imgdata.color.curve[imgdata.image[soff][c]];
          }
        }
        
//            bufp += stride;           // go to the next line
      }
 
    S.iheight = s_iheight;
    S.iwidth = s_iwidth;
    S.width = s_width;
    S.height = s_hwight;

    return 0;


}

Project: LibRaw

void LibRaw::setCancelFlag()
{
#ifdef WIN32
  InterlockedExchangeAdd(&_exitflag,1);
#else
  __sync_fetch_and_add(&_exitflag,1);
#endif
#ifdef RAWSPEED_FASTEXIT
  if(_rawspeed_decoder)
    {
      RawDecoder *d = static_cast<RawDecoder*>(_rawspeed_decoder);
      d->cancelProcessing();
    }
#endif
}

Project: LibRaw

void CLASS identify()
{
  static const short pana[][6] = {
    { 3130, 1743,  4,  0, -6,  0 },
    { 3130, 2055,  4,  0, -6,  0 },
    { 3130, 2319,  4,  0, -6,  0 },
    { 3170, 2103, 18,  0,-42, 20 },
    { 3170, 2367, 18, 13,-42,-21 },
    { 3177, 2367,  0,  0, -1,  0 },
    { 3304, 2458,  0,  0, -1,  0 },
    { 3330, 2463,  9,  0, -5,  0 },
    { 3330, 2479,  9,  0,-17,  4 },
    { 3370, 1899, 15,  0,-44, 20 },
    { 3370, 2235, 15,  0,-44, 20 },
    { 3370, 2511, 15, 10,-44,-21 },
    { 3690, 2751,  3,  0, -8, -3 },
    { 3710, 2751,  0,  0, -3,  0 },
    { 3724, 2450,  0,  0,  0, -2 },
    { 3770, 2487, 17,  0,-44, 19 },
    { 3770, 2799, 17, 15,-44,-19 },
    { 3880, 2170,  6,  0, -6,  0 },
    { 4060, 3018,  0,  0,  0, -2 },
    { 4290, 2391,  3,  0, -8, -1 },
    { 4330, 2439, 17, 15,-44,-19 },
    { 4508, 2962,  0,  0, -3, -4 },
    { 4508, 3330,  0,  0, -3, -6 },
  };
  static const ushort canon[][11] = {
    { 1944, 1416,   0,  0, 48,  0 },
    { 2144, 1560,   4,  8, 52,  2, 0, 0, 0, 25 },
    { 2224, 1456,  48,  6,  0,  2 },
    { 2376, 1728,  12,  6, 52,  2 },
    { 2672, 1968,  12,  6, 44,  2 },
    { 3152, 2068,  64, 12,  0,  0, 16 },
    { 3160, 2344,  44, 12,  4,  4 },
    { 3344, 2484,   4,  6, 52,  6 },
    { 3516, 2328,  42, 14,  0,  0 },
    { 3596, 2360,  74, 12,  0,  0 },
    { 3744, 2784,  52, 12,  8, 12 },
    { 3944, 2622,  30, 18,  6,  2 },
    { 3948, 2622,  42, 18,  0,  2 },
    { 3984, 2622,  76, 20,  0,  2, 14 },
    { 4104, 3048,  48, 12, 24, 12 },
    { 4116, 2178,   4,  2,  0,  0 },
    { 4152, 2772, 192, 12,  0,  0 },
    { 4160, 3124, 104, 11,  8, 65 },
    { 4176, 3062,  96, 17,  8,  0, 0, 16, 0, 7, 0x49 },
    { 4192, 3062,  96, 17, 24,  0, 0, 16, 0, 0, 0x49 },
    { 4312, 2876,  22, 18,  0,  2 },
    { 4352, 2874,  62, 18,  0,  0 },
    { 4476, 2954,  90, 34,  0,  0 },
    { 4480, 3348,  12, 10, 36, 12, 0, 0, 0, 18, 0x49 },
    { 4496, 3366,  80, 50, 12,  0 },
    { 4832, 3204,  62, 26,  0,  0 },
    { 4832, 3228,  62, 51,  0,  0 },
    { 5108, 3349,  98, 13,  0,  0 },
    { 5120, 3318, 142, 45, 62,  0 },
    { 5280, 3528,  72, 52,  0,  0 },
    { 5344, 3516, 142, 51,  0,  0 },
    { 5344, 3584, 126,100,  0,  2 },
    { 5360, 3516, 158, 51,  0,  0 },
    { 5568, 3708,  72, 38,  0,  0 },
    { 5712, 3774,  62, 20, 10,  2 },
    { 5792, 3804, 158, 51,  0,  0 },
    { 5920, 3950, 122, 80,  2,  0 },
  };
  static const struct {
    ushort id;
    char t_model[20];
  } unique[] = {
    { 0x168, "EOS 10D" },    { 0x001, "EOS-1D" },
    { 0x175, "EOS 20D" },    { 0x174, "EOS-1D Mark II" },
    { 0x234, "EOS 30D" },    { 0x232, "EOS-1D Mark II N" },
    { 0x190, "EOS 40D" },    { 0x169, "EOS-1D Mark III" },
    { 0x261, "EOS 50D" },    { 0x281, "EOS-1D Mark IV" },
    { 0x287, "EOS 60D" },    { 0x167, "EOS-1DS" },
    { 0x170, "EOS 300D" },   { 0x188, "EOS-1Ds Mark II" },
    { 0x176, "EOS 450D" },   { 0x215, "EOS-1Ds Mark III" },
    { 0x189, "EOS 350D" },   { 0x324, "EOS-1D C" },
    { 0x236, "EOS 400D" },   { 0x269, "EOS-1D X" },
    { 0x252, "EOS 500D" },   { 0x213, "EOS 5D" },
    { 0x270, "EOS 550D" },   { 0x218, "EOS 5D Mark II" },
    { 0x286, "EOS 600D" },   { 0x285, "EOS 5D Mark III" },
    { 0x301, "EOS 650D" },   { 0x302, "EOS 6D" },
    { 0x325, "EOS 70D" },    { 0x326, "EOS 700D" },   { 0x250, "EOS 7D" },
    { 0x254, "EOS 1000D" },
    { 0x288, "EOS 1100D" },
    { 0x346, "EOS 100D" },
    { 0x331, "EOS M" },
  };
  static const struct {
    ushort id;
    char t_model[20];
  } sony_unique[] = {
    {2,"DSC-R1"},
    {256,"DSLR-A100"},
    {257,"DSLR-A900"},
    {258,"DSLR-A700"},
    {259,"DSLR-A200"},
    {260,"DSLR-A350"},
    {261,"DSLR-A300"},
    {262,"DSLR-A900"},
    {263,"DSLR-A380"},
    {264,"DSLR-A330"},
    {265,"DSLR-A230"},
    {266,"DSLR-A290"},
    {269,"DSLR-A850"},
    {270,"DSLR-A850"},
    {273,"DSLR-A550"},
    {274,"DSLR-A500"},
    {275,"DSLR-A450"},
    {278,"NEX-5"},
    {279,"NEX-3"},
    {280,"SLT-A33"},
    {281,"SLT-A55"},
    {282,"DSLR-A560"},
    {283,"DSLR-A580"},
    {284,"NEX-C3"},
    {285,"SLT-A35"},
    {286,"SLT-A65"},
    {287,"SLT-A77"},
    {288,"NEX-5N"},
    {289,"NEX-7"},
    {290,"NEX-VG20E"},
    {291,"SLT-A37"},
    {292,"SLT-A57"},
    {293,"NEX-F3"},
    {294,"SLT-A99"},
    {295,"NEX-6"},
    {296,"NEX-5R"},
    {297,"DSC-RX100"},
    {298,"DSC-RX1"},
    {299,"NEX-VG900"},
    {300,"NEX-VG30E"},
    {302,"ILCE-3000"},
    {303,"SLT-A58"},
    {305,"NEX-3N"},
    {306,"ILCE-A7"},
    {307,"NEX-5T"},
    {308,"DSC-RX100M2"},
    {310,"DSC-RX1R"},
    {311,"ILCE-A7R"},
  };
  static const struct {
    unsigned fsize;
    ushort rw, rh;
    uchar lm, tm, rm, bm, lf, cf, max, flags;
    char t_make[10], t_model[20];
    ushort offset;
  } table[] = {
    {   786432,1024, 768, 0, 0, 0, 0, 0,0x94,0,0,"AVT","F-080C" },
    {  1447680,1392,1040, 0, 0, 0, 0, 0,0x94,0,0,"AVT","F-145C" },
    {  1920000,1600,1200, 0, 0, 0, 0, 0,0x94,0,0,"AVT","F-201C" },
    {  5067304,2588,1958, 0, 0, 0, 0, 0,0x94,0,0,"AVT","F-510C" },
    {  5067316,2588,1958, 0, 0, 0, 0, 0,0x94,0,0,"AVT","F-510C",12 },
    { 10134608,2588,1958, 0, 0, 0, 0, 9,0x94,0,0,"AVT","F-510C" },
    { 10134620,2588,1958, 0, 0, 0, 0, 9,0x94,0,0,"AVT","F-510C",12 },
    { 16157136,3272,2469, 0, 0, 0, 0, 9,0x94,0,0,"AVT","F-810C" },
    { 15980544,3264,2448, 0, 0, 0, 0, 8,0x61,0,1,"AgfaPhoto","DC-833m" },
    {  9631728,2532,1902, 0, 0, 0, 0,96,0x61,0,0,"Alcatel","5035D" },
    {  2868726,1384,1036, 0, 0, 0, 0,64,0x49,0,8,"Baumer","TXG14",1078 },
    {  5298000,2400,1766,12,12,44, 2,40,0x94,0,2,"Canon","PowerShot SD300" },
    {  6553440,2664,1968, 4, 4,44, 4,40,0x94,0,2,"Canon","PowerShot A460" },
    {  6573120,2672,1968,12, 8,44, 0,40,0x94,0,2,"Canon","PowerShot A610" },
    {  6653280,2672,1992,10, 6,42, 2,40,0x94,0,2,"Canon","PowerShot A530" },
    {  7710960,2888,2136,44, 8, 4, 0,40,0x94,0,2,"Canon","PowerShot S3 IS" },
    {  9219600,3152,2340,36,12, 4, 0,40,0x94,0,2,"Canon","PowerShot A620" },
    {  9243240,3152,2346,12, 7,44,13,40,0x49,0,2,"Canon","PowerShot A470" },
    { 10341600,3336,2480, 6, 5,32, 3,40,0x94,0,2,"Canon","PowerShot A720 IS" },
    { 10383120,3344,2484,12, 6,44, 6,40,0x94,0,2,"Canon","PowerShot A630" },
    { 12945240,3736,2772,12, 6,52, 6,40,0x94,0,2,"Canon","PowerShot A640" },
    { 15636240,4104,3048,48,12,24,12,40,0x94,0,2,"Canon","PowerShot A650" },
    { 15467760,3720,2772, 6,12,30, 0,40,0x94,0,2,"Canon","PowerShot SX110 IS" },
    { 15534576,3728,2778,12, 9,44, 9,40,0x94,0,2,"Canon","PowerShot SX120 IS" },
    { 18653760,4080,3048,24,12,24,12,40,0x94,0,2,"Canon","PowerShot SX20 IS" },
    { 19131120,4168,3060,92,16, 4, 1,40,0x94,0,2,"Canon","PowerShot SX220 HS" },
    { 21936096,4464,3276,25,10,73,12,40,0x16,0,2,"Canon","PowerShot SX30 IS" },
    { 24724224,4704,3504, 8,16,56, 8,40,0x49,0,2,"Canon","PowerShot A3300 IS" },
    {  1976352,1632,1211, 0, 2, 0, 1, 0,0x94,0,1,"Casio","QV-2000UX" },
    {  3217760,2080,1547, 0, 0,10, 1, 0,0x94,0,1,"Casio","QV-3*00EX" },
    {  6218368,2585,1924, 0, 0, 9, 0, 0,0x94,0,1,"Casio","QV-5700" },
    {  7816704,2867,2181, 0, 0,34,36, 0,0x16,0,1,"Casio","EX-Z60" },
    {  2937856,1621,1208, 0, 0, 1, 0, 0,0x94,7,13,"Casio","EX-S20" },
    {  4948608,2090,1578, 0, 0,32,34, 0,0x94,7,1,"Casio","EX-S100" },
    {  6054400,2346,1720, 2, 0,32, 0, 0,0x94,7,1,"Casio","QV-R41" },
    {  7426656,2568,1928, 0, 0, 0, 0, 0,0x94,0,1,"Casio","EX-P505" },
    {  7530816,2602,1929, 0, 0,22, 0, 0,0x94,7,1,"Casio","QV-R51" },
    {  7542528,2602,1932, 0, 0,32, 0, 0,0x94,7,1,"Casio","EX-Z50" },
    {  7562048,2602,1937, 0, 0,25, 0, 0,0x16,7,1,"Casio","EX-Z500" },
    {  7753344,2602,1986, 0, 0,32,26, 0,0x94,7,1,"Casio","EX-Z55" },
    {  9313536,2858,2172, 0, 0,14,30, 0,0x94,7,1,"Casio","EX-P600" },
    { 10834368,3114,2319, 0, 0,27, 0, 0,0x94,0,1,"Casio","EX-Z750" },
    { 10843712,3114,2321, 0, 0,25, 0, 0,0x94,0,1,"Casio","EX-Z75" },
    { 10979200,3114,2350, 0, 0,32,32, 0,0x94,7,1,"Casio","EX-P700" },
    { 12310144,3285,2498, 0, 0, 6,30, 0,0x94,0,1,"Casio","EX-Z850" },
    { 12489984,3328,2502, 0, 0,47,35, 0,0x94,0,1,"Casio","EX-Z8" },
    { 15499264,3754,2752, 0, 0,82, 0, 0,0x94,0,1,"Casio","EX-Z1050" },
    { 18702336,4096,3044, 0, 0,24, 0,80,0x94,7,1,"Casio","EX-ZR100" },
    {  7684000,2260,1700, 0, 0, 0, 0,13,0x94,0,1,"Casio","QV-4000" },
    {   787456,1024, 769, 0, 1, 0, 0, 0,0x49,0,0,"Creative","PC-CAM 600" },
    { 28829184,4384,3288, 0, 0, 0, 0,36,0x61,0,0,"DJI" },
    { 15151104,4608,3288, 0, 0, 0, 0, 0,0x94,0,0,"Matrix" },
    {  3840000,1600,1200, 0, 0, 0, 0,65,0x49,0,0,"Foculus","531C" },
    {   307200, 640, 480, 0, 0, 0, 0, 0,0x94,0,0,"Generic","640x480" },
    {    62464, 256, 244, 1, 1, 6, 1, 0,0x8d,0,0,"Kodak","DC20" },
    {   124928, 512, 244, 1, 1,10, 1, 0,0x8d,0,0,"Kodak","DC20" },
    {  1652736,1536,1076, 0,52, 0, 0, 0,0x61,0,0,"Kodak","DCS200" },
    {  4159302,2338,1779, 1,33, 1, 2, 0,0x94,0,0,"Kodak","C330" },
    {  4162462,2338,1779, 1,33, 1, 2, 0,0x94,0,0,"Kodak","C330",3160 },
    {  6163328,2864,2152, 0, 0, 0, 0, 0,0x94,0,0,"Kodak","C603" },
    {  6166488,2864,2152, 0, 0, 0, 0, 0,0x94,0,0,"Kodak","C603",3160 },
    {   460800, 640, 480, 0, 0, 0, 0, 0,0x00,0,0,"Kodak","C603" },
    {  9116448,2848,2134, 0, 0, 0, 0, 0,0x00,0,0,"Kodak","C603" },
    { 12241200,4040,3030, 2, 0, 0,13, 0,0x49,0,0,"Kodak","12MP" },
    { 12272756,4040,3030, 2, 0, 0,13, 0,0x49,0,0,"Kodak","12MP",31556 },
    { 18000000,4000,3000, 0, 0, 0, 0, 0,0x00,0,0,"Kodak","12MP" },
    {   614400, 640, 480, 0, 3, 0, 0,64,0x94,0,0,"Kodak","KAI-0340" },
    {  3884928,1608,1207, 0, 0, 0, 0,96,0x16,0,0,"Micron","2010",3212 },
    {  1138688,1534, 986, 0, 0, 0, 0, 0,0x61,0,0,"Minolta","RD175",513 },
    {  1581060,1305, 969, 0, 0,18, 6, 6,0x1e,4,1,"Nikon","E900" },
    {  2465792,1638,1204, 0, 0,22, 1, 6,0x4b,5,1,"Nikon","E950" },
    {  2940928,1616,1213, 0, 0, 0, 7,30,0x94,0,1,"Nikon","E2100" },
    {  4771840,2064,1541, 0, 0, 0, 1, 6,0xe1,0,1,"Nikon","E990" },
    {  4775936,2064,1542, 0, 0, 0, 0,30,0x94,0,1,"Nikon","E3700" },
    {  5865472,2288,1709, 0, 0, 0, 1, 6,0xb4,0,1,"Nikon","E4500" },
    {  5869568,2288,1710, 0, 0, 0, 0, 6,0x16,0,1,"Nikon","E4300" },
    {  7438336,2576,1925, 0, 0, 0, 1, 6,0xb4,0,1,"Nikon","E5000" },
    {  8998912,2832,2118, 0, 0, 0, 0,30,0x94,7,1,"Nikon","COOLPIX S6" },
    {  5939200,2304,1718, 0, 0, 0, 0,30,0x16,0,0,"Olympus","C770UZ" },
    {  3178560,2064,1540, 0, 0, 0, 0, 0,0x94,0,1,"Pentax","Optio S" },
    {  4841984,2090,1544, 0, 0,22, 0, 0,0x94,7,1,"Pentax","Optio S" },
    {  6114240,2346,1737, 0, 0,22, 0, 0,0x94,7,1,"Pentax","Optio S4" },
    { 10702848,3072,2322, 0, 0, 0,21,30,0x94,0,1,"Pentax","Optio 750Z" },
    { 13248000,2208,3000, 0, 0, 0, 0,13,0x61,0,0,"Pixelink","A782" },
    {  6291456,2048,1536, 0, 0, 0, 0,96,0x61,0,0,"RoverShot","3320AF" },
    {   311696, 644, 484, 0, 0, 0, 0, 0,0x16,0,8,"ST Micro","STV680 VGA" },
    { 16098048,3288,2448, 0, 0,24, 0, 9,0x94,0,1,"Samsung","S85" },
    { 16215552,3312,2448, 0, 0,48, 0, 9,0x94,0,1,"Samsung","S85" },
    { 20487168,3648,2808, 0, 0, 0, 0,13,0x94,5,1,"Samsung","WB550" },
    { 24000000,4000,3000, 0, 0, 0, 0,13,0x94,5,1,"Samsung","WB550" },
    { 12582980,3072,2048, 0, 0, 0, 0,33,0x61,0,0,"Sinar","3072x2048",68 },
    { 33292868,4080,4080, 0, 0, 0, 0,33,0x61,0,0,"Sinar","4080x4080",68 },
    { 44390468,4080,5440, 0, 0, 0, 0,33,0x61,0,0,"Sinar","4080x5440",68 },
    {  1409024,1376,1024, 0, 0, 1, 0, 0,0x49,0,0,"Sony","XCD-SX910CR" },
    {  2818048,1376,1024, 0, 0, 1, 0,97,0x49,0,0,"Sony","XCD-SX910CR" },
  };
  static const char *corp[] =
    { "AgfaPhoto", "Canon", "Casio", "Epson", "Fujifilm",
      "Mamiya", "Minolta", "Motorola", "Kodak", "Konica", "Leica",
      "Nikon", "Nokia", "Olympus", "Pentax", "Phase One", "Ricoh",
      "Samsung", "Sigma", "Sinar", "Sony" };
  char head[32], *cp;
  int hlen, flen, fsize, zero_fsize=1, i, c;
  struct jhead jh;

  tiff_flip = flip = filters = UINT_MAX;	/* unknown */
  raw_height = raw_width = fuji_width = fuji_layout = cr2_slice[0] = 0;
  maximum = height = width = top_margin = left_margin = 0;
  cdesc[0] = desc[0] = artist[0] = make[0] = model[0] = model2[0] = 0;
  iso_speed = shutter = aperture = focal_len = unique_id = 0;
  tiff_nifds = 0;
  memset (tiff_ifd, 0, sizeof tiff_ifd);
  memset (gpsdata, 0, sizeof gpsdata);
  memset (cblack, 0, sizeof cblack);
  memset (white, 0, sizeof white);
  memset (mask, 0, sizeof mask);
  thumb_offset = thumb_length = thumb_width = thumb_height = 0;
  load_raw = thumb_load_raw = 0;
  write_thumb = &CLASS jpeg_thumb;
  data_offset = meta_length = tiff_bps = tiff_compress = 0;
  kodak_cbpp = zero_after_ff = dng_version = load_flags = 0;
  timestamp = shot_order = tiff_samples = black = is_foveon = 0;
  mix_green = profile_length = data_error = zero_is_bad = 0;
  pixel_aspect = is_raw = raw_color = 1;
  tile_width = tile_length = 0;
  for (i=0; i < 4; i++) {
    cam_mul[i] = i == 1;
    pre_mul[i] = i < 3;
    FORC3 cmatrix[c][i] = 0;
    FORC3 rgb_cam[c][i] = c == i;
  }
  colors = 3;
  for (i=0; i < 0x10000; i++) curve[i] = i;

  order = get2();
  hlen = get4();
  fseek (ifp, 0, SEEK_SET);
  fread (head, 1, 32, ifp);
  fseek (ifp, 0, SEEK_END);
  flen = fsize = ftell(ifp);
  if ((cp = (char *) memmem (head, 32, (char*)"MMMM", 4)) ||
      (cp = (char *) memmem (head, 32, (char*)"IIII", 4))) {
    parse_phase_one (cp-head);
    if (cp-head && parse_tiff(0)) apply_tiff();
  } else if (order == 0x4949 || order == 0x4d4d) {
    if (!memcmp (head+6,"HEAPCCDR",8)) {
      data_offset = hlen;
      parse_ciff (hlen, flen-hlen, 0);
      load_raw = &CLASS canon_load_raw;
    } else if (parse_tiff(0)) apply_tiff();
  } else if (!memcmp (head,"\xff\xd8\xff\xe1",4) &&
	     !memcmp (head+6,"Exif",4)) {
    fseek (ifp, 4, SEEK_SET);
    data_offset = 4 + get2();
    fseek (ifp, data_offset, SEEK_SET);
    if (fgetc(ifp) != 0xff)
      parse_tiff(12);
    thumb_offset = 0;
  } else if (!memcmp (head+25,"ARECOYK",7)) {
    strcpy (make, "Contax");
    strcpy (model,"N Digital");
    fseek (ifp, 33, SEEK_SET);
    get_timestamp(1);
    fseek (ifp, 60, SEEK_SET);
    FORC4 cam_mul[c ^ (c >> 1)] = get4();
  } else if (!strcmp (head, "PXN")) {
    strcpy (make, "Logitech");
    strcpy (model,"Fotoman Pixtura");
  } else if (!strcmp (head, "qktk")) {
    strcpy (make, "Apple");
    strcpy (model,"QuickTake 100");
    load_raw = &CLASS quicktake_100_load_raw;
  } else if (!strcmp (head, "qktn")) {
    strcpy (make, "Apple");
    strcpy (model,"QuickTake 150");
    load_raw = &CLASS kodak_radc_load_raw;
  } else if (!memcmp (head,"FUJIFILM",8)) {
    fseek (ifp, 84, SEEK_SET);
    thumb_offset = get4();
    thumb_length = get4();
    fseek (ifp, 92, SEEK_SET);
    parse_fuji (get4());
    if (thumb_offset > 120) {
      fseek (ifp, 120, SEEK_SET);
      is_raw += (i = get4()) && 1;
      if (is_raw == 2 && shot_select)
	parse_fuji (i);
    }
    load_raw = &CLASS unpacked_load_raw;
    fseek (ifp, 100+28*(shot_select > 0), SEEK_SET);
    parse_tiff (data_offset = get4());
    parse_tiff (thumb_offset+12);
    apply_tiff();
  } else if (!memcmp (head,"RIFF",4)) {
    fseek (ifp, 0, SEEK_SET);
    parse_riff();
  } else if (!memcmp (head,"\0\001\0\001\0@",6)) {
    fseek (ifp, 6, SEEK_SET);
    fread (make, 1, 8, ifp);
    fread (model, 1, 8, ifp);
    fread (model2, 1, 16, ifp);
    data_offset = get2();
    get2();
    raw_width = get2();
    raw_height = get2();
    load_raw = &CLASS nokia_load_raw;
    filters = 0x61616161;
  } else if (!memcmp (head,"NOKIARAW",8)) {
    strcpy (make, "NOKIA");
    order = 0x4949;
    fseek (ifp, 300, SEEK_SET);
    data_offset = get4();
    i = get4();
    width = get2();
    height = get2();
    switch (tiff_bps = i*8 / (width * height)) {
      case  8: load_raw = &CLASS eight_bit_load_raw;  break;
      case 10: load_raw = &CLASS nokia_load_raw;
    }
    raw_height = height + (top_margin = i / (width * tiff_bps/8) - height);
    mask[0][3] = 1;
    filters = 0x61616161;
  } else if (!memcmp (head,"ARRI",4)) {
    order = 0x4949;
    fseek (ifp, 20, SEEK_SET);
    width = get4();
    height = get4();
    strcpy (make, "ARRI");
    fseek (ifp, 668, SEEK_SET);
    fread (model, 1, 64, ifp);
    data_offset = 4096;
    load_raw = &CLASS packed_load_raw;
    load_flags = 88;
    filters = 0x61616161;
  } else if (!memcmp (head,"XPDS",4)) {
    order = 0x4949;
    fseek (ifp, 0x800, SEEK_SET);
    fread (make, 1, 41, ifp);
    raw_height = get2();
    raw_width  = get2();
    fseek (ifp, 56, SEEK_CUR);
    fread (model, 1, 30, ifp);
    data_offset = 0x10000;
    load_raw = &CLASS canon_rmf_load_raw;
    gamma_curve (0, 12.25, 1, 1023);
  } else if (!memcmp (head+4,"RED1",4)) {
    strcpy (make, "Red");
    strcpy (model,"One");
    parse_redcine();
    load_raw = &CLASS redcine_load_raw;
    gamma_curve (1/2.4, 12.92, 1, 4095);
    filters = 0x49494949;
  } else if (!memcmp (head,"DSC-Image",9))
    parse_rollei();
  else if (!memcmp (head,"PWAD",4))
    parse_sinar_ia();
  else if (!memcmp (head,"\0MRM",4))
    parse_minolta(0);
  else if (!memcmp (head,"FOVb",4))
    {
#ifdef LIBRAW_LIBRARY_BUILD
#ifdef  LIBRAW_DEMOSAIC_PACK_GPL2
      if(!imgdata.params.force_foveon_x3f)
        parse_foveon();
      else
#endif
        parse_x3f();
#else
#ifdef  LIBRAW_DEMOSAIC_PACK_GPL2
      parse_foveon();
#endif
#endif
    }
  else if (!memcmp (head,"CI",2))
    parse_cine();
  else
    for (zero_fsize=i=0; i < sizeof table / sizeof *table; i++)
      if (fsize == table[i].fsize) {
	strcpy (make,  table[i].t_make );
	strcpy (model, table[i].t_model);
	flip = table[i].flags >> 2;
	zero_is_bad = table[i].flags & 2;
	if (table[i].flags & 1)
	  parse_external_jpeg();
	data_offset = table[i].offset;
	raw_width   = table[i].rw;
	raw_height  = table[i].rh;
	left_margin = table[i].lm;
	 top_margin = table[i].tm;
	width  = raw_width - left_margin - table[i].rm;
	height = raw_height - top_margin - table[i].bm;
	filters = 0x1010101 * table[i].cf;
	colors = 4 - !((filters & filters >> 1) & 0x5555);
	load_flags = table[i].lf;
	switch (tiff_bps = (fsize-data_offset)*8 / (raw_width*raw_height)) {
	  case 6:
	    load_raw = &CLASS minolta_rd175_load_raw;  break;
	  case 8:
	    load_raw = &CLASS eight_bit_load_raw;  break;
	  case 10: case 12:
	    load_flags |= 128;
	    load_raw = &CLASS packed_load_raw;     break;
	  case 16:
	    order = 0x4949 | 0x404 * (load_flags & 1);
	    tiff_bps -= load_flags >> 4;
	    tiff_bps -= load_flags = load_flags >> 1 & 7;
	    load_raw = &CLASS unpacked_load_raw;
	}
	maximum = (1 << tiff_bps) - (1 << table[i].max);
      }
  if (zero_fsize) fsize = 0;
  if (make[0] == 0) parse_smal (0, flen);
  if (make[0] == 0) {
    parse_jpeg(0);
    fseek(ifp,0,SEEK_END);
    int sz = ftell(ifp);
    if (!strncmp(model,"ov",2) && sz>=6404096 && !fseek (ifp, -6404096, SEEK_END) &&
	fread (head, 1, 32, ifp) && !strcmp(head,"BRCMn")) {
      strcpy (make, "OmniVision");
      data_offset = ftell(ifp) + 0x8000-32;
      width = raw_width;
      raw_width = 2611;
      load_raw = &CLASS nokia_load_raw;
      filters = 0x16161616;
    } else is_raw = 0;
  }

  for (i=0; i < sizeof corp / sizeof *corp; i++)
    if (strcasestr (make, corp[i]))	/* Simplify company names */
	    strcpy (make, corp[i]);
  if ((!strcmp(make,"Kodak") || !strcmp(make,"Leica")) &&
	((cp = strcasestr(model," DIGITAL CAMERA")) ||
	 (cp = strstr(model,"FILE VERSION"))))
     *cp = 0;
  if (!strncasecmp(model,"PENTAX",6))
    strcpy (make, "Pentax");
  cp = make + strlen(make);		/* Remove trailing spaces */
  while (*--cp == ' ') *cp = 0;
  cp = model + strlen(model);
  while (*--cp == ' ') *cp = 0;
  i = strlen(make);			/* Remove make from model */
  if (!strncasecmp (model, make, i) && model[i++] == ' ')
    memmove (model, model+i, 64-i);
  if (!strncmp (model,"FinePix ",8))
    strcpy (model, model+8);
  if (!strncmp (model,"Digital Camera ",15))
    strcpy (model, model+15);
  desc[511] = artist[63] = make[63] = model[63] = model2[63] = 0;
  if (!is_raw) goto notraw;

  if (!height) height = raw_height;
  if (!width)  width  = raw_width;
  if (height == 2624 && width == 3936)	/* Pentax K10D and Samsung GX10 */
    { height  = 2616;   width  = 3896; }
  if (height == 3136 && width == 4864)  /* Pentax K20D and Samsung GX20 */
    { height  = 3124;   width  = 4688; filters = 0x16161616; }
  if (width == 4352 && (!strcmp(model,"K-r") || !strcmp(model,"K-x")))
    {			width  = 4309; filters = 0x16161616; }
  if (width >= 4960 && !strncmp(model,"K-5",3))
    { left_margin = 10; width  = 4950; filters = 0x16161616; }
  if (width == 4736 && !strcmp(model,"K-7"))
    { height  = 3122;   width  = 4684; filters = 0x16161616; top_margin = 2; }
  if (width == 6080 && !strcmp(model,"K-3"))
    { left_margin = 4;  width  = 6040; }
  if (width == 7424 && !strcmp(model,"645D"))
    { height  = 5502;   width  = 7328; filters = 0x61616161; top_margin = 29;
      left_margin = 48; }
  if (height == 3014 && width == 4096)	/* Ricoh GX200 */
			width  = 4014;
  if (dng_version) {
    if (filters == UINT_MAX) filters = 0;
    if (filters) is_raw = tiff_samples;
    else	 colors = tiff_samples;
    switch (tiff_compress) {
    case 0:  /* Compression not set, assuming uncompressed */
      case 1:     load_raw = &CLASS   packed_dng_load_raw;  break;
      case 7:     load_raw = &CLASS lossless_dng_load_raw;  break;
      case 34892: load_raw = &CLASS    lossy_dng_load_raw;  break;
      default:    load_raw = 0;
    }
    goto dng_skip;
  }
  if (!strcmp(make,"Canon") && !fsize && tiff_bps != 15) {
    if (!load_raw)
      load_raw = &CLASS lossless_jpeg_load_raw;
    for (i=0; i < sizeof canon / sizeof *canon; i++)
      if (raw_width == canon[i][0] && raw_height == canon[i][1]) {
	width  = raw_width - (left_margin = canon[i][2]);
	height = raw_height - (top_margin = canon[i][3]);
	width  -= canon[i][4];
	height -= canon[i][5];
	mask[0][1] =  canon[i][6];
	mask[0][3] = -canon[i][7];
	mask[1][1] =  canon[i][8];
	mask[1][3] = -canon[i][9];
	if (canon[i][10]) filters = canon[i][10] * 0x01010101;
      }
    if ((unique_id | 0x20000) == 0x2720000) {
      left_margin = 8;
      top_margin = 16;
    }
  }
  if (!strcmp(make,"Canon") && unique_id)
    {
      for (i=0; i < sizeof unique / sizeof *unique; i++)
        if (unique_id == 0x80000000 + unique[i].id)
          {
            adobe_coeff ("Canon", unique[i].t_model);
            strcpy(model,unique[i].t_model);
          }
    }

  if (!strcasecmp(make,"Sony") && unique_id)
    {
      for (i=0; i < sizeof sony_unique / sizeof *sony_unique; i++)
        if (unique_id == sony_unique[i].id)
          {
            adobe_coeff ("Sony", sony_unique[i].t_model);
            strcpy(model,sony_unique[i].t_model);
          }
    }

  if (!strcmp(make,"Nikon")) {
    if (!load_raw)
      load_raw = &CLASS packed_load_raw;
    if (model[0] == 'E')
      load_flags |= !data_offset << 2 | 2;
  }

/* Set parameters based on camera name (for non-DNG files). */

  if (!strcmp(model,"KAI-0340")
	&& find_green (16, 16, 3840, 5120) < 25) {
    height = 480;
    top_margin = filters = 0;
    strcpy (model,"C603");
  }
  if (is_foveon) {
    if (height*2 < width) pixel_aspect = 0.5;
    if (height   > width) pixel_aspect = 2;
    filters = 0;
#ifdef LIBRAW_DEMOSAIC_PACK_GPL2
    if(!imgdata.params.force_foveon_x3f)
      simple_coeff(0);
#endif
  } else if (!strcmp(make,"Canon") && tiff_bps == 15) {
    switch (width) {
      case 3344: width -= 66;
      case 3872: width -= 6;
    }
    if (height > width) SWAP(height,width);
    filters = 0;
    tiff_samples = colors = 3;
    load_raw = &CLASS canon_sraw_load_raw;
  } else if (!strcmp(model,"PowerShot 600")) {
    height = 613;
    width  = 854;
    raw_width = 896;
    colors = 4;
    filters = 0xe1e4e1e4;
    load_raw = &CLASS canon_600_load_raw;
  } else if (!strcmp(model,"PowerShot A5") ||
	     !strcmp(model,"PowerShot A5 Zoom")) {
    height = 773;
    width  = 960;
    raw_width = 992;
    pixel_aspect = 256/235.0;
    filters = 0x1e4e1e4e;
    goto canon_a5;
  } else if (!strcmp(model,"PowerShot A50")) {
    height =  968;
    width  = 1290;
    raw_width = 1320;
    filters = 0x1b4e4b1e;
    goto canon_a5;
  } else if (!strcmp(model,"PowerShot Pro70")) {
    height = 1024;
    width  = 1552;
    filters = 0x1e4b4e1b;
canon_a5:
    colors = 4;
    tiff_bps = 10;
    load_raw = &CLASS packed_load_raw;
    load_flags = 40;
  } else if (!strcmp(model,"PowerShot Pro90 IS") ||
	     !strcmp(model,"PowerShot G1")) {
    colors = 4;
    filters = 0xb4b4b4b4;
  } else if (!strcmp(model,"PowerShot A610")) {
    if (canon_s2is()) strcpy (model+10, "S2 IS");
  } else if (!strcmp(model,"PowerShot SX220 HS")) {
    mask[1][3] = -4;
  } else if (!strcmp(model,"EOS D2000C")) {
    filters = 0x61616161;
    black = curve[200];
  } else if (!strcmp(model,"D1")) {
    cam_mul[0] *= 256/527.0;
    cam_mul[2] *= 256/317.0;
  } else if (!strcmp(model,"D1X")) {
    width -= 4;
    pixel_aspect = 0.5;
  } else if (!strcmp(model,"D40X") ||
	     !strcmp(model,"D60")  ||
	     !strcmp(model,"D80")  ||
	     !strcmp(model,"D3000")) {
    height -= 3;
    width  -= 4;
  } else if (!strcmp(model,"D3")   ||
	     !strcmp(model,"D3S")  ||
	     !strcmp(model,"D700")) {
    width -= 4;
    left_margin = 2;
  } else if (!strcmp(model,"D3100")) {
    width -= 28;
    left_margin = 6;
  } else if (!strcmp(model,"D5000") ||
	     !strcmp(model,"D90")) {
    width -= 42;
  } else if (!strcmp(model,"D5100") ||
	     !strcmp(model,"D7000") ||
	     !strcmp(model,"COOLPIX A")) {
    width -= 44;
  } else if (!strcmp(model,"D3200") ||
	     !strcmp(model,"D600")  ||
	     !strcmp(model,"D610")  ||
	    !strncmp(model,"D800",4)) {
    width -= 46;
  } else if (!strcmp(model,"D4") ||
	     !strcmp(model,"Df")) {
    width -= 52;
    left_margin = 2;
  } else if (!strncmp(model,"D40",3) ||
	     !strncmp(model,"D50",3) ||
	     !strncmp(model,"D70",3)) {
    width--;
  } else if (!strcmp(model,"D100")) {
    if (load_flags)
      raw_width = (width += 3) + 3;
  } else if (!strcmp(model,"D200")) {
    left_margin = 1;
    width -= 4;
    filters = 0x94949494;
  } else if (!strncmp(model,"D2H",3)) {
    left_margin = 6;
    width -= 14;
  } else if (!strncmp(model,"D2X",3)) {
    if (width == 3264) width -= 32;
    else width -= 8;
  } else if (!strncmp(model,"D300",4)) {
    width -= 32;
  } else if (!strcmp(make,"Nikon") && raw_width == 4032) {
    adobe_coeff ("Nikon","COOLPIX P7700");
  } else if (!strncmp(model,"COOLPIX P",9)) {
    load_flags = 24;
    filters = 0x94949494;
    if (model[9] == '7' && iso_speed >= 400)
      black = 255;
  } else if (!strncmp(model,"1 ",2)) {
    height -= 2;
  } else if (fsize == 1581060) {
    simple_coeff(3);
    pre_mul[0] = 1.2085;
    pre_mul[1] = 1.0943;
    pre_mul[3] = 1.1103;
  } else if (fsize == 3178560) {
    cam_mul[0] *= 4;
    cam_mul[2] *= 4;
  } else if (fsize == 4771840) {
    if (!timestamp && nikon_e995())
      strcpy (model, "E995");
    if (strcmp(model,"E995")) {
      filters = 0xb4b4b4b4;
      simple_coeff(3);
      pre_mul[0] = 1.196;
      pre_mul[1] = 1.246;
      pre_mul[2] = 1.018;
    }
  } else if (fsize == 2940928) {
    if (!timestamp && !nikon_e2100())
      strcpy (model,"E2500");
    if (!strcmp(model,"E2500")) {
      height -= 2;
      load_flags = 6;
      colors = 4;
      filters = 0x4b4b4b4b;
    }
  } else if (fsize == 4775936) {
    if (!timestamp) nikon_3700();
    if (model[0] == 'E' && atoi(model+1) < 3700)
      filters = 0x49494949;
    if (!strcmp(model,"Optio 33WR")) {
      flip = 1;
      filters = 0x16161616;
    }
    if (make[0] == 'O') {
      i = find_green (12, 32, 1188864, 3576832);
      c = find_green (12, 32, 2383920, 2387016);
      if (abs(i) < abs(c)) {
	SWAP(i,c);
	load_flags = 24;
      }
      if (i < 0) filters = 0x61616161;
    }
  } else if (fsize == 5869568) {
    if (!timestamp && minolta_z2()) {
      strcpy (make, "Minolta");
      strcpy (model,"DiMAGE Z2");
    }
    load_flags = 6 + 24*(make[0] == 'M');
  } else if (fsize == 6291456) {
    fseek (ifp, 0x300000, SEEK_SET);
    if ((order = guess_byte_order(0x10000)) == 0x4d4d) {
      height -= (top_margin = 16);
      width -= (left_margin = 28);
      maximum = 0xf5c0;
      strcpy (make, "ISG");
      model[0] = 0;
    }
  } else if (!strcmp(make,"Fujifilm")) {
    if (!strcmp(model+7,"S2Pro")) {
      strcpy (model,"S2Pro");
      height = 2144;
      width  = 2880;
      flip = 6;
    } else if (load_raw != &CLASS packed_load_raw)
      maximum = (is_raw == 2 && shot_select) ? 0x2f00 : 0x3e00;
    top_margin = (raw_height - height) >> 2 << 1;
    left_margin = (raw_width - width ) >> 2 << 1;
    if (width == 2848 || width == 3664) filters = 0x16161616;
    if (width == 4032 || width == 4952) left_margin = 0;
    if (width == 3328 && (width -= 66)) left_margin = 34;
    if (width == 4936) left_margin = 4;
    if (!strcmp(model,"HS50EXR") ||
	!strcmp(model,"F900EXR")) {
      width += 2;
      left_margin = 0;
      filters = 0x16161616;
    }
    if (fuji_layout) raw_width *= is_raw;
  } else if (!strcmp(model,"KD-400Z")) {
    height = 1712;
    width  = 2312;
    raw_width = 2336;
    goto konica_400z;
  } else if (!strcmp(model,"KD-510Z")) {
    goto konica_510z;
  } else if (!strcasecmp(make,"Minolta")) {
    if (!load_raw && (maximum = 0xfff))
      load_raw = &CLASS unpacked_load_raw;
    if (!strncmp(model,"DiMAGE A",8)) {
      if (!strcmp(model,"DiMAGE A200"))
	filters = 0x49494949;
      tiff_bps = 12;
      load_raw = &CLASS packed_load_raw;
    } else if (!strncmp(model,"ALPHA",5) ||
	       !strncmp(model,"DYNAX",5) ||
	       !strncmp(model,"MAXXUM",6)) {
      sprintf (model+20, "DYNAX %-10s", model+6+(model[0]=='M'));
      adobe_coeff (make, model+20);
      load_raw = &CLASS packed_load_raw;
    } else if (!strncmp(model,"DiMAGE G",8)) {
      if (model[8] == '4') {
	height = 1716;
	width  = 2304;
      } else if (model[8] == '5') {
konica_510z:
	height = 1956;
	width  = 2607;
	raw_width = 2624;
      } else if (model[8] == '6') {
	height = 2136;
	width  = 2848;
      }
      data_offset += 14;
      filters = 0x61616161;
konica_400z:
      load_raw = &CLASS unpacked_load_raw;
      maximum = 0x3df;
      order = 0x4d4d;
    }
  } else if (!strcmp(model,"*ist D")) {
    load_raw = &CLASS unpacked_load_raw;
    data_error = -1;
  } else if (!strcmp(model,"*ist DS")) {
    height -= 2;
  } else if (!strcmp(make,"Samsung") && raw_width == 4704) {
    height -= top_margin = 8;
    width -= 2 * (left_margin = 8);
    load_flags = 32;
  } else if (!strcmp(make,"Samsung") && raw_height == 3714) {
    height -= 18;
    width = 5536;
    filters = 0x61616161;
    colors = 3;
  } else if (!strcmp(make,"Samsung") && raw_width == 5632) {
    order = 0x4949;
    height = 3694;
    top_margin = 2;
    width  = 5574 - (left_margin = 32 + tiff_bps);
    if (tiff_bps == 12) load_flags = 80;
  } else if (!strcmp(model,"EX1")) {
    order = 0x4949;
    height -= 20;
    top_margin = 2;
    if ((width -= 6) > 3682) {
      height -= 10;
      width  -= 46;
      top_margin = 8;
    }
  } else if (!strcmp(model,"WB2000")) {
    order = 0x4949;
    height -= 3;
    top_margin = 2;
    if ((width -= 10) > 3718) {
      height -= 28;
      width  -= 56;
      top_margin = 8;
    }
  } else if (strstr(model,"WB550")) {
    strcpy (model, "WB550");
  } else if (!strcmp(model,"EX2F")) {
    height = 3045;
    width  = 4070;
    top_margin = 3;
    order = 0x4949;
    filters = 0x49494949;
    load_raw = &CLASS unpacked_load_raw;
  } else if (!strcmp(model,"STV680 VGA")) {
    black = 16;
  } else if (!strcmp(model,"N95")) {
    height = raw_height - (top_margin = 2);
  } else if (!strcmp(model,"640x480")) {
    gamma_curve (0.45, 4.5, 1, 255);
  } else if (!strcmp(make,"Hasselblad")) {
    if (load_raw == &CLASS lossless_jpeg_load_raw)
      load_raw = &CLASS hasselblad_load_raw;
    if (raw_width == 7262) {
      height = 5444;
      width  = 7248;
      top_margin  = 4;
      left_margin = 7;
      filters = 0x61616161;
    } else if (raw_width == 7410) {
      height = 5502;
      width  = 7328;
      top_margin  = 4;
      left_margin = 41;
      filters = 0x61616161;
    } else if (raw_width == 9044) {
      height = 6716;
      width  = 8964;
      top_margin  = 8;
      left_margin = 40;
      black += load_flags = 256;
      maximum = 0x8101;
    } else if (raw_width == 4090) {
      strcpy (model, "V96C");
      height -= (top_margin = 6);
      width -= (left_margin = 3) + 7;
      filters = 0x61616161;
    }
  } else if (!strcmp(make,"Sinar")) {
    if (!load_raw) load_raw = &CLASS unpacked_load_raw;
    maximum = 0x3fff;
  } else if (!strcmp(make,"Leaf")) {
    maximum = 0x3fff;
    fseek (ifp, data_offset, SEEK_SET);
    if (ljpeg_start (&jh, 1) && jh.bits == 15)
      maximum = 0x1fff;
    if (tiff_samples > 1) filters = 0;
    if (tiff_samples > 1 || tile_length < raw_height) {
      load_raw = &CLASS leaf_hdr_load_raw;
      raw_width = tile_width;
    }
    if ((width | height) == 2048) {
      if (tiff_samples == 1) {
	filters = 1;
	strcpy (cdesc, "RBTG");
	strcpy (model, "CatchLight");
	top_margin =  8; left_margin = 18; height = 2032; width = 2016;
      } else {
	strcpy (model, "DCB2");
	top_margin = 10; left_margin = 16; height = 2028; width = 2022;
      }
    } else if (width+height == 3144+2060) {
      if (!model[0]) strcpy (model, "Cantare");
      if (width > height) {
	 top_margin = 6; left_margin = 32; height = 2048;  width = 3072;
	filters = 0x61616161;
      } else {
	left_margin = 6;  top_margin = 32;  width = 2048; height = 3072;
	filters = 0x16161616;
      }
      if (!cam_mul[0] || model[0] == 'V') filters = 0;
      else is_raw = tiff_samples;
    } else if (width == 2116) {
      strcpy (model, "Valeo 6");
      height -= 2 * (top_margin = 30);
      width -= 2 * (left_margin = 55);
      filters = 0x49494949;
    } else if (width == 3171) {
      strcpy (model, "Valeo 6");
      height -= 2 * (top_margin = 24);
      width -= 2 * (left_margin = 24);
      filters = 0x16161616;
    }
  } else if (!strcmp(make,"Leica") || !strcmp(make,"Panasonic")) {
    if ((flen - data_offset) / (raw_width*8/7) == raw_height)
      load_raw = &CLASS panasonic_load_raw;
    if (!load_raw) {
      load_raw = &CLASS unpacked_load_raw;
      load_flags = 4;
    }
    zero_is_bad = 1;
    if ((height += 12) > raw_height) height = raw_height;
    for (i=0; i < sizeof pana / sizeof *pana; i++)
      if (raw_width == pana[i][0] && raw_height == pana[i][1]) {
	left_margin = pana[i][2];
	 top_margin = pana[i][3];
	     width += pana[i][4];
	    height += pana[i][5];
      }
    filters = 0x01010101 * (uchar) "\x94\x61\x49\x16"
	[((filters-1) ^ (left_margin & 1) ^ (top_margin << 1)) & 3];
  } else if (!strcmp(model,"C770UZ")) {
    height = 1718;
    width  = 2304;
    filters = 0x16161616;
    load_raw = &CLASS packed_load_raw;
    load_flags = 30;
  } else if (!strcmp(make,"Olympus")) {
    height += height & 1;
    if (exif_cfa) filters = exif_cfa;
    if (width == 4100) width -= 4;
    if (width == 4080) width -= 24;
    if (load_raw == &CLASS unpacked_load_raw)
      load_flags = 4;
    tiff_bps = 12;
    if (!strcmp(model,"E-300") ||
	!strcmp(model,"E-500")) {
      width -= 20;
      if (load_raw == &CLASS unpacked_load_raw) {
	maximum = 0xfc3;
	memset (cblack, 0, sizeof cblack);
      }
    } else if (!strcmp(model,"STYLUS1")) {
      width -= 14;
      maximum = 0xfff;
    } else if (!strcmp(model,"E-330")) {
      width -= 30;
      if (load_raw == &CLASS unpacked_load_raw)
	maximum = 0xf79;
    } else if (!strcmp(model,"SP550UZ")) {
      thumb_length = flen - (thumb_offset = 0xa39800);
      thumb_height = 480;
      thumb_width  = 640;
    }
  } else if (!strcmp(model,"N Digital")) {
    height = 2047;
    width  = 3072;
    filters = 0x61616161;
    data_offset = 0x1a00;
    load_raw = &CLASS packed_load_raw;
  } else if (!strcmp(model,"DSC-F828")) {
    width = 3288;
    left_margin = 5;
    mask[1][3] = -17;
    data_offset = 862144;
    load_raw = &CLASS sony_load_raw;
    filters = 0x9c9c9c9c;
    colors = 4;
    strcpy (cdesc, "RGBE");
  } else if (!strcmp(model,"DSC-V3")) {
    width = 3109;
    left_margin = 59;
    mask[0][1] = 9;
    data_offset = 787392;
    load_raw = &CLASS sony_load_raw;
  } else if (!strcmp(make,"Sony") && raw_width == 3984) {
    adobe_coeff ("Sony","DSC-R1");
    width = 3925;
    order = 0x4d4d;
  } else if (!strcmp(make,"Sony") && !strcmp(model,"ILCE-3000")) {
    width -= 32;
  } else if (!strcmp(make,"Sony") && raw_width == 5504) {
    width -= 8;
  } else if (!strcmp(make,"Sony") && raw_width == 6048) {
    width -= 24;
  } else if (!strcmp(make,"Sony") && raw_width == 7392) {
    width -= 24; // 21 pix really
  } else if (!strcmp(model,"DSLR-A100")) {
    if (width == 3880) {
      height--;
      width = ++raw_width;
    } else {
      order = 0x4d4d;
      load_flags = 2;
    }
    filters = 0x61616161;
  } else if (!strcmp(model,"DSLR-A350")) {
    height -= 4;
  } else if (!strcmp(model,"PIXL")) {
    height -= top_margin = 4;
    width -= left_margin = 32;
    gamma_curve (0, 7, 1, 255);
  } else if (!strcmp(model,"C603") || !strcmp(model,"C330")
	|| !strcmp(model,"12MP")) {
    order = 0x4949;
    if (filters && data_offset) {
      fseek (ifp, data_offset < 4096 ? 168 : 5252, SEEK_SET);
      read_shorts (curve, 256);
    } else gamma_curve (0, 3.875, 1, 255);
    load_raw = filters ? &CLASS eight_bit_load_raw
		       : &CLASS kodak_yrgb_load_raw;
  } else if (!strncasecmp(model,"EasyShare",9)) {
    data_offset = data_offset < 0x15000 ? 0x15000 : 0x17000;
    load_raw = &CLASS packed_load_raw;
  } else if (!strcasecmp(make,"Kodak")) {
    if (filters == UINT_MAX) filters = 0x61616161;
    if (!strncmp(model,"NC2000",6)) {
      width -= 4;
      left_margin = 2;
    } else if (!strcmp(model,"EOSDCS3B")) {
      width -= 4;
      left_margin = 2;
    } else if (!strcmp(model,"EOSDCS1")) {
      width -= 4;
      left_margin = 2;
    } else if (!strcmp(model,"DCS420")) {
      width -= 4;
      left_margin = 2;
    } else if (!strncmp(model,"DCS460 ",7)) {
      model[6] = 0;
      width -= 4;
      left_margin = 2;
    } else if (!strcmp(model,"DCS460A")) {
      width -= 4;
      left_margin = 2;
      colors = 1;
      filters = 0;
    } else if (!strcmp(model,"DCS660M")) {
      black = 214;
      colors = 1;
      filters = 0;
    } else if (!strcmp(model,"DCS760M")) {
      colors = 1;
      filters = 0;
    }
    if (!strcmp(model+4,"20X"))
      strcpy (cdesc, "MYCY");
    if (strstr(model,"DC25")) {
      strcpy (model, "DC25");
      data_offset = 15424;
    }
    if (!strncmp(model,"DC2",3)) {
      raw_height = 2 + (height = 242);
      if (flen < 100000) {
	raw_width = 256; width = 249;
	pixel_aspect = (4.0*height) / (3.0*width);
      } else {
	raw_width = 512; width = 501;
	pixel_aspect = (493.0*height) / (373.0*width);
      }
      top_margin = left_margin = 1;
      colors = 4;
      filters = 0x8d8d8d8d;
      simple_coeff(1);
      pre_mul[1] = 1.179;
      pre_mul[2] = 1.209;
      pre_mul[3] = 1.036;
      load_raw = &CLASS eight_bit_load_raw;
    } else if (!strcmp(model,"40")) {
      strcpy (model, "DC40");
      height = 512;
      width  = 768;
      data_offset = 1152;
      load_raw = &CLASS kodak_radc_load_raw;
    } else if (strstr(model,"DC50")) {
      strcpy (model, "DC50");
      height = 512;
      width  = 768;
      data_offset = 19712;
      load_raw = &CLASS kodak_radc_load_raw;
    } else if (strstr(model,"DC120")) {
      strcpy (model, "DC120");
      height = 976;
      width  = 848;
      pixel_aspect = height/0.75/width;
      load_raw = tiff_compress == 7 ?
	&CLASS kodak_jpeg_load_raw : &CLASS kodak_dc120_load_raw;
    } else if (!strcmp(model,"DCS200")) {
      thumb_height = 128;
      thumb_width  = 192;
      thumb_offset = 6144;
      thumb_misc   = 360;
      write_thumb = &CLASS layer_thumb;
      black = 17;
    }
  } else if (!strcmp(model,"Fotoman Pixtura")) {
    height = 512;
    width  = 768;
    data_offset = 3632;
    load_raw = &CLASS kodak_radc_load_raw;
    filters = 0x61616161;
    simple_coeff(2);
  } else if (!strncmp(model,"QuickTake",9)) {
    if (head[5]) strcpy (model+10, "200");
    fseek (ifp, 544, SEEK_SET);
    height = get2();
    width  = get2();
    data_offset = (get4(),get2()) == 30 ? 738:736;
    if (height > width) {
      SWAP(height,width);
      fseek (ifp, data_offset-6, SEEK_SET);
      flip = ~get2() & 3 ? 5:6;
    }
    filters = 0x61616161;
  } else if (!strcmp(make,"Rollei") && !load_raw) {
    switch (raw_width) {
      case 1316:
	height = 1030;
	width  = 1300;
	top_margin  = 1;
	left_margin = 6;
	break;
      case 2568:
	height = 1960;
	width  = 2560;
	top_margin  = 2;
	left_margin = 8;
    }
    filters = 0x16161616;
    load_raw = &CLASS rollei_load_raw;
  }
  else if (!strcmp(model,"GRAS-50S5C")) {
   height = 2048;
   width = 2440;
   load_raw = &CLASS unpacked_load_raw;
   data_offset = 0;
   filters = 0x49494949;
   order = 0x4949;
   maximum = 0xfffC;
  } else if (!strcmp(model,"BB-500CL")) {
   height = 2058;
   width = 2448;
   load_raw = &CLASS unpacked_load_raw;
   data_offset = 0;
   filters = 0x94949494;
   order = 0x4949;
   maximum = 0x3fff;
  } else if (!strcmp(model,"BB-500GE")) {
   height = 2058;
   width = 2456;
   load_raw = &CLASS unpacked_load_raw;
   data_offset = 0;
   filters = 0x94949494;
   order = 0x4949;
   maximum = 0x3fff;
  } else if (!strcmp(model,"SVS625CL")) {
   height = 2050;
   width = 2448;
   load_raw = &CLASS unpacked_load_raw;
   data_offset = 0;
   filters = 0x94949494;
   order = 0x4949;
   maximum = 0x0fff;
  }
  /* Early reject for damaged images */
  if (!load_raw || height < 22 || width < 22 ||
	tiff_bps > 16 || tiff_samples > 4 || colors > 4 || colors < 1)
    {
      is_raw = 0;
#ifdef LIBRAW_LIBRARY_BUILD
      RUN_CALLBACK(LIBRAW_PROGRESS_IDENTIFY,1,2);
#endif
      return;
    }
  if (!model[0])
    sprintf (model, "%dx%d", width, height);
  if (filters == UINT_MAX) filters = 0x94949494;
  if (thumb_offset && !thumb_height) {
    fseek (ifp, thumb_offset, SEEK_SET);
    if (ljpeg_start (&jh, 1)) {
      thumb_width  = jh.wide;
      thumb_height = jh.high;
    }
  }

dng_skip:
  if ((use_camera_matrix & (use_camera_wb || dng_version))
	&& cmatrix[0][0] > 0.125) {
    memcpy (rgb_cam, cmatrix, sizeof cmatrix);
    raw_color = 0;
  }
  if (raw_color) adobe_coeff (make, model);
  if (load_raw == &CLASS kodak_radc_load_raw)
    if (raw_color) adobe_coeff ("Apple","Quicktake");

  if (fuji_width) {
    fuji_width = width >> !fuji_layout;
    if (~fuji_width & 1) filters = 0x49494949;
    width = (height >> fuji_layout) + fuji_width;
    height = width - 1;
    pixel_aspect = 1;
  } else {
    if (raw_height < height) raw_height = height;
    if (raw_width  < width ) raw_width  = width;
  }
  if (!tiff_bps) tiff_bps = 12;
  if (!maximum) maximum = (1 << tiff_bps) - 1;
  if (!load_raw || height < 22 || width < 22 ||
	tiff_bps > 16 || tiff_samples > 4 || colors > 4)
    is_raw = 0;
#ifdef NO_JASPER
  if (load_raw == &CLASS redcine_load_raw) {
#ifdef DCRAW_VERBOSE
    fprintf (stderr,_("%s: You must link dcraw with %s!!\n"),
	ifname, "libjasper");
#endif
    is_raw = 0;
#ifdef LIBRAW_LIBRARY_BUILD
    imgdata.process_warnings |= LIBRAW_WARN_NO_JASPER;
#endif
  }
#endif
#ifdef NO_JPEG
  if (load_raw == &CLASS kodak_jpeg_load_raw ||
      load_raw == &CLASS lossy_dng_load_raw) {
#ifdef DCRAW_VERBOSE
    fprintf (stderr,_("%s: You must link dcraw with %s!!\n"),
	ifname, "libjpeg");
#endif
    is_raw = 0;
#ifdef LIBRAW_LIBRARY_BUILD
    imgdata.process_warnings |= LIBRAW_WARN_NO_JPEGLIB;
#endif
  }
#endif
  if (!cdesc[0])
    strcpy (cdesc, colors == 3 ? "RGBG":"GMCY");
  if (!raw_height) raw_height = height;
  if (!raw_width ) raw_width  = width;
  if (filters > 999 && colors == 3)
    filters |= ((filters >> 2 & 0x22222222) |
		(filters << 2 & 0x88888888)) & filters << 1;
notraw:
  if (flip == UINT_MAX) flip = tiff_flip;
  if (flip == UINT_MAX) flip = 0;

#ifdef LIBRAW_LIBRARY_BUILD
  RUN_CALLBACK(LIBRAW_PROGRESS_IDENTIFY,1,2);
#endif
}

Project: LibRaw

int CLASS parse_tiff_ifd (int base)
{
  unsigned entries, tag, type, len, plen=16, save;
  int ifd, use_cm=0, cfa, i, j, c, ima_len=0;
  char software[64], *cbuf, *cp;
  uchar cfa_pat[16], cfa_pc[] = { 0,1,2,3 }, tab[256];
  double cc[4][4], cm[4][3], cam_xyz[4][3], num;
  double ab[]={ 1,1,1,1 }, asn[] = { 0,0,0,0 }, xyz[] = { 1,1,1 };
  unsigned sony_curve[] = { 0,0,0,0,0,4095 };
  unsigned *buf, sony_offset=0, sony_length=0, sony_key=0;
  struct jhead jh;
#ifndef LIBRAW_LIBRARY_BUILD
  FILE *sfp;
#endif

  if (tiff_nifds >= sizeof tiff_ifd / sizeof tiff_ifd[0])
    return 1;
  ifd = tiff_nifds++;
  for (j=0; j < 4; j++)
    for (i=0; i < 4; i++)
      cc[j][i] = i == j;
  entries = get2();
  if (entries > 512) return 1;
  while (entries--) {
    tiff_get (base, &tag, &type, &len, &save);
    switch (tag) {
      case 5:   width  = get2();  break;
      case 6:   height = get2();  break;
      case 7:   width += get2();  break;
      case 9:   if ((i = get2())) filters = i;  break;
      case 17: case 18:
	if (type == 3 && len == 1)
	  cam_mul[(tag-17)*2] = get2() / 256.0;
	break;
      case 23:
	if (type == 3) iso_speed = get2();
	break;
      case 36: case 37: case 38:
	cam_mul[tag-0x24] = get2();
	break;
      case 39:
	if (len < 50 || cam_mul[0]) break;
	fseek (ifp, 12, SEEK_CUR);
	FORC3 cam_mul[c] = get2();
	break;
      case 46:
	if (type != 7 || fgetc(ifp) != 0xff || fgetc(ifp) != 0xd8) break;
	thumb_offset = ftell(ifp) - 2;
	thumb_length = len;
	break;
      case 61440:			/* Fuji HS10 table */
	parse_tiff_ifd (base);
	break;
      case 2: case 256: case 61441:	/* ImageWidth */
	tiff_ifd[ifd].t_width = getint(type);
	break;
      case 3: case 257: case 61442:	/* ImageHeight */
	tiff_ifd[ifd].t_height = getint(type);
	break;
      case 258:				/* BitsPerSample */
      case 61443:
	tiff_ifd[ifd].samples = len & 7;
	tiff_ifd[ifd].bps = getint(type);
	break;
      case 61446:
	raw_height = 0;
	if (tiff_ifd[ifd].bps > 12) break;
	load_raw = &CLASS packed_load_raw;
	load_flags = get4() ? 24:80;
	break;
      case 259:				/* Compression */
	tiff_ifd[ifd].comp = getint(type);
	break;
      case 262:				/* PhotometricInterpretation */
	tiff_ifd[ifd].phint = get2();
	break;
      case 270:				/* ImageDescription */
	fread (desc, 512, 1, ifp);
	break;
      case 271:				/* Make */
	fgets (make, 64, ifp);
	break;
      case 272:				/* Model */
	fgets (model, 64, ifp);
	break;
      case 280:				/* Panasonic RW2 offset */
	if (type != 4) break;
	load_raw = &CLASS panasonic_load_raw;
	load_flags = 0x2008;
      case 273:				/* StripOffset */
      case 513:				/* JpegIFOffset */
      case 61447:
	tiff_ifd[ifd].offset = get4()+base;
	if (!tiff_ifd[ifd].bps && tiff_ifd[ifd].offset > 0) {
	  fseek (ifp, tiff_ifd[ifd].offset, SEEK_SET);
	  if (ljpeg_start (&jh, 1)) {
	    tiff_ifd[ifd].comp    = 6;
	    tiff_ifd[ifd].t_width   = jh.wide;
	    tiff_ifd[ifd].t_height  = jh.high;
	    tiff_ifd[ifd].bps     = jh.bits;
	    tiff_ifd[ifd].samples = jh.clrs;
	    if (!(jh.sraw || (jh.clrs & 1)))
	      tiff_ifd[ifd].t_width *= jh.clrs;
	    i = order;
	    parse_tiff (tiff_ifd[ifd].offset + 12);
	    order = i;
	  }
	}
	break;
      case 274:				/* Orientation */
	tiff_ifd[ifd].t_flip = "50132467"[get2() & 7]-'0';
	break;
      case 277:				/* SamplesPerPixel */
	tiff_ifd[ifd].samples = getint(type) & 7;
	break;
      case 279:				/* StripByteCounts */
      case 514:
      case 61448:
	tiff_ifd[ifd].bytes = get4();
	break;
      case 61454:
	FORC3 cam_mul[(4-c) % 3] = getint(type);
	break;
      case 305:  case 11:		/* Software */
	fgets (software, 64, ifp);
	if (!strncmp(software,"Adobe",5) ||
	    !strncmp(software,"dcraw",5) ||
	    !strncmp(software,"UFRaw",5) ||
	    !strncmp(software,"Bibble",6) ||
	    !strncmp(software,"Nikon Scan",10) ||
	    !strcmp (software,"Digital Photo Professional"))
	  is_raw = 0;
	break;
      case 306:				/* DateTime */
	get_timestamp(0);
	break;
      case 315:				/* Artist */
	fread (artist, 64, 1, ifp);
	break;
      case 322:				/* TileWidth */
	tiff_ifd[ifd].t_tile_width = getint(type);
	break;
      case 323:				/* TileLength */
	tiff_ifd[ifd].t_tile_length = getint(type);
	break;
      case 324:				/* TileOffsets */
	tiff_ifd[ifd].offset = len > 1 ? ftell(ifp) : get4();
	if (len == 4) {
	  load_raw = &CLASS sinar_4shot_load_raw;
	  is_raw = 5;
	}
	break;
#ifdef LIBRAW_LIBRARY_BUILD
      case 325:				/* TileByteCount */
          tiff_ifd[ifd].tile_maxbytes = 0;
          for(int jj=0;jj<len;jj++)
              {
                  int s = get4();
                  if(s > tiff_ifd[ifd].tile_maxbytes) tiff_ifd[ifd].tile_maxbytes=s;
              }
	break;
#endif
      case 330:				/* SubIFDs */
	if (!strcmp(model,"DSLR-A100") && tiff_ifd[ifd].t_width == 3872) {
	  load_raw = &CLASS sony_arw_load_raw;
	  data_offset = get4()+base;
	  ifd++;  break;
	}
        if(len > 1000) len=1000; /* 1000 SubIFDs is enough */
	while (len--) {
	  i = ftell(ifp);
	  fseek (ifp, get4()+base, SEEK_SET);
	  if (parse_tiff_ifd (base)) break;
	  fseek (ifp, i+4, SEEK_SET);
	}
	break;
      case 400:
	strcpy (make, "Sarnoff");
	maximum = 0xfff;
	break;
      case 28688:
	FORC4 sony_curve[c+1] = get2() >> 2 & 0xfff;
	for (i=0; i < 5; i++)
	  for (j = sony_curve[i]+1; j <= sony_curve[i+1]; j++)
	    curve[j] = curve[j-1] + (1 << i);
	break;
      case 29184: sony_offset = get4();  break;
      case 29185: sony_length = get4();  break;
      case 29217: sony_key    = get4();  break;
      case 29264:
	parse_minolta (ftell(ifp));
	raw_width = 0;
	break;
      case 29443:
	FORC4 cam_mul[c ^ (c < 2)] = get2();
	break;
      case 29459:
	FORC4 cam_mul[c] = get2();
	i = (cam_mul[1] == 1024 && cam_mul[2] == 1024) << 1;
	SWAP (cam_mul[i],cam_mul[i+1])
	break;
    case 30720: // Sony matrix, Sony_SR2SubIFD_0x7800
      for (i=0; i < 3; i++)
        FORC3 cmatrix[i][c] = ((short) get2()) / 1024.0;
#ifdef DCRAW_VERBOSE
	if (verbose) fprintf (stderr, _(" Sony matrix:\n%f %f %f\n%f %f %f\n%f %f %f\n"), cmatrix[0][0],  cmatrix[0][1], cmatrix[0][2], cmatrix[1][0], cmatrix[1][1], cmatrix[1][2], cmatrix[2][0], cmatrix[2][1], cmatrix[2][2]);
#endif
	break;
    case 29456: // Sony black level, Sony_SR2SubIFD_0x7310, needs to be divided by 4
      FORC4 cblack[c ^ c >> 1] = get2()/4;
      i = cblack[3];
      FORC3 if(i>cblack[c]) i = cblack[c];
      FORC4 cblack[c]-=i;
      black = i;
#ifdef DCRAW_VERBOSE
      if (verbose) fprintf (stderr, _("...Sony black: %u cblack: %u %u %u %u\n"),black, cblack[0],cblack[1],cblack[2], cblack[3]);
#endif
      break;
      case 33405:			/* Model2 */
	fgets (model2, 64, ifp);
	break;
      case 33422:			/* CFAPattern */
      case 64777:			/* Kodak P-series */
	if ((plen=len) > 16) plen = 16;
	fread (cfa_pat, 1, plen, ifp);
	for (colors=cfa=i=0; i < plen && colors < 4; i++) {
	  colors += !(cfa & (1 << cfa_pat[i]));
	  cfa |= 1 << cfa_pat[i];
	}
	if (cfa == 070) memcpy (cfa_pc,"\003\004\005",3);	/* CMY */
	if (cfa == 072) memcpy (cfa_pc,"\005\003\004\001",4);	/* GMCY */
	goto guess_cfa_pc;
      case 33424:
      case 65024:
	fseek (ifp, get4()+base, SEEK_SET);
	parse_kodak_ifd (base);
	break;
      case 33434:			/* ExposureTime */
	shutter = getreal(type);
	break;
      case 33437:			/* FNumber */
	aperture = getreal(type);
	break;
      case 34306:			/* Leaf white balance */
	FORC4 cam_mul[c ^ 1] = 4096.0 / get2();
	break;
      case 34307:			/* Leaf CatchLight color matrix */
	fread (software, 1, 7, ifp);
	if (strncmp(software,"MATRIX",6)) break;
	colors = 4;
	for (raw_color = i=0; i < 3; i++) {
	  FORC4 fscanf (ifp, "%f", &rgb_cam[i][c^1]);
	  if (!use_camera_wb) continue;
	  num = 0;
	  FORC4 num += rgb_cam[i][c];
	  FORC4 rgb_cam[i][c] /= num;
	}
	break;
      case 34310:			/* Leaf metadata */
	parse_mos (ftell(ifp));
      case 34303:
	strcpy (make, "Leaf");
	break;
      case 34665:			/* EXIF tag */
	fseek (ifp, get4()+base, SEEK_SET);
	parse_exif (base);
	break;
      case 34853:			/* GPSInfo tag */
	fseek (ifp, get4()+base, SEEK_SET);
	parse_gps (base);
	break;
      case 34675:			/* InterColorProfile */
      case 50831:			/* AsShotICCProfile */
	profile_offset = ftell(ifp);
	profile_length = len;
	break;
      case 37122:			/* CompressedBitsPerPixel */
	kodak_cbpp = get4();
	break;
      case 37386:			/* FocalLength */
	focal_len = getreal(type);
	break;
      case 37393:			/* ImageNumber */
	shot_order = getint(type);
	break;
      case 37400:			/* old Kodak KDC tag */
	for (raw_color = i=0; i < 3; i++) {
	  getreal(type);
	  FORC3 rgb_cam[i][c] = getreal(type);
	}
	break;
      case 40976:
	strip_offset = get4();
	load_raw = &CLASS samsung_load_raw;
	break;
      case 46275:			/* Imacon tags */
	strcpy (make, "Imacon");
	data_offset = ftell(ifp);
	ima_len = len;
	break;
      case 46279:
	if (!ima_len) break;
	fseek (ifp, 38, SEEK_CUR);
      case 46274:
	fseek (ifp, 40, SEEK_CUR);
	raw_width  = get4();
	raw_height = get4();
	left_margin = get4() & 7;
	width = raw_width - left_margin - (get4() & 7);
	top_margin = get4() & 7;
	height = raw_height - top_margin - (get4() & 7);
	if (raw_width == 7262 && ima_len == 234317952 ) {
	  height = 5412;
	  width  = 7216;
	  left_margin = 7;
          filters=0;
	} else 	if (raw_width == 7262) {
	  height = 5444;
	  width  = 7244;
	  left_margin = 7;
	}
	fseek (ifp, 52, SEEK_CUR);
	FORC3 cam_mul[c] = getreal(11);
	fseek (ifp, 114, SEEK_CUR);
	flip = (get2() >> 7) * 90;
	if (width * height * 6 == ima_len) {
	  if (flip % 180 == 90) SWAP(width,height);
	  raw_width = width;
	  raw_height = height;
	  left_margin = top_margin = filters = flip = 0;
	}
	sprintf (model, "Ixpress %d-Mp", height*width/1000000);
	load_raw = &CLASS imacon_full_load_raw;
	if (filters) {
	  if (left_margin & 1) filters = 0x61616161;
	  load_raw = &CLASS unpacked_load_raw;
	}
	maximum = 0xffff;
	break;
      case 50454:			/* Sinar tag */
      case 50455:
	if (!(cbuf = (char *) malloc(len))) break;
	fread (cbuf, 1, len, ifp);
	for (cp = cbuf-1; cp && cp < cbuf+len; cp = strchr(cp,'\n'))
	  if (!strncmp (++cp,"Neutral ",8))
	    sscanf (cp+8, "%f %f %f", cam_mul, cam_mul+1, cam_mul+2);
	free (cbuf);
	break;
      case 50458:
	if (!make[0]) strcpy (make, "Hasselblad");
	break;
      case 50459:			/* Hasselblad tag */
	i = order;
	j = ftell(ifp);
	c = tiff_nifds;
	order = get2();
	fseek (ifp, j+(get2(),get4()), SEEK_SET);
	parse_tiff_ifd (j);
	maximum = 0xffff;
	tiff_nifds = c;
	order = i;
	break;
      case 50706:			/* DNGVersion */
	FORC4 dng_version = (dng_version << 8) + fgetc(ifp);
	if (!make[0]) strcpy (make, "DNG");
	is_raw = 1;
	break;
      case 50710:			/* CFAPlaneColor */
	if (len > 4) len = 4;
	colors = len;
	fread (cfa_pc, 1, colors, ifp);
guess_cfa_pc:
	FORCC tab[cfa_pc[c]] = c;
	cdesc[c] = 0;
	for (i=16; i--; )
	  filters = filters << 2 | tab[cfa_pat[i % plen]];
	filters -= !filters;
	break;
      case 50711:			/* CFALayout */
	if (get2() == 2) {
	  fuji_width = 1;
	  filters = 0x49494949;
	}
	break;
      case 291:
      case 50712:			/* LinearizationTable */
	linear_table (len);
	break;
      case 50713:			/* BlackLevelRepeatDim */
	cblack[4] = get2();
	cblack[5] = get2();
	if (cblack[4] * cblack[5] > (sizeof(cblack) / sizeof (cblack[0]) - 6))
	    cblack[4] = cblack[5] = 1;
	break;
      case 61450:
	cblack[4] = cblack[5] = MIN(sqrt(len),64);
      case 50714:			/* BlackLevel */
	FORC (cblack[4] * cblack[5])
	  cblack[6+c] = getreal(type);
	black = 0;
	break;
      case 50715:			/* BlackLevelDeltaH */
      case 50716:			/* BlackLevelDeltaV */
	for (num=i=0; i < len && i < 65536; i++)
	  num += getreal(type);
	black += num/len + 0.5;
	break;
      case 50717:			/* WhiteLevel */
	maximum = getint(type);
	break;
      case 50718:			/* DefaultScale */
	pixel_aspect  = getreal(type);
	pixel_aspect /= getreal(type);
	break;
      case 50721:			/* ColorMatrix1 */
      case 50722:			/* ColorMatrix2 */
	FORCC for (j=0; j < 3; j++)
	  cm[c][j] = getreal(type);
	use_cm = 1;
	break;
      case 50723:			/* CameraCalibration1 */
      case 50724:			/* CameraCalibration2 */
	for (i=0; i < colors; i++)
	  FORCC cc[i][c] = getreal(type);
	break;
      case 50727:			/* AnalogBalance */
	FORCC ab[c] = getreal(type);
	break;
      case 50728:			/* AsShotNeutral */
	FORCC asn[c] = getreal(type);
	break;
      case 50729:			/* AsShotWhiteXY */
	xyz[0] = getreal(type);
	xyz[1] = getreal(type);
	xyz[2] = 1 - xyz[0] - xyz[1];
	FORC3 xyz[c] /= d65_white[c];
	break;
      case 50740:			/* DNGPrivateData */
	if (dng_version) break;
	parse_minolta (j = get4()+base);
	fseek (ifp, j, SEEK_SET);
	parse_tiff_ifd (base);
	break;
      case 50752:
	read_shorts (cr2_slice, 3);
	break;
      case 50829:			/* ActiveArea */
	top_margin = getint(type);
	left_margin = getint(type);
	height = getint(type) - top_margin;
	width = getint(type) - left_margin;
	break;
      case 50830:			/* MaskedAreas */
        for (i=0; i < len && i < 32; i++)
	  mask[0][i] = getint(type);
	black = 0;
	break;
      case 51009:			/* OpcodeList2 */
	meta_offset = ftell(ifp);
	break;
      case 64772:			/* Kodak P-series */
	if (len < 13) break;
	fseek (ifp, 16, SEEK_CUR);
	data_offset = get4();
	fseek (ifp, 28, SEEK_CUR);
	data_offset += get4();
	load_raw = &CLASS packed_load_raw;
	break;
      case 65026:
	if (type == 2) fgets (model2, 64, ifp);
    }
    fseek (ifp, save, SEEK_SET);
  }
  if (sony_length && (buf = (unsigned *) malloc(sony_length))) {
    fseek (ifp, sony_offset, SEEK_SET);
    fread (buf, sony_length, 1, ifp);
    sony_decrypt (buf, sony_length/4, 1, sony_key);
#ifndef LIBRAW_LIBRARY_BUILD
    sfp = ifp;
    if ((ifp = tmpfile())) {
      fwrite (buf, sony_length, 1, ifp);
      fseek (ifp, 0, SEEK_SET);
      parse_tiff_ifd (-sony_offset);
      fclose (ifp);
    }
    ifp = sfp;
#else
    if( !ifp->tempbuffer_open(buf,sony_length))
        {
            parse_tiff_ifd(-sony_offset);
            ifp->tempbuffer_close();
        }
#endif
    free (buf);
  }
  for (i=0; i < colors; i++)
    FORCC cc[i][c] *= ab[i];
  if (use_cm) {
    FORCC for (i=0; i < 3; i++)
      for (cam_xyz[c][i]=j=0; j < colors; j++)
	cam_xyz[c][i] += cc[c][j] * cm[j][i] * xyz[i];
    cam_xyz_coeff (cmatrix, cam_xyz);
  }
  if (asn[0]) {
    cam_mul[3] = 0;
    FORCC cam_mul[c] = 1 / asn[c];
  }
  if (!use_cm)
    FORCC pre_mul[c] /= cc[c][c];
  return 0;
}

Project: LibRaw
File: libraw_cxx.cpp

void LibRaw::phase_one_subtract_black(ushort *src, ushort *dest)
{
  //	ushort *src = (ushort*)imgdata.rawdata.raw_alloc;
  if(O.user_black<0 && O.user_cblack[0] <= -1000000 && O.user_cblack[1] <= -1000000 && O.user_cblack[2] <= -1000000 && O.user_cblack[3] <= -1000000)
    {
      for(int row = 0; row < S.raw_height; row++)
        {
          ushort bl = imgdata.color.phase_one_data.t_black - imgdata.rawdata.ph1_black[row][0];
          for(int col=0; col < imgdata.color.phase_one_data.split_col && col < S.raw_width; col++)
            {
              int idx  = row*S.raw_width + col;
              ushort val = src[idx];
              dest[idx] = val>bl?val-bl:0;
            }
          bl = imgdata.color.phase_one_data.t_black - imgdata.rawdata.ph1_black[row][1];
          for(int col=imgdata.color.phase_one_data.split_col; col < S.raw_width; col++)
            {
              int idx  = row*S.raw_width + col;
              ushort val = src[idx];
              dest[idx] = val>bl?val-bl:0;
            }
        }
    }
  else // black set by user interaction
    {
      // Black level in cblack!
      for(int row = 0; row < S.raw_height; row++)
        {
          unsigned short cblk[16];
          for(int cc=0; cc<16;cc++)
            cblk[cc]=C.cblack[fcol(row,cc)];
          for(int col = 0; col < S.raw_width; col++)
            {
              int idx  = row*S.raw_width + col;
              ushort val = src[idx];
              ushort bl = cblk[col&0xf];
              dest[idx] = val>bl?val-bl:0;
            }
        }
    }
}

Project: LibRaw

void CLASS canon_rmf_load_raw()
{
  int row, col, bits, orow, ocol, c;

  for (row=0; row < raw_height; row++)
  {
#ifdef LIBRAW_LIBRARY_BUILD
    checkCancel();
#endif
    for (col=0; col < raw_width-2; col+=3) {
      bits = get4();
      FORC3 {
	orow = row;
	if ((ocol = col+c-4) < 0) {
	  ocol += raw_width;
	  if ((orow -= 2) < 0)
	    orow += raw_height;
	}
	RAW(orow,ocol) = curve[bits >> (10*c+2) & 0x3ff];
      }
    }
  }  
  maximum = curve[0x3ff];
}

Project: LibRaw

void CLASS parse_mos (int offset)
{
  char data[40];
  int skip, from, i, c, neut[4], planes=0, frot=0;
  static const char *mod[] =
  { "","DCB2","Volare","Cantare","CMost","Valeo 6","Valeo 11","Valeo 22",
    "Valeo 11p","Valeo 17","","Aptus 17","Aptus 22","Aptus 75","Aptus 65",
    "Aptus 54S","Aptus 65S","Aptus 75S","AFi 5","AFi 6","AFi 7",
    "Aptus-II 7","","","Aptus-II 6","","","Aptus-II 10","Aptus-II 5",
    "","","","","Aptus-II 10R","Aptus-II 8","","Aptus-II 12","","AFi-II 12" };
  float romm_cam[3][3];

  fseek (ifp, offset, SEEK_SET);
  while (1) {
    if (get4() != 0x504b5453) break;
    get4();
    fread (data, 1, 40, ifp);
    skip = get4();
    from = ftell(ifp);
    if (!strcmp(data,"JPEG_preview_data")) {
      thumb_offset = from;
      thumb_length = skip;
    }
    if (!strcmp(data,"icc_camera_profile")) {
      profile_offset = from;
      profile_length = skip;
    }
    if (!strcmp(data,"ShootObj_back_type")) {
      fscanf (ifp, "%d", &i);
      if ((unsigned) i < sizeof mod / sizeof (*mod))
	strcpy (model, mod[i]);
    }
    if (!strcmp(data,"icc_camera_to_tone_matrix")) {
      for (i=0; i < 9; i++)
	romm_cam[0][i] = int_to_float(get4());
      romm_coeff (romm_cam);
    }
    if (!strcmp(data,"CaptProf_color_matrix")) {
      for (i=0; i < 9; i++)
	fscanf (ifp, "%f", &romm_cam[0][i]);
      romm_coeff (romm_cam);
    }
    if (!strcmp(data,"CaptProf_number_of_planes"))
      fscanf (ifp, "%d", &planes);
    if (!strcmp(data,"CaptProf_raw_data_rotation"))
      fscanf (ifp, "%d", &flip);
    if (!strcmp(data,"CaptProf_mosaic_pattern"))
      FORC4 {
	fscanf (ifp, "%d", &i);
	if (i == 1) frot = c ^ (c >> 1);
      }
    if (!strcmp(data,"ImgProf_rotation_angle")) {
      fscanf (ifp, "%d", &i);
      flip = i - flip;
    }
    if (!strcmp(data,"NeutObj_neutrals") && !cam_mul[0]) {
      FORC4 fscanf (ifp, "%d", neut+c);
      FORC3 cam_mul[c] = (float) neut[0] / neut[c+1];
    }
    if (!strcmp(data,"Rows_data"))
      load_flags = get4();
    parse_mos (from);
    fseek (ifp, skip+from, SEEK_SET);
  }
  if (planes)
    filters = (planes == 1) * 0x01010101 *
	(uchar) "\x94\x61\x16\x49"[(flip/90 + frot) & 3];
}

Project: LibRaw

int LibRaw::raw2image_ex(int do_subtract_black)
{

  CHECK_ORDER_LOW(LIBRAW_PROGRESS_LOAD_RAW);

  try {
    raw2image_start();

    // Compressed P1 files with bl data!
    if (is_phaseone_compressed())
      {
        phase_one_allocate_tempbuffer();
        phase_one_subtract_black((ushort*)imgdata.rawdata.raw_alloc,imgdata.rawdata.raw_image);
        phase_one_correct();
      }

    // process cropping
    int do_crop = 0;
    unsigned save_width = S.width;
    if (~O.cropbox[2] && ~O.cropbox[3] 
#ifdef LIBRAW_DEMOSAIC_PACK_GPL2
        && load_raw != &LibRaw::foveon_sd_load_raw
#endif
        ) // Foveon SD to be cropped later
      {
        int crop[4],c,filt;
        for(int c=0;c<4;c++) 
          {
            crop[c] = O.cropbox[c];
            if(crop[c]<0)
              crop[c]=0;
          }
        
        if(IO.fuji_width && imgdata.idata.filters >= 1000) 
          {
            crop[0] = (crop[0]/4)*4;
            crop[1] = (crop[1]/4)*4;
            if(!libraw_internal_data.unpacker_data.fuji_layout)
              {
                crop[2]*=sqrt(2.0);
                crop[3]/=sqrt(2.0);
              }
            crop[2] = (crop[2]/4+1)*4;
            crop[3] = (crop[3]/4+1)*4;
          }
        else if (imgdata.idata.filters == 1)
          {
            crop[0] = (crop[0]/16)*16;
            crop[1] = (crop[1]/16)*16;
          }
        else if(imgdata.idata.filters == LIBRAW_XTRANS)
          {
            crop[0] = (crop[0]/6)*6;
            crop[1] = (crop[1]/6)*6;
          }
        do_crop = 1;
        
        crop[2] = MIN (crop[2], (signed) S.width-crop[0]);
        crop[3] = MIN (crop[3], (signed) S.height-crop[1]);
        if (crop[2] <= 0 || crop[3] <= 0)
          throw LIBRAW_EXCEPTION_BAD_CROP;
        
        // adjust sizes!
        S.left_margin+=crop[0];
        S.top_margin+=crop[1];
        S.width=crop[2];
        S.height=crop[3];
        
        S.iheight = (S.height + IO.shrink) >> IO.shrink;
        S.iwidth  = (S.width  + IO.shrink) >> IO.shrink;
        if(!IO.fuji_width && imgdata.idata.filters && imgdata.idata.filters >= 1000)
          {
            for (filt=c=0; c < 16; c++)
              filt |= FC((c >> 1)+(crop[1]),
                         (c &  1)+(crop[0])) << c*2;
            imgdata.idata.filters = filt;
          }
      }

    int alloc_width = S.iwidth;
    int alloc_height = S.iheight;
    
    if(IO.fuji_width && do_crop)
      {
        int IO_fw = S.width >> !libraw_internal_data.unpacker_data.fuji_layout;
        int t_alloc_width = (S.height >> libraw_internal_data.unpacker_data.fuji_layout) + IO_fw;
        int t_alloc_height = t_alloc_width - 1;
        alloc_height = (t_alloc_height + IO.shrink) >> IO.shrink;
        alloc_width = (t_alloc_width + IO.shrink) >> IO.shrink;
      }
    int alloc_sz = alloc_width*alloc_height;

    if(imgdata.image)
      {
        imgdata.image = (ushort (*)[4]) realloc (imgdata.image,alloc_sz *sizeof (*imgdata.image));
        memset(imgdata.image,0,alloc_sz *sizeof (*imgdata.image));
      }
    else
      imgdata.image = (ushort (*)[4]) calloc (alloc_sz, sizeof (*imgdata.image));
    merror (imgdata.image, "raw2image_ex()");

    libraw_decoder_info_t decoder_info;
    get_decoder_info(&decoder_info);

    // Adjust black levels
    unsigned short cblack[4]={0,0,0,0};
    unsigned short dmax = 0;
    if(do_subtract_black)
      {
        adjust_bl();
        for(int i=0; i< 4; i++)
          cblack[i] = (unsigned short)C.cblack[i];
      }
        
    // Move saved bitmap to imgdata.image
    if(decoder_info.decoder_flags & LIBRAW_DECODER_FLATFIELD)
      {
        if (IO.fuji_width) 
          {
            if(do_crop)
              {
                IO.fuji_width = S.width >> !libraw_internal_data.unpacker_data.fuji_layout;
                int IO_fwidth = (S.height >> libraw_internal_data.unpacker_data.fuji_layout) + IO.fuji_width;
                int IO_fheight = IO_fwidth - 1;
                
                int row,col;
                for(row=0;row<S.height;row++)
                  {
                    for(col=0;col<S.width;col++)
                      {
                        int r,c;
                        if (libraw_internal_data.unpacker_data.fuji_layout) {
                          r = IO.fuji_width - 1 - col + (row >> 1);
                          c = col + ((row+1) >> 1);
                        } else {
                          r = IO.fuji_width - 1 + row - (col >> 1);
                          c = row + ((col+1) >> 1);
                        }
                        
                        unsigned short val = imgdata.rawdata.raw_image[(row+S.top_margin)*S.raw_pitch/2
                                                            +(col+S.left_margin)];
                        int cc = FCF(row,col);
                        if(val > cblack[cc])
                          {
                            val-=cblack[cc];
                            if(dmax < val) dmax = val;
                          }
                        else
                          val = 0;
                        imgdata.image[((r) >> IO.shrink)*alloc_width + ((c) >> IO.shrink)][cc] = val;
                      }
                  }
                S.height = IO_fheight;
                S.width = IO_fwidth;
                S.iheight = (S.height + IO.shrink) >> IO.shrink;
                S.iwidth  = (S.width  + IO.shrink) >> IO.shrink;
                S.raw_height -= 2*S.top_margin;
              }
            else
              {
                copy_fuji_uncropped(cblack,&dmax);
              }
          } // end Fuji
        else 
          {
            copy_bayer(cblack,&dmax);
          }
      }
    else if(decoder_info.decoder_flags & LIBRAW_DECODER_LEGACY)
      {
        if(imgdata.rawdata.color4_image)
          {
            if(S.raw_pitch != S.width*8)
              {
                for(int row = 0; row < S.height; row++)
                  memmove(&imgdata.image[row*S.width],
                          &imgdata.rawdata.color4_image[(row+S.top_margin)*S.raw_pitch/8+S.left_margin],
                          S.width*sizeof(*imgdata.image));
              }
            else
              {
                // legacy is always 4channel and not shrinked!
                memmove(imgdata.image,imgdata.rawdata.color4_image,S.width*S.height*sizeof(*imgdata.image));
              }
          }
        else if(imgdata.rawdata.color3_image)
          {
            unsigned char *c3image = (unsigned char*) imgdata.rawdata.color3_image;
            for(int row = 0; row < S.height; row++)
              {
                ushort (*srcrow)[3] = (ushort (*)[3]) &c3image[(row+S.top_margin)*S.raw_pitch];
                ushort (*dstrow)[4] = (ushort (*)[4]) &imgdata.image[row*S.width];
                for(int col=0; col < S.width; col++)
                  {
                    for(int c=0; c< 3; c++)
                      dstrow[col][c] = srcrow[S.left_margin+col][c];
                    dstrow[col][3]=0;
                  }
              }
          }
        else
          {
            // legacy decoder, but no data?
            throw LIBRAW_EXCEPTION_DECODE_RAW;
          }
      }

    // Free PhaseOne separate copy allocated at function start
    if (is_phaseone_compressed())
      {
		  phase_one_free_tempbuffer();
      }
    if (load_raw == &CLASS canon_600_load_raw && S.width < S.raw_width) 
      {
        canon_600_correct();
      }

    if(do_subtract_black)
      {
        C.data_maximum = (int)dmax;
        C.maximum -= C.black;
        ZERO(C.cblack);
        C.black = 0;
      }

    // hack - clear later flags!
    imgdata.progress_flags 
      = LIBRAW_PROGRESS_START|LIBRAW_PROGRESS_OPEN | LIBRAW_PROGRESS_RAW2_IMAGE
      |LIBRAW_PROGRESS_IDENTIFY|LIBRAW_PROGRESS_SIZE_ADJUST|LIBRAW_PROGRESS_LOAD_RAW;
    return 0;
  }
  catch ( LibRaw_exceptions err) {
    EXCEPTION_HANDLER(err);
  }
}

Project: LibRaw

int LibRaw::dcraw_process(void)
{
  int quality,i;

  int iterations=-1, dcb_enhance=1, noiserd=0;
  int eeci_refine_fl=0, es_med_passes_fl=0;
  float cared=0,cablue=0;
  float linenoise=0; 
  float lclean=0,cclean=0;
  float thresh=0;
  float preser=0;
  float expos=1.0;


  CHECK_ORDER_LOW(LIBRAW_PROGRESS_LOAD_RAW);
  //    CHECK_ORDER_HIGH(LIBRAW_PROGRESS_PRE_INTERPOLATE);

  try {

    int no_crop = 1;

    if (~O.cropbox[2] && ~O.cropbox[3])
      no_crop=0;

    libraw_decoder_info_t di;
    get_decoder_info(&di);

    int subtract_inline = !O.bad_pixels && !O.dark_frame && !O.wf_debanding && !(di.decoder_flags & LIBRAW_DECODER_LEGACY) && !IO.zero_is_bad;

    raw2image_ex(subtract_inline); // allocate imgdata.image and copy data!

    // Adjust sizes
    if(0 && load_raw == &LibRaw::x3f_load_raw)
    {
        for(int i=0; i< foveon_count;i++)
            if(!strcasecmp(imgdata.idata.make,foveon_data[i].make) && !strcasecmp(imgdata.idata.model,foveon_data[i].model))
            {
                imgdata.color.maximum = foveon_data[i].white;
                break;
            }
    }

    int save_4color = O.four_color_rgb;

    if (IO.zero_is_bad) 
      {
        remove_zeroes();
        SET_PROC_FLAG(LIBRAW_PROGRESS_REMOVE_ZEROES);
      }

    if(O.bad_pixels && no_crop) 
      {
        bad_pixels(O.bad_pixels);
        SET_PROC_FLAG(LIBRAW_PROGRESS_BAD_PIXELS);
      }

    if (O.dark_frame && no_crop)
      {
        subtract (O.dark_frame);
        SET_PROC_FLAG(LIBRAW_PROGRESS_DARK_FRAME);
      }

    if (O.wf_debanding)
      {
        wf_remove_banding();
      }

    quality = 2 + !IO.fuji_width;

    if (O.user_qual >= 0) quality = O.user_qual;

    if(!subtract_inline || !C.data_maximum)
      {
        adjust_bl();
        subtract_black_internal();
      }

    adjust_maximum();

    if (O.user_sat > 0) C.maximum = O.user_sat;

    if (P1.is_foveon) 
      {
        if(load_raw == &LibRaw::x3f_load_raw)
          {
            // Filter out zeroes
            for (int i=0; i < S.height*S.width*4; i++)
              if ((short) imgdata.image[0][i] < 0) imgdata.image[0][i] = 0;
          }
#ifdef LIBRAW_DEMOSAIC_PACK_GPL2
        else if(load_raw == &LibRaw::foveon_dp_load_raw)
          {
            for (int i=0; i < S.height*S.width*4; i++)
              if ((short) imgdata.image[0][i] < 0) imgdata.image[0][i] = 0;
          }
        else
          {
            foveon_interpolate();
          }
#endif
        SET_PROC_FLAG(LIBRAW_PROGRESS_FOVEON_INTERPOLATE);
      }

    if (O.green_matching && !O.half_size)
      {
        green_matching();
      }

    if (
#ifdef LIBRAW_DEMOSAIC_PACK_GPL2
        (!P1.is_foveon || O.force_foveon_x3f) &&
#endif
        !O.no_auto_scale)
      {
        scale_colors();
        SET_PROC_FLAG(LIBRAW_PROGRESS_SCALE_COLORS);
      }

    pre_interpolate();

    SET_PROC_FLAG(LIBRAW_PROGRESS_PRE_INTERPOLATE);

    if (O.dcb_iterations >= 0) iterations = O.dcb_iterations;
    if (O.dcb_enhance_fl >=0 ) dcb_enhance = O.dcb_enhance_fl;
    if (O.fbdd_noiserd >=0 ) noiserd = O.fbdd_noiserd;
    if (O.eeci_refine >=0 ) eeci_refine_fl = O.eeci_refine;
    if (O.es_med_passes >0 ) es_med_passes_fl = O.es_med_passes;

    // LIBRAW_DEMOSAIC_PACK_GPL3

    if (!O.half_size && O.cfa_green >0) {thresh=O.green_thresh ;green_equilibrate(thresh);} 
    if (O.exp_correc >0) {expos=O.exp_shift ; preser=O.exp_preser; exp_bef(expos,preser);} 
    if (O.ca_correc >0 ) {cablue=O.cablue; cared=O.cared; CA_correct_RT(cablue, cared);}
    if (O.cfaline >0 ) {linenoise=O.linenoise; cfa_linedn(linenoise);}
    if (O.cfa_clean >0 ) {lclean=O.lclean; cclean=O.cclean; cfa_impulse_gauss(lclean,cclean);}

    if (P1.filters  && !O.no_interpolation) 
      {
        if (noiserd>0 && P1.colors==3 && P1.filters) fbdd(noiserd);
        if (quality == 0)
          lin_interpolate();
        else if (quality == 1 || P1.colors > 3)
          vng_interpolate();
        else if (quality == 2 && P1.filters > 1000)
          ppg_interpolate();
        else if (P1.filters == LIBRAW_XTRANS)
          {
            // Fuji X-Trans
            xtrans_interpolate(quality>2?3:1);
          }
        else if (quality == 3) 
          ahd_interpolate(); // really don't need it here due to fallback op
        else if (quality == 4)
          dcb(iterations, dcb_enhance);
        //  LIBRAW_DEMOSAIC_PACK_GPL2                
        else if (quality == 5)
          ahd_interpolate_mod();
        else if (quality == 6)
          afd_interpolate_pl(2,1);
        else if (quality == 7)
          vcd_interpolate(0);
        else if (quality == 8)
          vcd_interpolate(12);
        else if (quality == 9)
          lmmse_interpolate(1);
                
        // LIBRAW_DEMOSAIC_PACK_GPL3
        else if (quality == 10)
          amaze_demosaic_RT();
        // LGPL2
        else if (quality == 11)
          dht_interpolate();
        else if (quality == 12)
          aahd_interpolate();
        // fallback to AHD
        else
          ahd_interpolate();

        SET_PROC_FLAG(LIBRAW_PROGRESS_INTERPOLATE);
      }
    if (IO.mix_green)
      {
        for (P1.colors=3, i=0; i < S.height * S.width; i++)
          imgdata.image[i][1] = (imgdata.image[i][1] + imgdata.image[i][3]) >> 1;
        SET_PROC_FLAG(LIBRAW_PROGRESS_MIX_GREEN);
      }

    if(!P1.is_foveon)
      {
        if (P1.colors == 3) 
          {
                        
            if (quality == 8) 
              {
                if (eeci_refine_fl == 1) refinement();
                if (O.med_passes > 0)    median_filter_new();
                if (es_med_passes_fl > 0) es_median_filter();
              } 
            else {
              median_filter();
            }
            SET_PROC_FLAG(LIBRAW_PROGRESS_MEDIAN_FILTER);
          }
      }
        
    if (O.highlight == 2) 
      {
        blend_highlights();
        SET_PROC_FLAG(LIBRAW_PROGRESS_HIGHLIGHTS);
      }
        
    if (O.highlight > 2) 
      {
        recover_highlights();
        SET_PROC_FLAG(LIBRAW_PROGRESS_HIGHLIGHTS);
      }
        
    if (O.use_fuji_rotate) 
      {
        fuji_rotate();
        SET_PROC_FLAG(LIBRAW_PROGRESS_FUJI_ROTATE);
      }
    
    if(!libraw_internal_data.output_data.histogram)
      {
        libraw_internal_data.output_data.histogram = (int (*)[LIBRAW_HISTOGRAM_SIZE]) malloc(sizeof(*libraw_internal_data.output_data.histogram)*4);
        merror(libraw_internal_data.output_data.histogram,"LibRaw::dcraw_process()");
      }
#ifndef NO_LCMS
    if(O.camera_profile)
      {
        apply_profile(O.camera_profile,O.output_profile);
        SET_PROC_FLAG(LIBRAW_PROGRESS_APPLY_PROFILE);
      }
#endif

    convert_to_rgb();
    SET_PROC_FLAG(LIBRAW_PROGRESS_CONVERT_RGB);

    if (O.use_fuji_rotate) 
      {
        stretch();
        SET_PROC_FLAG(LIBRAW_PROGRESS_STRETCH);
      }
    O.four_color_rgb = save_4color; // also, restore

    return 0;
  }
  catch ( LibRaw_exceptions err) {
    EXCEPTION_HANDLER(err);
  }
}

Project: LibRaw
File: libraw_cxx.cpp

void LibRaw::fix_after_rawspeed(int bl)
{
  if (load_raw == &LibRaw::lossy_dng_load_raw)
    C.maximum = 0xffff;
  else if (load_raw == &LibRaw::sony_load_raw)
    C.maximum = 0x3ff0;
  else if 
    (
     (load_raw == &LibRaw::sony_arw2_load_raw 
      || (load_raw == &LibRaw::packed_load_raw && !strcasecmp(imgdata.idata.make,"Sony"))
      )
     && bl >= (C.black+C.cblack[0])*2
     )
    {
      C.maximum *=4;
      C.black *=4;
      for(int c=0; c< 4; c++)
        C.cblack[c]*=4;
    }
}

Project: LibRaw
File: libraw_cxx.cpp

void LibRaw::kodak_thumb_loader()
{
  // some kodak cameras
  ushort s_height = S.height, s_width = S.width,s_iwidth = S.iwidth,s_iheight=S.iheight;
  int s_colors = P1.colors;
  unsigned s_filters = P1.filters;
  ushort (*s_image)[4] = imgdata.image;

    
  S.height = T.theight;
  S.width  = T.twidth;
  P1.filters = 0;

  if (thumb_load_raw == &CLASS kodak_ycbcr_load_raw) 
    {
      S.height += S.height & 1;
      S.width  += S.width  & 1;
    }
    
  imgdata.image = (ushort (*)[4]) calloc (S.iheight*S.iwidth, sizeof (*imgdata.image));
  merror (imgdata.image, "LibRaw::kodak_thumb_loader()");

  ID.input->seek(ID.toffset, SEEK_SET);
  // read kodak thumbnail into T.image[]
  (this->*thumb_load_raw)();

  // copy-n-paste from image pipe
#define MIN(a,b) ((a) < (b) ? (a) : (b))
#define MAX(a,b) ((a) > (b) ? (a) : (b))
#define LIM(x,min,max) MAX(min,MIN(x,max))
#define CLIP(x) LIM(x,0,65535)
#define SWAP(a,b) { a ^= b; a ^= (b ^= a); }

  // from scale_colors
  {
    double   dmax;
    float scale_mul[4];
    int c,val;
    for (dmax=DBL_MAX, c=0; c < 3; c++) 
      if (dmax > C.pre_mul[c])
        dmax = C.pre_mul[c];

    for( c=0; c< 3; c++)
      scale_mul[c] = (C.pre_mul[c] / dmax) * 65535.0 / C.maximum;
    scale_mul[3] = scale_mul[1];

    size_t size = S.height * S.width;
    for (unsigned i=0; i < size*4 ; i++) 
      {
        val = imgdata.image[0][i];
        if(!val) continue;
        val *= scale_mul[i & 3];
        imgdata.image[0][i] = CLIP(val);
      }
  }

  // from convert_to_rgb
  ushort *img;
  int row,col;
    
  int  (*t_hist)[LIBRAW_HISTOGRAM_SIZE] =  (int (*)[LIBRAW_HISTOGRAM_SIZE]) calloc(sizeof(*t_hist),4);
  merror (t_hist, "LibRaw::kodak_thumb_loader()");
    
  float out[3], 
    out_cam[3][4] = 
    {
      {2.81761312, -1.98369181, 0.166078627, 0}, 
      {-0.111855984, 1.73688626, -0.625030339, 0}, 
      {-0.0379119813, -0.891268849, 1.92918086, 0}
    };

  for (img=imgdata.image[0], row=0; row < S.height; row++)
    for (col=0; col < S.width; col++, img+=4)
      {
        out[0] = out[1] = out[2] = 0;
        int c;
        for(c=0;c<3;c++) 
          {
            out[0] += out_cam[0][c] * img[c];
            out[1] += out_cam[1][c] * img[c];
            out[2] += out_cam[2][c] * img[c];
          }
        for(c=0; c<3; c++)
          img[c] = CLIP((int) out[c]);
        for(c=0; c<P1.colors;c++)
          t_hist[c][img[c] >> 3]++;
                    
      }

  // from gamma_lut
  int  (*save_hist)[LIBRAW_HISTOGRAM_SIZE] = libraw_internal_data.output_data.histogram;
  libraw_internal_data.output_data.histogram = t_hist;

  // make curve output curve!
  ushort (*t_curve) = (ushort*) calloc(sizeof(C.curve),1);
  merror (t_curve, "LibRaw::kodak_thumb_loader()");
  memmove(t_curve,C.curve,sizeof(C.curve));
  memset(C.curve,0,sizeof(C.curve));
  {
    int perc, val, total, t_white=0x2000,c;

    perc = S.width * S.height * 0.01;		/* 99th percentile white level */
    if (IO.fuji_width) perc /= 2;
    if (!((O.highlight & ~2) || O.no_auto_bright))
      for (t_white=c=0; c < P1.colors; c++) {
        for (val=0x2000, total=0; --val > 32; )
          if ((total += libraw_internal_data.output_data.histogram[c][val]) > perc) break;
        if (t_white < val) t_white = val;
      }
    gamma_curve (O.gamm[0], O.gamm[1], 2, (t_white << 3)/O.bright);
  }
    
  libraw_internal_data.output_data.histogram = save_hist;
  free(t_hist);
    
  // from write_ppm_tiff - copy pixels into bitmap
    
  S.iheight = S.height;
  S.iwidth  = S.width;
  if (S.flip & 4) SWAP(S.height,S.width);

  if(T.thumb) free(T.thumb);
  T.thumb = (char*) calloc (S.width * S.height, P1.colors);
  merror (T.thumb, "LibRaw::kodak_thumb_loader()");
  T.tlength = S.width * S.height * P1.colors;

  // from write_tiff_ppm
  {
    int soff  = flip_index (0, 0);
    int cstep = flip_index (0, 1) - soff;
    int rstep = flip_index (1, 0) - flip_index (0, S.width);
        
    for (int row=0; row < S.height; row++, soff += rstep) 
      {
        char *ppm = T.thumb + row*S.width*P1.colors;
        for (int col=0; col < S.width; col++, soff += cstep)
          for(int c = 0; c < P1.colors; c++)
            ppm [col*P1.colors+c] = imgdata.color.curve[imgdata.image[soff][c]]>>8;
      }
  }

  memmove(C.curve,t_curve,sizeof(C.curve));
  free(t_curve);

  // restore variables
  free(imgdata.image);
  imgdata.image  = s_image;
    
  T.twidth = S.width;
  S.width = s_width;

  S.iwidth = s_iwidth;
  S.iheight = s_iheight;

  T.theight = S.height;
  S.height = s_height;

  T.tcolors = P1.colors;
  P1.colors = s_colors;

  P1.filters = s_filters;
}

Project: LibRaw
File: libraw_cxx.cpp

int LibRaw::adjust_sizes_info_only(void)
{
  CHECK_ORDER_LOW(LIBRAW_PROGRESS_IDENTIFY);

  raw2image_start();
  if (O.use_fuji_rotate)
    {
      if (IO.fuji_width) 
        {
          IO.fuji_width = (IO.fuji_width - 1 + IO.shrink) >> IO.shrink;
          S.iwidth = (ushort)(IO.fuji_width / sqrt(0.5));
          S.iheight = (ushort)( (S.iheight - IO.fuji_width) / sqrt(0.5));
        } 
      else 
        {
          if (S.pixel_aspect < 1) S.iheight = (ushort)( S.iheight / S.pixel_aspect + 0.5);
          if (S.pixel_aspect > 1) S.iwidth  = (ushort) (S.iwidth  * S.pixel_aspect + 0.5);
        }
    }
  SET_PROC_FLAG(LIBRAW_PROGRESS_FUJI_ROTATE);
  if ( S.flip & 4)
    {
      unsigned short t = S.iheight;
      S.iheight=S.iwidth;
      S.iwidth = t;
      SET_PROC_FLAG(LIBRAW_PROGRESS_FLIP);
    }
  return 0;
}

Project: LibRaw

void CLASS colorcheck()
{
#define NSQ 24
// Coordinates of the GretagMacbeth ColorChecker squares
// width, height, 1st_column, 1st_row
  int cut[NSQ][4];			// you must set these
// ColorChecker Chart under 6500-kelvin illumination
  static const double gmb_xyY[NSQ][3] = {
    { 0.400, 0.350, 10.1 },		// Dark Skin
    { 0.377, 0.345, 35.8 },		// Light Skin
    { 0.247, 0.251, 19.3 },		// Blue Sky
    { 0.337, 0.422, 13.3 },		// Foliage
    { 0.265, 0.240, 24.3 },		// Blue Flower
    { 0.261, 0.343, 43.1 },		// Bluish Green
    { 0.506, 0.407, 30.1 },		// Orange
    { 0.211, 0.175, 12.0 },		// Purplish Blue
    { 0.453, 0.306, 19.8 },		// Moderate Red
    { 0.285, 0.202, 6.6 },		// Purple
    { 0.380, 0.489, 44.3 },		// Yellow Green
    { 0.473, 0.438, 43.1 },		// Orange Yellow
    { 0.187, 0.129, 6.1 },		// Blue
    { 0.305, 0.478, 23.4 },		// Green
    { 0.539, 0.313, 12.0 },		// Red
    { 0.448, 0.470, 59.1 },		// Yellow
    { 0.364, 0.233, 19.8 },		// Magenta
    { 0.196, 0.252, 19.8 },		// Cyan
    { 0.310, 0.316, 90.0 },		// White
    { 0.310, 0.316, 59.1 },		// Neutral 8
    { 0.310, 0.316, 36.2 },		// Neutral 6.5
    { 0.310, 0.316, 19.8 },		// Neutral 5
    { 0.310, 0.316, 9.0 },		// Neutral 3.5
    { 0.310, 0.316, 3.1 } };		// Black
  double gmb_cam[NSQ][4], gmb_xyz[NSQ][3];
  double inverse[NSQ][3], cam_xyz[4][3], num;
  int c, i, j, k, sq, row, col, count[4];

  memset (gmb_cam, 0, sizeof gmb_cam);
  for (sq=0; sq < NSQ; sq++) {
    FORCC count[c] = 0;
    for   (row=cut[sq][3]; row < cut[sq][3]+cut[sq][1]; row++)
      for (col=cut[sq][2]; col < cut[sq][2]+cut[sq][0]; col++) {
	c = FC(row,col);
	if (c >= colors) c -= 2;
	gmb_cam[sq][c] += BAYER(row,col);
	count[c]++;
      }
    FORCC gmb_cam[sq][c] = gmb_cam[sq][c]/count[c] - black;
    gmb_xyz[sq][0] = gmb_xyY[sq][2] * gmb_xyY[sq][0] / gmb_xyY[sq][1];
    gmb_xyz[sq][1] = gmb_xyY[sq][2];
    gmb_xyz[sq][2] = gmb_xyY[sq][2] *
		(1 - gmb_xyY[sq][0] - gmb_xyY[sq][1]) / gmb_xyY[sq][1];
  }
  pseudoinverse (gmb_xyz, inverse, NSQ);
  for (raw_color = i=0; i < colors; i++)
    for (j=0; j < 3; j++)
      for (cam_xyz[i][j] = k=0; k < NSQ; k++)
	cam_xyz[i][j] += gmb_cam[k][i] * inverse[k][j];
  cam_xyz_coeff (rgb_cam, cam_xyz);
  if (verbose) {
    printf ("    { \"%s %s\", %d,\n\t{", make, model, black);
    num = 10000 / (cam_xyz[1][0] + cam_xyz[1][1] + cam_xyz[1][2]);
    FORCC for (j=0; j < 3; j++)
      printf ("%c%d", (c | j) ? ',':' ', (int) (cam_xyz[c][j] * num + 0.5));
    puts (" } },");
  }
#undef NSQ
}

Project: LibRaw

void LibRaw::scale_colors_loop(float scale_mul[4])
{
  unsigned size = S.iheight*S.iwidth;
  

  if (C.cblack[4] && C.cblack[5])
    {
      int val;
      for (unsigned i=0; i < size*4; i++) 
        {
          if (!(val = imgdata.image[0][i])) continue;
          val -= C.cblack[6 + i/4 / S.iwidth % C.cblack[4] * C.cblack[4] +
			i/4 % S.iwidth % C.cblack[5]];
          val -= C.cblack[i & 3];
          val *= scale_mul[i & 3];
          imgdata.image[0][i] = CLIP(val);
        }
    }
  else if(C.cblack[0]||C.cblack[1]||C.cblack[2]||C.cblack[3])
    {
      for (unsigned i=0; i < size*4; i++) 
        {
          int val = imgdata.image[0][i];
          if (!val) continue;
          val -= C.cblack[i & 3];
          val *= scale_mul[i & 3];
          imgdata.image[0][i] = CLIP(val);
        }
    }
  else // BL is zero
    {
      for (unsigned i=0; i < size*4; i++) 
        {
          int val = imgdata.image[0][i];
          val *= scale_mul[i & 3];
          imgdata.image[0][i] = CLIP(val);
        }
    }
}

Project: LibRaw

void LibRaw::parse_x3f()
{
  x3f_t *x3f = x3f_new_from_file(libraw_internal_data.internal_data.input);
  if(!x3f)
      return;
  _x3f_data = x3f;

  x3f_header_t *H = NULL;
  x3f_directory_section_t *DS = NULL;

  H = &x3f->header;
  // Parse RAW size from RAW section
  x3f_directory_entry_t *DE = x3f_get_raw(x3f);
  if(!DE) return;
  imgdata.sizes.flip = H->rotation;
  x3f_directory_entry_header_t *DEH = &DE->header;
  x3f_image_data_t *ID = &DEH->data_subsection.image_data;
  imgdata.sizes.raw_width = ID->columns;
  imgdata.sizes.raw_height = ID->rows;
  // Parse other params from property section
  DE = x3f_get_prop(x3f);
  if(! (x3f_load_data(x3f,DE) == X3F_OK))
    return;
  DEH = &DE->header;
  x3f_property_list_t *PL = &DEH->data_subsection.property_list;
  if (PL->property_table.size != 0) {
    int i;
    x3f_property_t *P = PL->property_table.element;
    for (i=0; i<PL->num_properties; i++) {
      char name[100], value[100];
      utf2char(P[i].name,name);
      utf2char(P[i].value,value);
      if (!strcmp (name, "ISO"))
	imgdata.other.iso_speed = atoi(value);
      if (!strcmp (name, "CAMMANUF"))
        strcpy (imgdata.idata.make, value);
      if (!strcmp (name, "CAMMODEL"))
        strcpy (imgdata.idata.model, value);
      if (!strcmp (name, "WB_DESC"))
        strcpy (imgdata.color.model2, value);
      if (!strcmp (name, "TIME"))
	    imgdata.other.timestamp = atoi(value);
      if (!strcmp (name, "EXPTIME"))
        imgdata.other.shutter = atoi(value) / 1000000.0;
      if (!strcmp (name, "APERTURE"))
        imgdata.other.aperture = atof(value);
      if (!strcmp (name, "FLENGTH"))
        imgdata.other.focal_len = atof(value);
    }
    imgdata.idata.raw_count=1;
    load_raw = &LibRaw::x3f_load_raw;
    imgdata.sizes.raw_pitch = imgdata.sizes.raw_width*6;
    imgdata.idata.is_foveon = 1;
    libraw_internal_data.internal_output_params.raw_color=1; // Force adobe coeff
    imgdata.color.maximum=0x3fff; // To be reset by color table
    libraw_internal_data.unpacker_data.order = 0x4949;
  }
  // Try to get thumbnail data
  LibRaw_thumbnail_formats format = LIBRAW_THUMBNAIL_UNKNOWN;
  if(DE = x3f_get_thumb_jpeg(x3f))
    {
      format = LIBRAW_THUMBNAIL_JPEG;
    }
  else if(DE = x3f_get_thumb_plain(x3f))
    {
      format = LIBRAW_THUMBNAIL_BITMAP;
    }
  if(DE)
    {
      x3f_directory_entry_header_t *DEH = &DE->header;
      x3f_image_data_t *ID = &DEH->data_subsection.image_data;
      imgdata.thumbnail.twidth = ID->columns;
      imgdata.thumbnail.theight = ID->rows;
      imgdata.thumbnail.tcolors = 3;
      imgdata.thumbnail.tformat = format;
      libraw_internal_data.internal_data.toffset = DE->input.offset;
      write_thumb = &LibRaw::x3f_thumb_loader;
    }
}

Project: LibRaw

void CLASS sony_arw2_load_raw()
{
  uchar *data, *dp;
  ushort pix[16];
  int row, col, val, max, min, imax, imin, sh, bit, i;

  data = (uchar *) malloc (raw_width+1);
  merror (data, "sony_arw2_load_raw()");
#ifdef LIBRAW_LIBRARY_BUILD
  try {
#endif
  for (row=0; row < height; row++) {
#ifdef LIBRAW_LIBRARY_BUILD
    checkCancel();
#endif
    fread (data, 1, raw_width, ifp);
    for (dp=data, col=0; col < raw_width-30; dp+=16) {
      max = 0x7ff & (val = sget4(dp));
      min = 0x7ff & val >> 11;
      imax = 0x0f & val >> 22;
      imin = 0x0f & val >> 26;
      for (sh=0; sh < 4 && 0x80 << sh <= max-min; sh++);
      for (bit=30, i=0; i < 16; i++)
	if      (i == imax) pix[i] = max;
	else if (i == imin) pix[i] = min;
	else {
	  pix[i] = ((sget2(dp+(bit >> 3)) >> (bit & 7) & 0x7f) << sh) + min;
	  if (pix[i] > 0x7ff) pix[i] = 0x7ff;
	  bit += 7;
	}
#ifdef LIBRAW_LIBRARY_BUILD
      if(imgdata.params.sony_arw2_hack)
          {
              for (i=0; i < 16; i++, col+=2)
                  RAW(row,col) = curve[pix[i] << 1];
          }
      else
          {
              for (i=0; i < 16; i++, col+=2)
                  RAW(row,col) = curve[pix[i] << 1] >> 2;
          }
#else
      for (i=0; i < 16; i++, col+=2)
	RAW(row,col) = curve[pix[i] << 1] >> 2;
#endif
      col -= col & 1 ? 1:31;
    }
  }
#ifdef LIBRAW_LIBRARY_BUILD
  } catch(...) {
    free (data);
    throw;
  }
#endif
  free (data);
#ifdef LIBRAW_LIBRARY_BUILD
  if(imgdata.params.sony_arw2_hack)
  {
	black <<= 2;
	maximum <<=2;
  }
#endif
}

Project: LibRaw
File: libraw_cxx.cpp

CameraMetaDataLR::CameraMetaDataLR(char *data, int sz) : CameraMetaData() {
  ctxt = xmlNewParserCtxt();
  if (ctxt == NULL) {
    ThrowCME("CameraMetaData:Could not initialize context.");
  }
  
  xmlResetLastError();
  doc = xmlCtxtReadMemory(ctxt, data,sz, "", NULL, XML_PARSE_DTDVALID);
  
  if (doc == NULL) {
    ThrowCME("CameraMetaData: XML Document could not be parsed successfully. Error was: %s", ctxt->lastError.message);
  }
  
  if (ctxt->valid == 0) {
    if (ctxt->lastError.code == 0x5e) {
      // printf("CameraMetaData: Unable to locate DTD, attempting to ignore.");
    } else {
      ThrowCME("CameraMetaData: XML file does not validate. DTD Error was: %s", ctxt->lastError.message);
    }
  }
  
  xmlNodePtr cur;
  cur = xmlDocGetRootElement(doc);
  if (xmlStrcmp(cur->name, (const xmlChar *) "Cameras")) {
    ThrowCME("CameraMetaData: XML document of the wrong type, root node is not cameras.");
    return;
  }
  
  cur = cur->xmlChildrenNode;
  while (cur != NULL) {
    if ((!xmlStrcmp(cur->name, (const xmlChar *)"Camera"))) {
      Camera *camera = new Camera(doc, cur);
      addCamera(camera);
      
      // Create cameras for aliases.
      for (uint32 i = 0; i < camera->aliases.size(); i++) {
        addCamera(new Camera(camera, i));
      }
    }
    cur = cur->next;
  }
  if (doc)
    xmlFreeDoc(doc);
  doc = 0;
  if (ctxt)
    xmlFreeParserCtxt(ctxt);
  ctxt = 0;
}

Project: LibRaw

void CLASS parse_makernote (int base, int uptag)
{
  static const uchar xlat[2][256] = {
  { 0xc1,0xbf,0x6d,0x0d,0x59,0xc5,0x13,0x9d,0x83,0x61,0x6b,0x4f,0xc7,0x7f,0x3d,0x3d,
    0x53,0x59,0xe3,0xc7,0xe9,0x2f,0x95,0xa7,0x95,0x1f,0xdf,0x7f,0x2b,0x29,0xc7,0x0d,
    0xdf,0x07,0xef,0x71,0x89,0x3d,0x13,0x3d,0x3b,0x13,0xfb,0x0d,0x89,0xc1,0x65,0x1f,
    0xb3,0x0d,0x6b,0x29,0xe3,0xfb,0xef,0xa3,0x6b,0x47,0x7f,0x95,0x35,0xa7,0x47,0x4f,
    0xc7,0xf1,0x59,0x95,0x35,0x11,0x29,0x61,0xf1,0x3d,0xb3,0x2b,0x0d,0x43,0x89,0xc1,
    0x9d,0x9d,0x89,0x65,0xf1,0xe9,0xdf,0xbf,0x3d,0x7f,0x53,0x97,0xe5,0xe9,0x95,0x17,
    0x1d,0x3d,0x8b,0xfb,0xc7,0xe3,0x67,0xa7,0x07,0xf1,0x71,0xa7,0x53,0xb5,0x29,0x89,
    0xe5,0x2b,0xa7,0x17,0x29,0xe9,0x4f,0xc5,0x65,0x6d,0x6b,0xef,0x0d,0x89,0x49,0x2f,
    0xb3,0x43,0x53,0x65,0x1d,0x49,0xa3,0x13,0x89,0x59,0xef,0x6b,0xef,0x65,0x1d,0x0b,
    0x59,0x13,0xe3,0x4f,0x9d,0xb3,0x29,0x43,0x2b,0x07,0x1d,0x95,0x59,0x59,0x47,0xfb,
    0xe5,0xe9,0x61,0x47,0x2f,0x35,0x7f,0x17,0x7f,0xef,0x7f,0x95,0x95,0x71,0xd3,0xa3,
    0x0b,0x71,0xa3,0xad,0x0b,0x3b,0xb5,0xfb,0xa3,0xbf,0x4f,0x83,0x1d,0xad,0xe9,0x2f,
    0x71,0x65,0xa3,0xe5,0x07,0x35,0x3d,0x0d,0xb5,0xe9,0xe5,0x47,0x3b,0x9d,0xef,0x35,
    0xa3,0xbf,0xb3,0xdf,0x53,0xd3,0x97,0x53,0x49,0x71,0x07,0x35,0x61,0x71,0x2f,0x43,
    0x2f,0x11,0xdf,0x17,0x97,0xfb,0x95,0x3b,0x7f,0x6b,0xd3,0x25,0xbf,0xad,0xc7,0xc5,
    0xc5,0xb5,0x8b,0xef,0x2f,0xd3,0x07,0x6b,0x25,0x49,0x95,0x25,0x49,0x6d,0x71,0xc7 },
  { 0xa7,0xbc,0xc9,0xad,0x91,0xdf,0x85,0xe5,0xd4,0x78,0xd5,0x17,0x46,0x7c,0x29,0x4c,
    0x4d,0x03,0xe9,0x25,0x68,0x11,0x86,0xb3,0xbd,0xf7,0x6f,0x61,0x22,0xa2,0x26,0x34,
    0x2a,0xbe,0x1e,0x46,0x14,0x68,0x9d,0x44,0x18,0xc2,0x40,0xf4,0x7e,0x5f,0x1b,0xad,
    0x0b,0x94,0xb6,0x67,0xb4,0x0b,0xe1,0xea,0x95,0x9c,0x66,0xdc,0xe7,0x5d,0x6c,0x05,
    0xda,0xd5,0xdf,0x7a,0xef,0xf6,0xdb,0x1f,0x82,0x4c,0xc0,0x68,0x47,0xa1,0xbd,0xee,
    0x39,0x50,0x56,0x4a,0xdd,0xdf,0xa5,0xf8,0xc6,0xda,0xca,0x90,0xca,0x01,0x42,0x9d,
    0x8b,0x0c,0x73,0x43,0x75,0x05,0x94,0xde,0x24,0xb3,0x80,0x34,0xe5,0x2c,0xdc,0x9b,
    0x3f,0xca,0x33,0x45,0xd0,0xdb,0x5f,0xf5,0x52,0xc3,0x21,0xda,0xe2,0x22,0x72,0x6b,
    0x3e,0xd0,0x5b,0xa8,0x87,0x8c,0x06,0x5d,0x0f,0xdd,0x09,0x19,0x93,0xd0,0xb9,0xfc,
    0x8b,0x0f,0x84,0x60,0x33,0x1c,0x9b,0x45,0xf1,0xf0,0xa3,0x94,0x3a,0x12,0x77,0x33,
    0x4d,0x44,0x78,0x28,0x3c,0x9e,0xfd,0x65,0x57,0x16,0x94,0x6b,0xfb,0x59,0xd0,0xc8,
    0x22,0x36,0xdb,0xd2,0x63,0x98,0x43,0xa1,0x04,0x87,0x86,0xf7,0xa6,0x26,0xbb,0xd6,
    0x59,0x4d,0xbf,0x6a,0x2e,0xaa,0x2b,0xef,0xe6,0x78,0xb6,0x4e,0xe0,0x2f,0xdc,0x7c,
    0xbe,0x57,0x19,0x32,0x7e,0x2a,0xd0,0xb8,0xba,0x29,0x00,0x3c,0x52,0x7d,0xa8,0x49,
    0x3b,0x2d,0xeb,0x25,0x49,0xfa,0xa3,0xaa,0x39,0xa7,0xc5,0xa7,0x50,0x11,0x36,0xfb,
    0xc6,0x67,0x4a,0xf5,0xa5,0x12,0x65,0x7e,0xb0,0xdf,0xaf,0x4e,0xb3,0x61,0x7f,0x2f } };
  unsigned offset=0, entries, tag, type, len, save, c;
  unsigned ver97=0, serial=0, i, wbi=0, wb[4]={0,0,0,0};
  uchar buf97[324], ci, cj, ck;
  short morder, sorder=order;
  char buf[10];
  unsigned SamsungKey[11];
  static const double rgb_adobe[3][3] =		// inv(sRGB2XYZ_D65) * AdobeRGB2XYZ_D65
    {{ 1.398283396477404,     -0.398283116703571, 4.427165001263944E-08},
     {-1.233904514232401E-07,  0.999999995196570, 3.126724276714121e-08},
     { 4.561487232726535E-08, -0.042938290466635, 1.042938250416105    }};
  
  float adobe_cam [3][3];

/*
   The MakerNote might have its own TIFF header (possibly with
   its own byte-order!), or it might just be a table.
 */
  if (!strcmp(make,"Nokia")) return;
  fread (buf, 1, 10, ifp);
  if (!strncmp (buf,"KDK" ,3) ||	/* these aren't TIFF tables */
      !strncmp (buf,"VER" ,3) ||
      !strncmp (buf,"IIII",4) ||
      !strncmp (buf,"MMMM",4)) return;
  if (!strncmp (buf,"KC"  ,2) ||	/* Konica KD-400Z, KD-510Z */
      !strncmp (buf,"MLY" ,3)) {	/* Minolta DiMAGE G series */
    order = 0x4d4d;
    while ((i=ftell(ifp)) < data_offset && i < 16384) {
      wb[0] = wb[2];  wb[2] = wb[1];  wb[1] = wb[3];
      wb[3] = get2();
      if (wb[1] == 256 && wb[3] == 256 &&
	  wb[0] > 256 && wb[0] < 640 && wb[2] > 256 && wb[2] < 640)
	FORC4 cam_mul[c] = wb[c];
    }
    goto quit;
  }
  if (!strcmp (buf,"Nikon")) {
    base = ftell(ifp);
    order = get2();
    if (get2() != 42) goto quit;
    offset = get4();
    fseek (ifp, offset-8, SEEK_CUR);
  } else if (!strcmp (buf,"OLYMPUS") ||
             !strcmp (buf,"PENTAX ")) {
    base = ftell(ifp)-10;
    fseek (ifp, -2, SEEK_CUR);
    order = get2();
    if (buf[0] == 'O') get2();
  } else if (!strncmp (buf,"SONY",4) ||
	     !strcmp  (buf,"Panasonic")) {
    goto nf;
  } else if (!strncmp (buf,"FUJIFILM",8)) {
    base = ftell(ifp)-10;
nf: order = 0x4949;
    fseek (ifp,  2, SEEK_CUR);
  } else if (!strcmp (buf,"OLYMP") ||
	     !strcmp (buf,"LEICA") ||
	     !strcmp (buf,"Ricoh") ||
	     !strcmp (buf,"EPSON"))
    fseek (ifp, -2, SEEK_CUR);
  else if (!strcmp (buf,"AOC") ||
	   !strcmp (buf,"QVC"))
    fseek (ifp, -4, SEEK_CUR);
  else {
    fseek (ifp, -10, SEEK_CUR);
    if (!strncmp(make,"SAMSUNG",7))
      base = ftell(ifp);
  }
  entries = get2();
  if (entries > 1000) return;
  morder = order;
  while (entries--) {
    order = morder;
    tiff_get (base, &tag, &type, &len, &save);
    tag |= uptag << 16;
    if (tag == 2 && strstr(make,"NIKON") && !iso_speed)
      iso_speed = (get2(),get2());
    if (tag == 37 && strstr(make,"NIKON") && !iso_speed)
      {
        unsigned char cc;
        fread(&cc,1,1,ifp);
        iso_speed = int(100.0 * pow(2.0,double(cc)/12.0-5.0));
      }
    if (tag == 4 && len > 26 && len < 35) {
      if ((i=(get4(),get2())) != 0x7fff && !iso_speed)
	iso_speed = 50 * pow (2.0, i/32.0 - 4);
      if ((i=(get2(),get2())) != 0x7fff && !aperture)
	aperture = pow (2.0, i/64.0);
      if ((i=get2()) != 0xffff && !shutter)
	shutter = pow (2.0, (short) i/-32.0);
      wbi = (get2(),get2());
      shot_order = (get2(),get2());
    }
    if ((tag == 4 || tag == 0x114) && !strncmp(make,"KONICA",6)) {
      fseek (ifp, tag == 4 ? 140:160, SEEK_CUR);
      switch (get2()) {
	case 72:  flip = 0;  break;
	case 76:  flip = 6;  break;
	case 82:  flip = 5;  break;
      }
    }
    if (tag == 7 && type == 2 && len > 20)
      fgets (model2, 64, ifp);
    if (tag == 8 && type == 4)
      shot_order = get4();
    if (tag == 9 && !strcmp(make,"Canon"))
      fread (artist, 64, 1, ifp);
    if (tag == 0xc && len == 4)
      FORC3 cam_mul[(c << 1 | c >> 1) & 3] = getreal(type);
    if (tag == 0xd && type == 7 && get2() == 0xaaaa) {
      for (c=i=2; (ushort) c != 0xbbbb && i < len; i++)
	c = c << 8 | fgetc(ifp);
      while ((i+=4) < len-5)
	if (get4() == 257 && (i=len) && (c = (get4(),fgetc(ifp))) < 3)
	  flip = "065"[c]-'0';
    }
    if (tag == 0x10 && type == 4)
      unique_id = get4();
    if (tag == 0x11 && is_raw && !strncmp(make,"NIKON",5)) {
      fseek (ifp, get4()+base, SEEK_SET);
      parse_tiff_ifd (base);
    }
    if (tag == 0x14 && type == 7) {
      if (len == 2560) {
	fseek (ifp, 1248, SEEK_CUR);
	goto get2_256;
      }
      fread (buf, 1, 10, ifp);
      if (!strncmp(buf,"NRW ",4)) {
	fseek (ifp, strcmp(buf+4,"0100") ? 46:1546, SEEK_CUR);
	cam_mul[0] = get4() << 2;
	cam_mul[1] = get4() + get4();
	cam_mul[2] = get4() << 2;
      }
    }
    if (tag == 0x15 && type == 2 && is_raw)
      fread (model, 64, 1, ifp);
    if (strstr(make,"PENTAX")) {
      if (tag == 0x1b) tag = 0x1018;
      if (tag == 0x1c) tag = 0x1017;
    }
    if (tag == 0x1d)
      while ((c = fgetc(ifp)) && c != EOF)
	serial = serial*10 + (isdigit(c) ? c - '0' : c % 10);
    if (tag == 0x81 && type == 4) {
      data_offset = get4();
      fseek (ifp, data_offset + 41, SEEK_SET);
      raw_height = get2() * 2;
      raw_width  = get2();
      filters = 0x61616161;
    }
    if (tag == 0x29 && type == 1) {
      c = wbi < 18 ? "012347800000005896"[wbi]-'0' : 0;
      fseek (ifp, 8 + c*32, SEEK_CUR);
      FORC4 cam_mul[c ^ (c >> 1) ^ 1] = get4();
    }
    if ((tag == 0x81  && type == 7) ||
	(tag == 0x100 && type == 7) ||
	(tag == 0x280 && type == 1)) {
      thumb_offset = ftell(ifp);
      thumb_length = len;
    }
    if (tag == 0x88 && type == 4 && (thumb_offset = get4()))
      thumb_offset += base;
    if (tag == 0x89 && type == 4)
      thumb_length = get4();
    if (tag == 0x8c || tag == 0x96)
      meta_offset = ftell(ifp);
    if (tag == 0x97) {
      for (i=0; i < 4; i++)
	ver97 = ver97 * 10 + fgetc(ifp)-'0';
      switch (ver97) {
	case 100:
	  fseek (ifp, 68, SEEK_CUR);
	  FORC4 cam_mul[(c >> 1) | ((c & 1) << 1)] = get2();
	  break;
	case 102:
	  fseek (ifp, 6, SEEK_CUR);
	  goto get2_rggb;
	case 103:
	  fseek (ifp, 16, SEEK_CUR);
	  FORC4 cam_mul[c] = get2();
      }
      if (ver97 >= 200) {
	if (ver97 != 205) fseek (ifp, 280, SEEK_CUR);
	fread (buf97, 324, 1, ifp);
      }
    }
    if (tag == 0xa1 && type == 7) {
      order = 0x4949;
      fseek (ifp, 140, SEEK_CUR);
      FORC3 cam_mul[c] = get4();
    }
    if (tag == 0xa4 && type == 3) {
      fseek (ifp, wbi*48, SEEK_CUR);
      FORC3 cam_mul[c] = get2();
    }
    if (tag == 0xa7 && (unsigned) (ver97-200) < 17) {
      ci = xlat[0][serial & 0xff];
      cj = xlat[1][fgetc(ifp)^fgetc(ifp)^fgetc(ifp)^fgetc(ifp)];
      ck = 0x60;
      for (i=0; i < 324; i++)
	buf97[i] ^= (cj += ci * ck++);
      i = "66666>666;6A;:;55"[ver97-200] - '0';
      FORC4 cam_mul[c ^ (c >> 1) ^ (i & 1)] =
	sget2 (buf97 + (i & -2) + c*2);
    }
    if(tag == 0xb001 && type == 3)
      {
        unique_id = get2();
      }
    if (tag == 0x200 && len == 3)
      shot_order = (get4(),get4());
    if (tag == 0x200 && len == 4)
      FORC4 cblack[c ^ c >> 1] = get2();
    if (tag == 0x201 && len == 4)
      goto get2_rggb;
    if (tag == 0x220 && type == 7)
      meta_offset = ftell(ifp);
    if (tag == 0x401 && type == 4 && len == 4)
      FORC4 cblack[c ^ c >> 1] = get4();
    if (tag == 0x03d && strstr(make,"NIKON") && len == 4)
      FORC4 cblack[c ^ c >> 1] = get2();
    if (tag == 0xe01) {		/* Nikon Capture Note */
      order = 0x4949;
      fseek (ifp, 22, SEEK_CUR);
      for (offset=22; offset+22 < len; offset += 22+i) {
	tag = get4();
	fseek (ifp, 14, SEEK_CUR);
	i = get4()-4;
	if (tag == 0x76a43207) flip = get2();
	else fseek (ifp, i, SEEK_CUR);
      }
    }
    if (tag == 0xe80 && len == 256 && type == 7) {
      fseek (ifp, 48, SEEK_CUR);
      cam_mul[0] = get2() * 508 * 1.078 / 0x10000;
      cam_mul[2] = get2() * 382 * 1.173 / 0x10000;
    }
    if (tag == 0xf00 && type == 7) {
      if (len == 614)
	fseek (ifp, 176, SEEK_CUR);
      else if (len == 734 || len == 1502)
	fseek (ifp, 148, SEEK_CUR);
      else goto next;
      goto get2_256;
    }
    if ((tag == 0x1011 && len == 9) || tag == 0x20400200)
      {
        if(!strcasecmp(make,"Olympus"))
          {
            int j,k;
            for (i=0; i < 3; i++)
              FORC3 adobe_cam[i][c] = ((short) get2()) / 256.0;
            for (i=0; i < 3; i++)
              for (j=0; j < 3; j++)
                for (cmatrix[i][j] = k=0; k < 3; k++)
                  cmatrix[i][j] += rgb_adobe[i][k] * adobe_cam[k][j];
          }
        else
          for (i=0; i < 3; i++)
            FORC3 cmatrix[i][c] = ((short) get2()) / 256.0;
      }
    if ((tag == 0x1012 || tag == 0x20400600) && len == 4)
      FORC4 cblack[c ^ c >> 1] = get2();
    if (tag == 0x1017 || tag == 0x20400100)
      cam_mul[0] = get2() / 256.0;
    if (tag == 0x1018 || tag == 0x20400100)
      cam_mul[2] = get2() / 256.0;
    if (tag == 0x2011 && len == 2) {
get2_256:
      order = 0x4d4d;
      cam_mul[0] = get2() / 256.0;
      cam_mul[2] = get2() / 256.0;
    }
    if ((tag | 0x70) == 0x2070 && type == 4)
      fseek (ifp, get4()+base, SEEK_SET);
    if (tag == 0x2020)
      parse_thumb_note (base, 257, 258);
    if (tag == 0x2040)
      parse_makernote (base, 0x2040);
    if (tag == 0xb028) {
      fseek (ifp, get4()+base, SEEK_SET);
      parse_thumb_note (base, 136, 137);
    }
    if (tag == 0x4001 && len > 500) {
      i = len == 582 ? 50 : len == 653 ? 68 : len == 5120 ? 142 : 126;
      fseek (ifp, i, SEEK_CUR);
get2_rggb:
      FORC4 cam_mul[c ^ (c >> 1)] = get2();
      i = len >> 3 == 164 ? 112:22;
      fseek (ifp, i, SEEK_CUR);
      FORC4 sraw_mul[c ^ (c >> 1)] = get2();
    }
    if(!strcasecmp(make,"Samsung"))
      {
        if (tag == 0xa020) // get the full Samsung encryption key
            for (i=0; i<11; i++) SamsungKey[i] = get4();
        if (tag == 0xa021) // get and decode Samsung cam_mul array
            FORC4 cam_mul[c ^ (c >> 1)] = get4() - SamsungKey[c];
        if (tag == 0xa030 && len == 9)	// get and decode Samsung color matrix
            for (i=0; i < 3; i++)
              FORC3 cmatrix[i][c] = (short)((get4() + SamsungKey[i*3+c]))/256.0;
        if (tag == 0xa028)
          FORC4 cblack[c ^ (c >> 1)] = get4() - SamsungKey[c];
      }
    else
      {
        // Somebody else use 0xa021 and 0xa028?
        if (tag == 0xa021)
          FORC4 cam_mul[c ^ (c >> 1)] = get4();
        if (tag == 0xa028)
          FORC4 cam_mul[c ^ (c >> 1)] -= get4();
      }
next:
    fseek (ifp, save, SEEK_SET);
  }
quit:
  order = sorder;
}

Project: LibRaw

void LibRaw::checkCancel()
{
#ifdef WIN32
  if(InterlockedExchangeAdd(&_exitflag,0))
    throw LIBRAW_EXCEPTION_CANCELLED_BY_CALLBACK;
#else
  if( __sync_add_and_fetch(&_exitflag,0))
    throw LIBRAW_EXCEPTION_CANCELLED_BY_CALLBACK;
#endif
}

Project: LibRaw

int LibRaw::subtract_black_internal()
{
  CHECK_ORDER_LOW(LIBRAW_PROGRESS_RAW2_IMAGE);

  try {
    if(!is_phaseone_compressed() && (C.cblack[0] || C.cblack[1] || C.cblack[2] || C.cblack[3]))
      {
#define BAYERC(row,col,c) imgdata.image[((row) >> IO.shrink)*S.iwidth + ((col) >> IO.shrink)][c] 
        int cblk[4],i;
        for(i=0;i<4;i++)
          cblk[i] = C.cblack[i];

        int size = S.iheight * S.iwidth;
#define MIN(a,b) ((a) < (b) ? (a) : (b))
#define MAX(a,b) ((a) > (b) ? (a) : (b))
#define LIM(x,min,max) MAX(min,MIN(x,max))
#define CLIP(x) LIM(x,0,65535)
        int dmax = 0;
        for(i=0; i< size*4; i++)
          {
            int val = imgdata.image[0][i];
            val -= cblk[i & 3];
            imgdata.image[0][i] = CLIP(val);
            if(dmax < val) dmax = val;
          }
        C.data_maximum = dmax & 0xffff;
#undef MIN
#undef MAX
#undef LIM
#undef CLIP
        C.maximum -= C.black;
        ZERO(C.cblack);
        C.black = 0;
#undef BAYERC
      }
    else
      {
        // Nothing to Do, maximum is already calculated, black level is 0, so no change
        // only calculate channel maximum;
        int idx;
        ushort *p = (ushort*)imgdata.image;
        int dmax = 0;
        for(idx=0;idx<S.iheight*S.iwidth*4;idx++)
          if(dmax < p[idx]) dmax = p[idx];
        C.data_maximum = dmax;
      }
    return 0;
  }
  catch ( LibRaw_exceptions err) {
    EXCEPTION_HANDLER(err);
  }

}

Project: LibRaw
File: dcraw.c

void CLASS sony_decrypt (unsigned *data, int len, int start, int key)
{
#ifndef LIBRAW_NOTHREADS
#define pad tls->sony_decrypt.pad
#define p   tls->sony_decrypt.p
#else
  static unsigned pad[128], p;
#endif
  if (start) {
    for (p=0; p < 4; p++)
      pad[p] = key = key * 48828125 + 1;
    pad[3] = pad[3] << 1 | (pad[0]^pad[2]) >> 31;
    for (p=4; p < 127; p++)
      pad[p] = (pad[p-4]^pad[p-2]) << 1 | (pad[p-3]^pad[p-1]) >> 31;
    for (p=0; p < 127; p++)
      pad[p] = htonl(pad[p]);
  }
  while (len--)
    {
      *data++ ^= pad[p & 127] = pad[(p+1) & 127] ^ pad[(p+65) & 127];
      p++;     
    }
#ifndef LIBRAW_NOTHREADS
#undef pad
#undef p
#endif
}

Project: LibRaw

int LibRaw::unpack(void)
{
  CHECK_ORDER_HIGH(LIBRAW_PROGRESS_LOAD_RAW);
  CHECK_ORDER_LOW(LIBRAW_PROGRESS_IDENTIFY);
  try {

    if(!libraw_internal_data.internal_data.input)
      return LIBRAW_INPUT_CLOSED;

    RUN_CALLBACK(LIBRAW_PROGRESS_LOAD_RAW,0,2);
    if (O.shot_select >= P1.raw_count)
      return LIBRAW_REQUEST_FOR_NONEXISTENT_IMAGE;
        
    if(!load_raw)
      return LIBRAW_UNSPECIFIED_ERROR;
        
    // already allocated ?
    if(imgdata.image)
      {
        free(imgdata.image);
        imgdata.image = 0;
      }
    if(imgdata.rawdata.raw_alloc)
      {
        free(imgdata.rawdata.raw_alloc);
        imgdata.rawdata.raw_alloc = 0;
      }
    if (libraw_internal_data.unpacker_data.meta_length) 
      {
        libraw_internal_data.internal_data.meta_data = 
          (char *) malloc (libraw_internal_data.unpacker_data.meta_length);
        merror (libraw_internal_data.internal_data.meta_data, "LibRaw::unpack()");
      }

    libraw_decoder_info_t decoder_info;
    get_decoder_info(&decoder_info);

    int save_iwidth = S.iwidth, save_iheight = S.iheight, save_shrink = IO.shrink;

    int rwidth = S.raw_width, rheight = S.raw_height;
    if( !IO.fuji_width)
      {
        // adjust non-Fuji allocation
        if(rwidth < S.width + S.left_margin)
          rwidth = S.width + S.left_margin;
        if(rheight < S.height + S.top_margin)
          rheight = S.height + S.top_margin;
      }

    imgdata.rawdata.raw_image = 0;
    imgdata.rawdata.color4_image = 0;
    imgdata.rawdata.color3_image = 0;
#ifdef USE_RAWSPEED
    // RawSpeed Supported, 
    if(O.use_rawspeed 
       && !(is_sraw() && O.sraw_ycc)
       && (decoder_info.decoder_flags & LIBRAW_DECODER_TRYRAWSPEED) && _rawspeed_camerameta)
      {
        INT64 spos = ID.input->tell();
        void *_rawspeed_buffer = 0;
        try 
          {
            //                printf("Using rawspeed\n");
            ID.input->seek(0,SEEK_SET);
            INT64 _rawspeed_buffer_sz = ID.input->size()+32;
            _rawspeed_buffer = malloc(_rawspeed_buffer_sz);
            if(!_rawspeed_buffer) throw LIBRAW_EXCEPTION_ALLOC;
            ID.input->read(_rawspeed_buffer,_rawspeed_buffer_sz,1);
            FileMap map((uchar8*)_rawspeed_buffer,_rawspeed_buffer_sz);
            RawParser t(&map);
            RawDecoder *d = 0;
            CameraMetaDataLR *meta = static_cast<CameraMetaDataLR*>(_rawspeed_camerameta);
            d = t.getDecoder();
            if(!d) throw "Unable to find decoder";
            try {
              d->checkSupport(meta);
            }
            catch (const RawDecoderException& e)
              {
                imgdata.process_warnings |= LIBRAW_WARN_RAWSPEED_UNSUPPORTED;
                throw e;
              }
            d->interpolateBadPixels = FALSE;
            d->applyStage1DngOpcodes = FALSE;
            _rawspeed_decoder = static_cast<void*>(d);
            d->decodeRaw();
            d->decodeMetaData(meta);
            RawImage r = d->mRaw;
            if( r->errors.size()>0)
              {
                delete d;
                _rawspeed_decoder = 0;
                throw; 
              }
            if (r->isCFA) {
              imgdata.rawdata.raw_image = (ushort*) r->getDataUncropped(0,0);
            } else if(r->getCpp()==4) {
              imgdata.rawdata.color4_image = (ushort(*)[4]) r->getDataUncropped(0,0);
			  C.maximum = r->whitePoint;
            } else if(r->getCpp() == 3)
              {
                imgdata.rawdata.color3_image = (ushort(*)[3]) r->getDataUncropped(0,0);
              }
            else
              {
                delete d;
                _rawspeed_decoder = 0;
              }
            if(_rawspeed_decoder)
              {
                // set sizes
                iPoint2D rsdim = r->getUncroppedDim();
                S.raw_pitch = r->pitch;
                S.raw_width = rsdim.x;
                S.raw_height = rsdim.y;
                //C.maximum = r->whitePoint;
                fix_after_rawspeed(r->blackLevel);
              }
            free(_rawspeed_buffer);
            _rawspeed_buffer = 0;
            imgdata.process_warnings |= LIBRAW_WARN_RAWSPEED_PROCESSED;
          } 
        catch (...) 
          {
            // We may get here due to cancellation flag
            imgdata.process_warnings |= LIBRAW_WARN_RAWSPEED_PROBLEM;
            if(_rawspeed_buffer)
              {
                free(_rawspeed_buffer);
                _rawspeed_buffer = 0;
              }
          }
        ID.input->seek(spos,SEEK_SET);
      }
#endif
    if(!imgdata.rawdata.raw_image && !imgdata.rawdata.color4_image && !imgdata.rawdata.color3_image) //RawSpeed failed!
      {
        // Not allocated on RawSpeed call, try call LibRaw
        if(decoder_info.decoder_flags &  LIBRAW_DECODER_OWNALLOC)
          {
            // x3f foveon decoder
            // Do nothing! Decoder will allocate data internally
          }
        else if(decoder_info.decoder_flags &  LIBRAW_DECODER_FLATFIELD)
          {
            imgdata.rawdata.raw_alloc = malloc(rwidth*(rheight+7)*sizeof(imgdata.rawdata.raw_image[0]));
            imgdata.rawdata.raw_image = (ushort*) imgdata.rawdata.raw_alloc;
            if(!S.raw_pitch)
                S.raw_pitch = S.raw_width*2; // Bayer case, not set before
          }
        else if (decoder_info.decoder_flags & LIBRAW_DECODER_LEGACY)
          {
            // sRAW and old Foveon decoders only, so extra buffer size is just 1/4
            S.iwidth = S.width;
            S.iheight= S.height;        
            IO.shrink = 0;
            S.raw_pitch = S.width*8;
            // allocate image as temporary buffer, size 
            imgdata.rawdata.raw_alloc = 0;
            imgdata.image = (ushort (*)[4]) calloc(S.iwidth*S.iheight,sizeof(*imgdata.image));
          }
        ID.input->seek(libraw_internal_data.unpacker_data.data_offset, SEEK_SET);
            
        unsigned m_save = C.maximum;
        if(load_raw == &LibRaw::unpacked_load_raw && !strcasecmp(imgdata.idata.make,"Nikon"))
          C.maximum=65535;
        (this->*load_raw)();
        if(load_raw == &LibRaw::unpacked_load_raw && !strcasecmp(imgdata.idata.make,"Nikon"))
          C.maximum = m_save;
        if(decoder_info.decoder_flags &  LIBRAW_DECODER_OWNALLOC)
          {
            // x3f foveon decoder only: do nothing

          }
        else if (decoder_info.decoder_flags & LIBRAW_DECODER_LEGACY)
          {
            // successfully decoded legacy image, attach image to raw_alloc
            imgdata.rawdata.raw_alloc = imgdata.image;
            imgdata.image = 0; 
            // Restore saved values. Note: Foveon have masked frame
            // Other 4-color legacy data: no borders
            S.raw_width = S.width;
            S.left_margin = 0;
            S.raw_height = S.height;
            S.top_margin = 0; 
          }
      }

    if(imgdata.rawdata.raw_image)
      crop_masked_pixels(); // calculate black levels

    // recover saved
    if( (decoder_info.decoder_flags & LIBRAW_DECODER_LEGACY) && !imgdata.rawdata.color4_image)
      {
        imgdata.image = 0; 
        imgdata.rawdata.color4_image = (ushort (*)[4]) imgdata.rawdata.raw_alloc;
      }

    // recover image sizes
    S.iwidth = save_iwidth;
    S.iheight = save_iheight;
    IO.shrink = save_shrink;

    // adjust black to possible maximum
    unsigned int i = C.cblack[3];
    unsigned int c;
    for(c=0;c<3;c++)
      if (i > C.cblack[c]) i = C.cblack[c];
    for (c=0;c<4;c++)
      C.cblack[c] -= i;
    C.black += i;

    // Save color,sizes and internal data into raw_image fields
    memmove(&imgdata.rawdata.color,&imgdata.color,sizeof(imgdata.color));
    memmove(&imgdata.rawdata.sizes,&imgdata.sizes,sizeof(imgdata.sizes));
    memmove(&imgdata.rawdata.iparams,&imgdata.idata,sizeof(imgdata.idata));
    memmove(&imgdata.rawdata.ioparams,&libraw_internal_data.internal_output_params,sizeof(libraw_internal_data.internal_output_params));

    SET_PROC_FLAG(LIBRAW_PROGRESS_LOAD_RAW);
    RUN_CALLBACK(LIBRAW_PROGRESS_LOAD_RAW,1,2);
        
    return 0;
  }
  catch ( LibRaw_exceptions err) {
    EXCEPTION_HANDLER(err);
  }
  catch (std::exception ee) {
    EXCEPTION_HANDLER(LIBRAW_EXCEPTION_IO_CORRUPT);
  }
}

Project: LibRaw
File: libraw_cxx.cpp

void LibRaw::adjust_bl()
{

   if (O.user_black >= 0) 
     C.black = O.user_black;
   for(int i=0; i<4; i++)
     if(O.user_cblack[i]>-1000000)
       C.cblack[i] = O.user_cblack[i];

  // remove common part from C.cblack[]
  int i = C.cblack[3];
  int c;
  for(c=0;c<3;c++) if (i > C.cblack[c]) i = C.cblack[c];
  for(c=0;c<4;c++) C.cblack[c] -= i;
  C.black += i;
  for(c=0;c<4;c++) C.cblack[c] += C.black;
}

Project: LibRaw
File: libraw_cxx.cpp

void LibRaw::derror()
{
  if (!libraw_internal_data.unpacker_data.data_error && libraw_internal_data.internal_data.input) 
    {
      if (libraw_internal_data.internal_data.input->eof())
        {
          if(callbacks.data_cb)(*callbacks.data_cb)(callbacks.datacb_data,
                                                    libraw_internal_data.internal_data.input->fname(),-1);
          throw LIBRAW_EXCEPTION_IO_EOF;
        }
      else
        {
          if(callbacks.data_cb)(*callbacks.data_cb)(callbacks.datacb_data,
                                                    libraw_internal_data.internal_data.input->fname(),
                                                    libraw_internal_data.internal_data.input->tell());
          throw LIBRAW_EXCEPTION_IO_CORRUPT;
        }
    }
  libraw_internal_data.unpacker_data.data_error++;
}

Project: LibRaw

void CLASS bad_pixels (const char *cfname)
{
  FILE *fp=NULL;
#ifndef LIBRAW_LIBRARY_BUILD
  char *fname, *cp, line[128];
  int len, time, row, col, r, c, rad, tot, n, fixed=0;
#else
  char *cp, line[128];
  int time, row, col, r, c, rad, tot, n;
#ifdef DCRAW_VERBOSE
  int fixed = 0;
#endif
#endif

  if (!filters) return;
#ifdef LIBRAW_LIBRARY_BUILD
  RUN_CALLBACK(LIBRAW_PROGRESS_BAD_PIXELS,0,2);
#endif
  if (cfname)
    fp = fopen (cfname, "r");
#line 4145 "dcraw/dcraw.c"
  if (!fp)
      {
#ifdef LIBRAW_LIBRARY_BUILD
          imgdata.process_warnings |= LIBRAW_WARN_NO_BADPIXELMAP;
#endif
          return;
      }
  while (fgets (line, 128, fp)) {
    cp = strchr (line, '#');
    if (cp) *cp = 0;
    if (sscanf (line, "%d %d %d", &col, &row, &time) != 3) continue;
    if ((unsigned) col >= width || (unsigned) row >= height) continue;
    if (time > timestamp) continue;
    for (tot=n=0, rad=1; rad < 3 && n==0; rad++)
      for (r = row-rad; r <= row+rad; r++)
	for (c = col-rad; c <= col+rad; c++)
	  if ((unsigned) r < height && (unsigned) c < width &&
		(r != row || c != col) && fcol(r,c) == fcol(row,col)) {
	    tot += BAYER2(r,c);
	    n++;
	  }
    BAYER2(row,col) = tot/n;
#ifdef DCRAW_VERBOSE
    if (verbose) {
      if (!fixed++)
	fprintf (stderr,_("Fixed dead pixels at:"));
      fprintf (stderr, " %d,%d", col, row);
    }
#endif
  }
#ifdef DCRAW_VERBOSE
  if (fixed) fputc ('\n', stderr);
#endif
  fclose (fp);
#ifdef LIBRAW_LIBRARY_BUILD
  RUN_CALLBACK(LIBRAW_PROGRESS_BAD_PIXELS,1,2);
#endif
}

Project: LibRaw

int LibRaw::is_sraw() { return load_raw == &LibRaw::canon_sraw_load_raw; }

Project: LibRaw

void LibRaw:: recycle() 
{
  recycle_datastream();
#define FREE(a) do { if(a) { free(a); a = NULL;} }while(0)
            
  FREE(imgdata.image); 
  FREE(imgdata.thumbnail.thumb);
  FREE(libraw_internal_data.internal_data.meta_data);
  FREE(libraw_internal_data.output_data.histogram);
  FREE(libraw_internal_data.output_data.oprof);
  FREE(imgdata.color.profile);
  FREE(imgdata.rawdata.ph1_black);
  FREE(imgdata.rawdata.raw_alloc); 
#undef FREE
  ZERO(imgdata.rawdata);
  ZERO(imgdata.sizes);
  ZERO(imgdata.color);
  ZERO(libraw_internal_data);
  _exitflag = 0;
#ifdef USE_RAWSPEED
  if(_rawspeed_decoder)
    {
      RawDecoder *d = static_cast<RawDecoder*>(_rawspeed_decoder);
      delete d;
    }
  _rawspeed_decoder = 0;
#endif
  if(_x3f_data)
    {
      x3f_clear(_x3f_data);
      _x3f_data = 0;
    }

  memmgr.cleanup();
  imgdata.thumbnail.tformat = LIBRAW_THUMBNAIL_UNKNOWN;
  imgdata.progress_flags = 0;
  
  tls->init();
}

Project: LibRaw

void CLASS crop_masked_pixels()
{
  int row, col;
  unsigned 
#ifndef LIBRAW_LIBRARY_BUILD
    r, raw_pitch = raw_width*2,
    c, m, mblack[8], zero, val;
#else
    c, m, zero, val;
#define mblack imgdata.color.black_stat
#endif

#ifndef LIBRAW_LIBRARY_BUILD
  if (load_raw == &CLASS phase_one_load_raw ||
      load_raw == &CLASS phase_one_load_raw_c)
    phase_one_correct();
  if (fuji_width) {
    for (row=0; row < raw_height-top_margin*2; row++) {
      for (col=0; col < fuji_width << !fuji_layout; col++) {
	if (fuji_layout) {
	  r = fuji_width - 1 - col + (row >> 1);
	  c = col + ((row+1) >> 1);
	} else {
	  r = fuji_width - 1 + row - (col >> 1);
	  c = row + ((col+1) >> 1);
	}
	if (r < height && c < width)
	  BAYER(r,c) = RAW(row+top_margin,col+left_margin);
      }
    }
  } else {
    for (row=0; row < height; row++)
      for (col=0; col < width; col++)
	BAYER2(row,col) = RAW(row+top_margin,col+left_margin);
  }
#endif
  if (mask[0][3] > 0) goto mask_set;
  if (load_raw == &CLASS canon_load_raw ||
      load_raw == &CLASS lossless_jpeg_load_raw) {
    mask[0][1] = mask[1][1] += 2;
    mask[0][3] -= 2;
    goto sides;
  }
  if (load_raw == &CLASS canon_600_load_raw ||
      load_raw == &CLASS sony_load_raw ||
     (load_raw == &CLASS eight_bit_load_raw && strncmp(model,"DC2",3)) ||
      load_raw == &CLASS kodak_262_load_raw ||
     (load_raw == &CLASS packed_load_raw && (load_flags & 32))) {
sides:
    mask[0][0] = mask[1][0] = top_margin;
    mask[0][2] = mask[1][2] = top_margin+height;
    mask[0][3] += left_margin;
    mask[1][1] += left_margin+width;
    mask[1][3] += raw_width;
  }
  if (load_raw == &CLASS nokia_load_raw) {
    mask[0][2] = top_margin;
    mask[0][3] = width;
  }
mask_set:
  memset (mblack, 0, sizeof mblack);
  for (zero=m=0; m < 8; m++)
    for (row=MAX(mask[m][0],0); row < MIN(mask[m][2],raw_height); row++)
      for (col=MAX(mask[m][1],0); col < MIN(mask[m][3],raw_width); col++) {
	c = FC(row-top_margin,col-left_margin);
	mblack[c] += val = raw_image[(row)*raw_pitch/2+(col)];
	mblack[4+c]++;
	zero += !val;
      }
  if (load_raw == &CLASS canon_600_load_raw && width < raw_width) {
    black = (mblack[0]+mblack[1]+mblack[2]+mblack[3]) /
	    (mblack[4]+mblack[5]+mblack[6]+mblack[7]) - 4;
#ifndef LIBRAW_LIBRARY_BUILD
    canon_600_correct();
#endif
  } else if (zero < mblack[4] && mblack[5] && mblack[6] && mblack[7])
    FORC4 cblack[c] = mblack[c] / mblack[4+c];
}

Project: LibRaw

LibRaw:: LibRaw(unsigned int flags)
{
  double aber[4] = {1,1,1,1};
  double gamm[6] = { 0.45,4.5,0,0,0,0 };
  unsigned greybox[4] =  { 0, 0, UINT_MAX, UINT_MAX };
  unsigned cropbox[4] =  { 0, 0, UINT_MAX, UINT_MAX };
#ifdef DCRAW_VERBOSE
  verbose = 1;
#else
  verbose = 0;
#endif
  ZERO(imgdata);
  ZERO(libraw_internal_data);
  ZERO(callbacks);
  
  _rawspeed_camerameta = _rawspeed_decoder = NULL;
  _x3f_data = NULL;

#ifdef USE_RAWSPEED
  CameraMetaDataLR *camerameta = make_camera_metadata(); // May be NULL in case of exception in make_camera_metadata()
  _rawspeed_camerameta = static_cast<void*>(camerameta);
#endif
  callbacks.mem_cb = (flags & LIBRAW_OPIONS_NO_MEMERR_CALLBACK) ? NULL:  &default_memory_callback;
  callbacks.data_cb = (flags & LIBRAW_OPIONS_NO_DATAERR_CALLBACK)? NULL : &default_data_callback;
  memmove(&imgdata.params.aber,&aber,sizeof(aber));
  memmove(&imgdata.params.gamm,&gamm,sizeof(gamm));
  memmove(&imgdata.params.greybox,&greybox,sizeof(greybox));
  memmove(&imgdata.params.cropbox,&cropbox,sizeof(cropbox));
  
  imgdata.params.bright=1;
  imgdata.params.use_camera_matrix=1;
  imgdata.params.user_flip=-1;
  imgdata.params.user_black=-1;
  imgdata.params.user_cblack[0]=imgdata.params.user_cblack[1]=imgdata.params.user_cblack[2]=imgdata.params.user_cblack[3]=-1000001;
  imgdata.params.user_sat=-1;
  imgdata.params.user_qual=-1;
  imgdata.params.output_color=1;
  imgdata.params.output_bps=8;
  imgdata.params.use_fuji_rotate=1;
  imgdata.params.exp_shift = 1.0;
  imgdata.params.auto_bright_thr = LIBRAW_DEFAULT_AUTO_BRIGHTNESS_THRESHOLD;
  imgdata.params.adjust_maximum_thr= LIBRAW_DEFAULT_ADJUST_MAXIMUM_THRESHOLD;
  imgdata.params.use_rawspeed = 1;
  imgdata.params.no_auto_scale = 0;
  imgdata.params.no_interpolation = 0;
  imgdata.params.sraw_ycc = 0;
  imgdata.params.force_foveon_x3f = 0;
  imgdata.params.green_matching = 0;
  imgdata.parent_class = this;
  imgdata.progress_flags = 0;
  _exitflag = 0;
  tls = new LibRaw_TLS;
  tls->init();
}

Project: LibRaw

int LibRaw::open_datastream(LibRaw_abstract_datastream *stream)
{

  if(!stream)
    return ENOENT;
  if(!stream->valid())
    return LIBRAW_IO_ERROR;
  recycle();

  try {
    ID.input = stream;
    SET_PROC_FLAG(LIBRAW_PROGRESS_OPEN);

    identify();
    // Adjust sizes for X3F processing
    if(load_raw == &LibRaw::x3f_load_raw)
    {
        for(int i=0; i< foveon_count;i++)
            if(!strcasecmp(imgdata.idata.make,foveon_data[i].make) && !strcasecmp(imgdata.idata.model,foveon_data[i].model)
                && imgdata.sizes.raw_width == foveon_data[i].raw_width
                && imgdata.sizes.raw_height == foveon_data[i].raw_height
                )
            {
                imgdata.sizes.top_margin = foveon_data[i].top_margin;
                imgdata.sizes.left_margin = foveon_data[i].left_margin;
                imgdata.sizes.width = imgdata.sizes.iwidth = foveon_data[i].width;
                imgdata.sizes.height = imgdata.sizes.iheight = foveon_data[i].height;
                break;
            }
    }
#if 0
    size_t bytes = ID.input->size()-libraw_internal_data.unpacker_data.data_offset;
    float bpp = float(bytes)/float(S.raw_width)/float(S.raw_height);
    float bpp2 = float(bytes)/float(S.width)/float(S.height);
    printf("RawSize: %dx%d data offset: %d data size:%d bpp: %g bpp2: %g\n",S.raw_width,S.raw_height,libraw_internal_data.unpacker_data.data_offset,bytes,bpp,bpp2);
    if(!strcasecmp(imgdata.idata.make,"Hasselblad") && bpp == 6.0f)
      {
        load_raw = &LibRaw::hasselblad_full_load_raw;
        S.width = S.raw_width;
        S.height = S.raw_height;
        P1.filters = 0;
        P1.colors=3;
        P1.raw_count=1;
        C.maximum=0xffff;
        printf("3 channel hassy found\n");
      }
#endif
    if(C.profile_length)
      {
        if(C.profile) free(C.profile);
        C.profile = malloc(C.profile_length);
        merror(C.profile,"LibRaw::open_file()");
        ID.input->seek(ID.profile_offset,SEEK_SET);
        ID.input->read(C.profile,C.profile_length,1);
      }
        
    SET_PROC_FLAG(LIBRAW_PROGRESS_IDENTIFY);
  }
  catch ( LibRaw_exceptions err) {
    EXCEPTION_HANDLER(err);
  }
  catch (std::exception ee) {
    EXCEPTION_HANDLER(LIBRAW_EXCEPTION_IO_CORRUPT);
  }

  if(P1.raw_count < 1) 
    return LIBRAW_FILE_UNSUPPORTED;

    
  write_fun = &LibRaw::write_ppm_tiff;
    
  if (load_raw == &LibRaw::kodak_ycbcr_load_raw) 
    {
      S.height += S.height & 1;
      S.width  += S.width  & 1;
    }

  IO.shrink = P1.filters && (O.half_size ||
                             ((O.threshold || O.aber[0] != 1 || O.aber[2] != 1) ));

  S.iheight = (S.height + IO.shrink) >> IO.shrink;
  S.iwidth  = (S.width  + IO.shrink) >> IO.shrink;

  // Save color,sizes and internal data into raw_image fields
  memmove(&imgdata.rawdata.color,&imgdata.color,sizeof(imgdata.color));
  memmove(&imgdata.rawdata.sizes,&imgdata.sizes,sizeof(imgdata.sizes));
  memmove(&imgdata.rawdata.iparams,&imgdata.idata,sizeof(imgdata.idata));
  memmove(&imgdata.rawdata.ioparams,&libraw_internal_data.internal_output_params,sizeof(libraw_internal_data.internal_output_params));
    
  SET_PROC_FLAG(LIBRAW_PROGRESS_SIZE_ADJUST);


  return LIBRAW_SUCCESS;
}

Project: LibRaw

void CLASS scale_colors()
{
  unsigned bottom, right, size, row, col, ur, uc, i, x, y, c, sum[8];
  int val, dark, sat;
  double dsum[8], dmin, dmax;
  float scale_mul[4], fr, fc;
  ushort *img=0, *pix;

#ifdef LIBRAW_LIBRARY_BUILD
  RUN_CALLBACK(LIBRAW_PROGRESS_SCALE_COLORS,0,2);
#endif

  if (user_mul[0])
    memcpy (pre_mul, user_mul, sizeof pre_mul);
  if (use_auto_wb || (use_camera_wb && cam_mul[0] == -1)) {
    memset (dsum, 0, sizeof dsum);
    bottom = MIN (greybox[1]+greybox[3], height);
    right  = MIN (greybox[0]+greybox[2], width);
    for (row=greybox[1]; row < bottom; row += 8)
      for (col=greybox[0]; col < right; col += 8) {
	memset (sum, 0, sizeof sum);
	for (y=row; y < row+8 && y < bottom; y++)
	  for (x=col; x < col+8 && x < right; x++)
	    FORC4 {
	      if (filters) {
		c = fcol(y,x);
		val = BAYER2(y,x);
	      } else
		val = image[y*width+x][c];
	      if (val > maximum-25) goto skip_block;
	      if ((val -= cblack[c]) < 0) val = 0;
	      sum[c] += val;
	      sum[c+4]++;
	      if (filters) break;
	    }
	FORC(8) dsum[c] += sum[c];
skip_block: ;
      }
    FORC4 if (dsum[c]) pre_mul[c] = dsum[c+4] / dsum[c];
  }
  if (use_camera_wb && cam_mul[0] != -1) {
    memset (sum, 0, sizeof sum);
    for (row=0; row < 8; row++)
      for (col=0; col < 8; col++) {
	c = FC(row,col);
	if ((val = white[row][col] - cblack[c]) > 0)
	  sum[c] += val;
	sum[c+4]++;
      }
    if (sum[0] && sum[1] && sum[2] && sum[3])
      FORC4 pre_mul[c] = (float) sum[c+4] / sum[c];
    else if (cam_mul[0] && cam_mul[2])
      memcpy (pre_mul, cam_mul, sizeof pre_mul);
    else
      {
#ifdef LIBRAW_LIBRARY_BUILD
            imgdata.process_warnings |= LIBRAW_WARN_BAD_CAMERA_WB;
#endif
#ifdef DCRAW_VERBOSE
            fprintf (stderr,_("%s: Cannot use camera white balance.\n"), ifname);
#endif
      }
  }
  if (pre_mul[1] == 0) pre_mul[1] = 1;
  if (pre_mul[3] == 0) pre_mul[3] = colors < 4 ? pre_mul[1] : 1;
  dark = black;
  sat = maximum;
  if (threshold) wavelet_denoise();
  maximum -= black;
  for (dmin=DBL_MAX, dmax=c=0; c < 4; c++) {
    if (dmin > pre_mul[c])
	dmin = pre_mul[c];
    if (dmax < pre_mul[c])
	dmax = pre_mul[c];
  }
  if (!highlight) dmax = dmin;
  FORC4 scale_mul[c] = (pre_mul[c] /= dmax) * 65535.0 / maximum;
#ifdef DCRAW_VERBOSE
  if (verbose) {
    fprintf (stderr,
      _("Scaling with darkness %d, saturation %d, and\nmultipliers"), dark, sat);
    FORC4 fprintf (stderr, " %f", pre_mul[c]);
    fputc ('\n', stderr);
  }
#endif
  if (filters > 1000 && (cblack[4]+1)/2 == 1 && (cblack[5]+1)/2 == 1) {
    FORC4 cblack[FC(c/2,c%2)] +=
	cblack[6 + c/2 % cblack[4] * cblack[4] + c%2 % cblack[5]];
    cblack[4] = cblack[5] = 0;
  }
  size = iheight*iwidth;
#ifdef LIBRAW_LIBRARY_BUILD
  scale_colors_loop(scale_mul);
#else
  for (i=0; i < size*4; i++) {
    if (!(val = image[0][i])) continue;
    if (cblack[4] && cblack[5])
      val -= cblack[6 + i/4 / iwidth % cblack[4] * cblack[4] +
			i/4 % iwidth % cblack[5]];
    val -= cblack[i & 3];
    val *= scale_mul[i & 3];
    image[0][i] = CLIP(val);
  }
#endif
  if ((aber[0] != 1 || aber[2] != 1) && colors == 3) {
#ifdef DCRAW_VERBOSE
    if (verbose)
      fprintf (stderr,_("Correcting chromatic aberration...\n"));
#endif
    for (c=0; c < 4; c+=2) {
      if (aber[c] == 1) continue;
      img = (ushort *) malloc (size * sizeof *img);
      merror (img, "scale_colors()");
      for (i=0; i < size; i++)
	img[i] = image[i][c];
      for (row=0; row < iheight; row++) {
	ur = fr = (row - iheight*0.5) * aber[c] + iheight*0.5;
	if (ur > iheight-2) continue;
	fr -= ur;
	for (col=0; col < iwidth; col++) {
	  uc = fc = (col - iwidth*0.5) * aber[c] + iwidth*0.5;
	  if (uc > iwidth-2) continue;
	  fc -= uc;
	  pix = img + ur*iwidth + uc;
	  image[row*iwidth+col][c] =
	    (pix[     0]*(1-fc) + pix[       1]*fc) * (1-fr) +
	    (pix[iwidth]*(1-fc) + pix[iwidth+1]*fc) * fr;
	}
      }
      free(img);
    }
  }
#ifdef LIBRAW_LIBRARY_BUILD
  RUN_CALLBACK(LIBRAW_PROGRESS_SCALE_COLORS,1,2);
#endif
}