Commit message: SECUNIA advisory 76000 #1 (wrong fuji width set via tiff tag
CVE: CVE-2017-16909
CWE: CWE-125
Vulnerability description: An error related to the "LibRaw::panasonic_load_raw()" function (dcraw_common.cpp) in LibRaw versions prior to 0.18.6 can be exploited to cause a heap-based buffer overflow and subsequently cause a crash via a specially crafted TIFF image.

Project: LibRaw
File: dcraw.c

void CLASS kodak_ycbcr_load_raw()
{
  short buf[384], *bp;
  int row, col, len, c, i, j, k, y[2][2], cb, cr, rgb[3];
  ushort *ip;

  if (!image)
    return;
  unsigned int bits = (load_flags && load_flags > 9 && load_flags < 17) ? load_flags : 10;
  for (row = 0; row < height; row += 2)
  {
#ifdef LIBRAW_LIBRARY_BUILD
    checkCancel();
#endif
    for (col = 0; col < width; col += 128)
    {
      len = MIN(128, width - col);
      kodak_65000_decode(buf, len * 3);
      y[0][1] = y[1][1] = cb = cr = 0;
      for (bp = buf, i = 0; i < len; i += 2, bp += 2)
      {
        cb += bp[4];
        cr += bp[5];
        rgb[1] = -((cb + cr + 2) >> 2);
        rgb[2] = rgb[1] + cb;
        rgb[0] = rgb[1] + cr;
        for (j = 0; j < 2; j++)
          for (k = 0; k < 2; k++)
          {
            if ((y[j][k] = y[j][k ^ 1] + *bp++) >> bits)
              derror();
            ip = image[(row + j) * width + col + i + k];
            FORC3 ip[c] = curve[LIM(y[j][k] + rgb[c], 0, 0xfff)];
          }
      }
    }
  }
}

Project: LibRaw
File: dcraw.c

void CLASS processNikonLensData(uchar *LensData, unsigned len)
{
  ushort i;
  if (!(imgdata.lens.nikon.NikonLensType & 0x01))
  {
    imgdata.lens.makernotes.LensFeatures_pre[0] = 'A';
    imgdata.lens.makernotes.LensFeatures_pre[1] = 'F';
  }
  else
  {
    imgdata.lens.makernotes.LensFeatures_pre[0] = 'M';
    imgdata.lens.makernotes.LensFeatures_pre[1] = 'F';
  }

  if (imgdata.lens.nikon.NikonLensType & 0x02)
  {
    if (imgdata.lens.nikon.NikonLensType & 0x04)
      imgdata.lens.makernotes.LensFeatures_suf[0] = 'G';
    else
      imgdata.lens.makernotes.LensFeatures_suf[0] = 'D';
    imgdata.lens.makernotes.LensFeatures_suf[1] = ' ';
  }

  if (imgdata.lens.nikon.NikonLensType & 0x08)
  {
    imgdata.lens.makernotes.LensFeatures_suf[2] = 'V';
    imgdata.lens.makernotes.LensFeatures_suf[3] = 'R';
  }

  if (imgdata.lens.nikon.NikonLensType & 0x10)
  {
    imgdata.lens.makernotes.LensMount = imgdata.lens.makernotes.CameraMount = LIBRAW_MOUNT_Nikon_CX;
    imgdata.lens.makernotes.CameraFormat = imgdata.lens.makernotes.LensFormat = LIBRAW_FORMAT_1INCH;
  }
  else
    imgdata.lens.makernotes.LensMount = imgdata.lens.makernotes.CameraMount = LIBRAW_MOUNT_Nikon_F;

  if (imgdata.lens.nikon.NikonLensType & 0x20)
  {
    strcpy(imgdata.lens.makernotes.Adapter, "FT-1");
    imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_Nikon_F;
    imgdata.lens.makernotes.CameraMount = LIBRAW_MOUNT_Nikon_CX;
    imgdata.lens.makernotes.CameraFormat = LIBRAW_FORMAT_1INCH;
  }

  imgdata.lens.nikon.NikonLensType = imgdata.lens.nikon.NikonLensType & 0xdf;

  if (len < 20)
  {
    switch (len)
    {
    case 9:
      i = 2;
      break;
    case 15:
      i = 7;
      break;
    case 16:
      i = 8;
      break;
    }
    imgdata.lens.nikon.NikonLensIDNumber = LensData[i];
    imgdata.lens.nikon.NikonLensFStops = LensData[i + 1];
    imgdata.lens.makernotes.LensFStops = (float)imgdata.lens.nikon.NikonLensFStops / 12.0f;
    if (fabsf(imgdata.lens.makernotes.MinFocal) < 1.1f)
    {
      if ((imgdata.lens.nikon.NikonLensType ^ (uchar)0x01) || LensData[i + 2])
        imgdata.lens.makernotes.MinFocal = 5.0f * powf64(2.0f, (float)LensData[i + 2] / 24.0f);
      if ((imgdata.lens.nikon.NikonLensType ^ (uchar)0x01) || LensData[i + 3])
        imgdata.lens.makernotes.MaxFocal = 5.0f * powf64(2.0f, (float)LensData[i + 3] / 24.0f);
      if ((imgdata.lens.nikon.NikonLensType ^ (uchar)0x01) || LensData[i + 4])
        imgdata.lens.makernotes.MaxAp4MinFocal = powf64(2.0f, (float)LensData[i + 4] / 24.0f);
      if ((imgdata.lens.nikon.NikonLensType ^ (uchar)0x01) || LensData[i + 5])
        imgdata.lens.makernotes.MaxAp4MaxFocal = powf64(2.0f, (float)LensData[i + 5] / 24.0f);
    }
    imgdata.lens.nikon.NikonMCUVersion = LensData[i + 6];
    if (i != 2)
    {
      if ((LensData[i - 1]) && (fabsf(imgdata.lens.makernotes.CurFocal) < 1.1f))
        imgdata.lens.makernotes.CurFocal = 5.0f * powf64(2.0f, (float)LensData[i - 1] / 24.0f);
      if (LensData[i + 7])
        imgdata.lens.nikon.NikonEffectiveMaxAp = powf64(2.0f, (float)LensData[i + 7] / 24.0f);
    }
    imgdata.lens.makernotes.LensID =
        (unsigned long long)LensData[i] << 56 | (unsigned long long)LensData[i + 1] << 48 |
        (unsigned long long)LensData[i + 2] << 40 | (unsigned long long)LensData[i + 3] << 32 |
        (unsigned long long)LensData[i + 4] << 24 | (unsigned long long)LensData[i + 5] << 16 |
        (unsigned long long)LensData[i + 6] << 8 | (unsigned long long)imgdata.lens.nikon.NikonLensType;
  }
  else if ((len == 459) || (len == 590))
  {
    memcpy(imgdata.lens.makernotes.Lens, LensData + 390, 64);
  }
  else if (len == 509)
  {
    memcpy(imgdata.lens.makernotes.Lens, LensData + 391, 64);
  }
  else if (len == 879)
  {
    memcpy(imgdata.lens.makernotes.Lens, LensData + 680, 64);
  }
  return;
}

Project: LibRaw
File: dcraw.c

void CLASS process_Sony_0x9050(uchar *buf, unsigned id)
{
  ushort lid;

  if ((imgdata.lens.makernotes.CameraMount != LIBRAW_MOUNT_Sony_E) &&
      (imgdata.lens.makernotes.CameraMount != LIBRAW_MOUNT_FixedLens))
  {
    if (buf[0])
      imgdata.lens.makernotes.MaxAp4CurFocal =
          my_roundf(powf64(2.0f, ((float)SonySubstitution[buf[0]] / 8.0 - 1.06f) / 2.0f) * 10.0f) / 10.0f;

    if (buf[1])
      imgdata.lens.makernotes.MinAp4CurFocal =
          my_roundf(powf64(2.0f, ((float)SonySubstitution[buf[1]] / 8.0 - 1.06f) / 2.0f) * 10.0f) / 10.0f;
  }

  if (imgdata.lens.makernotes.CameraMount != LIBRAW_MOUNT_FixedLens)
  {
    if (buf[0x3d] | buf[0x3c])
    {
      lid = SonySubstitution[buf[0x3d]] << 8 | SonySubstitution[buf[0x3c]];
      imgdata.lens.makernotes.CurAp = powf64(2.0f, ((float)lid / 256.0f - 16.0f) / 2.0f);
    }
    if (buf[0x105] && (imgdata.lens.makernotes.LensMount != LIBRAW_MOUNT_Canon_EF) &&
        (imgdata.lens.makernotes.LensMount != LIBRAW_MOUNT_Sigma_X3F))
      imgdata.lens.makernotes.LensMount = SonySubstitution[buf[0x105]];
    if (buf[0x106])
      imgdata.lens.makernotes.LensFormat = SonySubstitution[buf[0x106]];
  }

  if (imgdata.lens.makernotes.CameraMount == LIBRAW_MOUNT_Sony_E)
  {
    parseSonyLensType2(SonySubstitution[buf[0x0108]], // LensType2 - Sony lens ids
                       SonySubstitution[buf[0x0107]]);
  }
  if ((imgdata.lens.makernotes.LensID == -1) && (imgdata.lens.makernotes.CameraMount == LIBRAW_MOUNT_Minolta_A) &&
      (buf[0x010a] | buf[0x0109]))
  {
    imgdata.lens.makernotes.LensID = // LensType - Minolta/Sony lens ids
        SonySubstitution[buf[0x010a]] << 8 | SonySubstitution[buf[0x0109]];

    if ((imgdata.lens.makernotes.LensID > 0x4900) && (imgdata.lens.makernotes.LensID <= 0x5900))
    {
      imgdata.lens.makernotes.AdapterID = 0x4900;
      imgdata.lens.makernotes.LensID -= imgdata.lens.makernotes.AdapterID;
      imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_Sigma_X3F;
      strcpy(imgdata.lens.makernotes.Adapter, "MC-11");
    }

    else if ((imgdata.lens.makernotes.LensID > 0xEF00) && (imgdata.lens.makernotes.LensID < 0xFFFF) &&
             (imgdata.lens.makernotes.LensID != 0xFF00))
    {
      imgdata.lens.makernotes.AdapterID = 0xEF00;
      imgdata.lens.makernotes.LensID -= imgdata.lens.makernotes.AdapterID;
      imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_Canon_EF;
    }
  }

  if ((id >= 286) && (id <= 293))
    // "SLT-A65", "SLT-A77", "NEX-7", "NEX-VG20E",
    // "SLT-A37", "SLT-A57", "NEX-F3", "Lunar"
    parseSonyLensFeatures(SonySubstitution[buf[0x115]], SonySubstitution[buf[0x116]]);
  else if (imgdata.lens.makernotes.CameraMount != LIBRAW_MOUNT_FixedLens)
    parseSonyLensFeatures(SonySubstitution[buf[0x116]], SonySubstitution[buf[0x117]]);

  if ((id == 347) || (id == 350) || (id == 357))
  {
    unsigned long long b88 = SonySubstitution[buf[0x88]];
    unsigned long long b89 = SonySubstitution[buf[0x89]];
    unsigned long long b8a = SonySubstitution[buf[0x8a]];
    unsigned long long b8b = SonySubstitution[buf[0x8b]];
    unsigned long long b8c = SonySubstitution[buf[0x8c]];
    unsigned long long b8d = SonySubstitution[buf[0x8d]];
    sprintf(imgdata.shootinginfo.InternalBodySerial, "%06llx",
            (b88 << 40) + (b89 << 32) + (b8a << 24) + (b8b << 16) + (b8c << 8) + b8d);
  }
  else if ((imgdata.lens.makernotes.CameraMount == LIBRAW_MOUNT_Minolta_A) && (id > 279) && (id != 282) && (id != 283))
  {
    unsigned long long bf0 = SonySubstitution[buf[0xf0]];
    unsigned long long bf1 = SonySubstitution[buf[0xf1]];
    unsigned long long bf2 = SonySubstitution[buf[0xf2]];
    unsigned long long bf3 = SonySubstitution[buf[0xf3]];
    unsigned long long bf4 = SonySubstitution[buf[0xf4]];
    sprintf(imgdata.shootinginfo.InternalBodySerial, "%05llx",
            (bf0 << 32) + (bf1 << 24) + (bf2 << 16) + (bf3 << 8) + bf4);
  }
  else if ((imgdata.lens.makernotes.CameraMount == LIBRAW_MOUNT_Sony_E) && (id != 288) && (id != 289) && (id != 290))
  {
    unsigned b7c = SonySubstitution[buf[0x7c]];
    unsigned b7d = SonySubstitution[buf[0x7d]];
    unsigned b7e = SonySubstitution[buf[0x7e]];
    unsigned b7f = SonySubstitution[buf[0x7f]];
    sprintf(imgdata.shootinginfo.InternalBodySerial, "%04x", (b7c << 24) + (b7d << 16) + (b7e << 8) + b7f);
  }

  return;
}

Project: LibRaw
File: dcraw.c

void CLASS parse_fuji(int offset)
{
  unsigned entries, tag, len, save, c;

  fseek(ifp, offset, SEEK_SET);
  entries = get4();
  if (entries > 255)
    return;
#ifdef LIBRAW_LIBRARY_BUILD
  imgdata.process_warnings |=  LIBRAW_WARN_PARSEFUJI_PROCESSED; 
#endif
  while (entries--)
  {
    tag = get2();
    len = get2();
    save = ftell(ifp);

    if (tag == 0x100)
    {
      raw_height = get2();
      raw_width = get2();
    }
    else if (tag == 0x121)
    {
      height = get2();
      if ((width = get2()) == 4284)
        width += 3;
    }
    else if (tag == 0x130)
    {
      fuji_layout = fgetc(ifp) >> 7;
      fuji_width = !(fgetc(ifp) & 8);
    }
    else if (tag == 0x131)
    {
      filters = 9;
      FORC(36)
        {
	   int q = fgetc(ifp);
	   xtrans_abs[0][35 - c] = MAX(0,MIN(q,2)); /* & 3;*/
	}
    }
    else if (tag == 0x2ff0)
    {
      FORC4 cam_mul[c ^ 1] = get2();

// IB start
#ifdef LIBRAW_LIBRARY_BUILD
    }
    else if (tag == 0x9650)
    {
      short a = (short)get2();
      float b = fMAX(1.0f, get2());
      imgdata.makernotes.fuji.FujiExpoMidPointShift = a / b;
    }

    else if (tag == 0x2f00)
    {
      int nWBs = get4();
      nWBs = MIN(nWBs, 6);
      for (int wb_ind = 0; wb_ind < nWBs; wb_ind++)
      {
        FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_Custom1 + wb_ind][c ^ 1] = get2();
        fseek(ifp, 8, SEEK_CUR);
      }
    }

    else if (tag == 0x2000)
    {
      FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_Auto][c ^ 1] = get2();
    }
    else if (tag == 0x2100)
    {
      FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_FineWeather][c ^ 1] = get2();
    }
    else if (tag == 0x2200)
    {
      FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_Shade][c ^ 1] = get2();
    }
    else if (tag == 0x2300)
    {
      FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_FL_D][c ^ 1] = get2();
    }
    else if (tag == 0x2301)
    {
      FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_FL_N][c ^ 1] = get2();
    }
    else if (tag == 0x2302)
    {
      FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_FL_WW][c ^ 1] = get2();
    }
    else if (tag == 0x2310)
    {
      FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_FL_L][c ^ 1] = get2();
    }
    else if (tag == 0x2400)
    {
      FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_Tungsten][c ^ 1] = get2();
    }
    else if (tag == 0x2410)
    {
      FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_Flash][c ^ 1] = get2();
#endif
      // IB end
    }
    else if (tag == 0xc000)
    /* 0xc000 tag versions, second ushort; valid if the first ushort is 0
    X100F	0x0259
    X100T	0x0153
    X-E2	0x014f	0x024f depends on firmware
    X-A1	0x014e
    XQ2		0x0150
    XQ1		0x0150
    X100S	0x0149	0x0249 depends on firmware
    X30		0x0152
    X20		0x0146
    X-T10	0x0154
    X-T2	0x0258
    X-M1	0x014d
    X-E2s	0x0355
    X-A2	0x014e
    X-T20	0x025b
    GFX 50S	0x025a
    X-T1	0x0151	0x0251 0x0351 depends on firmware
    X70		0x0155
    X-Pro2	0x0255
    */
    {
      c = order;
      order = 0x4949;
      if ((tag = get4()) > 10000)
        tag = get4();
      if (tag > 10000)
        tag = get4();
      width = tag;
      height = get4();
#ifdef LIBRAW_LIBRARY_BUILD
      if (!strcmp(model, "X-A3") || !strcmp(model, "X-A10"))
      {
        int wb[4];
        int nWB, tWB, pWB;
        int iCCT = 0;
        int cnt;
        fseek(ifp, save + 0x200, SEEK_SET);
        for (int wb_ind = 0; wb_ind < 42; wb_ind++)
        {
          nWB = get4();
          tWB = get4();
          wb[0] = get4() << 1;
          wb[1] = get4();
          wb[3] = get4();
          wb[2] = get4() << 1;
          if (tWB && (iCCT < 255))
          {
            imgdata.color.WBCT_Coeffs[iCCT][0] = tWB;
            for (cnt = 0; cnt < 4; cnt++)
              imgdata.color.WBCT_Coeffs[iCCT][cnt + 1] = wb[cnt];
            iCCT++;
          }
          if (nWB != 70)
          {
            for (pWB = 1; pWB < nFuji_wb_list2; pWB += 2)
            {
              if (Fuji_wb_list2[pWB] == nWB)
              {
                for (cnt = 0; cnt < 4; cnt++)
                  imgdata.color.WB_Coeffs[Fuji_wb_list2[pWB - 1]][cnt] = wb[cnt];
                break;
              }
            }
          }
        }
      }
      else
      {
        libraw_internal_data.unpacker_data.posRAFData = save;
        libraw_internal_data.unpacker_data.lenRAFData = (len >> 1);
      }
#endif
      order = c;
    }
    fseek(ifp, save + len, SEEK_SET);
  }
  height <<= fuji_layout;
  width >>= fuji_layout;
}

Project: LibRaw
File: dcraw.c

void CLASS parseSonyLensFeatures(uchar a, uchar b)
{

  ushort features;
  features = (((ushort)a) << 8) | ((ushort)b);

  if ((imgdata.lens.makernotes.LensMount == LIBRAW_MOUNT_Canon_EF) ||
      (imgdata.lens.makernotes.LensMount != LIBRAW_MOUNT_Sigma_X3F) || !features)
    return;

  imgdata.lens.makernotes.LensFeatures_pre[0] = 0;
  imgdata.lens.makernotes.LensFeatures_suf[0] = 0;
  if ((features & 0x0200) && (features & 0x0100))
    strcpy(imgdata.lens.makernotes.LensFeatures_pre, "E");
  else if (features & 0x0200)
    strcpy(imgdata.lens.makernotes.LensFeatures_pre, "FE");
  else if (features & 0x0100)
    strcpy(imgdata.lens.makernotes.LensFeatures_pre, "DT");

  if (!imgdata.lens.makernotes.LensFormat && !imgdata.lens.makernotes.LensMount)
  {
    imgdata.lens.makernotes.LensFormat = LIBRAW_FORMAT_FF;
    imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_Minolta_A;

    if ((features & 0x0200) && (features & 0x0100))
    {
      imgdata.lens.makernotes.LensFormat = LIBRAW_FORMAT_APSC;
      imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_Sony_E;
    }
    else if (features & 0x0200)
    {
      imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_Sony_E;
    }
    else if (features & 0x0100)
    {
      imgdata.lens.makernotes.LensFormat = LIBRAW_FORMAT_APSC;
    }
  }

  if (features & 0x4000)
    strnXcat(imgdata.lens.makernotes.LensFeatures_pre, " PZ");

  if (features & 0x0008)
    strnXcat(imgdata.lens.makernotes.LensFeatures_suf, " G");
  else if (features & 0x0004)
    strnXcat(imgdata.lens.makernotes.LensFeatures_suf, " ZA");

  if ((features & 0x0020) && (features & 0x0040))
    strnXcat(imgdata.lens.makernotes.LensFeatures_suf, " Macro");
  else if (features & 0x0020)
    strnXcat(imgdata.lens.makernotes.LensFeatures_suf, " STF");
  else if (features & 0x0040)
    strnXcat(imgdata.lens.makernotes.LensFeatures_suf, " Reflex");
  else if (features & 0x0080)
    strnXcat(imgdata.lens.makernotes.LensFeatures_suf, " Fisheye");

  if (features & 0x0001)
    strnXcat(imgdata.lens.makernotes.LensFeatures_suf, " SSM");
  else if (features & 0x0002)
    strnXcat(imgdata.lens.makernotes.LensFeatures_suf, " SAM");

  if (features & 0x8000)
    strnXcat(imgdata.lens.makernotes.LensFeatures_suf, " OSS");

  if (features & 0x2000)
    strnXcat(imgdata.lens.makernotes.LensFeatures_suf, " LE");

  if (features & 0x0800)
    strnXcat(imgdata.lens.makernotes.LensFeatures_suf, " II");

  if (imgdata.lens.makernotes.LensFeatures_suf[0] == ' ')
    memmove(imgdata.lens.makernotes.LensFeatures_suf, imgdata.lens.makernotes.LensFeatures_suf + 1,
            strbuflen(imgdata.lens.makernotes.LensFeatures_suf) - 1);

  return;
}

Project: LibRaw
File: dcraw.c

void CLASS sinar_4shot_load_raw()
{
  ushort *pixel;
  unsigned shot, row, col, r, c;

  if (raw_image)
  {
    shot = LIM(shot_select, 1, 4) - 1;
    fseek(ifp, data_offset + shot * 4, SEEK_SET);
    fseek(ifp, get4(), SEEK_SET);
    unpacked_load_raw();
    return;
  }
  pixel = (ushort *)calloc(raw_width, sizeof *pixel);
  merror(pixel, "sinar_4shot_load_raw()");
#ifdef LIBRAW_LIBRARY_BUILD
  try
  {
#endif
    for (shot = 0; shot < 4; shot++)
    {
#ifdef LIBRAW_LIBRARY_BUILD
      checkCancel();
#endif
      fseek(ifp, data_offset + shot * 4, SEEK_SET);
      fseek(ifp, get4(), SEEK_SET);
      for (row = 0; row < raw_height; row++)
      {
        read_shorts(pixel, raw_width);
        if ((r = row - top_margin - (shot >> 1 & 1)) >= height)
          continue;
        for (col = 0; col < raw_width; col++)
        {
          if ((c = col - left_margin - (shot & 1)) >= width)
            continue;
          image[r * width + c][(row & 1) * 3 ^ (~col & 1)] = pixel[col];
        }
      }
    }
#ifdef LIBRAW_LIBRARY_BUILD
  }
  catch (...)
  {
    free(pixel);
    throw;
  }
#endif
  free(pixel);
  mix_green = 1;
}

Project: LibRaw
File: dcraw.c

void CLASS tiff_get(unsigned base, unsigned *tag, unsigned *type, unsigned *len, unsigned *save)
{
  *tag = get2();
  *type = get2();
  *len = get4();
  *save = ftell(ifp) + 4;
  if (*len * ("11124811248484"[*type < 14 ? *type : 0] - '0') > 4)
    fseek(ifp, get4() + base, SEEK_SET);
}

Project: LibRaw
File: dcraw.c

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]++;
      }
#ifdef LIBRAW_LIBRARY_BUILD
    if (load_raw == &LibRaw::nikon_load_sraw)
    {
      // Nikon sRAW: camera WB already applied:
      pre_mul[0] = pre_mul[1] = pre_mul[2] = pre_mul[3] = 1.0;
    }
    else
#endif
        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
    }
  }
#ifdef LIBRAW_LIBRARY_BUILD
  // Nikon sRAW, daylight
  if (load_raw == &LibRaw::nikon_load_sraw && !use_camera_wb && !use_auto_wb && cam_mul[0] > 0.001f &&
      cam_mul[1] > 0.001f && cam_mul[2] > 0.001f)
  {
    for (c = 0; c < 3; c++)
      pre_mul[c] /= cam_mul[c];
  }
#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[5] + 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 = ((ushort *)image)[i]))
      continue;
    if (cblack[4] && cblack[5])
      val -= cblack[6 + i / 4 / iwidth % cblack[4] * cblack[5] + i / 4 % iwidth % cblack[5]];
    val -= cblack[i & 3];
    val *= scale_mul[i & 3];
    ((ushort *)image)[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
}

Project: LibRaw
File: dcraw.c

void CLASS panasonic_load_raw()
{
  int row, col, i, j, sh = 0, pred[2], nonz[2];

  pana_bits(0);
  for (row = 0; row < raw_height; row++)
  {
#ifdef LIBRAW_LIBRARY_BUILD
    checkCancel();
#endif
    for (col = 0; col < raw_width; col++)
    {
      if ((i = col % 14) == 0)
        pred[0] = pred[1] = nonz[0] = nonz[1] = 0;
      if (i % 3 == 2)
        sh = 4 >> (3 - pana_bits(2));
      if (nonz[i & 1])
      {
        if ((j = pana_bits(8)))
        {
          if ((pred[i & 1] -= 0x80 << sh) < 0 || sh == 4)
            pred[i & 1] &= ~((~0u) << sh);
          pred[i & 1] += j << sh;
        }
      }
      else if ((nonz[i & 1] = pana_bits(8)) || i > 11)
        pred[i & 1] = nonz[i & 1] << 4 | pana_bits(4);
      if ((RAW(row, col) = pred[col & 1]) > 4098 && col < width && row < height)
        derror();
    }
  }
}

Project: LibRaw
File: dcraw.c

void CLASS PentaxLensInfo(unsigned id, unsigned len) // tag 0x0207
{
  ushort iLensData = 0;
  uchar *table_buf;
  table_buf = (uchar *)malloc(MAX(len, 128));
  fread(table_buf, len, 1, ifp);
  if ((id < 0x12b9c) || (((id == 0x12b9c) ||  // K100D
                          (id == 0x12b9d) ||  // K110D
                          (id == 0x12ba2)) && // K100D Super
                         ((!table_buf[20] || (table_buf[20] == 0xff)))))
  {
    iLensData = 3;
    if (imgdata.lens.makernotes.LensID == -1)
      imgdata.lens.makernotes.LensID = (((unsigned)table_buf[0]) << 8) + table_buf[1];
  }
  else
    switch (len)
    {
    case 90: // LensInfo3
      iLensData = 13;
      if (imgdata.lens.makernotes.LensID == -1)
        imgdata.lens.makernotes.LensID = ((unsigned)((table_buf[1] & 0x0f) + table_buf[3]) << 8) + table_buf[4];
      break;
    case 91: // LensInfo4
      iLensData = 12;
      if (imgdata.lens.makernotes.LensID == -1)
        imgdata.lens.makernotes.LensID = ((unsigned)((table_buf[1] & 0x0f) + table_buf[3]) << 8) + table_buf[4];
      break;
    case 80: // LensInfo5
    case 128:
      iLensData = 15;
      if (imgdata.lens.makernotes.LensID == -1)
        imgdata.lens.makernotes.LensID = ((unsigned)((table_buf[1] & 0x0f) + table_buf[4]) << 8) + table_buf[5];
      break;
    default:
      if (id >= 0x12b9c) // LensInfo2
      {
        iLensData = 4;
        if (imgdata.lens.makernotes.LensID == -1)
          imgdata.lens.makernotes.LensID = ((unsigned)((table_buf[0] & 0x0f) + table_buf[2]) << 8) + table_buf[3];
      }
    }
  if (iLensData)
  {
    if (table_buf[iLensData + 9] && (fabs(imgdata.lens.makernotes.CurFocal) < 0.1f))
      imgdata.lens.makernotes.CurFocal =
          10 * (table_buf[iLensData + 9] >> 2) * powf64(4, (table_buf[iLensData + 9] & 0x03) - 2);
    if (table_buf[iLensData + 10] & 0xf0)
      imgdata.lens.makernotes.MaxAp4CurFocal = powf64(2.0f, (float)((table_buf[iLensData + 10] & 0xf0) >> 4) / 4.0f);
    if (table_buf[iLensData + 10] & 0x0f)
      imgdata.lens.makernotes.MinAp4CurFocal = powf64(2.0f, (float)((table_buf[iLensData + 10] & 0x0f) + 10) / 4.0f);

    if (iLensData != 12)
    {
      switch (table_buf[iLensData] & 0x06)
      {
      case 0:
        imgdata.lens.makernotes.MinAp4MinFocal = 22.0f;
        break;
      case 2:
        imgdata.lens.makernotes.MinAp4MinFocal = 32.0f;
        break;
      case 4:
        imgdata.lens.makernotes.MinAp4MinFocal = 45.0f;
        break;
      case 6:
        imgdata.lens.makernotes.MinAp4MinFocal = 16.0f;
        break;
      }
      if (table_buf[iLensData] & 0x70)
        imgdata.lens.makernotes.LensFStops = ((float)(((table_buf[iLensData] & 0x70) >> 4) ^ 0x07)) / 2.0f + 5.0f;

      imgdata.lens.makernotes.MinFocusDistance = (float)(table_buf[iLensData + 3] & 0xf8);
      imgdata.lens.makernotes.FocusRangeIndex = (float)(table_buf[iLensData + 3] & 0x07);

      if ((table_buf[iLensData + 14] > 1) && (fabs(imgdata.lens.makernotes.MaxAp4CurFocal) < 0.7f))
        imgdata.lens.makernotes.MaxAp4CurFocal = powf64(2.0f, (float)((table_buf[iLensData + 14] & 0x7f) - 1) / 32.0f);
    }
    else if ((id != 0x12e76) && // K-5
             (table_buf[iLensData + 15] > 1) && (fabs(imgdata.lens.makernotes.MaxAp4CurFocal) < 0.7f))
    {
      imgdata.lens.makernotes.MaxAp4CurFocal = powf64(2.0f, (float)((table_buf[iLensData + 15] & 0x7f) - 1) / 32.0f);
    }
  }
  free(table_buf);
  return;
}

Project: LibRaw
File: dcraw.c

void CLASS parse_gps(int base)
{
  unsigned entries, tag, type, len, save, c;

  entries = get2();
  while (entries--)
  {
    tiff_get(base, &tag, &type, &len, &save);
    if (len > 1024)
      continue; // no GPS tags are 1k or larger
    switch (tag)
    {
    case 1:
    case 3:
    case 5:
      gpsdata[29 + tag / 2] = getc(ifp);
      break;
    case 2:
    case 4:
    case 7:
      FORC(6) gpsdata[tag / 3 * 6 + c] = get4();
      break;
    case 6:
      FORC(2) gpsdata[18 + c] = get4();
      break;
    case 18:
    case 29:
      fgets((char *)(gpsdata + 14 + tag / 3), MIN(len, 12), ifp);
    }
    fseek(ifp, save, SEEK_SET);
  }
}

Project: LibRaw
File: dcraw.c

void CLASS packed_load_raw()
{
  int vbits = 0, bwide, rbits, bite, half, irow, row, col, val, i;
  UINT64 bitbuf = 0;

  bwide = raw_width * tiff_bps / 8;
  bwide += bwide & load_flags >> 7;
  rbits = bwide * 8 - raw_width * tiff_bps;
  if (load_flags & 1)
    bwide = bwide * 16 / 15;
  bite = 8 + (load_flags & 24);
  half = (raw_height + 1) >> 1;
  for (irow = 0; irow < raw_height; irow++)
  {
#ifdef LIBRAW_LIBRARY_BUILD
    checkCancel();
#endif
    row = irow;
    if (load_flags & 2 && (row = irow % half * 2 + irow / half) == 1 && load_flags & 4)
    {
      if (vbits = 0, tiff_compress)
        fseek(ifp, data_offset - (-half * bwide & -2048), SEEK_SET);
      else
      {
        fseek(ifp, 0, SEEK_END);
        fseek(ifp, ftell(ifp) >> 3 << 2, SEEK_SET);
      }
    }
    for (col = 0; col < raw_width; col++)
    {
      for (vbits -= tiff_bps; vbits < 0; vbits += bite)
      {
        bitbuf <<= bite;
        for (i = 0; i < bite; i += 8)
          bitbuf |= (unsigned)(fgetc(ifp) << i);
      }
      val = bitbuf << (64 - tiff_bps - vbits) >> (64 - tiff_bps);
      RAW(row, col ^ (load_flags >> 6 & 1)) = val;
      if (load_flags & 1 && (col % 10) == 9 && fgetc(ifp) && row < height + top_margin && col < width + left_margin)
        derror();
    }
    vbits -= rbits;
  }
}

Project: LibRaw
File: dcraw.c

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 *cbuf, *cp;
  uchar cfa_pat[16], cfa_pc[] = {0, 1, 2, 3}, tab[256];
  double fm[3][4], 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;
  int pana_raw = 0;
#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;
#ifdef LIBRAW_LIBRARY_BUILD
  INT64 fsize = ifp->size();
#endif
  while (entries--)
  {
    tiff_get(base, &tag, &type, &len, &save);
#ifdef LIBRAW_LIBRARY_BUILD
    INT64 savepos = ftell(ifp);
    if (len > 8 && len + savepos > fsize * 2)
      continue; // skip tag pointing out of 2xfile
    if (callbacks.exif_cb)
    {
      callbacks.exif_cb(callbacks.exifparser_data, tag | (pana_raw ? 0x30000 : 0), type, len, order, ifp);
      fseek(ifp, savepos, SEEK_SET);
    }
#endif

#ifdef LIBRAW_LIBRARY_BUILD
    if (!strncasecmp(make, "SONY", 4) ||
        (!strncasecmp(make, "Hasselblad", 10) &&
         (!strncasecmp(model, "Stellar", 7) ||
          !strncasecmp(model, "Lunar", 5) ||
          !strncasecmp(model, "HV", 2))))
    {
      switch (tag)
      {
      case 0x7300: // SR2 black level
        for (int i = 0; i < 4 && i < len; i++)
          cblack[i] = get2();
        break;
      case 0x7302:
        FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_Auto][c ^ (c < 2)] = get2();
        break;
      case 0x7312:
      {
        int i, lc[4];
        FORC4 lc[c] = get2();
        i = (lc[1] == 1024 && lc[2] == 1024) << 1;
        SWAP(lc[i], lc[i + 1]);
        FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_Auto][c] = lc[c];
      }
      break;
      case 0x7480:
      case 0x7820:
        FORC3 imgdata.color.WB_Coeffs[LIBRAW_WBI_Daylight][c] = get2();
        imgdata.color.WB_Coeffs[LIBRAW_WBI_Daylight][3] = imgdata.color.WB_Coeffs[LIBRAW_WBI_Daylight][1];
        break;
      case 0x7481:
      case 0x7821:
        FORC3 imgdata.color.WB_Coeffs[LIBRAW_WBI_Cloudy][c] = get2();
        imgdata.color.WB_Coeffs[LIBRAW_WBI_Cloudy][3] = imgdata.color.WB_Coeffs[LIBRAW_WBI_Cloudy][1];
        break;
      case 0x7482:
      case 0x7822:
        FORC3 imgdata.color.WB_Coeffs[LIBRAW_WBI_Tungsten][c] = get2();
        imgdata.color.WB_Coeffs[LIBRAW_WBI_Tungsten][3] = imgdata.color.WB_Coeffs[LIBRAW_WBI_Tungsten][1];
        break;
      case 0x7483:
      case 0x7823:
        FORC3 imgdata.color.WB_Coeffs[LIBRAW_WBI_Flash][c] = get2();
        imgdata.color.WB_Coeffs[LIBRAW_WBI_Flash][3] = imgdata.color.WB_Coeffs[LIBRAW_WBI_Flash][1];
        break;
      case 0x7484:
      case 0x7824:
        imgdata.color.WBCT_Coeffs[0][0] = 4500;
        FORC3 imgdata.color.WBCT_Coeffs[0][c + 1] = get2();
        imgdata.color.WBCT_Coeffs[0][4] = imgdata.color.WBCT_Coeffs[0][2];
        break;
      case 0x7486:
        FORC3 imgdata.color.WB_Coeffs[LIBRAW_WBI_Fluorescent][c] = get2();
        imgdata.color.WB_Coeffs[LIBRAW_WBI_Fluorescent][3] = imgdata.color.WB_Coeffs[LIBRAW_WBI_Fluorescent][1];
        break;
      case 0x7825:
        FORC3 imgdata.color.WB_Coeffs[LIBRAW_WBI_Shade][c] = get2();
        imgdata.color.WB_Coeffs[LIBRAW_WBI_Shade][3] = imgdata.color.WB_Coeffs[LIBRAW_WBI_Shade][1];
        break;
      case 0x7826:
        FORC3 imgdata.color.WB_Coeffs[LIBRAW_WBI_FL_W][c] = get2();
        imgdata.color.WB_Coeffs[LIBRAW_WBI_FL_W][3] = imgdata.color.WB_Coeffs[LIBRAW_WBI_FL_W][1];
        break;
      case 0x7827:
        FORC3 imgdata.color.WB_Coeffs[LIBRAW_WBI_FL_N][c] = get2();
        imgdata.color.WB_Coeffs[LIBRAW_WBI_FL_N][3] = imgdata.color.WB_Coeffs[LIBRAW_WBI_FL_N][1];
        break;
      case 0x7828:
        FORC3 imgdata.color.WB_Coeffs[LIBRAW_WBI_FL_D][c] = get2();
        imgdata.color.WB_Coeffs[LIBRAW_WBI_FL_D][3] = imgdata.color.WB_Coeffs[LIBRAW_WBI_FL_D][1];
        break;
      case 0x7829:
        FORC3 imgdata.color.WB_Coeffs[LIBRAW_WBI_FL_L][c] = get2();
        imgdata.color.WB_Coeffs[LIBRAW_WBI_FL_L][3] = imgdata.color.WB_Coeffs[LIBRAW_WBI_FL_L][1];
        break;
      case 0x782a:
        imgdata.color.WBCT_Coeffs[1][0] = 8500;
        FORC3 imgdata.color.WBCT_Coeffs[1][c + 1] = get2();
        imgdata.color.WBCT_Coeffs[1][4] = imgdata.color.WBCT_Coeffs[1][2];
        break;
      case 0x782b:
        imgdata.color.WBCT_Coeffs[2][0] = 6000;
        FORC3 imgdata.color.WBCT_Coeffs[2][c + 1] = get2();
        imgdata.color.WBCT_Coeffs[2][4] = imgdata.color.WBCT_Coeffs[2][2];
        break;
      case 0x782c:
        imgdata.color.WBCT_Coeffs[3][0] = 3200;
        FORC3 imgdata.color.WB_Coeffs[LIBRAW_WBI_StudioTungsten][c] = imgdata.color.WBCT_Coeffs[3][c + 1] = get2();
        imgdata.color.WB_Coeffs[LIBRAW_WBI_StudioTungsten][3] = imgdata.color.WBCT_Coeffs[3][4] =
            imgdata.color.WB_Coeffs[LIBRAW_WBI_StudioTungsten][1];
        break;
      case 0x782d:
        imgdata.color.WBCT_Coeffs[4][0] = 2500;
        FORC3 imgdata.color.WBCT_Coeffs[4][c + 1] = get2();
        imgdata.color.WBCT_Coeffs[4][4] = imgdata.color.WBCT_Coeffs[4][2];
        break;
      case 0x787f:
        FORC3 imgdata.color.linear_max[c] = get2();
        imgdata.color.linear_max[3] = imgdata.color.linear_max[1];
        break;
      }
    }
#endif

    switch (tag)
    {
    case 1:
      if (len == 4)
        pana_raw = get4();
      break;
    case 5:
      width = get2();
      break;
    case 6:
      height = get2();
      break;
    case 7:
      width += get2();
      break;
    case 9:
      if ((i = get2()))
        filters = i;
#ifdef LIBRAW_LIBRARY_BUILD
      if (pana_raw && len == 1 && type == 3)
        pana_black[3] += i;
#endif
      break;
    case 8:
    case 10:
#ifdef LIBRAW_LIBRARY_BUILD
      if (pana_raw && len == 1 && type == 3)
        pana_black[3] += get2();
#endif
      break;
    case 14:
    case 15:
    case 16:
#ifdef LIBRAW_LIBRARY_BUILD
      if (pana_raw)
      {
        imgdata.color.linear_max[tag - 14] = get2();
        if (tag == 15)
          imgdata.color.linear_max[3] = imgdata.color.linear_max[1];
      }
#endif
      break;
    case 17:
    case 18:
      if (type == 3 && len == 1)
        cam_mul[(tag - 17) * 2] = get2() / 256.0;
      break;
#ifdef LIBRAW_LIBRARY_BUILD
    case 19:
      if (pana_raw)
      {
        ushort nWB, cnt, tWB;
        nWB = get2();
        if (nWB > 0x100)
          break;
        for (cnt = 0; cnt < nWB; cnt++)
        {
          tWB = get2();
          if (tWB < 0x100)
          {
            imgdata.color.WB_Coeffs[tWB][0] = get2();
            imgdata.color.WB_Coeffs[tWB][2] = get2();
            imgdata.color.WB_Coeffs[tWB][1] = imgdata.color.WB_Coeffs[tWB][3] = 0x100;
          }
          else
            get4();
        }
      }
      break;
#endif
    case 23:
      if (type == 3)
        iso_speed = get2();
      break;
    case 28:
    case 29:
    case 30:
#ifdef LIBRAW_LIBRARY_BUILD
      if (pana_raw && len == 1 && type == 3)
      {
        pana_black[tag - 28] = get2();
      }
      else
#endif
      {
        cblack[tag - 28] = get2();
        cblack[3] = cblack[1];
      }
      break;
    case 36:
    case 37:
    case 38:
      cam_mul[tag - 36] = get2();
      break;
    case 39:
#ifdef LIBRAW_LIBRARY_BUILD
      if (pana_raw)
      {
        ushort nWB, cnt, tWB;
        nWB = get2();
        if (nWB > 0x100)
          break;
        for (cnt = 0; cnt < nWB; cnt++)
        {
          tWB = get2();
          if (tWB < 0x100)
          {
            imgdata.color.WB_Coeffs[tWB][0] = get2();
            imgdata.color.WB_Coeffs[tWB][1] = imgdata.color.WB_Coeffs[tWB][3] = get2();
            imgdata.color.WB_Coeffs[tWB][2] = get2();
          }
          else
            fseek(ifp, 6, SEEK_CUR);
        }
      }
      break;
#endif
      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 */
      fseek(ifp, get4() + base, SEEK_SET);
      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);
      if (tiff_bps < tiff_ifd[ifd].bps)
        tiff_bps = tiff_ifd[ifd].bps;
      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;
#ifdef LIBRAW_LIBRARY_BUILD
    case 278:
      tiff_ifd[ifd].rows_per_strip = getint(type);
      break;
#endif
    case 280: /* Panasonic RW2 offset */
      if (type != 4)
        break;
      load_raw = &CLASS panasonic_load_raw;
      load_flags = 0x2008;
    case 273: /* StripOffset */
#ifdef LIBRAW_LIBRARY_BUILD
      if (len > 1 && len < 16384)
      {
        off_t sav = ftell(ifp);
        tiff_ifd[ifd].strip_offsets = (int *)calloc(len, sizeof(int));
        tiff_ifd[ifd].strip_offsets_count = len;
        for (int i = 0; i < len; i++)
          tiff_ifd[ifd].strip_offsets[i] = get4() + base;
        fseek(ifp, sav, SEEK_SET); // restore position
      }
/* fallback */
#endif
    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;
          if ((tiff_ifd[ifd].t_width > 4 * tiff_ifd[ifd].t_height) & ~jh.clrs)
          {
            tiff_ifd[ifd].t_width /= 2;
            tiff_ifd[ifd].t_height *= 2;
          }
          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 */
#ifdef LIBRAW_LIBRARY_BUILD
      if (len > 1 && len < 16384)
      {
        off_t sav = ftell(ifp);
        tiff_ifd[ifd].strip_byte_counts = (int *)calloc(len, sizeof(int));
        tiff_ifd[ifd].strip_byte_counts_count = len;
        for (int i = 0; i < len; i++)
          tiff_ifd[ifd].strip_byte_counts[i] = get4();
        fseek(ifp, sav, SEEK_SET); // restore position
      }
/* fallback */
#endif
    case 514:
    case 61448:
      tiff_ifd[ifd].bytes = get4();
      break;
    case 61454: // FujiFilm "As Shot"
      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) || !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 317:
      tiff_ifd[ifd].predictor = getint(type);
      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 == 1)
        tiff_ifd[ifd].t_tile_width = tiff_ifd[ifd].t_tile_length = 0;
      if (len == 4)
      {
        load_raw = &CLASS sinar_4shot_load_raw;
        is_raw = 5;
      }
      break;
    case 325:
      tiff_ifd[ifd].bytes = len > 1 ? ftell(ifp) : get4();
      break;
    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++;
#ifdef LIBRAW_LIBRARY_BUILD
        if (ifd >= sizeof tiff_ifd / sizeof tiff_ifd[0])
          throw LIBRAW_EXCEPTION_IO_CORRUPT;
#endif
        break;
      }
#ifdef LIBRAW_LIBRARY_BUILD
      if (!strncmp(make, "Hasselblad", 10) && libraw_internal_data.unpacker_data.hasselblad_parser_flag)
      {
        fseek(ifp, ftell(ifp) + 4, SEEK_SET);
        fseek(ifp, get4() + base, SEEK_SET);
        parse_tiff_ifd(base);
        break;
      }
#endif
      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 339:
      tiff_ifd[ifd].sample_format = getint(type);
      break;
    case 400:
      strcpy(make, "Sarnoff");
      maximum = 0xfff;
      break;
#ifdef LIBRAW_LIBRARY_BUILD
    case 700:
      if ((type == 1 || type == 2 || type == 6 || type == 7) && len > 1 && len < 5100000)
      {
        xmpdata = (char *)malloc(xmplen = len + 1);
        fread(xmpdata, len, 1, ifp);
        xmpdata[len] = 0;
      }
      break;
#endif
    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;
#ifdef LIBRAW_LIBRARY_BUILD
    case 30720: // Sony matrix, Sony_SR2SubIFD_0x7800
      for (i = 0; i < 3; i++)
      {
        float num = 0.0;
        for (c = 0; c < 3; c++)
        {
          imgdata.color.ccm[i][c] = (float)((short)get2());
          num += imgdata.color.ccm[i][c];
        }
        if (num > 0.01)
          FORC3 imgdata.color.ccm[i][c] = imgdata.color.ccm[i][c] / num;
      }
      break;
#endif
    case 29456: // Sony black level, Sony_SR2SubIFD_0x7310, no more needs to be divided by 4
      FORC4 cblack[c ^ c >> 1] = get2();
      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 33421: /* CFARepeatPatternDim */
      if (get2() == 6 && get2() == 6)
        filters = 9;
      break;
    case 33422: /* CFAPattern */
      if (filters == 9)
      {
        FORC(36)((char *)xtrans)[c] = fgetc(ifp) & 3;
        break;
      }
    case 64777: /* Kodak P-series */
      if (len == 36)
      {
        filters = 9;
        colors = 3;
        FORC(36) xtrans[0][c] = fgetc(ifp) & 3;
      }
      else if (len > 0)
      {
        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;
      }
      break;
    case 33424:
    case 65024:
      fseek(ifp, get4() + base, SEEK_SET);
      parse_kodak_ifd(base);
      break;
    case 33434: /* ExposureTime */
      tiff_ifd[ifd].t_shutter = shutter = getreal(type);
      break;
    case 33437: /* FNumber */
      aperture = getreal(type);
      break;
#ifdef LIBRAW_LIBRARY_BUILD
    // IB start
    case 0x9400:
      imgdata.other.exifAmbientTemperature = getreal(type);
      if ((imgdata.other.CameraTemperature > -273.15f) &&
          (OlyID == 0x4434353933ULL))  // TG-5
        imgdata.other.CameraTemperature += imgdata.other.exifAmbientTemperature;
      break;
    case 0x9401:
      imgdata.other.exifHumidity = getreal(type);
      break;
    case 0x9402:
      imgdata.other.exifPressure = getreal(type);
      break;
    case 0x9403:
      imgdata.other.exifWaterDepth = getreal(type);
      break;
    case 0x9404:
      imgdata.other.exifAcceleration = getreal(type);
      break;
    case 0x9405:
      imgdata.other.exifCameraElevationAngle = getreal(type);
      break;
    case 0xa405: // FocalLengthIn35mmFormat
      imgdata.lens.FocalLengthIn35mmFormat = get2();
      break;
    case 0xa431: // BodySerialNumber
    case 0xc62f:
      stmread(imgdata.shootinginfo.BodySerial, len, ifp);
      break;
    case 0xa432: // LensInfo, 42034dec, Lens Specification per EXIF standard
      imgdata.lens.MinFocal = getreal(type);
      imgdata.lens.MaxFocal = getreal(type);
      imgdata.lens.MaxAp4MinFocal = getreal(type);
      imgdata.lens.MaxAp4MaxFocal = getreal(type);
      break;
    case 0xa435: // LensSerialNumber
      stmread(imgdata.lens.LensSerial, len, ifp);
      break;
    case 0xc630: // DNG LensInfo, Lens Specification per EXIF standard
      imgdata.lens.MinFocal = getreal(type);
      imgdata.lens.MaxFocal = getreal(type);
      imgdata.lens.MaxAp4MinFocal = getreal(type);
      imgdata.lens.MaxAp4MaxFocal = getreal(type);
      break;
    case 0xa433: // LensMake
      stmread(imgdata.lens.LensMake, len, ifp);
      break;
    case 0xa434: // LensModel
      stmread(imgdata.lens.Lens, len, ifp);
      if (!strncmp(imgdata.lens.Lens, "----", 4))
        imgdata.lens.Lens[0] = 0;
      break;
    case 0x9205:
      imgdata.lens.EXIF_MaxAp = powf64(2.0f, (getreal(type) / 2.0f));
      break;
// IB end
#endif
    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] /= MAX(1, 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 */
    {
      unsigned pos;
      fseek(ifp, pos = (get4() + base), SEEK_SET);
      parse_gps(base);
#ifdef LIBRAW_LIBRARY_BUILD
      fseek(ifp, pos, SEEK_SET);
      parse_gps_libraw(base);
#endif
    }
    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();
      switch (tiff_ifd[ifd].comp)
      {
      case 32770:
        load_raw = &CLASS samsung_load_raw;
        break;
      case 32772:
        load_raw = &CLASS samsung2_load_raw;
        break;
      case 32773:
        load_raw = &CLASS samsung3_load_raw;
        break;
      }
      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 (len < 1 || len > 2560000 || !(cbuf = (char *)malloc(len)))
        break;
#ifndef LIBRAW_LIBRARY_BUILD
      fread(cbuf, 1, len, ifp);
#else
      if (fread(cbuf, 1, len, ifp) != len)
        throw LIBRAW_EXCEPTION_IO_CORRUPT; // cbuf to be free'ed in recycle
#endif
      cbuf[len - 1] = 0;
      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 */
#ifdef LIBRAW_LIBRARY_BUILD
      libraw_internal_data.unpacker_data.hasselblad_parser_flag = 1;
#endif
      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 50708: /* UniqueCameraModel */
#ifdef LIBRAW_LIBRARY_BUILD
      stmread(imgdata.color.UniqueCameraModel, len, ifp);
      imgdata.color.UniqueCameraModel[sizeof(imgdata.color.UniqueCameraModel) - 1] = 0;
#endif
      if (model[0])
        break;
#ifndef LIBRAW_LIBRARY_BUILD
      fgets(make, 64, ifp);
#else
      strncpy(make, imgdata.color.UniqueCameraModel, MIN(len, sizeof(imgdata.color.UniqueCameraModel)));
#endif
      if ((cp = strchr(make, ' ')))
      {
        strcpy(model, cp + 1);
        *cp = 0;
      }
      break;
    case 50710: /* CFAPlaneColor */
      if (filters == 9)
        break;
      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;
      break;
    case 291:
    case 50712: /* LinearizationTable */
#ifdef LIBRAW_LIBRARY_BUILD
      tiff_ifd[ifd].dng_levels.parsedfields |= LIBRAW_DNGFM_LINTABLE;
      tiff_ifd[ifd].lineartable_offset = ftell(ifp);
      tiff_ifd[ifd].lineartable_len = len;
#endif
      linear_table(len);
      break;
    case 50713: /* BlackLevelRepeatDim */
#ifdef LIBRAW_LIBRARY_BUILD
      tiff_ifd[ifd].dng_levels.parsedfields |= LIBRAW_DNGFM_BLACK;
      tiff_ifd[ifd].dng_levels.dng_cblack[4] =
#endif
          cblack[4] = get2();
#ifdef LIBRAW_LIBRARY_BUILD
      tiff_ifd[ifd].dng_levels.dng_cblack[5] =
#endif
          cblack[5] = get2();
      if (cblack[4] * cblack[5] > (sizeof(cblack) / sizeof(cblack[0]) - 6))
#ifdef LIBRAW_LIBRARY_BUILD
        tiff_ifd[ifd].dng_levels.dng_cblack[4] = tiff_ifd[ifd].dng_levels.dng_cblack[5] =
#endif
            cblack[4] = cblack[5] = 1;
      break;

#ifdef LIBRAW_LIBRARY_BUILD
    case 0xf00d:
      if (strcmp(model, "X-A3") && strcmp(model, "X-A10"))
      {
        FORC3 imgdata.color.WB_Coeffs[LIBRAW_WBI_Auto][(4 - c) % 3] = getint(type);
        imgdata.color.WB_Coeffs[LIBRAW_WBI_Auto][3] = imgdata.color.WB_Coeffs[LIBRAW_WBI_Auto][1];
      }
      break;
    case 0xf00c:
      if (strcmp(model, "X-A3") && strcmp(model, "X-A10"))
      {
        unsigned fwb[4];
        FORC4 fwb[c] = get4();
        if (fwb[3] < 0x100)
        {
          imgdata.color.WB_Coeffs[fwb[3]][0] = fwb[1];
          imgdata.color.WB_Coeffs[fwb[3]][1] = imgdata.color.WB_Coeffs[fwb[3]][3] = fwb[0];
          imgdata.color.WB_Coeffs[fwb[3]][2] = fwb[2];
          if ((fwb[3] == 17) && (libraw_internal_data.unpacker_data.lenRAFData > 3) &&
              (libraw_internal_data.unpacker_data.lenRAFData < 10240000))
          {
            INT64 f_save = ftell(ifp);
            ushort *rafdata = (ushort *)malloc(sizeof(ushort) * libraw_internal_data.unpacker_data.lenRAFData);
            fseek(ifp, libraw_internal_data.unpacker_data.posRAFData, SEEK_SET);
            fread(rafdata, sizeof(ushort), libraw_internal_data.unpacker_data.lenRAFData, ifp);
            fseek(ifp, f_save, SEEK_SET);
            int fj, found = 0;
            for (int fi = 0; fi < (libraw_internal_data.unpacker_data.lenRAFData - 3); fi++)
            {
              if ((fwb[0] == rafdata[fi]) && (fwb[1] == rafdata[fi + 1]) && (fwb[2] == rafdata[fi + 2]))
              {
                if (rafdata[fi - 15] != fwb[0])
                  continue;

                for (int wb_ind = 0, ofst = fi - 15; wb_ind < nFuji_wb_list1; wb_ind++, ofst += 3)
                {
                  imgdata.color.WB_Coeffs[Fuji_wb_list1[wb_ind]][1] =
                      imgdata.color.WB_Coeffs[Fuji_wb_list1[wb_ind]][3] = rafdata[ofst];
                  imgdata.color.WB_Coeffs[Fuji_wb_list1[wb_ind]][0] = rafdata[ofst + 1];
                  imgdata.color.WB_Coeffs[Fuji_wb_list1[wb_ind]][2] = rafdata[ofst + 2];
                }
                fi += 0x60;
                for (fj = fi; fj < (fi + 15); fj += 3)
                  if (rafdata[fj] != rafdata[fi])
                  {
                    found = 1;
                    break;
                  }
                if (found)
                {
                  fj = fj - 93;
                  for (int iCCT = 0; iCCT < 31; iCCT++)
                  {
                    imgdata.color.WBCT_Coeffs[iCCT][0] = FujiCCT_K[iCCT];
                    imgdata.color.WBCT_Coeffs[iCCT][1] = rafdata[iCCT * 3 + 1 + fj];
                    imgdata.color.WBCT_Coeffs[iCCT][2] = imgdata.color.WBCT_Coeffs[iCCT][4] = rafdata[iCCT * 3 + fj];
                    imgdata.color.WBCT_Coeffs[iCCT][3] = rafdata[iCCT * 3 + 2 + fj];
                  }
                }
                free(rafdata);
                break;
              }
            }
          }
        }
        FORC4 fwb[c] = get4();
        if (fwb[3] < 0x100)
        {
          imgdata.color.WB_Coeffs[fwb[3]][0] = fwb[1];
          imgdata.color.WB_Coeffs[fwb[3]][1] = imgdata.color.WB_Coeffs[fwb[3]][3] = fwb[0];
          imgdata.color.WB_Coeffs[fwb[3]][2] = fwb[2];
        }
      }
      break;
#endif

#ifdef LIBRAW_LIBRARY_BUILD
    case 50709:
      stmread(imgdata.color.LocalizedCameraModel, len, ifp);
      break;
#endif

    case 61450:
      cblack[4] = cblack[5] = MIN(sqrt((double)len), 64);
    case 50714: /* BlackLevel */
#ifdef LIBRAW_LIBRARY_BUILD
      if (tiff_ifd[ifd].samples > 1 && tiff_ifd[ifd].samples == len) // LinearDNG, per-channel black
      {
        tiff_ifd[ifd].dng_levels.parsedfields |= LIBRAW_DNGFM_BLACK;
        for (i = 0; i < colors && i < 4 && i < len; i++)
          tiff_ifd[ifd].dng_levels.dng_cblack[i] = cblack[i] = getreal(type) + 0.5;

        tiff_ifd[ifd].dng_levels.dng_black = black = 0;
      }
      else
#endif
          if ((cblack[4] * cblack[5] < 2) && len == 1)
      {
#ifdef LIBRAW_LIBRARY_BUILD
        tiff_ifd[ifd].dng_levels.parsedfields |= LIBRAW_DNGFM_BLACK;
        tiff_ifd[ifd].dng_levels.dng_black =
#endif
            black = getreal(type);
      }
      else if (cblack[4] * cblack[5] <= len)
      {
        FORC(cblack[4] * cblack[5])
        cblack[6 + c] = getreal(type);
        black = 0;
        FORC4
        cblack[c] = 0;

#ifdef LIBRAW_LIBRARY_BUILD
        if (tag == 50714)
        {
          tiff_ifd[ifd].dng_levels.parsedfields |= LIBRAW_DNGFM_BLACK;
          FORC(cblack[4] * cblack[5])
          tiff_ifd[ifd].dng_levels.dng_cblack[6 + c] = cblack[6 + c];
          tiff_ifd[ifd].dng_levels.dng_black = 0;
          FORC4
          tiff_ifd[ifd].dng_levels.dng_cblack[c] = 0;
        }
#endif
      }
      break;
    case 50715: /* BlackLevelDeltaH */
    case 50716: /* BlackLevelDeltaV */
      for (num = i = 0; i < len && i < 65536; i++)
        num += getreal(type);
      black += num / len + 0.5;
#ifdef LIBRAW_LIBRARY_BUILD
      tiff_ifd[ifd].dng_levels.dng_black += num / len + 0.5;
      tiff_ifd[ifd].dng_levels.parsedfields |= LIBRAW_DNGFM_BLACK;
#endif
      break;
    case 50717: /* WhiteLevel */
#ifdef LIBRAW_LIBRARY_BUILD
      tiff_ifd[ifd].dng_levels.parsedfields |= LIBRAW_DNGFM_WHITE;
      tiff_ifd[ifd].dng_levels.dng_whitelevel[0] =
#endif
          maximum = getint(type);
#ifdef LIBRAW_LIBRARY_BUILD
      if (tiff_ifd[ifd].samples > 1) // Linear DNG case
        for (i = 1; i < colors && i < 4 && i < len; i++)
          tiff_ifd[ifd].dng_levels.dng_whitelevel[i] = getint(type);
#endif
      break;
    case 50718: /* DefaultScale */
      pixel_aspect = getreal(type);
      pixel_aspect /= getreal(type);
      if (pixel_aspect > 0.995 && pixel_aspect < 1.005)
        pixel_aspect = 1.0;
      break;
#ifdef LIBRAW_LIBRARY_BUILD
    case 50719: /* DefaultCropOrigin */
      if (len == 2)
      {
        tiff_ifd[ifd].dng_levels.parsedfields |= LIBRAW_DNGFM_CROPORIGIN;
        tiff_ifd[ifd].dng_levels.default_crop[0] = getreal(type);
        tiff_ifd[ifd].dng_levels.default_crop[1] = getreal(type);
      }
      break;
    case 50720: /* DefaultCropSize */
      if (len == 2)
      {
        tiff_ifd[ifd].dng_levels.parsedfields |= LIBRAW_DNGFM_CROPSIZE;
        tiff_ifd[ifd].dng_levels.default_crop[2] = getreal(type);
        tiff_ifd[ifd].dng_levels.default_crop[3] = getreal(type);
      }
      break;
#endif
#ifdef LIBRAW_LIBRARY_BUILD
    case 50778:
      tiff_ifd[ifd].dng_color[0].illuminant = get2();
      tiff_ifd[ifd].dng_color[0].parsedfields |= LIBRAW_DNGFM_ILLUMINANT;
      break;
    case 50779:
      tiff_ifd[ifd].dng_color[1].illuminant = get2();
      tiff_ifd[ifd].dng_color[1].parsedfields |= LIBRAW_DNGFM_ILLUMINANT;
      break;
#endif
    case 50721: /* ColorMatrix1 */
    case 50722: /* ColorMatrix2 */
#ifdef LIBRAW_LIBRARY_BUILD
      i = tag == 50721 ? 0 : 1;
      tiff_ifd[ifd].dng_color[i].parsedfields |= LIBRAW_DNGFM_COLORMATRIX;
#endif
      FORCC for (j = 0; j < 3; j++)
      {
#ifdef LIBRAW_LIBRARY_BUILD
        tiff_ifd[ifd].dng_color[i].colormatrix[c][j] =
#endif
            cm[c][j] = getreal(type);
      }
      use_cm = 1;
      break;

    case 0xc714: /* ForwardMatrix1 */
    case 0xc715: /* ForwardMatrix2 */
#ifdef LIBRAW_LIBRARY_BUILD
      i = tag == 0xc714 ? 0 : 1;
      tiff_ifd[ifd].dng_color[i].parsedfields |= LIBRAW_DNGFM_FORWARDMATRIX;
#endif
      for (j = 0; j < 3; j++)
        FORCC
        {
#ifdef LIBRAW_LIBRARY_BUILD
          tiff_ifd[ifd].dng_color[i].forwardmatrix[j][c] =
#endif
              fm[j][c] = getreal(type);
        }
      break;

    case 50723: /* CameraCalibration1 */
    case 50724: /* CameraCalibration2 */
#ifdef LIBRAW_LIBRARY_BUILD
      j = tag == 50723 ? 0 : 1;
      tiff_ifd[ifd].dng_color[j].parsedfields |= LIBRAW_DNGFM_CALIBRATION;
#endif
      for (i = 0; i < colors; i++)
        FORCC
        {
#ifdef LIBRAW_LIBRARY_BUILD
          tiff_ifd[ifd].dng_color[j].calibration[i][c] =
#endif
              cc[i][c] = getreal(type);
        }
      break;
    case 50727: /* AnalogBalance */
#ifdef LIBRAW_LIBRARY_BUILD
      tiff_ifd[ifd].dng_levels.parsedfields |= LIBRAW_DNGFM_ANALOGBALANCE;
#endif
      FORCC
      {
#ifdef LIBRAW_LIBRARY_BUILD
        tiff_ifd[ifd].dng_levels.analogbalance[c] =
#endif
            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;
#ifdef LIBRAW_LIBRARY_BUILD
    case 50730: /* DNG: Baseline Exposure */
      baseline_exposure = getreal(type);
      break;
#endif
    // IB start
    case 50740: /* tag 0xc634 : DNG Adobe, DNG Pentax, Sony SR2, DNG Private */
#ifdef LIBRAW_LIBRARY_BUILD
    {
      char mbuf[64];
      unsigned short makernote_found = 0;
      INT64 curr_pos, start_pos = ftell(ifp);
      unsigned MakN_order, m_sorder = order;
      unsigned MakN_length;
      unsigned pos_in_original_raw;
      fread(mbuf, 1, 6, ifp);

      if (!strcmp(mbuf, "Adobe"))
      {
        order = 0x4d4d; // Adobe header is always in "MM" / big endian
        curr_pos = start_pos + 6;
        while (curr_pos + 8 - start_pos <= len)
        {
          fread(mbuf, 1, 4, ifp);
          curr_pos += 8;
          if (!strncmp(mbuf, "MakN", 4))
          {
            makernote_found = 1;
            MakN_length = get4();
            MakN_order = get2();
            pos_in_original_raw = get4();
            order = MakN_order;
            parse_makernote_0xc634(curr_pos + 6 - pos_in_original_raw, 0, AdobeDNG);
            break;
          }
        }
      }
      else
      {
        fread(mbuf + 6, 1, 2, ifp);
        if (!strcmp(mbuf, "PENTAX ") || !strcmp(mbuf, "SAMSUNG"))
        {
          makernote_found = 1;
          fseek(ifp, start_pos, SEEK_SET);
          parse_makernote_0xc634(base, 0, CameraDNG);
        }
      }

      fseek(ifp, start_pos, SEEK_SET);
      order = m_sorder;
    }
// IB end
#endif
      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++)
        ((int *)mask)[i] = getint(type);
      black = 0;
      break;
#ifdef LIBRAW_LIBRARY_BUILD
    case 50970: /* PreviewColorSpace */
      tiff_ifd[ifd].dng_levels.parsedfields |= LIBRAW_DNGFM_PREVIEWCS;
      tiff_ifd[ifd].dng_levels.preview_colorspace = getint(type);
      break;
#endif
    case 51009: /* OpcodeList2 */
#ifdef LIBRAW_LIBRARY_BUILD
      tiff_ifd[ifd].dng_levels.parsedfields |= LIBRAW_DNGFM_OPCODE2;
      tiff_ifd[ifd].opcode2_offset =
#endif
          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 && sony_length < 10240000 && (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: dcraw.c

static float _CanonConvertAperture(ushort in)
{
  if ((in == (ushort)0xffe0) || (in == (ushort)0x7fff))
    return 0.0f;
  return powf64(2.0, in / 64.0);
}

Project: LibRaw
File: dcraw.c

void CLASS parse_minolta(int base)
{
  int save, tag, len, offset, high = 0, wide = 0, i, c;
  short sorder = order;

  fseek(ifp, base, SEEK_SET);
  if (fgetc(ifp) || fgetc(ifp) - 'M' || fgetc(ifp) - 'R')
    return;
  order = fgetc(ifp) * 0x101;
  offset = base + get4() + 8;
  while ((save = ftell(ifp)) < offset)
  {
    for (tag = i = 0; i < 4; i++)
      tag = tag << 8 | fgetc(ifp);
    len = get4();
    switch (tag)
    {
    case 0x505244: /* PRD */
      fseek(ifp, 8, SEEK_CUR);
      high = get2();
      wide = get2();
      break;
#ifdef LIBRAW_LIBRARY_BUILD
    case 0x524946: /* RIF */
      if (!strncasecmp(model, "DSLR-A100", 9))
      {
        fseek(ifp, 8, SEEK_CUR);
        imgdata.color.WB_Coeffs[LIBRAW_WBI_Tungsten][0] = get2();
        imgdata.color.WB_Coeffs[LIBRAW_WBI_Tungsten][2] = get2();
        imgdata.color.WB_Coeffs[LIBRAW_WBI_Daylight][0] = get2();
        imgdata.color.WB_Coeffs[LIBRAW_WBI_Daylight][2] = get2();
        imgdata.color.WB_Coeffs[LIBRAW_WBI_Cloudy][0] = get2();
        imgdata.color.WB_Coeffs[LIBRAW_WBI_Cloudy][2] = get2();
        imgdata.color.WB_Coeffs[LIBRAW_WBI_FL_W][0] = get2();
        imgdata.color.WB_Coeffs[LIBRAW_WBI_FL_W][2] = get2();
        imgdata.color.WB_Coeffs[LIBRAW_WBI_Flash][0] = get2();
        imgdata.color.WB_Coeffs[LIBRAW_WBI_Flash][2] = get2();
        get4();
        imgdata.color.WB_Coeffs[LIBRAW_WBI_Shade][0] = get2();
        imgdata.color.WB_Coeffs[LIBRAW_WBI_Shade][2] = get2();
        imgdata.color.WB_Coeffs[LIBRAW_WBI_FL_D][0] = get2();
        imgdata.color.WB_Coeffs[LIBRAW_WBI_FL_D][2] = get2();
        imgdata.color.WB_Coeffs[LIBRAW_WBI_FL_N][0] = get2();
        imgdata.color.WB_Coeffs[LIBRAW_WBI_FL_N][2] = get2();
        imgdata.color.WB_Coeffs[LIBRAW_WBI_FL_WW][0] = get2();
        imgdata.color.WB_Coeffs[LIBRAW_WBI_FL_WW][2] = get2();
        imgdata.color.WB_Coeffs[LIBRAW_WBI_Daylight][1] =
        imgdata.color.WB_Coeffs[LIBRAW_WBI_Daylight][3] =
        imgdata.color.WB_Coeffs[LIBRAW_WBI_Tungsten][1] =
        imgdata.color.WB_Coeffs[LIBRAW_WBI_Tungsten][3] =
        imgdata.color.WB_Coeffs[LIBRAW_WBI_Flash][1] =
        imgdata.color.WB_Coeffs[LIBRAW_WBI_Flash][3] =
        imgdata.color.WB_Coeffs[LIBRAW_WBI_Cloudy][1] =
        imgdata.color.WB_Coeffs[LIBRAW_WBI_Cloudy][3] =
        imgdata.color.WB_Coeffs[LIBRAW_WBI_Shade][1] =
        imgdata.color.WB_Coeffs[LIBRAW_WBI_Shade][3] =
        imgdata.color.WB_Coeffs[LIBRAW_WBI_FL_D][1] =
        imgdata.color.WB_Coeffs[LIBRAW_WBI_FL_D][3] =
        imgdata.color.WB_Coeffs[LIBRAW_WBI_FL_N][1] =
        imgdata.color.WB_Coeffs[LIBRAW_WBI_FL_N][3] =
        imgdata.color.WB_Coeffs[LIBRAW_WBI_FL_W][1] =
        imgdata.color.WB_Coeffs[LIBRAW_WBI_FL_W][3] =
        imgdata.color.WB_Coeffs[LIBRAW_WBI_FL_WW][1] =
        imgdata.color.WB_Coeffs[LIBRAW_WBI_FL_WW][3] = 0x100;
      }
      break;
#endif
    case 0x574247: /* WBG */
      get4();
      i = strcmp(model, "DiMAGE A200") ? 0 : 3;
      FORC4 cam_mul[c ^ (c >> 1) ^ i] = get2();
      break;
    case 0x545457: /* TTW */
      parse_tiff(ftell(ifp));
      data_offset = offset;
    }
    fseek(ifp, save + len + 8, SEEK_SET);
  }
  raw_height = high;
  raw_width = wide;
  order = sorder;
}

Project: LibRaw
File: dcraw.c

void CLASS parse_phase_one(int base)
{
  unsigned entries, tag, type, len, data, save, i, c;
  float romm_cam[3][3];
  char *cp;

  memset(&ph1, 0, sizeof ph1);
  fseek(ifp, base, SEEK_SET);
  order = get4() & 0xffff;
  if (get4() >> 8 != 0x526177)
    return; /* "Raw" */
  fseek(ifp, get4() + base, SEEK_SET);
  entries = get4();
  get4();
  while (entries--)
  {
    tag = get4();
    type = get4();
    len = get4();
    data = get4();
    save = ftell(ifp);
    fseek(ifp, base + data, SEEK_SET);
    switch (tag)
    {

#ifdef LIBRAW_LIBRARY_BUILD
    case 0x0102:
      stmread(imgdata.shootinginfo.BodySerial, len, ifp);
      if ((imgdata.shootinginfo.BodySerial[0] == 0x4c) && (imgdata.shootinginfo.BodySerial[1] == 0x49))
      {
        unique_id =
            (((imgdata.shootinginfo.BodySerial[0] & 0x3f) << 5) | (imgdata.shootinginfo.BodySerial[2] & 0x3f)) - 0x41;
      }
      else
      {
        unique_id =
            (((imgdata.shootinginfo.BodySerial[0] & 0x3f) << 5) | (imgdata.shootinginfo.BodySerial[1] & 0x3f)) - 0x41;
      }
      setPhaseOneFeatures(unique_id);
      break;
    case 0x0211:
      imgdata.other.SensorTemperature2 = int_to_float(data);
      break;
    case 0x0401:
      if (type == 4)
        imgdata.lens.makernotes.CurAp = powf64(2.0f, (int_to_float(data) / 2.0f));
      else
        imgdata.lens.makernotes.CurAp = powf64(2.0f, (getreal(type) / 2.0f));
      break;
    case 0x0403:
      if (type == 4)
        imgdata.lens.makernotes.CurFocal = int_to_float(data);
      else
        imgdata.lens.makernotes.CurFocal = getreal(type);
      break;
    case 0x0410:
      stmread(imgdata.lens.makernotes.body, len, ifp);
      break;
    case 0x0412:
      stmread(imgdata.lens.makernotes.Lens, len, ifp);
      break;
    case 0x0414:
      if (type == 4)
      {
        imgdata.lens.makernotes.MaxAp4CurFocal = powf64(2.0f, (int_to_float(data) / 2.0f));
      }
      else
      {
        imgdata.lens.makernotes.MaxAp4CurFocal = powf64(2.0f, (getreal(type) / 2.0f));
      }
      break;
    case 0x0415:
      if (type == 4)
      {
        imgdata.lens.makernotes.MinAp4CurFocal = powf64(2.0f, (int_to_float(data) / 2.0f));
      }
      else
      {
        imgdata.lens.makernotes.MinAp4CurFocal = powf64(2.0f, (getreal(type) / 2.0f));
      }
      break;
    case 0x0416:
      if (type == 4)
      {
        imgdata.lens.makernotes.MinFocal = int_to_float(data);
      }
      else
      {
        imgdata.lens.makernotes.MinFocal = getreal(type);
      }
      if (imgdata.lens.makernotes.MinFocal > 1000.0f)
      {
        imgdata.lens.makernotes.MinFocal = 0.0f;
      }
      break;
    case 0x0417:
      if (type == 4)
      {
        imgdata.lens.makernotes.MaxFocal = int_to_float(data);
      }
      else
      {
        imgdata.lens.makernotes.MaxFocal = getreal(type);
      }
      break;
#endif

    case 0x100:
      flip = "0653"[data & 3] - '0';
      break;
    case 0x106:
      for (i = 0; i < 9; i++)
#ifdef LIBRAW_LIBRARY_BUILD
        imgdata.color.P1_color[0].romm_cam[i] =
#endif
            ((float *)romm_cam)[i] = getreal(11);
      romm_coeff(romm_cam);
      break;
    case 0x107:
      FORC3 cam_mul[c] = getreal(11);
      break;
    case 0x108:
      raw_width = data;
      break;
    case 0x109:
      raw_height = data;
      break;
    case 0x10a:
      left_margin = data;
      break;
    case 0x10b:
      top_margin = data;
      break;
    case 0x10c:
      width = data;
      break;
    case 0x10d:
      height = data;
      break;
    case 0x10e:
      ph1.format = data;
      break;
    case 0x10f:
      data_offset = data + base;
      break;
    case 0x110:
      meta_offset = data + base;
      meta_length = len;
      break;
    case 0x112:
      ph1.key_off = save - 4;
      break;
    case 0x210:
      ph1.tag_210 = int_to_float(data);
#ifdef LIBRAW_LIBRARY_BUILD
      imgdata.other.SensorTemperature = ph1.tag_210;
#endif
      break;
    case 0x21a:
      ph1.tag_21a = data;
      break;
    case 0x21c:
      strip_offset = data + base;
      break;
    case 0x21d:
      ph1.t_black = data;
      break;
    case 0x222:
      ph1.split_col = data;
      break;
    case 0x223:
      ph1.black_col = data + base;
      break;
    case 0x224:
      ph1.split_row = data;
      break;
    case 0x225:
      ph1.black_row = data + base;
      break;
#ifdef LIBRAW_LIBRARY_BUILD
    case 0x226:
      for (i = 0; i < 9; i++)
        imgdata.color.P1_color[1].romm_cam[i] = getreal(11);
      break;
#endif
    case 0x301:
      model[63] = 0;
      fread(model, 1, 63, ifp);
      if ((cp = strstr(model, " camera")))
        *cp = 0;
    }
    fseek(ifp, save, SEEK_SET);
  }

#ifdef LIBRAW_LIBRARY_BUILD
  if (!imgdata.lens.makernotes.body[0] && !imgdata.shootinginfo.BodySerial[0])
  {
    fseek(ifp, meta_offset, SEEK_SET);
    order = get2();
    fseek(ifp, 6, SEEK_CUR);
    fseek(ifp, meta_offset + get4(), SEEK_SET);
    entries = get4();
    get4();
    while (entries--)
    {
      tag = get4();
      len = get4();
      data = get4();
      save = ftell(ifp);
      fseek(ifp, meta_offset + data, SEEK_SET);
      if (tag == 0x0407)
      {
        stmread(imgdata.shootinginfo.BodySerial, len, ifp);
        if ((imgdata.shootinginfo.BodySerial[0] == 0x4c) && (imgdata.shootinginfo.BodySerial[1] == 0x49))
        {
          unique_id =
              (((imgdata.shootinginfo.BodySerial[0] & 0x3f) << 5) | (imgdata.shootinginfo.BodySerial[2] & 0x3f)) - 0x41;
        }
        else
        {
          unique_id =
              (((imgdata.shootinginfo.BodySerial[0] & 0x3f) << 5) | (imgdata.shootinginfo.BodySerial[1] & 0x3f)) - 0x41;
        }
        setPhaseOneFeatures(unique_id);
      }
      fseek(ifp, save, SEEK_SET);
    }
  }
#endif

  load_raw = ph1.format < 3 ? &CLASS phase_one_load_raw : &CLASS phase_one_load_raw_c;
  maximum = 0xffff;
  strcpy(make, "Phase One");
  if (model[0])
    return;
  switch (raw_height)
  {
  case 2060:
    strcpy(model, "LightPhase");
    break;
  case 2682:
    strcpy(model, "H 10");
    break;
  case 4128:
    strcpy(model, "H 20");
    break;
  case 5488:
    strcpy(model, "H 25");
    break;
  }
}

Project: LibRaw
File: dcraw.c

void CLASS leaf_hdr_load_raw()
{
  ushort *pixel = 0;
  unsigned tile = 0, r, c, row, col;

  if (!filters || !raw_image)
  {
    pixel = (ushort *)calloc(raw_width, sizeof *pixel);
    merror(pixel, "leaf_hdr_load_raw()");
  }
#ifdef LIBRAW_LIBRARY_BUILD
  try
  {
#endif
    FORC(tiff_samples)
    for (r = 0; r < raw_height; r++)
    {
#ifdef LIBRAW_LIBRARY_BUILD
      checkCancel();
#endif
      if (r % tile_length == 0)
      {
        fseek(ifp, data_offset + 4 * tile++, SEEK_SET);
        fseek(ifp, get4(), SEEK_SET);
      }
      if (filters && c != shot_select)
        continue;
      if (filters && raw_image)
        pixel = raw_image + r * raw_width;
      read_shorts(pixel, raw_width);
      if (!filters && image && (row = r - top_margin) < height)
        for (col = 0; col < width; col++)
          image[row * width + col][c] = pixel[col + left_margin];
    }
#ifdef LIBRAW_LIBRARY_BUILD
  }
  catch (...)
  {
    if (!filters)
      free(pixel);
    throw;
  }
#endif
  if (!filters)
  {
    maximum = 0xffff;
    raw_color = 1;
    free(pixel);
  }
}

Project: LibRaw
File: dcraw.c

void CLASS parseSonyLensType2(uchar a, uchar b)
{
  ushort lid2;
  lid2 = (((ushort)a) << 8) | ((ushort)b);
  if (!lid2)
    return;
  if (lid2 < 0x100)
  {
    if ((imgdata.lens.makernotes.AdapterID != 0x4900) && (imgdata.lens.makernotes.AdapterID != 0xEF00))
    {
      imgdata.lens.makernotes.AdapterID = lid2;
      switch (lid2)
      {
      case 1:
      case 2:
      case 3:
      case 6:
        imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_Minolta_A;
        break;
      case 44:
      case 78:
      case 239:
        imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_Canon_EF;
        break;
      }
    }
  }
  else
    imgdata.lens.makernotes.LensID = lid2;
  if ((lid2 >= 50481) && (lid2 < 50500))
  {
    strcpy(imgdata.lens.makernotes.Adapter, "MC-11");
    imgdata.lens.makernotes.AdapterID = 0x4900;
  }
  return;
}

Project: LibRaw
File: dcraw.c

void CLASS parseFujiMakernotes(unsigned tag, unsigned type)
{
  switch (tag)
  {
  case 0x1002:
    imgdata.makernotes.fuji.WB_Preset = get2();
    break;
  case 0x1011:
    imgdata.other.FlashEC = getreal(type);
    break;
  case 0x1020:
    imgdata.makernotes.fuji.Macro = get2();
    break;
  case 0x1021:
    imgdata.makernotes.fuji.FocusMode = get2();
    break;
  case 0x1022:
    imgdata.makernotes.fuji.AFMode = get2();
    break;
  case 0x1023:
    imgdata.makernotes.fuji.FocusPixel[0] = get2();
    imgdata.makernotes.fuji.FocusPixel[1] = get2();
    break;
  case 0x1034:
    imgdata.makernotes.fuji.ExrMode = get2();
    break;
  case 0x1050:
    imgdata.makernotes.fuji.ShutterType = get2();
    break;
  case 0x1400:
    imgdata.makernotes.fuji.FujiDynamicRange = get2();
    break;
  case 0x1401:
    imgdata.makernotes.fuji.FujiFilmMode = get2();
    break;
  case 0x1402:
    imgdata.makernotes.fuji.FujiDynamicRangeSetting = get2();
    break;
  case 0x1403:
    imgdata.makernotes.fuji.FujiDevelopmentDynamicRange = get2();
    break;
  case 0x140b:
    imgdata.makernotes.fuji.FujiAutoDynamicRange = get2();
    break;
  case 0x1404:
    imgdata.lens.makernotes.MinFocal = getreal(type);
    break;
  case 0x1405:
    imgdata.lens.makernotes.MaxFocal = getreal(type);
    break;
  case 0x1406:
    imgdata.lens.makernotes.MaxAp4MinFocal = getreal(type);
    break;
  case 0x1407:
    imgdata.lens.makernotes.MaxAp4MaxFocal = getreal(type);
    break;
  case 0x1422:
    imgdata.makernotes.fuji.ImageStabilization[0] = get2();
    imgdata.makernotes.fuji.ImageStabilization[1] = get2();
    imgdata.makernotes.fuji.ImageStabilization[2] = get2();
    imgdata.shootinginfo.ImageStabilization =
        (imgdata.makernotes.fuji.ImageStabilization[0] << 9) + imgdata.makernotes.fuji.ImageStabilization[1];
    break;
  case 0x1431:
    imgdata.makernotes.fuji.Rating = get4();
    break;
  case 0x3820:
    imgdata.makernotes.fuji.FrameRate = get2();
    break;
  case 0x3821:
    imgdata.makernotes.fuji.FrameWidth = get2();
    break;
  case 0x3822:
    imgdata.makernotes.fuji.FrameHeight = get2();
    break;
  }
  return;
}

Project: LibRaw
File: dcraw.c

void CLASS initdata()
{
  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);
  for (int i = 0; i < LIBRAW_IFD_MAXCOUNT; i++)
  {
    tiff_ifd[i].dng_color[0].illuminant = tiff_ifd[i].dng_color[1].illuminant = 0xffff;
    for (int c = 0; c < 4; c++)
      tiff_ifd[i].dng_levels.analogbalance[c] = 1.0f;
  }
  for (int i = 0; i < 0x10000; i++)
    curve[i] = i;
  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_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;
}

Project: LibRaw
File: dcraw.c

void CLASS parse_ciff(int offset, int length, int depth)
{
  int tboff, nrecs, c, type, len, save, wbi = -1;
  ushort key[] = {0x410, 0x45f3};

  fseek(ifp, offset + length - 4, SEEK_SET);
  tboff = get4() + offset;
  fseek(ifp, tboff, SEEK_SET);
  nrecs = get2();
  if ((nrecs | depth) > 127)
    return;
  while (nrecs--)
  {
    type = get2();
    len = get4();
    save = ftell(ifp) + 4;
    fseek(ifp, offset + get4(), SEEK_SET);
    if ((((type >> 8) + 8) | 8) == 0x38)
    {
      parse_ciff(ftell(ifp), len, depth + 1); /* Parse a sub-table */
    }
#ifdef LIBRAW_LIBRARY_BUILD
    if (type == 0x3004)
      parse_ciff(ftell(ifp), len, depth + 1);
#endif
    if (type == 0x0810)
      fread(artist, 64, 1, ifp);
    if (type == 0x080a)
    {
      fread(make, 64, 1, ifp);
      fseek(ifp, strbuflen(make) - 63, SEEK_CUR);
      fread(model, 64, 1, ifp);
    }
    if (type == 0x1810)
    {
      width = get4();
      height = get4();
      pixel_aspect = int_to_float(get4());
      flip = get4();
    }
    if (type == 0x1835) /* Get the decoder table */
      tiff_compress = get4();
    if (type == 0x2007)
    {
      thumb_offset = ftell(ifp);
      thumb_length = len;
    }
    if (type == 0x1818)
    {
      shutter = powf64(2.0f, -int_to_float((get4(), get4())));
      aperture = powf64(2.0f, int_to_float(get4()) / 2);
#ifdef LIBRAW_LIBRARY_BUILD
      imgdata.lens.makernotes.CurAp = aperture;
#endif
    }
    if (type == 0x102a)
    {
      //      iso_speed = pow (2.0, (get4(),get2())/32.0 - 4) * 50;
      iso_speed = powf64(2.0f, ((get2(), get2()) + get2()) / 32.0f - 5.0f) * 100.0f;
#ifdef LIBRAW_LIBRARY_BUILD
      aperture = _CanonConvertAperture((get2(), get2()));
      imgdata.lens.makernotes.CurAp = aperture;
#else
      aperture = powf64(2.0, (get2(), (short)get2()) / 64.0);
#endif
      shutter = powf64(2.0, -((short)get2()) / 32.0);
      wbi = (get2(), get2());
      if (wbi > 17)
        wbi = 0;
      fseek(ifp, 32, SEEK_CUR);
      if (shutter > 1e6)
        shutter = get2() / 10.0;
    }
    if (type == 0x102c)
    {
      if (get2() > 512)
      { /* Pro90, G1 */
        fseek(ifp, 118, SEEK_CUR);
        FORC4 cam_mul[c ^ 2] = get2();
      }
      else
      { /* G2, S30, S40 */
        fseek(ifp, 98, SEEK_CUR);
        FORC4 cam_mul[c ^ (c >> 1) ^ 1] = get2();
      }
    }
#ifdef LIBRAW_LIBRARY_BUILD
    if (type == 0x10a9)
    {
      INT64 o = ftell(ifp);
      fseek(ifp, (0x1 << 1), SEEK_CUR);
      FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_Auto][c ^ (c >> 1)] = get2();
      Canon_WBpresets(0, 0);
      fseek(ifp, o, SEEK_SET);
    }
    if (type == 0x102d)
    {
      INT64 o = ftell(ifp);
      Canon_CameraSettings();
      fseek(ifp, o, SEEK_SET);
    }
    if (type == 0x580b)
    {
      if (strcmp(model, "Canon EOS D30"))
        sprintf(imgdata.shootinginfo.BodySerial, "%d", len);
      else
        sprintf(imgdata.shootinginfo.BodySerial, "%0x-%05d", len >> 16, len & 0xffff);
    }
#endif
    if (type == 0x0032)
    {
      if (len == 768)
      { /* EOS D30 */
        fseek(ifp, 72, SEEK_CUR);
        FORC4 cam_mul[c ^ (c >> 1)] = 1024.0 / get2();
        if (!wbi)
          cam_mul[0] = -1; /* use my auto white balance */
      }
      else if (!cam_mul[0])
      {
        if (get2() == key[0]) /* Pro1, G6, S60, S70 */
          c = (strstr(model, "Pro1") ? "012346000000000000" : "01345:000000006008")[LIM(0, wbi, 17)] - '0' + 2;
        else
        { /* G3, G5, S45, S50 */
          c = "023457000000006000"[LIM(0, wbi, 17)] - '0';
          key[0] = key[1] = 0;
        }
        fseek(ifp, 78 + c * 8, SEEK_CUR);
        FORC4 cam_mul[c ^ (c >> 1) ^ 1] = get2() ^ key[c & 1];
        if (!wbi)
          cam_mul[0] = -1;
      }
    }
    if (type == 0x10a9)
    { /* D60, 10D, 300D, and clones */
      if (len > 66)
        wbi = "0134567028"[LIM(0, wbi, 9)] - '0';
      fseek(ifp, 2 + wbi * 8, SEEK_CUR);
      FORC4 cam_mul[c ^ (c >> 1)] = get2();
    }
    if (type == 0x1030 && wbi >= 0 && (0x18040 >> wbi & 1))
      ciff_block_1030(); /* all that don't have 0x10a9 */
    if (type == 0x1031)
    {
      raw_width = (get2(), get2());
      raw_height = get2();
    }
    if (type == 0x501c)
    {
      iso_speed = len & 0xffff;
    }
    if (type == 0x5029)
    {
#ifdef LIBRAW_LIBRARY_BUILD
      imgdata.lens.makernotes.CurFocal = len >> 16;
      imgdata.lens.makernotes.FocalType = len & 0xffff;
      if (imgdata.lens.makernotes.FocalType == 2)
      {
        imgdata.lens.makernotes.CanonFocalUnits = 32;
        if (imgdata.lens.makernotes.CanonFocalUnits > 1)
          imgdata.lens.makernotes.CurFocal /= (float)imgdata.lens.makernotes.CanonFocalUnits;
      }
      focal_len = imgdata.lens.makernotes.CurFocal;
#else
      focal_len = len >> 16;
      if ((len & 0xffff) == 2)
        focal_len /= 32;
#endif
    }
    if (type == 0x5813)
      flash_used = int_to_float(len);
    if (type == 0x5814)
      canon_ev = int_to_float(len);
    if (type == 0x5817)
      shot_order = len;
    if (type == 0x5834)
    {
      unique_id = len;
#ifdef LIBRAW_LIBRARY_BUILD
      unique_id = setCanonBodyFeatures(unique_id);
#endif
    }
    if (type == 0x580e)
      timestamp = len;
    if (type == 0x180e)
      timestamp = get4();
#ifdef LOCALTIME
    if ((type | 0x4000) == 0x580e)
      timestamp = mktime(gmtime(&timestamp));
#endif
    fseek(ifp, save, SEEK_SET);
  }
}

Project: LibRaw
File: dcraw.c

void CLASS parse_exif(int base)
{
  unsigned kodak, entries, tag, type, len, save, c;
  double expo, ape;

  kodak = !strncmp(make, "EASTMAN", 7) && tiff_nifds < 3;
  entries = get2();
  if (!strncmp(make, "Hasselblad", 10) && (tiff_nifds > 3) && (entries > 512))
    return;
#ifdef LIBRAW_LIBRARY_BUILD
  INT64 fsize = ifp->size();
#endif
  while (entries--)
  {
    tiff_get(base, &tag, &type, &len, &save);

#ifdef LIBRAW_LIBRARY_BUILD
    INT64 savepos = ftell(ifp);
    if (len > 8 && savepos + len > fsize * 2)
      continue;
    if (callbacks.exif_cb)
    {
      callbacks.exif_cb(callbacks.exifparser_data, tag, type, len, order, ifp);
      fseek(ifp, savepos, SEEK_SET);
    }
#endif
    switch (tag)
    {
#ifdef LIBRAW_LIBRARY_BUILD

    case 0x9400:
      imgdata.other.exifAmbientTemperature = getreal(type);
      if ((imgdata.other.CameraTemperature > -273.15f) &&
          (OlyID == 0x4434353933ULL))  // TG-5
        imgdata.other.CameraTemperature += imgdata.other.exifAmbientTemperature;
      break;
    case 0x9401:
      imgdata.other.exifHumidity = getreal(type);
      break;
    case 0x9402:
      imgdata.other.exifPressure = getreal(type);
      break;
    case 0x9403:
      imgdata.other.exifWaterDepth = getreal(type);
      break;
    case 0x9404:
      imgdata.other.exifAcceleration = getreal(type);
      break;
    case 0x9405:
      imgdata.other.exifCameraElevationAngle = getreal(type);
      break;

    case 0xa405: // FocalLengthIn35mmFormat
      imgdata.lens.FocalLengthIn35mmFormat = get2();
      break;
    case 0xa431: // BodySerialNumber
      stmread(imgdata.shootinginfo.BodySerial, len, ifp);
      break;
    case 0xa432: // LensInfo, 42034dec, Lens Specification per EXIF standard
      imgdata.lens.MinFocal = getreal(type);
      imgdata.lens.MaxFocal = getreal(type);
      imgdata.lens.MaxAp4MinFocal = getreal(type);
      imgdata.lens.MaxAp4MaxFocal = getreal(type);
      break;
    case 0xa435: // LensSerialNumber
      stmread(imgdata.lens.LensSerial, len, ifp);
      break;
    case 0xc630: // DNG LensInfo, Lens Specification per EXIF standard
      imgdata.lens.dng.MinFocal = getreal(type);
      imgdata.lens.dng.MaxFocal = getreal(type);
      imgdata.lens.dng.MaxAp4MinFocal = getreal(type);
      imgdata.lens.dng.MaxAp4MaxFocal = getreal(type);
      break;
    case 0xa433: // LensMake
      stmread(imgdata.lens.LensMake, len, ifp);
      break;
    case 0xa434: // LensModel
      stmread(imgdata.lens.Lens, len, ifp);
      if (!strncmp(imgdata.lens.Lens, "----", 4))
        imgdata.lens.Lens[0] = 0;
      break;
    case 0x9205:
      imgdata.lens.EXIF_MaxAp = powf64(2.0f, (getreal(type) / 2.0f));
      break;
#endif
    case 33434:
      tiff_ifd[tiff_nifds - 1].t_shutter = shutter = getreal(type);
      break;
    case 33437:
      aperture = getreal(type);
      break; // 0x829d FNumber
    case 34855:
      iso_speed = get2();
      break;
    case 34865:
      if (iso_speed == 0xffff && !strncasecmp(make, "FUJI", 4))
        iso_speed = getreal(type);
      break;
    case 34866:
      if (iso_speed == 0xffff && (!strncasecmp(make, "SONY", 4) || !strncasecmp(make, "CANON", 5)))
        iso_speed = getreal(type);
      break;
    case 36867:
    case 36868:
      get_timestamp(0);
      break;
    case 37377:
      if ((expo = -getreal(type)) < 128 && shutter == 0.)
        tiff_ifd[tiff_nifds - 1].t_shutter = shutter = powf64(2.0, expo);
      break;
    case 37378: // 0x9202 ApertureValue
      if ((fabs(ape = getreal(type)) < 256.0) && (!aperture))
        aperture = powf64(2.0, ape / 2);
      break;
    case 37385:
      flash_used = getreal(type);
      break;
    case 37386:
      focal_len = getreal(type);
      break;
    case 37500: // tag 0x927c
#ifdef LIBRAW_LIBRARY_BUILD
      if (((make[0] == '\0') && (!strncmp(model, "ov5647", 6))) ||
          ((!strncmp(make, "RaspberryPi", 11)) && (!strncmp(model, "RP_OV5647", 9))) ||
          ((!strncmp(make, "RaspberryPi", 11)) && (!strncmp(model, "RP_imx219", 9))))
      {
        char mn_text[512];
        char *pos;
        char ccms[512];
        ushort l;
        float num;

        fgets(mn_text, len, ifp);
        pos = strstr(mn_text, "gain_r=");
        if (pos)
          cam_mul[0] = atof(pos + 7);
        pos = strstr(mn_text, "gain_b=");
        if (pos)
          cam_mul[2] = atof(pos + 7);
        if ((cam_mul[0] > 0.001f) && (cam_mul[2] > 0.001f))
          cam_mul[1] = cam_mul[3] = 1.0f;
        else
          cam_mul[0] = cam_mul[2] = 0.0f;

        pos = strstr(mn_text, "ccm=") + 4;
        l = strstr(pos, " ") - pos;
        memcpy(ccms, pos, l);
        ccms[l] = '\0';

        pos = strtok(ccms, ",");
        for (l = 0; l < 4; l++)
        {
          num = 0.0;
          for (c = 0; c < 3; c++)
          {
            imgdata.color.ccm[l][c] = (float)atoi(pos);
            num += imgdata.color.ccm[l][c];
            pos = strtok(NULL, ",");
          }
          if (num > 0.01)
            FORC3 imgdata.color.ccm[l][c] = imgdata.color.ccm[l][c] / num;
        }
      }
      else
#endif
        parse_makernote(base, 0);
      break;
    case 40962:
      if (kodak)
        raw_width = get4();
      break;
    case 40963:
      if (kodak)
        raw_height = get4();
      break;
    case 41730:
      if (get4() == 0x20002)
        for (exif_cfa = c = 0; c < 8; c += 2)
          exif_cfa |= fgetc(ifp) * 0x01010101 << c;
    }
    fseek(ifp, save, SEEK_SET);
  }
}

Project: LibRaw
File: dcraw.c

void CLASS kodak_65000_load_raw()
{
  short buf[272]; /* 264 looks enough */
  int row, col, len, pred[2], ret, i;

  for (row = 0; row < height; row++)
  {
#ifdef LIBRAW_LIBRARY_BUILD
    checkCancel();
#endif
    for (col = 0; col < width; col += 256)
    {
      pred[0] = pred[1] = 0;
      len = MIN(256, width - col);
      ret = kodak_65000_decode(buf, len);
      for (i = 0; i < len; i++)
      {
        int idx = ret ? buf[i] : (pred[i & 1] += buf[i]);
	if(idx >=0 && idx < 0xffff)
	 {
           if ((RAW(row, col + i) = curve[idx]) >> 12)
          derror();
	  }
	 else
	  derror();
      }
    }
  }
}

Project: LibRaw
File: dcraw.c

void CLASS parse_makernote_0xc634(int base, int uptag, unsigned dng_writer) { /*placeholder */}

Project: LibRaw
File: dcraw.c

void CLASS remove_zeroes()
{
  unsigned row, col, tot, n, r, c;

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

  for (row = 0; row < height; row++)
    for (col = 0; col < width; col++)
      if (BAYER(row, col) == 0)
      {
        tot = n = 0;
        for (r = row - 2; r <= row + 2; r++)
          for (c = col - 2; c <= col + 2; c++)
            if (r < height && c < width && FC(r, c) == FC(row, col) && BAYER(r, c))
              tot += (n++, BAYER(r, c));
        if (n)
          BAYER(row, col) = tot / n;
      }
#ifdef LIBRAW_LIBRARY_BUILD
  RUN_CALLBACK(LIBRAW_PROGRESS_REMOVE_ZEROES, 1, 2);
#endif
}

Project: LibRaw
File: dcraw.c

void CLASS lossy_dng_load_raw()
{
  struct jpeg_decompress_struct cinfo;
  struct jpeg_error_mgr jerr;
  JSAMPARRAY buf;
  JSAMPLE(*pixel)[3];
  unsigned sorder = order, ntags, opcode, deg, i, j, c;
  unsigned save = data_offset - 4, trow = 0, tcol = 0, row, col;
  ushort cur[3][256];
  double coeff[9], tot;

  if (meta_offset)
  {
    fseek(ifp, meta_offset, SEEK_SET);
    order = 0x4d4d;
    ntags = get4();
    while (ntags--)
    {
      opcode = get4();
      get4();
      get4();
      if (opcode != 8)
      {
        fseek(ifp, get4(), SEEK_CUR);
        continue;
      }
      fseek(ifp, 20, SEEK_CUR);
      if ((c = get4()) > 2)
        break;
      fseek(ifp, 12, SEEK_CUR);
      if ((deg = get4()) > 8)
        break;
      for (i = 0; i <= deg && i < 9; i++)
        coeff[i] = getreal(12);
      for (i = 0; i < 256; i++)
      {
        for (tot = j = 0; j <= deg; j++)
          tot += coeff[j] * pow(i / 255.0, (int)j);
        cur[c][i] = tot * 0xffff;
      }
    }
    order = sorder;
  }
  else
  {
    gamma_curve(1 / 2.4, 12.92, 1, 255);
    FORC3 memcpy(cur[c], curve, sizeof cur[0]);
  }
  cinfo.err = jpeg_std_error(&jerr);
  jpeg_create_decompress(&cinfo);
  while (trow < raw_height)
  {
    fseek(ifp, save += 4, SEEK_SET);
    if (tile_length < INT_MAX)
      fseek(ifp, get4(), SEEK_SET);
#ifdef LIBRAW_LIBRARY_BUILD
    if (libraw_internal_data.internal_data.input->jpeg_src(&cinfo) == -1)
    {
      jpeg_destroy_decompress(&cinfo);
      throw LIBRAW_EXCEPTION_DECODE_JPEG;
    }
#else
    jpeg_stdio_src(&cinfo, ifp);
#endif
    jpeg_read_header(&cinfo, TRUE);
    jpeg_start_decompress(&cinfo);
    buf = (*cinfo.mem->alloc_sarray)((j_common_ptr)&cinfo, JPOOL_IMAGE, cinfo.output_width * 3, 1);
#ifdef LIBRAW_LIBRARY_BUILD
    try
    {
#endif
      while (cinfo.output_scanline < cinfo.output_height && (row = trow + cinfo.output_scanline) < height)
      {
#ifdef LIBRAW_LIBRARY_BUILD
        checkCancel();
#endif
        jpeg_read_scanlines(&cinfo, buf, 1);
        pixel = (JSAMPLE(*)[3])buf[0];
        for (col = 0; col < cinfo.output_width && tcol + col < width; col++)
        {
          FORC3 image[row * width + tcol + col][c] = cur[c][pixel[col][c]];
        }
      }
#ifdef LIBRAW_LIBRARY_BUILD
    }
    catch (...)
    {
      jpeg_destroy_decompress(&cinfo);
      throw;
    }
#endif
    jpeg_abort_decompress(&cinfo);
    if ((tcol += tile_width) >= raw_width)
      trow += tile_length + (tcol = 0);
  }
  jpeg_destroy_decompress(&cinfo);
  maximum = 0xffff;
}

Project: LibRaw
File: dcraw.c

static void remove_trailing_spaces(char *string, size_t len)
{
  if (len < 1)
    return; // not needed, b/c sizeof of make/model is 64
  string[len - 1] = 0;
  if (len < 3)
    return; // also not needed
  len = strnlen(string, len - 1);
  for (int i = len - 1; i >= 0; i--)
  {
    if (isspace(string[i]))
      string[i] = 0;
    else
      break;
  }
}

Project: LibRaw
File: dcraw.c

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");
  // @end FILEIO
  else
  {
    for (len = 32;; len *= 2)
    {
      fname = (char *)malloc(len);
      if (!fname)
        return;
      if (getcwd(fname, len - 16))
        break;
      free(fname);
      if (errno != ERANGE)
        return;
    }
#if defined(WIN32) || defined(DJGPP)
    if (fname[1] == ':')
      memmove(fname, fname + 2, len - 2);
    for (cp = fname; *cp; cp++)
      if (*cp == '\\')
        *cp = '/';
#endif
    cp = fname + strlen(fname);
    if (cp[-1] == '/')
      cp--;
    while (*fname == '/')
    {
      strcpy(cp, "/.badpixels");
      if ((fp = fopen(fname, "r")))
        break;
      if (cp == fname)
        break;
      while (*--cp != '/')
        ;
    }
    free(fname);
  }
  // @out FILEIO
  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
File: dcraw.c

void CLASS parseCanonMakernotes(unsigned tag, unsigned type, unsigned len)
{

  if (tag == 0x0001)
    Canon_CameraSettings();
  else if (tag == 0x0002) // focal length
  {
    imgdata.lens.makernotes.FocalType = get2();
    imgdata.lens.makernotes.CurFocal = get2();
    if (imgdata.lens.makernotes.CanonFocalUnits > 1)
    {
      imgdata.lens.makernotes.CurFocal /= (float)imgdata.lens.makernotes.CanonFocalUnits;
    }
  }

  else if (tag == 0x0004) // shot info
  {
    short tempAp;

    fseek(ifp, 24, SEEK_CUR);
    tempAp = get2();
    if (tempAp != 0) imgdata.other.CameraTemperature = (float)(tempAp-128);
    tempAp = get2();
    if (tempAp != -1) imgdata.other.FlashGN = ((float)tempAp) / 32;
    get2();

    // fseek(ifp, 30, SEEK_CUR);
    imgdata.other.FlashEC = _CanonConvertEV((signed short)get2());
    fseek(ifp, 8 - 32, SEEK_CUR);
    if ((tempAp = get2()) != 0x7fff)
      imgdata.lens.makernotes.CurAp = _CanonConvertAperture(tempAp);
    if (imgdata.lens.makernotes.CurAp < 0.7f)
    {
      fseek(ifp, 32, SEEK_CUR);
      imgdata.lens.makernotes.CurAp = _CanonConvertAperture(get2());
    }
    if (!aperture)
      aperture = imgdata.lens.makernotes.CurAp;
  }

  else if (tag == 0x0095 && // lens model tag
           !imgdata.lens.makernotes.Lens[0])
  {
    fread(imgdata.lens.makernotes.Lens, 2, 1, ifp);
    imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_Canon_EF;
    if (imgdata.lens.makernotes.Lens[0] < 65) // non-Canon lens
      fread(imgdata.lens.makernotes.Lens + 2, 62, 1, ifp);
    else
    {
      char efs[2];
      imgdata.lens.makernotes.LensFeatures_pre[0] = imgdata.lens.makernotes.Lens[0];
      imgdata.lens.makernotes.LensFeatures_pre[1] = imgdata.lens.makernotes.Lens[1];
      fread(efs, 2, 1, ifp);
      if (efs[0] == 45 && (efs[1] == 83 || efs[1] == 69 || efs[1] == 77))
      { // "EF-S, TS-E, MP-E, EF-M" lenses
        imgdata.lens.makernotes.Lens[2] = imgdata.lens.makernotes.LensFeatures_pre[2] = efs[0];
        imgdata.lens.makernotes.Lens[3] = imgdata.lens.makernotes.LensFeatures_pre[3] = efs[1];
        imgdata.lens.makernotes.Lens[4] = 32;
        if (efs[1] == 83)
        {
          imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_Canon_EF_S;
          imgdata.lens.makernotes.LensFormat = LIBRAW_FORMAT_APSC;
        }
        else if (efs[1] == 77)
        {
          imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_Canon_EF_M;
        }
      }
      else
      { // "EF" lenses
        imgdata.lens.makernotes.Lens[2] = 32;
        imgdata.lens.makernotes.Lens[3] = efs[0];
        imgdata.lens.makernotes.Lens[4] = efs[1];
      }
      fread(imgdata.lens.makernotes.Lens + 5, 58, 1, ifp);
    }
  }

  else if (tag == 0x00a9)
  {
    long int save1 = ftell(ifp);
    int c;
    fseek(ifp, (0x1 << 1), SEEK_CUR);
    FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_Auto][c ^ (c >> 1)] = get2();
    Canon_WBpresets(0, 0);
    fseek(ifp, save1, SEEK_SET);
  }

  else if (tag == 0x00e0) // sensor info
  {
    imgdata.makernotes.canon.SensorWidth = (get2(), get2());
    imgdata.makernotes.canon.SensorHeight = get2();
    imgdata.makernotes.canon.SensorLeftBorder = (get2(), get2(), get2());
    imgdata.makernotes.canon.SensorTopBorder = get2();
    imgdata.makernotes.canon.SensorRightBorder = get2();
    imgdata.makernotes.canon.SensorBottomBorder = get2();
    imgdata.makernotes.canon.BlackMaskLeftBorder = get2();
    imgdata.makernotes.canon.BlackMaskTopBorder = get2();
    imgdata.makernotes.canon.BlackMaskRightBorder = get2();
    imgdata.makernotes.canon.BlackMaskBottomBorder = get2();
  }

  else if (tag == 0x4001 && len > 500)
  {
    int c;
    long int save1 = ftell(ifp);
    switch (len)
    {
    case 582:
      imgdata.makernotes.canon.CanonColorDataVer = 1; // 20D / 350D
      {
        fseek(ifp, save1 + (0x1e << 1), SEEK_SET);
        FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_Auto][c ^ (c >> 1)] = get2();
        fseek(ifp, save1 + (0x41 << 1), SEEK_SET);
        FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_Custom1][c ^ (c >> 1)] = get2();
        fseek(ifp, save1 + (0x46 << 1), SEEK_SET);
        FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_Custom2][c ^ (c >> 1)] = get2();

        fseek(ifp, save1 + (0x23 << 1), SEEK_SET);
        Canon_WBpresets(2, 2);
        fseek(ifp, save1 + (0x4b << 1), SEEK_SET);
        Canon_WBCTpresets(1); // ABCT
      }
      break;
    case 653:
      imgdata.makernotes.canon.CanonColorDataVer = 2; // 1Dmk2 / 1DsMK2
      {
        fseek(ifp, save1 + (0x18 << 1), SEEK_SET);
        FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_Auto][c ^ (c >> 1)] = get2();
        fseek(ifp, save1 + (0x90 << 1), SEEK_SET);
        FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_Custom1][c ^ (c >> 1)] = get2();
        fseek(ifp, save1 + (0x95 << 1), SEEK_SET);
        FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_Custom2][c ^ (c >> 1)] = get2();
        fseek(ifp, save1 + (0x9a << 1), SEEK_SET);
        FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_Custom3][c ^ (c >> 1)] = get2();

        fseek(ifp, save1 + (0x27 << 1), SEEK_SET);
        Canon_WBpresets(2, 12);
        fseek(ifp, save1 + (0xa4 << 1), SEEK_SET);
        Canon_WBCTpresets(1); // ABCT
      }
      break;
    case 796:
      imgdata.makernotes.canon.CanonColorDataVer = 3; // 1DmkIIN / 5D / 30D / 400D
      imgdata.makernotes.canon.CanonColorDataSubVer = get2();
      {
        fseek(ifp, save1 + (0x44 << 1), SEEK_SET);
        FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_Auto][c ^ (c >> 1)] = get2();
        fseek(ifp, save1 + (0x49 << 1), SEEK_SET);
        FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_Measured][c ^ (c >> 1)] = get2();
        fseek(ifp, save1 + (0x71 << 1), SEEK_SET);
        FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_Custom1][c ^ (c >> 1)] = get2();
        fseek(ifp, save1 + (0x76 << 1), SEEK_SET);
        FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_Custom2][c ^ (c >> 1)] = get2();
        fseek(ifp, save1 + (0x7b << 1), SEEK_SET);
        FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_Custom3][c ^ (c >> 1)] = get2();
        fseek(ifp, save1 + (0x80 << 1), SEEK_SET);
        FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_Custom][c ^ (c >> 1)] = get2();

        fseek(ifp, save1 + (0x4e << 1), SEEK_SET);
        Canon_WBpresets(2, 12);
        fseek(ifp, save1 + (0x85 << 1), SEEK_SET);
        Canon_WBCTpresets(0);                       // BCAT
        fseek(ifp, save1 + (0x0c4 << 1), SEEK_SET); // offset 196 short
        int bls = 0;
        FORC4
        bls += (imgdata.makernotes.canon.ChannelBlackLevel[c] = get2());
        imgdata.makernotes.canon.AverageBlackLevel = bls / 4;
      }
      break;
    // 1DmkIII / 1DSmkIII / 1DmkIV / 5DmkII
    // 7D / 40D / 50D / 60D / 450D / 500D
    // 550D / 1000D / 1100D
    case 674:
    case 692:
    case 702:
    case 1227:
    case 1250:
    case 1251:
    case 1337:
    case 1338:
    case 1346:
      imgdata.makernotes.canon.CanonColorDataVer = 4;
      imgdata.makernotes.canon.CanonColorDataSubVer = get2();
      {
        fseek(ifp, save1 + (0x44 << 1), SEEK_SET);
        FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_Auto][c ^ (c >> 1)] = get2();
        fseek(ifp, save1 + (0x49 << 1), SEEK_SET);
        FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_Measured][c ^ (c >> 1)] = get2();

        fseek(ifp, save1 + (0x53 << 1), SEEK_SET);
        Canon_WBpresets(2, 12);
        fseek(ifp, save1 + (0xa8 << 1), SEEK_SET);
        Canon_WBCTpresets(0);                       // BCAT
        fseek(ifp, save1 + (0x0e7 << 1), SEEK_SET); // offset 231 short
        int bls = 0;
        FORC4
        bls += (imgdata.makernotes.canon.ChannelBlackLevel[c] = get2());
        imgdata.makernotes.canon.AverageBlackLevel = bls / 4;
      }
      if ((imgdata.makernotes.canon.CanonColorDataSubVer == 4) || (imgdata.makernotes.canon.CanonColorDataSubVer == 5))
      {
        fseek(ifp, save1 + (0x2b9 << 1), SEEK_SET); // offset 697 shorts
        imgdata.makernotes.canon.SpecularWhiteLevel = get2();
        FORC4 imgdata.color.linear_max[c] = imgdata.makernotes.canon.SpecularWhiteLevel;
      }
      else if ((imgdata.makernotes.canon.CanonColorDataSubVer == 6) ||
               (imgdata.makernotes.canon.CanonColorDataSubVer == 7))
      {
        fseek(ifp, save1 + (0x2d0 << 1), SEEK_SET); // offset 720 shorts
        imgdata.makernotes.canon.SpecularWhiteLevel = get2();
        FORC4 imgdata.color.linear_max[c] = imgdata.makernotes.canon.SpecularWhiteLevel;
      }
      else if (imgdata.makernotes.canon.CanonColorDataSubVer == 9)
      {
        fseek(ifp, save1 + (0x2d4 << 1), SEEK_SET); // offset 724 shorts
        imgdata.makernotes.canon.SpecularWhiteLevel = get2();
        FORC4 imgdata.color.linear_max[c] = imgdata.makernotes.canon.SpecularWhiteLevel;
      }
      break;

    case 5120:
      imgdata.makernotes.canon.CanonColorDataVer = 5; // PowerSot G10, G12, G5 X, G7 X, G9 X, EOS M3, EOS M5, EOS M6
      {
        if ((unique_id == 0x03970000) || // G7 X Mark II
            (unique_id == 0x04100000) || // G9 X Mark II
            (unique_id == 0x04180000) || // G1 X Mark III
            (unique_id == 0x80000394) || // EOS M5
            (unique_id == 0x80000398) || // EOS M100
            (unique_id == 0x80000407))   // EOS M6
        {
          fseek(ifp, save1 + (0x4f << 1), SEEK_SET);
          FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_Auto][c ^ (c >> 1)] = get2();
          fseek(ifp, 8, SEEK_CUR);
          FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_Measured][c ^ (c >> 1)] = get2();
          fseek(ifp, 8, SEEK_CUR);
          FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_Other][c ^ (c >> 1)] = get2();
          fseek(ifp, 8, SEEK_CUR);
          Canon_WBpresets(8, 24);
          fseek(ifp, 168, SEEK_CUR);
          FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_FL_WW][c ^ (c >> 1)] = get2();
          fseek(ifp, 24, SEEK_CUR);
          Canon_WBCTpresets(2); // BCADT
          fseek(ifp, 6, SEEK_CUR);
        }
        else
        {
          fseek(ifp, save1 + (0x4c << 1), SEEK_SET);
          FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_Auto][c ^ (c >> 1)] = get2();
          get2();
          FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_Measured][c ^ (c >> 1)] = get2();
          get2();
          FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_Other][c ^ (c >> 1)] = get2();
          get2();
          Canon_WBpresets(2, 12);
          fseek(ifp, save1 + (0xba << 1), SEEK_SET);
          Canon_WBCTpresets(2);                       // BCADT
          fseek(ifp, save1 + (0x108 << 1), SEEK_SET); // offset 264 short
        }
        int bls = 0;
        FORC4 bls += (imgdata.makernotes.canon.ChannelBlackLevel[c] = get2());
        imgdata.makernotes.canon.AverageBlackLevel = bls / 4;
      }
      break;

    case 1273:
    case 1275:
      imgdata.makernotes.canon.CanonColorDataVer = 6; // 600D / 1200D
      imgdata.makernotes.canon.CanonColorDataSubVer = get2();
      {
        fseek(ifp, save1 + (0x44 << 1), SEEK_SET);
        FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_Auto][c ^ (c >> 1)] = get2();
        fseek(ifp, save1 + (0x49 << 1), SEEK_SET);
        FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_Measured][c ^ (c >> 1)] = get2();

        fseek(ifp, save1 + (0x67 << 1), SEEK_SET);
        Canon_WBpresets(2, 12);
        fseek(ifp, save1 + (0xbc << 1), SEEK_SET);
        Canon_WBCTpresets(0);                       // BCAT
        fseek(ifp, save1 + (0x0fb << 1), SEEK_SET); // offset 251 short
        int bls = 0;
        FORC4
        bls += (imgdata.makernotes.canon.ChannelBlackLevel[c] = get2());
        imgdata.makernotes.canon.AverageBlackLevel = bls / 4;
      }
      fseek(ifp, save1 + (0x1e4 << 1), SEEK_SET); // offset 484 shorts
      imgdata.makernotes.canon.SpecularWhiteLevel = get2();
      FORC4 imgdata.color.linear_max[c] = imgdata.makernotes.canon.SpecularWhiteLevel;
      break;

    // 1DX / 5DmkIII / 6D / 100D / 650D / 700D / EOS M / 7DmkII / 750D / 760D
    case 1312:
    case 1313:
    case 1316:
    case 1506:
      imgdata.makernotes.canon.CanonColorDataVer = 7;
      imgdata.makernotes.canon.CanonColorDataSubVer = get2();
      {
        fseek(ifp, save1 + (0x44 << 1), SEEK_SET);
        FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_Auto][c ^ (c >> 1)] = get2();
        fseek(ifp, save1 + (0x49 << 1), SEEK_SET);
        FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_Measured][c ^ (c >> 1)] = get2();

        fseek(ifp, save1 + (0x80 << 1), SEEK_SET);
        Canon_WBpresets(2, 12);
        fseek(ifp, save1 + (0xd5 << 1), SEEK_SET);
        Canon_WBCTpresets(0);                       // BCAT
        fseek(ifp, save1 + (0x114 << 1), SEEK_SET); // offset 276 shorts
        int bls = 0;
        FORC4
        bls += (imgdata.makernotes.canon.ChannelBlackLevel[c] = get2());
        imgdata.makernotes.canon.AverageBlackLevel = bls / 4;
      }
      if (imgdata.makernotes.canon.CanonColorDataSubVer == 10)
      {
        fseek(ifp, save1 + (0x1fd << 1), SEEK_SET); // offset 509 shorts
        imgdata.makernotes.canon.SpecularWhiteLevel = get2();
        FORC4 imgdata.color.linear_max[c] = imgdata.makernotes.canon.SpecularWhiteLevel;
      }
      else if (imgdata.makernotes.canon.CanonColorDataSubVer == 11)
      {
        fseek(ifp, save1 + (0x2dd << 1), SEEK_SET); // offset 733 shorts
        imgdata.makernotes.canon.SpecularWhiteLevel = get2();
        FORC4 imgdata.color.linear_max[c] = imgdata.makernotes.canon.SpecularWhiteLevel;
      }
      break;

    // 5DS / 5DS R / 80D / 1300D / 5D4 / 800D / 77D / 6D II / 200D
    case 1560:
    case 1592:
    case 1353:
    case 1602:
      imgdata.makernotes.canon.CanonColorDataVer = 8;
      imgdata.makernotes.canon.CanonColorDataSubVer = get2();
      {
        fseek(ifp, save1 + (0x44 << 1), SEEK_SET);
        FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_Auto][c ^ (c >> 1)] = get2();
        fseek(ifp, save1 + (0x49 << 1), SEEK_SET);
        FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_Measured][c ^ (c >> 1)] = get2();

        fseek(ifp, save1 + (0x85 << 1), SEEK_SET);
        Canon_WBpresets(2, 12);
        fseek(ifp, save1 + (0x107 << 1), SEEK_SET);
        Canon_WBCTpresets(0);                       // BCAT
        fseek(ifp, save1 + (0x146 << 1), SEEK_SET); // offset 326 shorts
        int bls = 0;
        FORC4
        bls += (imgdata.makernotes.canon.ChannelBlackLevel[c] = get2());
        imgdata.makernotes.canon.AverageBlackLevel = bls / 4;
      }
      if (imgdata.makernotes.canon.CanonColorDataSubVer == 14) // 1300D
      {
        fseek(ifp, save1 + (0x231 << 1), SEEK_SET);
        imgdata.makernotes.canon.SpecularWhiteLevel = get2();
        FORC4 imgdata.color.linear_max[c] = imgdata.makernotes.canon.SpecularWhiteLevel;
      }
      else
      {
        fseek(ifp, save1 + (0x30f << 1), SEEK_SET); // offset 783 shorts
        imgdata.makernotes.canon.SpecularWhiteLevel = get2();
        FORC4 imgdata.color.linear_max[c] = imgdata.makernotes.canon.SpecularWhiteLevel;
      }
      break;
    }
    fseek(ifp, save1, SEEK_SET);
  }
}

Project: LibRaw
File: dcraw.c

void CLASS wavelet_denoise()
{
  float *fimg = 0, *temp, thold, mul[2], avg, diff;
  int scale = 1, size, lev, hpass, lpass, row, col, nc, c, i, wlast, blk[2];
  ushort *window[4];
  static const float noise[] = {0.8002, 0.2735, 0.1202, 0.0585, 0.0291, 0.0152, 0.0080, 0.0044};

#ifdef DCRAW_VERBOSE
  if (verbose)
    fprintf(stderr, _("Wavelet denoising...\n"));
#endif

  while (maximum << scale < 0x10000)
    scale++;
  maximum <<= --scale;
  black <<= scale;
  FORC4 cblack[c] <<= scale;
  if ((size = iheight * iwidth) < 0x15550000)
    fimg = (float *)malloc((size * 3 + iheight + iwidth) * sizeof *fimg);
  merror(fimg, "wavelet_denoise()");
  temp = fimg + size * 3;
  if ((nc = colors) == 3 && filters)
    nc++;
#ifdef LIBRAW_LIBRARY_BUILD
#pragma omp parallel default(shared) private(i, col, row, thold, lev, lpass, hpass, temp, c) firstprivate(scale, size)
#endif
  {
    temp = (float *)malloc((iheight + iwidth) * sizeof *fimg);
    FORC(nc)
    { /* denoise R,G1,B,G3 individually */
#ifdef LIBRAW_LIBRARY_BUILD
#pragma omp for
#endif
      for (i = 0; i < size; i++)
        fimg[i] = 256 * sqrt((double)(image[i][c] << scale));
      for (hpass = lev = 0; lev < 5; lev++)
      {
        lpass = size * ((lev & 1) + 1);
#ifdef LIBRAW_LIBRARY_BUILD
#pragma omp for
#endif
        for (row = 0; row < iheight; row++)
        {
          hat_transform(temp, fimg + hpass + row * iwidth, 1, iwidth, 1 << lev);
          for (col = 0; col < iwidth; col++)
            fimg[lpass + row * iwidth + col] = temp[col] * 0.25;
        }
#ifdef LIBRAW_LIBRARY_BUILD
#pragma omp for
#endif
        for (col = 0; col < iwidth; col++)
        {
          hat_transform(temp, fimg + lpass + col, iwidth, iheight, 1 << lev);
          for (row = 0; row < iheight; row++)
            fimg[lpass + row * iwidth + col] = temp[row] * 0.25;
        }
        thold = threshold * noise[lev];
#ifdef LIBRAW_LIBRARY_BUILD
#pragma omp for
#endif
        for (i = 0; i < size; i++)
        {
          fimg[hpass + i] -= fimg[lpass + i];
          if (fimg[hpass + i] < -thold)
            fimg[hpass + i] += thold;
          else if (fimg[hpass + i] > thold)
            fimg[hpass + i] -= thold;
          else
            fimg[hpass + i] = 0;
          if (hpass)
            fimg[i] += fimg[hpass + i];
        }
        hpass = lpass;
      }
#ifdef LIBRAW_LIBRARY_BUILD
#pragma omp for
#endif
      for (i = 0; i < size; i++)
        image[i][c] = CLIP(SQR(fimg[i] + fimg[lpass + i]) / 0x10000);
    }
    free(temp);
  } /* end omp parallel */
  /* the following loops are hard to parallize, no idea yes,
   * problem is wlast which is carrying dependency
   * second part should be easyer, but did not yet get it right.
   */
  if (filters && colors == 3)
  { /* pull G1 and G3 closer together */
    for (row = 0; row < 2; row++)
    {
      mul[row] = 0.125 * pre_mul[FC(row + 1, 0) | 1] / pre_mul[FC(row, 0) | 1];
      blk[row] = cblack[FC(row, 0) | 1];
    }
    for (i = 0; i < 4; i++)
      window[i] = (ushort *)fimg + width * i;
    for (wlast = -1, row = 1; row < height - 1; row++)
    {
      while (wlast < row + 1)
      {
        for (wlast++, i = 0; i < 4; i++)
          window[(i + 3) & 3] = window[i];
        for (col = FC(wlast, 1) & 1; col < width; col += 2)
          window[2][col] = BAYER(wlast, col);
      }
      thold = threshold / 512;
      for (col = (FC(row, 0) & 1) + 1; col < width - 1; col += 2)
      {
        avg = (window[0][col - 1] + window[0][col + 1] + window[2][col - 1] + window[2][col + 1] - blk[~row & 1] * 4) *
                  mul[row & 1] +
              (window[1][col] + blk[row & 1]) * 0.5;
        avg = avg < 0 ? 0 : sqrt(avg);
        diff = sqrt((double)BAYER(row, col)) - avg;
        if (diff < -thold)
          diff += thold;
        else if (diff > thold)
          diff -= thold;
        else
          diff = 0;
        BAYER(row, col) = CLIP(SQR(avg + diff) + 0.5);
      }
    }
  }
  free(fimg);
}

Project: LibRaw
File: dcraw.c

void CLASS setPentaxBodyFeatures(unsigned id)
{
  imgdata.lens.makernotes.CamID = id;

  switch (id)
  {
  case 0x12994:
  case 0x12aa2:
  case 0x12b1a:
  case 0x12b60:
  case 0x12b62:
  case 0x12b7e:
  case 0x12b80:
  case 0x12b9c:
  case 0x12b9d:
  case 0x12ba2:
  case 0x12c1e:
  case 0x12c20:
  case 0x12cd2:
  case 0x12cd4:
  case 0x12cfa:
  case 0x12d72:
  case 0x12d73:
  case 0x12db8:
  case 0x12dfe:
  case 0x12e6c:
  case 0x12e76:
  case 0x12ef8:
  case 0x12f52:
  case 0x12f70:
  case 0x12f71:
  case 0x12fb6:
  case 0x12fc0:
  case 0x12fca:
  case 0x1301a:
  case 0x13024:
  case 0x1309c:
  case 0x13222:
  case 0x1322c:
    imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_Pentax_K;
    imgdata.lens.makernotes.CameraMount = LIBRAW_MOUNT_Pentax_K;
    imgdata.lens.makernotes.CameraFormat = LIBRAW_FORMAT_APSC;
    break;
  case 0x13092:
    imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_Pentax_K;
    imgdata.lens.makernotes.CameraMount = LIBRAW_MOUNT_Pentax_K;
    imgdata.lens.makernotes.CameraFormat = LIBRAW_FORMAT_FF;
    break;
  case 0x12e08:
  case 0x13010:
    imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_Pentax_645;
    imgdata.lens.makernotes.LensFormat = LIBRAW_FORMAT_MF;
    imgdata.lens.makernotes.CameraMount = LIBRAW_MOUNT_Pentax_645;
    imgdata.lens.makernotes.CameraFormat = LIBRAW_FORMAT_MF;
    break;
  case 0x12ee4:
  case 0x12f66:
  case 0x12f7a:
  case 0x1302e:
    imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_Pentax_Q;
    imgdata.lens.makernotes.CameraMount = LIBRAW_MOUNT_Pentax_Q;
    break;
  default:
    imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_FixedLens;
    imgdata.lens.makernotes.CameraMount = LIBRAW_MOUNT_FixedLens;
  }
  return;
}

Project: LibRaw
File: dcraw.c

void CLASS parse_makernote_0xc634(int base, int uptag, unsigned dng_writer)
{
  unsigned ver97 = 0, offset = 0, entries, tag, type, len, save, c;
  unsigned i;

  uchar NikonKey, ci, cj, ck;
  unsigned serial = 0;
  unsigned custom_serial = 0;
  unsigned NikonLensDataVersion = 0;
  unsigned lenNikonLensData = 0;
  unsigned NikonFlashInfoVersion = 0;

  uchar *CanonCameraInfo;
  unsigned lenCanonCameraInfo = 0;
  unsigned typeCanonCameraInfo = 0;

  uchar *table_buf;
  uchar *table_buf_0x9050;
  ushort table_buf_0x9050_present = 0;
  uchar *table_buf_0x9402;
  ushort table_buf_0x9402_present = 0;
  uchar *table_buf_0x9403;
  ushort table_buf_0x9403_present = 0;
  uchar *table_buf_0x9406;
  ushort table_buf_0x9406_present = 0;
  uchar *table_buf_0x940c;
  ushort table_buf_0x940c_present = 0;
  uchar *table_buf_0x0116;
  ushort table_buf_0x0116_present = 0;

  short morder, sorder = order;
  char buf[10];
  INT64 fsize = ifp->size();

  fread(buf, 1, 10, ifp);

/*
  printf("===>>buf: 0x");
  for (int i = 0; i < sizeof buf; i ++) {
        printf("%02x", buf[i]);
  }
  putchar('\n');
*/

  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 ") ||
           (!strncmp(make, "SAMSUNG", 7) && (dng_writer == CameraDNG)))
  {
    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) && (dng_writer == AdobeDNG)))
      base = ftell(ifp);
  }

  entries = get2();
  if (entries > 1000)
    return;
  morder = order;

  while (entries--)
  {
    order = morder;
    tiff_get(base, &tag, &type, &len, &save);
    INT64 pos = ifp->tell();
    if (len > 8 && pos + len > 2 * fsize)
      continue;
    tag |= uptag << 16;
    if (len > 100 * 1024 * 1024)
      goto next; // 100Mb tag? No!

    if (!strncmp(make, "Canon", 5))
    {
      if (tag == 0x000d && len < 256000) // camera info
      {
        if (type != 4) {
          CanonCameraInfo = (uchar *)malloc(MAX(16,len));
          fread(CanonCameraInfo, len, 1, ifp);
        } else {
          CanonCameraInfo = (uchar *)malloc(MAX(16,len*4));
          fread(CanonCameraInfo, len, 4, ifp);
        }
        lenCanonCameraInfo = len;
        typeCanonCameraInfo = type;
      }

      else if (tag == 0x10) // Canon ModelID
      {
        unique_id = get4();
        unique_id = setCanonBodyFeatures(unique_id);
        if (lenCanonCameraInfo)
        {
          processCanonCameraInfo(unique_id, CanonCameraInfo, lenCanonCameraInfo, typeCanonCameraInfo);
          free(CanonCameraInfo);
          CanonCameraInfo = 0;
          lenCanonCameraInfo = 0;
        }
      }

      else
        parseCanonMakernotes(tag, type, len);
    }

    else if (!strncmp(make, "FUJI", 4))
      parseFujiMakernotes(tag, type);

    else if (!strncasecmp(make, "LEICA", 5))
    {

      if ((tag == 0x0320) && (type == 9) && (len == 1) &&
          !strncasecmp (make, "Leica Camera AG", 15)   &&
          !strncmp (buf, "LEICA", 5) && (buf[5] == 0) && (buf[6] == 0) && (buf[7] == 0)
         ) imgdata.other.CameraTemperature = getreal(type);

      if (tag == 0x34003402) imgdata.other.CameraTemperature = getreal(type);

      if (((tag == 0x035e) || (tag == 0x035f)) && (type == 10) && (len == 9))
      {
        int ind = tag == 0x035e ? 0 : 1;
        for (int j = 0; j < 3; j++)
          FORCC imgdata.color.dng_color[ind].forwardmatrix[j][c] = getreal(type);
        imgdata.color.dng_color[ind].parsedfields |= LIBRAW_DNGFM_FORWARDMATRIX;
      }
      if ((tag == 0x0303) && (type != 4))
      {
        stmread(imgdata.lens.makernotes.Lens, len, ifp);
      }

      if ((tag == 0x3405) || (tag == 0x0310) || (tag == 0x34003405))
      {
        imgdata.lens.makernotes.LensID = get4();
        imgdata.lens.makernotes.LensID =
            ((imgdata.lens.makernotes.LensID >> 2) << 8) | (imgdata.lens.makernotes.LensID & 0x3);
        if (imgdata.lens.makernotes.LensID != -1)
        {
          if ((model[0] == 'M') || !strncasecmp(model, "LEICA M", 7))
          {
            imgdata.lens.makernotes.CameraMount = LIBRAW_MOUNT_Leica_M;
            if (imgdata.lens.makernotes.LensID)
              imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_Leica_M;
          }
          else if ((model[0] == 'S') || !strncasecmp(model, "LEICA S", 7))
          {
            imgdata.lens.makernotes.CameraMount = LIBRAW_MOUNT_Leica_S;
            if (imgdata.lens.makernotes.Lens[0])
              imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_Leica_S;
          }
        }
      }

      else if (((tag == 0x0313) || (tag == 0x34003406)) && (fabs(imgdata.lens.makernotes.CurAp) < 0.17f) &&
               ((type == 10) || (type == 5)))
      {
        imgdata.lens.makernotes.CurAp = getreal(type);
        if (imgdata.lens.makernotes.CurAp > 126.3)
          imgdata.lens.makernotes.CurAp = 0.0f;
      }

      else if (tag == 0x3400)
      {
        parse_makernote(base, 0x3400);
      }
    }

    else if (!strncmp(make, "NIKON", 5))
    {
      if (tag == 0x1d) // serial number
        while ((c = fgetc(ifp)) && c != EOF)
        {
          if ((!custom_serial) && (!isdigit(c)))
          {
            if ((strbuflen(model) == 3) && (!strcmp(model, "D50")))
            {
              custom_serial = 34;
            }
            else
            {
              custom_serial = 96;
            }
          }
          serial = serial * 10 + (isdigit(c) ? c - '0' : c % 10);
        }
      else if (tag == 0x000a)
      {
        imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_FixedLens;
        imgdata.lens.makernotes.CameraMount = LIBRAW_MOUNT_FixedLens;
      }
      else if (tag == 0x0082) // lens attachment
      {
        stmread(imgdata.lens.makernotes.Attachment, len, ifp);
      }
      else if (tag == 0x0083) // lens type
      {
        imgdata.lens.nikon.NikonLensType = fgetc(ifp);
      }
      else if (tag == 0x0084) // lens
      {
        imgdata.lens.makernotes.MinFocal = getreal(type);
        imgdata.lens.makernotes.MaxFocal = getreal(type);
        imgdata.lens.makernotes.MaxAp4MinFocal = getreal(type);
        imgdata.lens.makernotes.MaxAp4MaxFocal = getreal(type);
      }
      else if (tag == 0x008b) // lens f-stops
      {
        uchar a, b, c;
        a = fgetc(ifp);
        b = fgetc(ifp);
        c = fgetc(ifp);
        if (c)
        {
          imgdata.lens.nikon.NikonLensFStops = a * b * (12 / c);
          imgdata.lens.makernotes.LensFStops = (float)imgdata.lens.nikon.NikonLensFStops / 12.0f;
        }
      }
      else if (tag == 0x0093)
      {
        imgdata.makernotes.nikon.NEFCompression = i = get2();
        if ((i == 7) || (i == 9))
        {
          imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_FixedLens;
          imgdata.lens.makernotes.CameraMount = LIBRAW_MOUNT_FixedLens;
        }
      }
      else if (tag == 0x0097)
      {
        for (i = 0; i < 4; i++)
          ver97 = ver97 * 10 + fgetc(ifp) - '0';
        if (ver97 == 601) // Coolpix A
        {
          imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_FixedLens;
          imgdata.lens.makernotes.CameraMount = LIBRAW_MOUNT_FixedLens;
        }
      }
      else if (tag == 0x0098) // contains lens data
      {
        for (i = 0; i < 4; i++)
        {
          NikonLensDataVersion = NikonLensDataVersion * 10 + fgetc(ifp) - '0';
        }
        switch (NikonLensDataVersion)
        {
        case 100:
          lenNikonLensData = 9;
          break;
        case 101:
        case 201: // encrypted, starting from v.201
        case 202:
        case 203:
          lenNikonLensData = 15;
          break;
        case 204:
          lenNikonLensData = 16;
          break;
        case 400:
          lenNikonLensData = 459;
          break;
        case 401:
          lenNikonLensData = 590;
          break;
        case 402:
          lenNikonLensData = 509;
          break;
        case 403:
          lenNikonLensData = 879;
          break;
        }
        if (lenNikonLensData)
        {
          table_buf = (uchar *)malloc(lenNikonLensData);
          fread(table_buf, lenNikonLensData, 1, ifp);
          if ((NikonLensDataVersion < 201) && lenNikonLensData)
          {
            processNikonLensData(table_buf, lenNikonLensData);
            free(table_buf);
            lenNikonLensData = 0;
          }
        }
      }

      else if (tag == 0xa7) // shutter count
      {
        NikonKey = fgetc(ifp) ^ fgetc(ifp) ^ fgetc(ifp) ^ fgetc(ifp);
        if ((NikonLensDataVersion > 200) && lenNikonLensData)
        {
          if (custom_serial)
          {
            ci = xlat[0][custom_serial];
          }
          else
          {
            ci = xlat[0][serial & 0xff];
          }
          cj = xlat[1][NikonKey];
          ck = 0x60;
          for (i = 0; i < lenNikonLensData; i++)
            table_buf[i] ^= (cj += ci * ck++);
          processNikonLensData(table_buf, lenNikonLensData);
          lenNikonLensData = 0;
          free(table_buf);
        }
      }
      else if (tag == 0x00a8) // contains flash data
      {
        for (i = 0; i < 4; i++)
        {
          NikonFlashInfoVersion = NikonFlashInfoVersion * 10 + fgetc(ifp) - '0';
        }
      }

      else if (tag == 37 && (!iso_speed || iso_speed == 65535))
      {
        unsigned char cc;
        fread(&cc, 1, 1, ifp);
        iso_speed = (int)(100.0 * powf64(2.0, (double)(cc) / 12.0 - 5.0));
        break;
      }
    }

    else if (!strncmp(make, "OLYMPUS", 7))
    {
      int SubDirOffsetValid = strncmp(model, "E-300", 5) && strncmp(model, "E-330", 5) && strncmp(model, "E-400", 5) &&
                              strncmp(model, "E-500", 5) && strncmp(model, "E-1", 3);

      if ((tag == 0x2010) || (tag == 0x2020))
      {
        fseek(ifp, save - 4, SEEK_SET);
        fseek(ifp, base + get4(), SEEK_SET);
        parse_makernote_0xc634(base, tag, dng_writer);
      }
      if (!SubDirOffsetValid && ((len > 4) || (((type == 3) || (type == 8)) && (len > 2)) ||
                                 (((type == 4) || (type == 9)) && (len > 1)) || (type == 5) || (type > 9)))
        goto skip_Oly_broken_tags;

      switch (tag)
      {
      case 0x0207:
      case 0x20100100:
      {
        uchar sOlyID[8];
        fread(sOlyID, MIN(len, 7), 1, ifp);
        sOlyID[7] = 0;
        OlyID = sOlyID[0];
        i = 1;
        while (i < 7 && sOlyID[i])
        {
          OlyID = OlyID << 8 | sOlyID[i];
          i++;
        }
        setOlympusBodyFeatures(OlyID);
      }
      break;
      case 0x1002:
        imgdata.lens.makernotes.CurAp = powf64(2.0f, getreal(type) / 2);
        break;
      case 0x20100102:
        stmread(imgdata.shootinginfo.InternalBodySerial, len, ifp);
        break;
      case 0x20100201:
        imgdata.lens.makernotes.LensID = (unsigned long long)fgetc(ifp) << 16 |
                                         (unsigned long long)(fgetc(ifp), fgetc(ifp)) << 8 |
                                         (unsigned long long)fgetc(ifp);
        imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_FT;
        imgdata.lens.makernotes.LensFormat = LIBRAW_FORMAT_FT;
        if (((imgdata.lens.makernotes.LensID < 0x20000) || (imgdata.lens.makernotes.LensID > 0x4ffff)) &&
            (imgdata.lens.makernotes.LensID & 0x10))
        {
          imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_mFT;
        }
        break;
      case 0x20100202:
        if ((!imgdata.lens.LensSerial[0]))
          stmread(imgdata.lens.LensSerial, len, ifp);
        break;
      case 0x20100203:
        stmread(imgdata.lens.makernotes.Lens, len, ifp);
        break;
      case 0x20100205:
        imgdata.lens.makernotes.MaxAp4MinFocal = powf64(sqrt(2.0f), get2() / 256.0f);
        break;
      case 0x20100206:
        imgdata.lens.makernotes.MaxAp4MaxFocal = powf64(sqrt(2.0f), get2() / 256.0f);
        break;
      case 0x20100207:
        imgdata.lens.makernotes.MinFocal = (float)get2();
        break;
      case 0x20100208:
        imgdata.lens.makernotes.MaxFocal = (float)get2();
        if (imgdata.lens.makernotes.MaxFocal > 1000.0f)
          imgdata.lens.makernotes.MaxFocal = imgdata.lens.makernotes.MinFocal;
        break;
      case 0x2010020a:
        imgdata.lens.makernotes.MaxAp4CurFocal = powf64(sqrt(2.0f), get2() / 256.0f);
        break;
      case 0x20100301:
        imgdata.lens.makernotes.TeleconverterID = fgetc(ifp) << 8;
        fgetc(ifp);
        imgdata.lens.makernotes.TeleconverterID = imgdata.lens.makernotes.TeleconverterID | fgetc(ifp);
        break;
      case 0x20100303:
        stmread(imgdata.lens.makernotes.Teleconverter, len, ifp);
        break;
      case 0x20100403:
        stmread(imgdata.lens.makernotes.Attachment, len, ifp);
        break;
      case 0x20200401:
        imgdata.other.FlashEC = getreal(type);
        break;
      case 0x1007:
        imgdata.other.SensorTemperature = (float)get2();
        break;
      case 0x1008:
        imgdata.other.LensTemperature = (float)get2();
        break;
      case 0x20401306:
        {
          int temp = get2();
          if ((temp != 0) && (temp != 100)) {
						if (temp < 61) imgdata.other.CameraTemperature = (float) temp;
						else imgdata.other.CameraTemperature = (float) (temp-32) / 1.8f;
						if ((OlyID == 0x4434353933ULL) &&   // TG-5
								(imgdata.other.exifAmbientTemperature > -273.15f))
							imgdata.other.CameraTemperature += imgdata.other.exifAmbientTemperature;
						}
        }
        break;
      case 0x20501500:
        if (OlyID != 0x0ULL) {
          short temp = get2();
          if ((OlyID == 0x4434303430ULL) || // E-1
              (OlyID == 0x5330303336ULL) || // E-M5
              (len != 1))
            imgdata.other.SensorTemperature = (float)temp;
          else if ((temp != -32768) && (temp != 0)) {
            if (temp > 199) imgdata.other.SensorTemperature = 86.474958f - 0.120228f*(float)temp;
            else imgdata.other.SensorTemperature = (float)temp;
          }
        }
        break;
      }
    skip_Oly_broken_tags:;
    }

    else if (!strncmp(make, "PENTAX", 6) || !strncmp(model, "PENTAX", 6) ||
             (!strncmp(make, "SAMSUNG", 7) && (dng_writer == CameraDNG)))
    {
      if (tag == 0x0005)
      {
        unique_id = get4();
        setPentaxBodyFeatures(unique_id);
      }
      else if (tag == 0x0013)
      {
        imgdata.lens.makernotes.CurAp = (float)get2() / 10.0f;
      }
      else if (tag == 0x0014)
      {
        PentaxISO(get2());
      }
      else if (tag == 0x001d)
      {
        imgdata.lens.makernotes.CurFocal = (float)get4() / 100.0f;
      }
      else if (tag == 0x003f)
      {
        imgdata.lens.makernotes.LensID = fgetc(ifp) << 8 | fgetc(ifp);
      }
      else if (tag == 0x0047)
      {
        imgdata.other.CameraTemperature = (float)fgetc(ifp);
      }
      else if (tag == 0x004d)
      {
        if (type == 9)
          imgdata.other.FlashEC = getreal(type) / 256.0f;
        else
          imgdata.other.FlashEC = (float)((signed short)fgetc(ifp)) / 6.0f;
      }
      else if (tag == 0x007e)
      {
        imgdata.color.linear_max[0] = imgdata.color.linear_max[1] = imgdata.color.linear_max[2] =
            imgdata.color.linear_max[3] = (long)(-1) * get4();
      }
      else if (tag == 0x0207)
      {
        if (len < 65535) // Safety belt
          PentaxLensInfo(imgdata.lens.makernotes.CamID, len);
      }
      else if ((tag >= 0x020d) && (tag <= 0x0214))
      {
        FORC4 imgdata.color.WB_Coeffs[Pentax_wb_list1[tag - 0x020d]][c ^ (c >> 1)] = get2();
      }
      else if (tag == 0x0221)
      {
        int nWB = get2();
        if (nWB <= sizeof(imgdata.color.WBCT_Coeffs) / sizeof(imgdata.color.WBCT_Coeffs[0]))
          for (int i = 0; i < nWB; i++)
          {
            imgdata.color.WBCT_Coeffs[i][0] = (unsigned)0xcfc6 - get2();
            fseek(ifp, 2, SEEK_CUR);
            imgdata.color.WBCT_Coeffs[i][1] = get2();
            imgdata.color.WBCT_Coeffs[i][2] = imgdata.color.WBCT_Coeffs[i][4] = 0x2000;
            imgdata.color.WBCT_Coeffs[i][3] = get2();
          }
      }
      else if (tag == 0x0215)
      {
        fseek(ifp, 16, SEEK_CUR);
        sprintf(imgdata.shootinginfo.InternalBodySerial, "%d", get4());
      }
      else if (tag == 0x0229)
      {
        stmread(imgdata.shootinginfo.BodySerial, len, ifp);
      }
      else if (tag == 0x022d)
      {
        int wb_ind;
        getc(ifp);
        for (int wb_cnt = 0; wb_cnt < nPentax_wb_list2; wb_cnt++)
        {
          wb_ind = getc(ifp);
          if (wb_ind < nPentax_wb_list2)
            FORC4 imgdata.color.WB_Coeffs[Pentax_wb_list2[wb_ind]][c ^ (c >> 1)] = get2();
        }
      }
      else if (tag == 0x0239) // Q-series lens info (LensInfoQ)
      {
        char LensInfo[20];
        fseek(ifp, 12, SEEK_CUR);
        stread(imgdata.lens.makernotes.Lens, 30, ifp);
        strcat(imgdata.lens.makernotes.Lens, " ");
        stread(LensInfo, 20, ifp);
        strcat(imgdata.lens.makernotes.Lens, LensInfo);
      }
    }

    else if (!strncmp(make, "SAMSUNG", 7) && (dng_writer == AdobeDNG))
    {
      if (tag == 0x0002)
      {
        if (get4() == 0x2000)
        {
          imgdata.lens.makernotes.CameraMount = LIBRAW_MOUNT_Samsung_NX;
        }
        else if (!strncmp(model, "NX mini", 7))
        {
          imgdata.lens.makernotes.CameraMount = LIBRAW_MOUNT_Samsung_NX_M;
        }
        else
        {
          imgdata.lens.makernotes.CameraMount = LIBRAW_MOUNT_FixedLens;
          imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_FixedLens;
        }
      }
      else if (tag == 0x0003)
      {
        imgdata.lens.makernotes.CamID = unique_id = get4();
      }
      else if (tag == 0x0043)
      {
        int temp = get4();
        if (temp) {
          imgdata.other.CameraTemperature = (float) temp;
          if (get4() == 10) imgdata.other.CameraTemperature /= 10.0f;
        }
      }
      else if (tag == 0xa003)
      {
        imgdata.lens.makernotes.LensID = get2();
        if (imgdata.lens.makernotes.LensID)
          imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_Samsung_NX;
      }
      else if (tag == 0xa005)
      {
        stmread(imgdata.lens.InternalLensSerial, len, ifp);
      }
      else if (tag == 0xa019)
      {
        imgdata.lens.makernotes.CurAp = getreal(type);
      }
      else if (tag == 0xa01a)
      {
        imgdata.lens.makernotes.FocalLengthIn35mmFormat = get4() / 10.0f;
        if (imgdata.lens.makernotes.FocalLengthIn35mmFormat < 10.0f)
          imgdata.lens.makernotes.FocalLengthIn35mmFormat *= 10.0f;
      }
    }

    else if (!strncasecmp(make, "SONY", 4) ||
             !strncasecmp(make, "Konica", 6) ||
             !strncasecmp(make, "Minolta", 7) ||
             (!strncasecmp(make, "Hasselblad", 10) &&
              (!strncasecmp(model, "Stellar", 7) ||
               !strncasecmp(model, "Lunar", 5) ||
               !strncasecmp(model, "Lusso", 5) ||
               !strncasecmp(model, "HV", 2))))
    {
      parseSonyMakernotes(tag, type, len, AdobeDNG,
                          table_buf_0x9050, table_buf_0x9050_present,
                          table_buf_0x940c, table_buf_0x940c_present,
                          table_buf_0x0116, table_buf_0x0116_present,
                          table_buf_0x9402, table_buf_0x9402_present,
                          table_buf_0x9403, table_buf_0x9403_present,
                          table_buf_0x9406, table_buf_0x9406_present);
    }
  next:
    fseek(ifp, save, SEEK_SET);
  }
quit:
  order = sorder;
}

Project: LibRaw
File: dcraw.c

void CLASS sony_load_raw()
{
  uchar head[40];
  ushort *pixel;
  unsigned i, key, row, col;

  fseek(ifp, 200896, SEEK_SET);
  fseek(ifp, (unsigned)fgetc(ifp) * 4 - 1, SEEK_CUR);
  order = 0x4d4d;
  key = get4();
  fseek(ifp, 164600, SEEK_SET);
  fread(head, 1, 40, ifp);
  sony_decrypt((unsigned *)head, 10, 1, key);
  for (i = 26; i-- > 22;)
    key = key << 8 | head[i];
  fseek(ifp, data_offset, SEEK_SET);
  for (row = 0; row < raw_height; row++)
  {
#ifdef LIBRAW_LIBRARY_BUILD
    checkCancel();
#endif
    pixel = raw_image + row * raw_width;
    if (fread(pixel, 2, raw_width, ifp) < raw_width)
      derror();
    sony_decrypt((unsigned *)pixel, raw_width / 2, !row, key);
    for (col = 0; col < raw_width; col++)
      if ((pixel[col] = ntohs(pixel[col])) >> 14)
        derror();
  }
  maximum = 0x3ff0;
}

Project: LibRaw
File: dcraw.c

void CLASS adobe_copy_pixel(unsigned row, unsigned col, ushort **rp)
{
  int c;

  if (tiff_samples == 2 && shot_select)
    (*rp)++;
  if (raw_image)
  {
    if (row < raw_height && col < raw_width)
      RAW(row, col) = curve[**rp];
    *rp += tiff_samples;
  }
  else
  {
#ifdef LIBRAW_LIBRARY_BUILD
    if (row < raw_height && col < raw_width)
    FORC(tiff_samples)
    image[row * raw_width + col][c] = curve[(*rp)[c]];
    *rp += tiff_samples;
#else
    if (row < height && col < width)
      FORC(tiff_samples)
    image[row * width + col][c] = curve[(*rp)[c]];
    *rp += tiff_samples;
#endif
  }
  if (tiff_samples == 2 && shot_select)
    (*rp)--;
}

Project: LibRaw
File: dcraw.c

int CLASS parse_jpeg(int offset)
{
  int len, save, hlen, mark;
  fseek(ifp, offset, SEEK_SET);
  if (fgetc(ifp) != 0xff || fgetc(ifp) != 0xd8)
    return 0;

  while (fgetc(ifp) == 0xff && (mark = fgetc(ifp)) != 0xda)
  {
    order = 0x4d4d;
    len = get2() - 2;
    save = ftell(ifp);
    if (mark == 0xc0 || mark == 0xc3 || mark == 0xc9)
    {
      fgetc(ifp);
      raw_height = get2();
      raw_width = get2();
    }
    order = get2();
    hlen = get4();
    if (get4() == 0x48454150
#ifdef LIBRAW_LIBRARY_BUILD
        && (save + hlen) >= 0 && (save + hlen) <= ifp->size()
#endif
    ) /* "HEAP" */
    {
#ifdef LIBRAW_LIBRARY_BUILD
      imgdata.lens.makernotes.CameraMount = LIBRAW_MOUNT_FixedLens;
      imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_FixedLens;
#endif
      parse_ciff(save + hlen, len - hlen, 0);
    }
    if (parse_tiff(save + 6))
      apply_tiff();
    fseek(ifp, save + len, SEEK_SET);
  }
  return 1;
}

Project: LibRaw
File: dcraw.c

void CLASS parseSonyMakernotes(unsigned tag, unsigned type, unsigned len, unsigned dng_writer,
                               uchar *&table_buf_0x9050, ushort &table_buf_0x9050_present,
                               uchar *&table_buf_0x940c, ushort &table_buf_0x940c_present,
                               uchar *&table_buf_0x0116, ushort &table_buf_0x0116_present,
                               uchar *&table_buf_0x9402, ushort &table_buf_0x9402_present,
                               uchar *&table_buf_0x9403, ushort &table_buf_0x9403_present,
                               uchar *&table_buf_0x9406, ushort &table_buf_0x9406_present)
{

  ushort lid;
  uchar *table_buf;

  if (tag == 0xb001) // Sony ModelID
  {
    unique_id = get2();
    setSonyBodyFeatures(unique_id);

    if (table_buf_0x0116_present) {
      process_Sony_0x0116(table_buf_0x0116, unique_id);
      free(table_buf_0x0116);
      table_buf_0x0116_present = 0;
    }

    if (table_buf_0x9050_present) {
      process_Sony_0x9050(table_buf_0x9050, unique_id);
      free(table_buf_0x9050);
      table_buf_0x9050_present = 0;
    }

    if (table_buf_0x9402_present) {
      process_Sony_0x9402(table_buf_0x9402);
      free(table_buf_0x9402);
      table_buf_0x9402_present = 0;
    }

    if (table_buf_0x9403_present) {
      process_Sony_0x9403(table_buf_0x9403);
      free(table_buf_0x9403);
      table_buf_0x9403_present = 0;
    }

    if (table_buf_0x9406_present) {
      process_Sony_0x9406(table_buf_0x9406);
      free(table_buf_0x9406);
      table_buf_0x9406_present = 0;
    }

    if (table_buf_0x940c_present) {
      if (imgdata.lens.makernotes.CameraMount == LIBRAW_MOUNT_Sony_E) {
        process_Sony_0x940c(table_buf_0x940c);
      }
      free(table_buf_0x940c);
      table_buf_0x940c_present = 0;
    }
  }

  else if ((tag == 0x0010) && // CameraInfo
           strncasecmp(model, "DSLR-A100", 9) && strncasecmp(model, "NEX-5C", 6) && !strncasecmp(make, "SONY", 4) &&
           ((len == 368) ||  // a700
            (len == 5478) || // a850, a900
            (len == 5506) || // a200, a300, a350
            (len == 6118) || // a230, a290, a330, a380, a390
                             // a450, a500, a550, a560, a580
                             // a33, a35, a55
                             // NEX3, NEX5, NEX5C, NEXC3, VG10E
            (len == 15360)))
  {
    table_buf = (uchar *)malloc(len);
    fread(table_buf, len, 1, ifp);
    if (memcmp(table_buf, "\xff\xff\xff\xff\xff\xff\xff\xff", 8) &&
        memcmp(table_buf, "\x00\x00\x00\x00\x00\x00\x00\x00", 8))
    {
      switch (len)
      {
      case 368:
      case 5478:
        // a700, a850, a900: CameraInfo
        if ((!dng_writer) ||
            (saneSonyCameraInfo(table_buf[0], table_buf[3], table_buf[2], table_buf[5], table_buf[4], table_buf[7])))
        {
          if (table_buf[0] | table_buf[3])
            imgdata.lens.makernotes.MinFocal = bcd2dec(table_buf[0]) * 100 + bcd2dec(table_buf[3]);
          if (table_buf[2] | table_buf[5])
            imgdata.lens.makernotes.MaxFocal = bcd2dec(table_buf[2]) * 100 + bcd2dec(table_buf[5]);
          if (table_buf[4])
            imgdata.lens.makernotes.MaxAp4MinFocal = bcd2dec(table_buf[4]) / 10.0f;
          if (table_buf[4])
            imgdata.lens.makernotes.MaxAp4MaxFocal = bcd2dec(table_buf[7]) / 10.0f;
          parseSonyLensFeatures(table_buf[1], table_buf[6]);
        }
        break;
      default:
        // CameraInfo2 & 3
        if ((!dng_writer) ||
            (saneSonyCameraInfo(table_buf[1], table_buf[2], table_buf[3], table_buf[4], table_buf[5], table_buf[6])))
        {
          if (table_buf[1] | table_buf[2])
            imgdata.lens.makernotes.MinFocal = bcd2dec(table_buf[1]) * 100 + bcd2dec(table_buf[2]);
          if (table_buf[3] | table_buf[4])
            imgdata.lens.makernotes.MaxFocal = bcd2dec(table_buf[3]) * 100 + bcd2dec(table_buf[4]);
          if (table_buf[5])
            imgdata.lens.makernotes.MaxAp4MinFocal = bcd2dec(table_buf[5]) / 10.0f;
          if (table_buf[6])
            imgdata.lens.makernotes.MaxAp4MaxFocal = bcd2dec(table_buf[6]) / 10.0f;
          parseSonyLensFeatures(table_buf[0], table_buf[7]);
        }
      }
    }
    free(table_buf);
  }

  else if ((!dng_writer) && (tag == 0x0020) && // WBInfoA100, needs 0xb028 processing
           !strncasecmp(model, "DSLR-A100", 9))
  {
    fseek(ifp, 0x49dc, SEEK_CUR);
    stmread(imgdata.shootinginfo.InternalBodySerial, 12, ifp);
  }

  else if (tag == 0x0104)
  {
    imgdata.other.FlashEC = getreal(type);
  }

  else if (tag == 0x0105) // Teleconverter
  {
    imgdata.lens.makernotes.TeleconverterID = get2();
  }

  else if (tag == 0x0114 && len < 256000) // CameraSettings
  {
    table_buf = (uchar *)malloc(len);
    fread(table_buf, len, 1, ifp);
    switch (len)
    {
    case 280:
    case 364:
    case 332:
      // CameraSettings and CameraSettings2 are big endian
      if (table_buf[2] | table_buf[3])
      {
        lid = (((ushort)table_buf[2]) << 8) | ((ushort)table_buf[3]);
        imgdata.lens.makernotes.CurAp = powf64(2.0f, ((float)lid / 8.0f - 1.0f) / 2.0f);
      }
      break;
    case 1536:
    case 2048:
      // CameraSettings3 are little endian
      parseSonyLensType2(table_buf[1016], table_buf[1015]);
      if (imgdata.lens.makernotes.LensMount != LIBRAW_MOUNT_Canon_EF)
      {
        switch (table_buf[153])
        {
        case 16:
          imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_Minolta_A;
          break;
        case 17:
          imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_Sony_E;
          break;
        }
      }
      break;
    }
    free(table_buf);
  }

  else if (tag == 0x0116  && len < 256000) {
    table_buf_0x0116 = (uchar *)malloc(len);
    table_buf_0x0116_present = 1;
    fread(table_buf_0x0116, len, 1, ifp);
    if (imgdata.lens.makernotes.CamID) {
      process_Sony_0x0116 (table_buf_0x0116, unique_id);
      free(table_buf_0x0116);
      table_buf_0x0116_present = 0;
    }
  }

  else if (tag == 0x9050 && len < 256000) // little endian
  {
    table_buf_0x9050 = (uchar *)malloc(len);
    table_buf_0x9050_present = 1;
    fread(table_buf_0x9050, len, 1, ifp);

    if (imgdata.lens.makernotes.CamID)
    {
      process_Sony_0x9050(table_buf_0x9050, imgdata.lens.makernotes.CamID);
      free(table_buf_0x9050);
      table_buf_0x9050_present = 0;
    }
  }

  else if (tag == 0x9402 && len < 256000) {
    table_buf_0x9402 = (uchar *)malloc(len);
    table_buf_0x9402_present = 1;
    fread(table_buf_0x9402, len, 1, ifp);
    if (imgdata.lens.makernotes.CamID) {
      process_Sony_0x9402(table_buf_0x9402);
      free(table_buf_0x9402);
      table_buf_0x9402_present = 0;
    }
  }

    else if (tag == 0x9403 && len < 256000) {
    table_buf_0x9403 = (uchar *)malloc(len);
    table_buf_0x9403_present = 1;
    fread(table_buf_0x9403, len, 1, ifp);
    if (imgdata.lens.makernotes.CamID) {
      process_Sony_0x9403(table_buf_0x9403);
      free(table_buf_0x9403);
      table_buf_0x9403_present = 0;
    }
  }

  else if (tag == 0x9406 && len < 256000) {
    table_buf_0x9406 = (uchar *)malloc(len);
    table_buf_0x9406_present = 1;
    fread(table_buf_0x9406, len, 1, ifp);
    if (imgdata.lens.makernotes.CamID) {
      process_Sony_0x9406(table_buf_0x9406);
      free(table_buf_0x9406);
      table_buf_0x9406_present = 0;
    }
  }

  else if (tag == 0x940c && len < 256000)
  {
    table_buf_0x940c = (uchar *)malloc(len);
    table_buf_0x940c_present = 1;
    fread(table_buf_0x940c, len, 1, ifp);
    if ((imgdata.lens.makernotes.CamID) && (imgdata.lens.makernotes.CameraMount == LIBRAW_MOUNT_Sony_E))
    {
      process_Sony_0x940c(table_buf_0x940c);
      free(table_buf_0x940c);
      table_buf_0x940c_present = 0;
    }
  }

  else if (((tag == 0xb027) || (tag == 0x010c)) && (imgdata.lens.makernotes.LensID == -1))
  {
    imgdata.lens.makernotes.LensID = get4();
    if ((imgdata.lens.makernotes.LensID > 0x4900) && (imgdata.lens.makernotes.LensID <= 0x5900))
    {
      imgdata.lens.makernotes.AdapterID = 0x4900;
      imgdata.lens.makernotes.LensID -= imgdata.lens.makernotes.AdapterID;
      imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_Sigma_X3F;
      strcpy(imgdata.lens.makernotes.Adapter, "MC-11");
    }

    else if ((imgdata.lens.makernotes.LensID > 0xEF00) && (imgdata.lens.makernotes.LensID < 0xFFFF) &&
             (imgdata.lens.makernotes.LensID != 0xFF00))
    {
      imgdata.lens.makernotes.AdapterID = 0xEF00;
      imgdata.lens.makernotes.LensID -= imgdata.lens.makernotes.AdapterID;
      imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_Canon_EF;
    }
    if (tag == 0x010c)
      imgdata.lens.makernotes.CameraMount = LIBRAW_MOUNT_Minolta_A;
  }

  else if (tag == 0xb02a && len < 256000) // Sony LensSpec
  {
    table_buf = (uchar *)malloc(len);
    fread(table_buf, len, 1, ifp);
    if ((!dng_writer) ||
        (saneSonyCameraInfo(table_buf[1], table_buf[2], table_buf[3], table_buf[4], table_buf[5], table_buf[6])))
    {
      if (table_buf[1] | table_buf[2])
        imgdata.lens.makernotes.MinFocal = bcd2dec(table_buf[1]) * 100 + bcd2dec(table_buf[2]);
      if (table_buf[3] | table_buf[4])
        imgdata.lens.makernotes.MaxFocal = bcd2dec(table_buf[3]) * 100 + bcd2dec(table_buf[4]);
      if (table_buf[5])
        imgdata.lens.makernotes.MaxAp4MinFocal = bcd2dec(table_buf[5]) / 10.0f;
      if (table_buf[6])
        imgdata.lens.makernotes.MaxAp4MaxFocal = bcd2dec(table_buf[6]) / 10.0f;
      parseSonyLensFeatures(table_buf[0], table_buf[7]);
    }
    free(table_buf);
  }
}

Project: LibRaw
File: dcraw.c

void CLASS read_shorts(ushort *pixel, int count)
{
  if (fread(pixel, 2, count, ifp) < count)
    derror();
  if ((order == 0x4949) == (ntohs(0x1234) == 0x1234))
    swab((char *)pixel, (char *)pixel, count * 2);
}

Project: LibRaw
File: dcraw.c

void CLASS parse_kodak_ifd(int base)
{
  unsigned entries, tag, type, len, save;
  int i, c, wbi = -2, wbtemp = 6500;
  float mul[3] = {1, 1, 1}, num;
  static const int wbtag[] = {64037, 64040, 64039, 64041, -1, -1, 64042};

  entries = get2();
  if (entries > 1024)
    return;
  while (entries--)
  {
    tiff_get(base, &tag, &type, &len, &save);
    if (tag == 1020)
      wbi = getint(type);
    if (tag == 1021 && len == 72)
    { /* WB set in software */
      fseek(ifp, 40, SEEK_CUR);
      FORC3 cam_mul[c] = 2048.0 / fMAX(1.0, get2());
      wbi = -2;
    }
    if (tag == 2118)
      wbtemp = getint(type);
    if (tag == 2120 + wbi && wbi >= 0)
      FORC3 cam_mul[c] = 2048.0 / fMAX(1.0, getreal(type));
    if (tag == 2130 + wbi)
      FORC3 mul[c] = getreal(type);
    if (tag == 2140 + wbi && wbi >= 0)
      FORC3
      {
        for (num = i = 0; i < 4; i++)
          num += getreal(type) * pow(wbtemp / 100.0, i);
        cam_mul[c] = 2048 / fMAX(1.0, (num * mul[c]));
      }
    if (tag == 2317)
      linear_table(len);
    if (tag == 6020)
      iso_speed = getint(type);
    if (tag == 64013)
      wbi = fgetc(ifp);
    if ((unsigned)wbi < 7 && tag == wbtag[wbi])
      FORC3 cam_mul[c] = get4();
    if (tag == 64019)
      width = getint(type);
    if (tag == 64020)
      height = (getint(type) + 1) & -2;
    fseek(ifp, save, SEEK_SET);
  }
}

Project: LibRaw
File: dcraw.c

void CLASS samsung3_load_raw()
{
  int opt, init, mag, pmode, row, tab, col, pred, diff, i, c;
  ushort lent[3][2], len[4], *prow[2];

  order = 0x4949;
  fseek(ifp, 9, SEEK_CUR);
  opt = fgetc(ifp);
  init = (get2(), get2());
  for (row = 0; row < raw_height; row++)
  {
#ifdef LIBRAW_LIBRARY_BUILD
    checkCancel();
#endif
    fseek(ifp, (data_offset - ftell(ifp)) & 15, SEEK_CUR);
    ph1_bits(-1);
    mag = 0;
    pmode = 7;
    FORC(6)((ushort *)lent)[c] = row < 2 ? 7 : 4;
    prow[row & 1] = &RAW(row - 1, 1 - ((row & 1) << 1)); // green
    prow[~row & 1] = &RAW(row - 2, 0);                   // red and blue
    for (tab = 0; tab + 15 < raw_width; tab += 16)
    {
      if (~opt & 4 && !(tab & 63))
      {
        i = ph1_bits(2);
        mag = i < 3 ? mag - '2' + "204"[i] : ph1_bits(12);
      }
      if (opt & 2)
        pmode = 7 - 4 * ph1_bits(1);
      else if (!ph1_bits(1))
        pmode = ph1_bits(3);
      if (opt & 1 || !ph1_bits(1))
      {
        FORC4 len[c] = ph1_bits(2);
        FORC4
        {
          i = ((row & 1) << 1 | (c & 1)) % 3;
          len[c] = len[c] < 3 ? lent[i][0] - '1' + "120"[len[c]] : ph1_bits(4);
          lent[i][0] = lent[i][1];
          lent[i][1] = len[c];
        }
      }
      FORC(16)
      {
        col = tab + (((c & 7) << 1) ^ (c >> 3) ^ (row & 1));
        pred =
            (pmode == 7 || row < 2)
                ? (tab ? RAW(row, tab - 2 + (col & 1)) : init)
                : (prow[col & 1][col - '4' + "0224468"[pmode]] + prow[col & 1][col - '4' + "0244668"[pmode]] + 1) >> 1;
        diff = ph1_bits(i = len[c >> 2]);
        if (diff >> (i - 1))
          diff -= 1 << i;
        diff = diff * (mag * 2 + 1) + mag;
        RAW(row, col) = pred + diff;
      }
    }
  }
}

Project: LibRaw
File: dcraw.c

double CLASS getreal(int type)
{
  union {
    char c[8];
    double d;
  } u, v;
  int i, rev;

  switch (type)
  {
  case 3:
    return (unsigned short)get2();
  case 4:
    return (unsigned int)get4();
  case 5:
    u.d = (unsigned int)get4();
    v.d = (unsigned int)get4();
    return u.d / (v.d ? v.d : 1);
  case 8:
    return (signed short)get2();
  case 9:
    return (signed int)get4();
  case 10:
    u.d = (signed int)get4();
    v.d = (signed int)get4();
    return u.d / (v.d ? v.d : 1);
  case 11:
    return int_to_float(get4());
  case 12:
    rev = 7 * ((order == 0x4949) == (ntohs(0x1234) == 0x1234));
    for (i = 0; i < 8; i++)
      u.c[i ^ rev] = fgetc(ifp);
    return u.d;
  default:
    return fgetc(ifp);
  }
}

Project: LibRaw
File: dcraw.c

void CLASS unpacked_load_raw()
{
  int row, col, bits = 0;
  while (1 << ++bits < maximum)
    ;
  read_shorts(raw_image, raw_width * raw_height);
  if (maximum < 0xffff || load_flags)
    for (row = 0; row < raw_height; row++)
    {
#ifdef LIBRAW_LIBRARY_BUILD
      checkCancel();
#endif
      for (col = 0; col < raw_width; col++)
        if ((RAW(row, col) >>= load_flags) >> bits && (unsigned)(row - top_margin) < height &&
            (unsigned)(col - left_margin) < width)
          derror();
    }
}

Project: LibRaw
File: dcraw.c

void CLASS process_Sony_0x9406(uchar *buf) {

  short bufx = SonySubstitution[buf[0]];
  if ((bufx != 0x00) &&
      (bufx == 0x01) &&
      (bufx == 0x03)) return;
  bufx = SonySubstitution[buf[2]];
  if ((bufx != 0x02) &&
      (bufx == 0x03)) return;

  imgdata.other.BatteryTemperature = (float) (SonySubstitution[buf[5]]-32) / 1.8f;

  return;
}

Project: LibRaw
File: dcraw.c

void CLASS panasonic_16x10_load_raw()
{
#ifdef LIBRAW_LIBRARY_BUILD
	throw LIBRAW_EXCEPTION_DECODE_RAW;
#endif
}

Project: LibRaw
File: dcraw.c

void CLASS parse_kodak_ifd(int base)
{
  unsigned entries, tag, type, len, save;
  int i, c, wbi = -2;
  float mul[3] = {1, 1, 1}, num;
  static const int wbtag[] = {64037, 64040, 64039, 64041, -1, -1, 64042};
  //  int a_blck = 0;

  entries = get2();
  if (entries > 1024)
    return;
  INT64 fsize = ifp->size();
  while (entries--)
  {
    tiff_get(base, &tag, &type, &len, &save);
    INT64 savepos = ftell(ifp);
    if (len > 8 && len + savepos > 2 * fsize)
      continue;
    if (callbacks.exif_cb)
    {
      callbacks.exif_cb(callbacks.exifparser_data, tag | 0x20000, type, len, order, ifp);
      fseek(ifp, savepos, SEEK_SET);
    }
    if (tag == 1011)
      imgdata.other.FlashEC = getreal(type);
    if (tag == 1020)
      wbi = getint(type);
    if (tag == 1021 && len == 72)
    { /* WB set in software */
      fseek(ifp, 40, SEEK_CUR);
      FORC3 cam_mul[c] = 2048.0 / fMAX(1.0f, get2());
      wbi = -2;
    }

    if ((tag == 1030) && (len == 1))
      imgdata.other.CameraTemperature = getreal(type);
    if ((tag == 1043) && (len == 1))
      imgdata.other.SensorTemperature = getreal(type);

    if ((tag == 0x03ef) && (!strcmp(model, "EOS D2000C")))
      black = get2();
    if ((tag == 0x03f0) && (!strcmp(model, "EOS D2000C")))
    {
      if (black) // already set by tag 0x03ef
        black = (black + get2()) / 2;
      else
        black = get2();
    }
    INT64 _pos2 = ftell(ifp);
    if (tag == 0x0848)
      Kodak_WB_0x08tags(LIBRAW_WBI_Daylight, type);
    if (tag == 0x0849)
      Kodak_WB_0x08tags(LIBRAW_WBI_Tungsten, type);
    if (tag == 0x084a)
      Kodak_WB_0x08tags(LIBRAW_WBI_Fluorescent, type);
    if (tag == 0x084b)
      Kodak_WB_0x08tags(LIBRAW_WBI_Flash, type);
    if (tag == 0x084c)
      Kodak_WB_0x08tags(LIBRAW_WBI_Custom, type);
    if (tag == 0x084d)
      Kodak_WB_0x08tags(LIBRAW_WBI_Auto, type);
    if (tag == 0x0e93)
      imgdata.color.linear_max[0] = imgdata.color.linear_max[1] = imgdata.color.linear_max[2] =
          imgdata.color.linear_max[3] = get2();
    if (tag == 0x09ce)
      stmread(imgdata.shootinginfo.InternalBodySerial, len, ifp);
    if (tag == 0xfa00)
      stmread(imgdata.shootinginfo.BodySerial, len, ifp);
    if (tag == 0xfa27)
    {
      FORC3 imgdata.color.WB_Coeffs[LIBRAW_WBI_Tungsten][c] = get4();
      imgdata.color.WB_Coeffs[LIBRAW_WBI_Tungsten][3] = imgdata.color.WB_Coeffs[LIBRAW_WBI_Tungsten][1];
    }
    if (tag == 0xfa28)
    {
      FORC3 imgdata.color.WB_Coeffs[LIBRAW_WBI_Fluorescent][c] = get4();
      imgdata.color.WB_Coeffs[LIBRAW_WBI_Fluorescent][3] = imgdata.color.WB_Coeffs[LIBRAW_WBI_Fluorescent][1];
    }
    if (tag == 0xfa29)
    {
      FORC3 imgdata.color.WB_Coeffs[LIBRAW_WBI_Daylight][c] = get4();
      imgdata.color.WB_Coeffs[LIBRAW_WBI_Daylight][3] = imgdata.color.WB_Coeffs[LIBRAW_WBI_Daylight][1];
    }
    if (tag == 0xfa2a)
    {
      FORC3 imgdata.color.WB_Coeffs[LIBRAW_WBI_Shade][c] = get4();
      imgdata.color.WB_Coeffs[LIBRAW_WBI_Shade][3] = imgdata.color.WB_Coeffs[LIBRAW_WBI_Shade][1];
    }

    fseek(ifp, _pos2, SEEK_SET);

    if (tag == 2120 + wbi || (wbi < 0 && tag == 2125)) /* use Auto WB if illuminant index is not set */
    {
      FORC3 mul[c] = (num = getreal(type)) == 0 ? 1 : num;
      FORC3 cam_mul[c] = mul[1] / mul[c]; /* normalise against green */
    }
    if (tag == 2317)
      linear_table(len);
    if (tag == 0x903)
      iso_speed = getreal(type);
    // if (tag == 6020) iso_speed = getint(type);
    if (tag == 64013)
      wbi = fgetc(ifp);
    if ((unsigned)wbi < 7 && tag == wbtag[wbi])
      FORC3 cam_mul[c] = get4();
    if (tag == 64019)
      width = getint(type);
    if (tag == 64020)
      height = (getint(type) + 1) & -2;
    fseek(ifp, save, SEEK_SET);
  }
}

Project: LibRaw
File: dcraw.c

void CLASS kodak_rgb_load_raw()
{
  short buf[768], *bp;
  int row, col, len, c, i, rgb[3], ret;
  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);
      ret = kodak_65000_decode(buf, len * 3);
      memset(rgb, 0, sizeof rgb);
      for (bp = buf, i = 0; i < len; i++, ip += 4)
#ifdef LIBRAW_LIBRARY_BUILD
        if (load_flags == 12)
        {
          FORC3 ip[c] = ret ? (*bp++) : (rgb[c] += *bp++);
        }
        else
#endif
          FORC3 if ((ip[c] = ret ? (*bp++) : (rgb[c] += *bp++)) >> 12) derror();
    }
  }
}

Project: LibRaw
File: dcraw.c

void CLASS parse_gps_libraw(int base)
{
  unsigned entries, tag, type, len, save, c;

  entries = get2();
  if (entries > 200)
    return;
  if (entries > 0)
    imgdata.other.parsed_gps.gpsparsed = 1;
  while (entries--)
  {
    tiff_get(base, &tag, &type, &len, &save);
    if (len > 1024)
      continue; // no GPS tags are 1k or larger
    switch (tag)
    {
    case 1:
      imgdata.other.parsed_gps.latref = getc(ifp);
      break;
    case 3:
      imgdata.other.parsed_gps.longref = getc(ifp);
      break;
    case 5:
      imgdata.other.parsed_gps.altref = getc(ifp);
      break;
    case 2:
      if (len == 3)
        FORC(3) imgdata.other.parsed_gps.latitude[c] = getreal(type);
      break;
    case 4:
      if (len == 3)
        FORC(3) imgdata.other.parsed_gps.longtitude[c] = getreal(type);
      break;
    case 7:
      if (len == 3)
        FORC(3) imgdata.other.parsed_gps.gpstimestamp[c] = getreal(type);
      break;
    case 6:
      imgdata.other.parsed_gps.altitude = getreal(type);
      break;
    case 9:
      imgdata.other.parsed_gps.gpsstatus = getc(ifp);
      break;
    }
    fseek(ifp, save, SEEK_SET);
  }
}

Project: LibRaw
File: dcraw.c

void CLASS Kodak_WB_0x08tags(int wb, unsigned type)
{
  float mul[3] = {1, 1, 1}, num, mul2;
  int c;
  FORC3 mul[c] = (num = getreal(type)) == 0 ? 1 : num;
  imgdata.color.WB_Coeffs[wb][1] = imgdata.color.WB_Coeffs[wb][3] = mul[1];
  mul2 = mul[1] * mul[1];
  imgdata.color.WB_Coeffs[wb][0] = mul2 / mul[0];
  imgdata.color.WB_Coeffs[wb][2] = mul2 / mul[2];
  return;
}

Project: LibRaw
File: dcraw.c

void CLASS process_Sony_0x9402(uchar *buf) {

  if (buf[2] != 0xff) return;
  short bufx = SonySubstitution[buf[0]];
  if ((bufx < 0x0f) ||
      (bufx > 0x1a) ||
      (bufx == 0x16) ||
      (bufx == 0x18)) return;

  imgdata.other.AmbientTemperature = (float) ((short) SonySubstitution[buf[4]]);

  return;
}

Project: LibRaw
File: dcraw.c

void CLASS kodak_radc_load_raw()
{
  static const signed char src[] = {
      1, 1,   2, 3,   3, 4,   4, 2,   5, 7,   6, 5,   7, 6,  7, 8,   1, 0,   2, 1,  3, 3,  4, 4,  5, 2,   6, 7,   7, 6,
      8, 5,   8, 8,   2, 1,   2, 3,   3, 0,   3, 2,   3, 4,  4, 6,   5, 5,   6, 7,  6, 8,  2, 0,  2, 1,   2, 3,   3, 2,
      4, 4,   5, 6,   6, 7,   7, 5,   7, 8,   2, 1,   2, 4,  3, 0,   3, 2,   3, 3,  4, 7,  5, 5,  6, 6,   6, 8,   2, 3,
      3, 1,   3, 2,   3, 4,   3, 5,   3, 6,   4, 7,   5, 0,  5, 8,   2, 3,   2, 6,  3, 0,  3, 1,  4, 4,   4, 5,   4, 7,
      5, 2,   5, 8,   2, 4,   2, 7,   3, 3,   3, 6,   4, 1,  4, 2,   4, 5,   5, 0,  5, 8,  2, 6,  3, 1,   3, 3,   3, 5,
      3, 7,   3, 8,   4, 0,   5, 2,   5, 4,   2, 0,   2, 1,  3, 2,   3, 3,   4, 4,  4, 5,  5, 6,  5, 7,   4, 8,   1, 0,
      2, 2,   2, -2,  1, -3,  1, 3,   2, -17, 2, -5,  2, 5,  2, 17,  2, -7,  2, 2,  2, 9,  2, 18, 2, -18, 2, -9,  2, -2,
      2, 7,   2, -28, 2, 28,  3, -49, 3, -9,  3, 9,   4, 49, 5, -79, 5, 79,  2, -1, 2, 13, 2, 26, 3, 39,  4, -16, 5, 55,
      6, -37, 6, 76,  2, -26, 2, -13, 2, 1,   3, -39, 4, 16, 5, -55, 6, -76, 6, 37};
  ushort huff[19][256];
  int row, col, tree, nreps, rep, step, i, c, s, r, x, y, val;
  short last[3] = {16, 16, 16}, mul[3], buf[3][3][386];
  static const ushort pt[] = {0, 0, 1280, 1344, 2320, 3616, 3328, 8000, 4095, 16383, 65535, 16383};

  for (i = 2; i < 12; i += 2)
    for (c = pt[i - 2]; c <= pt[i]; c++)
      curve[c] = (float)(c - pt[i - 2]) / (pt[i] - pt[i - 2]) * (pt[i + 1] - pt[i - 1]) + pt[i - 1] + 0.5;
  for (s = i = 0; i < sizeof src; i += 2)
    FORC(256 >> src[i])
  ((ushort *)huff)[s++] = src[i] << 8 | (uchar)src[i + 1];
  s = kodak_cbpp == 243 ? 2 : 3;
  FORC(256) huff[18][c] = (8 - s) << 8 | c >> s << s | 1 << (s - 1);
  getbits(-1);
  for (i = 0; i < sizeof(buf) / sizeof(short); i++)
    ((short *)buf)[i] = 2048;
  for (row = 0; row < height; row += 4)
  {
#ifdef LIBRAW_LIBRARY_BUILD
    checkCancel();
#endif
    FORC3 mul[c] = getbits(6);
#ifdef LIBRAW_LIBRARY_BUILD
    if(!mul[0] || !mul[1] || !mul[2])
      throw LIBRAW_EXCEPTION_IO_CORRUPT;
#endif
    FORC3
    {
      val = ((0x1000000 / last[c] + 0x7ff) >> 12) * mul[c];
      s = val > 65564 ? 10 : 12;
      x = ~((~0u) << (s - 1));
      val <<= 12 - s;
      for (i = 0; i < sizeof(buf[0]) / sizeof(short); i++)
        ((short *)buf[c])[i] = (((short *)buf[c])[i] * val + x) >> s;
      last[c] = mul[c];
      for (r = 0; r <= !c; r++)
      {
        buf[c][1][width / 2] = buf[c][2][width / 2] = mul[c] << 7;
        for (tree = 1, col = width / 2; col > 0;)
        {
          if ((tree = radc_token(tree)))
          {
            col -= 2;
            if (tree == 8)
              FORYX buf[c][y][x] = (uchar)radc_token(18) * mul[c];
            else
              FORYX buf[c][y][x] = radc_token(tree + 10) * 16 + PREDICTOR;
          }
          else
            do
            {
              nreps = (col > 2) ? radc_token(9) + 1 : 1;
              for (rep = 0; rep < 8 && rep < nreps && col > 0; rep++)
              {
                col -= 2;
                FORYX buf[c][y][x] = PREDICTOR;
                if (rep & 1)
                {
                  step = radc_token(10) << 4;
                  FORYX buf[c][y][x] += step;
                }
              }
            } while (nreps == 9);
        }
        for (y = 0; y < 2; y++)
          for (x = 0; x < width / 2; x++)
          {
            val = (buf[c][y + 1][x] << 4) / mul[c];
            if (val < 0)
              val = 0;
            if (c)
              RAW(row + y * 2 + c - 1, x * 2 + 2 - c) = val;
            else
              RAW(row + r * 2 + y, x * 2 + y) = val;
          }
        memcpy(buf[c][0] + !c, buf[c][2], sizeof buf[c][0] - 2 * !c);
      }
    }
    for (y = row; y < row + 4; y++)
      for (x = 0; x < width; x++)
        if ((x + y) & 1)
        {
          r = x ? x - 1 : x + 1;
          s = x + 1 < width ? x + 1 : x - 1;
          val = (RAW(y, x) - 2048) * 2 + (RAW(y, r) + RAW(y, s)) / 2;
          if (val < 0)
            val = 0;
          RAW(y, x) = val;
        }
  }
  for (i = 0; i < height * width; i++)
    raw_image[i] = curve[raw_image[i]];
  maximum = 0x3fff;
}