Commit message: Development branch merged to master
CVE: CVE-2020-24889
Vulnerability description: A buffer overflow vulnerability in LibRaw version < 20.0 LibRaw::GetNormalizedModel in src/metadata/normalize_model.cpp may lead to context-dependent arbitrary code execution.

Project: LibRaw

void LibRaw::parseCanonMakernotes(unsigned tag, unsigned type, unsigned len, unsigned dng_writer)
{
  int c;
  unsigned i;

  if (tag == 0x0001) {
    Canon_CameraSettings(len);

  } else if (tag == 0x0002) { // focal length
    ilm.FocalType = get2();
    ilm.CurFocal = get2();
    if (ilm.FocalUnits > 1) {
      ilm.CurFocal /= (float)ilm.FocalUnits;
    }

  } else if (tag == 0x0004) { // subdir, ShotInfo
    short tempAp;
    if (dng_writer == nonDNG) {
      if ((i = (get4(), get2())) != 0x7fff &&
          (!iso_speed || iso_speed == 65535)) {
        iso_speed = 50 * libraw_powf64l(2.0, i / 32.0 - 4);
      }
      get4();
      if (((i = get2()) != 0xffff) && !shutter) {
        shutter = libraw_powf64l(2.0, (short)i / -32.0);
      }
      imCanon.wbi = (get2(), get2());
      shot_order = (get2(), get2());
      fseek(ifp, 4, SEEK_CUR);
    } else
      fseek(ifp, 24, SEEK_CUR);
    tempAp = get2();
    if (tempAp != 0)
      imgdata.makernotes.common.CameraTemperature = (float)(tempAp - 128);
    tempAp = get2();
    if (tempAp != -1)
      imgdata.makernotes.common.FlashGN = ((float)tempAp) / 32;
    get2();

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

  } else if ((tag == 0x0007) && (dng_writer == nonDNG)) {
    fgets(model2, 64, ifp);

  } else if ((tag == 0x0008) && (dng_writer == nonDNG)) {
    shot_order = get4();

  } else if ((tag == 0x0009)  && (dng_writer == nonDNG)) {
    fread(artist, 64, 1, ifp);

  } else if (tag == 0x000c) {
    unsigned tS = get4();
    sprintf(imgdata.shootinginfo.BodySerial, "%d", tS);

  } else if ((tag == 0x0029) && (dng_writer == nonDNG)) { // PowerShot G9
      c = imCanon.wbi < 18 ? "012347800000005896"[imCanon.wbi] - '0' : 0;
      fseek(ifp, 8 + c * 32, SEEK_CUR);
      FORC4 cam_mul[c ^ (c >> 1) ^ 1] = get4();

  } else if ((tag == 0x0081) && (dng_writer == nonDNG)) { // EOS-1D, EOS-1DS
    data_offset = get4();
    fseek(ifp, data_offset + 41, SEEK_SET);
    raw_height = get2() * 2;
    raw_width = get2();
    filters = 0x61616161;

  } else if (tag == 0x0095 && !ilm.Lens[0])
  { // lens model tag
    fread(ilm.Lens, 64, 1, ifp);
    if (!strncmp(ilm.Lens, "EF-S", 4))
    {
      memmove(ilm.Lens + 5, ilm.Lens + 4, 60);
      ilm.Lens[4] = ' ';
      memcpy(ilm.LensFeatures_pre, ilm.Lens, 4);
      ilm.LensMount = LIBRAW_MOUNT_Canon_EF_S;
      ilm.LensFormat = LIBRAW_FORMAT_APSC;
    }
    else if (!strncmp(ilm.Lens, "EF-M", 4))
    {
      memmove(ilm.Lens + 5, ilm.Lens + 4, 60);
      ilm.Lens[4] = ' ';
      memcpy(ilm.LensFeatures_pre, ilm.Lens, 4);
      ilm.LensMount = LIBRAW_MOUNT_Canon_EF_M;
      ilm.LensFormat = LIBRAW_FORMAT_APSC;
    }
    else if (!strncmp(ilm.Lens, "EF", 2))
    {
      memmove(ilm.Lens + 3, ilm.Lens + 2, 62);
      ilm.Lens[2] = ' ';
      memcpy(ilm.LensFeatures_pre, ilm.Lens, 2);
      ilm.LensMount = LIBRAW_MOUNT_Canon_EF;
      ilm.LensFormat = LIBRAW_FORMAT_FF;
    }
    else if (!strncmp(ilm.Lens, "CN-E", 4))
    {
      memmove(ilm.Lens + 5, ilm.Lens + 4, 60);
      ilm.Lens[4] = ' ';
      memcpy(ilm.LensFeatures_pre, ilm.Lens, 4);
      ilm.LensMount = LIBRAW_MOUNT_Canon_EF;
      ilm.LensFormat = LIBRAW_FORMAT_FF;
    }
    else if (!strncmp(ilm.Lens, "TS-E", 4))
    {
      memmove(ilm.Lens + 5, ilm.Lens + 4, 60);
      ilm.Lens[4] = ' ';
      memcpy(ilm.LensFeatures_pre, ilm.Lens, 4);
      ilm.LensMount = LIBRAW_MOUNT_Canon_EF;
      ilm.LensFormat = LIBRAW_FORMAT_FF;
    }
    else if (!strncmp(ilm.Lens, "MP-E", 4))
    {
      memmove(ilm.Lens + 5, ilm.Lens + 4, 60);
      ilm.Lens[4] = ' ';
      memcpy(ilm.LensFeatures_pre, ilm.Lens, 4);
      ilm.LensMount = LIBRAW_MOUNT_Canon_EF;
      ilm.LensFormat = LIBRAW_FORMAT_FF;
    }
    else if (!strncmp(ilm.Lens, "RF", 2))
    {
      memmove(ilm.Lens + 3, ilm.Lens + 2, 62);
      ilm.Lens[2] = ' ';
      memcpy(ilm.LensFeatures_pre, ilm.Lens, 2);
      ilm.LensMount = LIBRAW_MOUNT_Canon_RF;
      ilm.LensFormat = LIBRAW_FORMAT_FF;
    }
  }
  else if (tag == 0x009a)
  { // AspectInfo
    i = get4();
    switch (i)
    {
    case 0:
    case 12: /* APS-H crop */
    case 13: /* APS-C crop */
      imgdata.sizes.raw_inset_crop.aspect = LIBRAW_IMAGE_ASPECT_3to2;
      break;
    case 1:
      imgdata.sizes.raw_inset_crop.aspect = LIBRAW_IMAGE_ASPECT_1to1;
      break;
    case 2:
      imgdata.sizes.raw_inset_crop.aspect = LIBRAW_IMAGE_ASPECT_4to3;
      break;
    case 7:
      imgdata.sizes.raw_inset_crop.aspect = LIBRAW_IMAGE_ASPECT_16to9;
      break;
    case 8:
      imgdata.sizes.raw_inset_crop.aspect = LIBRAW_IMAGE_ASPECT_5to4;
      break;
    default:
      imgdata.sizes.raw_inset_crop.aspect = LIBRAW_IMAGE_ASPECT_OTHER;
      break;
    }
    imgdata.sizes.raw_inset_crop.cwidth = get4();
    imgdata.sizes.raw_inset_crop.cheight = get4();
    imgdata.sizes.raw_inset_crop.cleft = get4();
    imgdata.sizes.raw_inset_crop.ctop = get4();

  } else if ((tag == 0x00a4) && (dng_writer == nonDNG)) { // EOS-1D, EOS-1DS
    fseek(ifp, imCanon.wbi * 48, SEEK_CUR);
    FORC3 cam_mul[c] = get2();

  } else if (tag == 0x00a9) {
    long int save1 = 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, save1, SEEK_SET);
  }
  else if (tag == 0x00e0)
  { // SensorInfo
    imCanon.SensorWidth = (get2(), get2());
    imCanon.SensorHeight = get2();
    imCanon.SensorLeftBorder = (get2(), get2(), get2());
    imCanon.SensorTopBorder = get2();
    imCanon.SensorRightBorder = get2();
    imCanon.SensorBottomBorder = get2();
    imCanon.BlackMaskLeftBorder = get2();
    imCanon.BlackMaskTopBorder = get2();
    imCanon.BlackMaskRightBorder = get2();
    imCanon.BlackMaskBottomBorder = get2();
  }
  else if (tag == 0x4001 && len > 500)
  {
    int bls = 0;
    long int offsetChannelBlackLevel = 0L;
    long int offsetChannelBlackLevel2 = 0L;
    long int offsetWhiteLevels = 0L;
    long int save1 = ftell(ifp);

    switch (len)
    {

    case 582:
      imCanon.ColorDataVer = 1; // 20D / 350D

      fseek(ifp, save1 + (0x0019 << 1), SEEK_SET);
      FORC4 cam_mul[c ^ (c >> 1)] = (float)get2();
      fseek(ifp, save1 + (0x001e << 1), SEEK_SET);
      FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_Auto][c ^ (c >> 1)] = get2();
      fseek(ifp, save1 + (0x0041 << 1), SEEK_SET);
      FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_Custom1][c ^ (c >> 1)] = get2();
      fseek(ifp, save1 + (0x0046 << 1), SEEK_SET);
      FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_Custom2][c ^ (c >> 1)] = get2();

      fseek(ifp, save1 + (0x0023 << 1), SEEK_SET);
      Canon_WBpresets(2, 2);
      fseek(ifp, save1 + (0x004b << 1), SEEK_SET);
      Canon_WBCTpresets(1); // ABCT
      offsetChannelBlackLevel = save1 + (0x00a6 << 1);
      break;

    case 653:
      imCanon.ColorDataVer = 2; // 1Dmk2 / 1DsMK2

      fseek(ifp, save1 + (0x0018 << 1), SEEK_SET);
      FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_Auto][c ^ (c >> 1)] = get2();
      fseek(ifp, save1 + (0x0022 << 1), SEEK_SET);
      FORC4 cam_mul[c ^ (c >> 1)] = (float)get2();
      fseek(ifp, save1 + (0x0090 << 1), SEEK_SET);
      FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_Custom1][c ^ (c >> 1)] = get2();
      fseek(ifp, save1 + (0x0095 << 1), SEEK_SET);
      FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_Custom2][c ^ (c >> 1)] = get2();
      fseek(ifp, save1 + (0x009a << 1), SEEK_SET);
      FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_Custom3][c ^ (c >> 1)] = get2();

      fseek(ifp, save1 + (0x0027 << 1), SEEK_SET);
      Canon_WBpresets(2, 12);
      fseek(ifp, save1 + (0x00a4 << 1), SEEK_SET);
      Canon_WBCTpresets(1); // ABCT
      offsetChannelBlackLevel = save1 + (0x011e << 1);
      break;

    case 796:
      imCanon.ColorDataVer = 3; // 1DmkIIN / 5D / 30D / 400D
      imCanon.ColorDataSubVer = get2();

      fseek(ifp, save1 + (0x003f << 1), SEEK_SET);
      FORC4 cam_mul[c ^ (c >> 1)] = (float)get2();
      fseek(ifp, save1 + (0x0044 << 1), SEEK_SET);
      FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_Auto][c ^ (c >> 1)] = get2();
      fseek(ifp, save1 + (0x0049 << 1), SEEK_SET);
      FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_Measured][c ^ (c >> 1)] = get2();
      fseek(ifp, save1 + (0x0071 << 1), SEEK_SET);
      FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_Custom1][c ^ (c >> 1)] = get2();
      fseek(ifp, save1 + (0x0076 << 1), SEEK_SET);
      FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_Custom2][c ^ (c >> 1)] = get2();
      fseek(ifp, save1 + (0x007b << 1), SEEK_SET);
      FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_Custom3][c ^ (c >> 1)] = get2();
      fseek(ifp, save1 + (0x0080 << 1), SEEK_SET);
      FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_Custom][c ^ (c >> 1)] = get2();

      fseek(ifp, save1 + (0x004e << 1), SEEK_SET);
      Canon_WBpresets(2, 12);
      fseek(ifp, save1 + (0x0085 << 1), SEEK_SET);
      Canon_WBCTpresets(0); // BCAT
      offsetChannelBlackLevel = save1 + (0x00c4 << 1);
      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:
      imCanon.ColorDataVer = 4;
      imCanon.ColorDataSubVer = get2();

      fseek(ifp, save1 + (0x003f << 1), SEEK_SET);
      FORC4 cam_mul[c ^ (c >> 1)] = (float)get2();
      fseek(ifp, save1 + (0x0044 << 1), SEEK_SET);
      FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_Auto][c ^ (c >> 1)] = get2();
      fseek(ifp, save1 + (0x0049 << 1), SEEK_SET);
      FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_Measured][c ^ (c >> 1)] = get2();

      fseek(ifp, save1 + (0x004e << 1), SEEK_SET);
      FORC4 sraw_mul[c ^ (c >> 1)] = get2();
      fseek(ifp, save1 + (0x0053 << 1), SEEK_SET);
      Canon_WBpresets(2, 12);
      fseek(ifp, save1 + (0x00a8 << 1), SEEK_SET);
      Canon_WBCTpresets(0); // BCAT

      if ((imCanon.ColorDataSubVer == 4) ||
          (imCanon.ColorDataSubVer == 5))
      {
        offsetChannelBlackLevel = save1 + (0x02b4 << 1);
        offsetWhiteLevels = save1 + (0x02b8 << 1);
      }
      else if ((imCanon.ColorDataSubVer == 6) ||
               (imCanon.ColorDataSubVer == 7))
      {
        offsetChannelBlackLevel = save1 + (0x02cb << 1);
        offsetWhiteLevels = save1 + (0x02cf << 1);
      }
      else if (imCanon.ColorDataSubVer == 9)
      {
        offsetChannelBlackLevel = save1 + (0x02cf << 1);
        offsetWhiteLevels = save1 + (0x02d3 << 1);
      }
      else
        offsetChannelBlackLevel = save1 + (0x00e7 << 1);
      break;

    case 5120:  // PowerShot G10, G12, G5 X, G7 X, G9 X, EOS M3, EOS M5, EOS M6
      imCanon.ColorDataVer = 5;
      imCanon.ColorDataSubVer = get2();

      fseek(ifp, save1 + (0x0047 << 1), SEEK_SET);
      FORC4 cam_mul[c ^ (c >> 1)] = (float)get2();

      if (imCanon.ColorDataSubVer == 0xfffc)
      { // -4: G7 X Mark II, G9 X Mark II, G1 X Mark III, M5, M100, M6
        fseek(ifp, save1 + (0x004f << 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
        offsetChannelBlackLevel = save1 + (0x014d << 1);
        offsetWhiteLevels = save1 + (0x0569 << 1);
      }
      else if (imCanon.ColorDataSubVer == 0xfffd)
      { // -3: M10/M3/G1 X/G1 X II/G10/G11/G12/G15/G16/G3 X/G5 X/G7 X/G9
        // X/S100/S110/S120/S90/S95/SX1 IX/SX50 HS/SX60 HS
        fseek(ifp, save1 + (0x004c << 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 + (0x00ba << 1), SEEK_SET);
        Canon_WBCTpresets(2); // BCADT
        offsetChannelBlackLevel = save1 + (0x0108 << 1);
      }
      break;

    case 1273:
    case 1275:
      imCanon.ColorDataVer = 6; // 600D / 1200D
      imCanon.ColorDataSubVer = get2();

      fseek(ifp, save1 + (0x003f << 1), SEEK_SET);
      FORC4 cam_mul[c ^ (c >> 1)] = (float)get2();
      fseek(ifp, save1 + (0x0044 << 1), SEEK_SET);
      FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_Auto][c ^ (c >> 1)] = get2();
      fseek(ifp, save1 + (0x0049 << 1), SEEK_SET);
      FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_Measured][c ^ (c >> 1)] = get2();

      fseek(ifp, save1 + (0x0062 << 1), SEEK_SET);
      FORC4 sraw_mul[c ^ (c >> 1)] = get2();
      fseek(ifp, save1 + (0x0067 << 1), SEEK_SET);
      Canon_WBpresets(2, 12);
      fseek(ifp, save1 + (0x00bc << 1), SEEK_SET);
      Canon_WBCTpresets(0); // BCAT
      offsetChannelBlackLevel = save1 + (0x01df << 1);
      offsetWhiteLevels = save1 + (0x01e3 << 1);
      break;

    // 1DX / 5DmkIII / 6D / 100D / 650D / 700D / EOS M / 7DmkII / 750D / 760D
    case 1312:
    case 1313:
    case 1316:
    case 1506:
      imCanon.ColorDataVer = 7;
      imCanon.ColorDataSubVer = get2();

      fseek(ifp, save1 + (0x003f << 1), SEEK_SET);
      FORC4 cam_mul[c ^ (c >> 1)] = (float)get2();
      fseek(ifp, save1 + (0x0044 << 1), SEEK_SET);
      FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_Auto][c ^ (c >> 1)] = get2();
      fseek(ifp, save1 + (0x0049 << 1), SEEK_SET);
      FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_Measured][c ^ (c >> 1)] = get2();

      fseek(ifp, save1 + (0x007b << 1), SEEK_SET);
      FORC4 sraw_mul[c ^ (c >> 1)] = get2();
      fseek(ifp, save1 + (0x0080 << 1), SEEK_SET);
      Canon_WBpresets(2, 12);
      fseek(ifp, save1 + (0x00d5 << 1), SEEK_SET);
      Canon_WBCTpresets(0); // BCAT

      if (imCanon.ColorDataSubVer == 10)
      {
        offsetChannelBlackLevel = save1 + (0x01f8 << 1);
        offsetWhiteLevels = save1 + (0x01fc << 1);
      }
      else if (imCanon.ColorDataSubVer == 11)
      {
        offsetChannelBlackLevel = save1 + (0x02d8 << 1);
        offsetWhiteLevels = save1 + (0x02dc << 1);
      }
      break;

    // 5DS / 5DS R / 80D / 1300D / 1500D / 3000D / 5D4 / 800D / 77D / 6D II /
    // 200D
    case 1560:
    case 1592:
    case 1353:
    case 1602:
      imCanon.ColorDataVer = 8;
      imCanon.ColorDataSubVer = get2();

      fseek(ifp, save1 + (0x003f << 1), SEEK_SET);
      FORC4 cam_mul[c ^ (c >> 1)] = (float)get2();
      fseek(ifp, save1 + (0x0044 << 1), SEEK_SET);
      FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_Auto][c ^ (c >> 1)] = get2();
      fseek(ifp, save1 + (0x0049 << 1), SEEK_SET);
      FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_Measured][c ^ (c >> 1)] = get2();

      fseek(ifp, save1 + (0x0080 << 1), SEEK_SET);
      FORC4 sraw_mul[c ^ (c >> 1)] = get2();
      fseek(ifp, save1 + (0x0085 << 1), SEEK_SET);
      Canon_WBpresets(2, 12);
      fseek(ifp, save1 + (0x0107 << 1), SEEK_SET);
      Canon_WBCTpresets(0); // BCAT

      if (imCanon.ColorDataSubVer == 14)
      { // 1300D / 1500D / 3000D
        offsetChannelBlackLevel = save1 + (0x022c << 1);
        offsetWhiteLevels = save1 + (0x0230 << 1);
      }
      else
      {
        offsetChannelBlackLevel = save1 + (0x030a << 1);
        offsetWhiteLevels = save1 + (0x030e << 1);
      }
      break;

    case 1820: // M50, ColorDataSubVer 16
    case 1824: // EOS R, SX740HS, ColorDataSubVer 17
    case 1816: // EOS RP, SX70HS, ColorDataSubVer 18;
               // EOS M6 Mark II, EOS 90D, G7XmkIII, ColorDataSubVer 19
      imCanon.ColorDataVer = 9;
      imCanon.ColorDataSubVer = get2();

      fseek(ifp, save1 + (0x0047 << 1), SEEK_SET);
      FORC4 cam_mul[c ^ (c >> 1)] = (float)get2();
      get2();
      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();
      fseek(ifp, save1 + (0x0088 << 1), SEEK_SET);
      Canon_WBpresets(2, 12);
      fseek(ifp, save1 + (0x010a << 1), SEEK_SET);
      Canon_WBCTpresets(0);
      offsetChannelBlackLevel = save1 + (0x0318 << 1);
      offsetChannelBlackLevel2 = save1 + (0x0149 << 1);
      offsetWhiteLevels = save1 + (0x031c << 1);
      break;
    }

    if (offsetChannelBlackLevel)
    {
      fseek(ifp, offsetChannelBlackLevel, SEEK_SET);
      FORC4
        bls += (imCanon.ChannelBlackLevel[c ^ (c >> 1)] = get2());
      imCanon.AverageBlackLevel = bls / 4;
    }
    if (offsetWhiteLevels)
    {
      if ((offsetWhiteLevels - offsetChannelBlackLevel) != 8L)
        fseek(ifp, offsetWhiteLevels, SEEK_SET);
      imCanon.NormalWhiteLevel = get2();
      imCanon.SpecularWhiteLevel = get2();
      FORC4
        imgdata.color.linear_max[c] = imCanon.SpecularWhiteLevel;
    }

    if(!imCanon.AverageBlackLevel && offsetChannelBlackLevel2)
    {
        fseek(ifp, offsetChannelBlackLevel2, SEEK_SET);
        FORC4
            bls += (imCanon.ChannelBlackLevel[c ^ (c >> 1)] = get2());
        imCanon.AverageBlackLevel = bls / 4;
    }
    fseek(ifp, save1, SEEK_SET);

  } else if (tag == 0x4013) {
    get4();
    imCanon.AFMicroAdjMode = get4();
    float a = get4();
    float b = get4();
    if (fabsf(b) > 0.001f)
      imCanon.AFMicroAdjValue = a / b;

  } else if ((tag == 0x4021) && (dng_writer == nonDNG) &&
             (imCanon.multishot[0] = get4()) &&
             (imCanon.multishot[1] = get4())) {
    if (len >= 4) {
      imCanon.multishot[2] = get4();
      imCanon.multishot[3] = get4();
    }
    FORC4 cam_mul[c] = 1024;
  }

}

Project: LibRaw

  libraw_dng_stream(LibRaw_abstract_datastream *p)
      : dng_stream((dng_abort_sniffer *)NULL, kBigBufferSize, 0),
        parent_stream(p)
  {
    if (parent_stream)
    {
      off = parent_stream->tell();
      parent_stream->seek(0UL, SEEK_SET); /* seek to start */
    }
  }

Project: LibRaw

unsigned LibRaw::capabilities()
{
  unsigned ret = 0;
#ifdef USE_RAWSPEED
  ret |= LIBRAW_CAPS_RAWSPEED;
#endif
#ifdef USE_DNGSDK
  ret |= LIBRAW_CAPS_DNGSDK;
#ifdef USE_GPRSDK
  ret |= LIBRAW_CAPS_GPRSDK;
#endif
#ifdef LIBRAW_WIN32_UNICODEPATHS
  ret |= LIBRAW_CAPS_UNICODEPATHS;
#endif
#endif
  return ret;
}

Project: LibRaw

void LibRaw::parseSonyMakernotes(
    int base, unsigned tag, unsigned type, unsigned len, unsigned dng_writer,
    uchar *&table_buf_0x0116, ushort &table_buf_0x0116_len,
    uchar *&table_buf_0x2010, ushort &table_buf_0x2010_len,
    uchar *&table_buf_0x9050, ushort &table_buf_0x9050_len,
    uchar *&table_buf_0x9400, ushort &table_buf_0x9400_len,
    uchar *&table_buf_0x9402, ushort &table_buf_0x9402_len,
    uchar *&table_buf_0x9403, ushort &table_buf_0x9403_len,
    uchar *&table_buf_0x9406, ushort &table_buf_0x9406_len,
    uchar *&table_buf_0x940c, ushort &table_buf_0x940c_len,
    uchar *&table_buf_0x940e, ushort &table_buf_0x940e_len)
{

  ushort lid, a, b, c, d;
  uchar *table_buf;
  uchar uc;
  uchar s[2];
  int LensDataValid = 0;
  unsigned uitemp;

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

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

    if (table_buf_0x2010_len)
    {
      process_Sony_0x2010(table_buf_0x2010, table_buf_0x2010_len);
      free(table_buf_0x2010);
      table_buf_0x2010_len = 0;
    }

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

    if (table_buf_0x9400_len)
    {
      process_Sony_0x9400(table_buf_0x9400, table_buf_0x9400_len, unique_id);
      free(table_buf_0x9400);
      table_buf_0x9400_len = 0;
    }

    if (table_buf_0x9402_len)
    {
      process_Sony_0x9402(table_buf_0x9402, table_buf_0x9402_len);
      free(table_buf_0x9402);
      table_buf_0x9402_len = 0;
    }

    if (table_buf_0x9403_len)
    {
      process_Sony_0x9403(table_buf_0x9403, table_buf_0x9403_len);
      free(table_buf_0x9403);
      table_buf_0x9403_len = 0;
    }

    if (table_buf_0x9406_len)
    {
      process_Sony_0x9406(table_buf_0x9406, table_buf_0x9406_len);
      free(table_buf_0x9406);
      table_buf_0x9406_len = 0;
    }

    if (table_buf_0x940c_len)
    {
      process_Sony_0x940c(table_buf_0x940c, table_buf_0x940c_len);
      free(table_buf_0x940c);
      table_buf_0x940c_len = 0;
    }

    if (table_buf_0x940e_len)
    {
      process_Sony_0x940e(table_buf_0x940e, table_buf_0x940e_len, unique_id);
      free(table_buf_0x940e);
      table_buf_0x940e_len = 0;
    }
  }
  else if (tag == 0xb000)
  {
    FORC4 imSony.FileFormat = imSony.FileFormat * 10 + fgetc(ifp);
  }
  else if (tag == 0xb026)
  {
    uitemp = get4();
    if (uitemp != 0xffffffff)
      imgdata.shootinginfo.ImageStabilization = uitemp;
  }
  else if (((tag == 0x0001) || // Minolta CameraSettings, big endian
            (tag == 0x0003)) &&
           (len >= 196))
  {
    table_buf = (uchar *)malloc(len);
    fread(table_buf, len, 1, ifp);

    lid = 0x01 << 2;
    imgdata.shootinginfo.ExposureMode =
        (unsigned)table_buf[lid] << 24 | (unsigned)table_buf[lid + 1] << 16 |
        (unsigned)table_buf[lid + 2] << 8 | (unsigned)table_buf[lid + 3];

    lid = 0x06 << 2;
    imgdata.shootinginfo.DriveMode =
        (unsigned)table_buf[lid] << 24 | (unsigned)table_buf[lid + 1] << 16 |
        (unsigned)table_buf[lid + 2] << 8 | (unsigned)table_buf[lid + 3];

    lid = 0x07 << 2;
    imgdata.shootinginfo.MeteringMode =
        (unsigned)table_buf[lid] << 24 | (unsigned)table_buf[lid + 1] << 16 |
        (unsigned)table_buf[lid + 2] << 8 | (unsigned)table_buf[lid + 3];

    lid = 0x25 << 2;
    imSony.MinoltaCamID =
        (unsigned)table_buf[lid] << 24 | (unsigned)table_buf[lid + 1] << 16 |
        (unsigned)table_buf[lid + 2] << 8 | (unsigned)table_buf[lid + 3];
    if (imSony.MinoltaCamID != -1)
      ilm.CamID = imSony.MinoltaCamID;

    lid = 0x30 << 2;
    imgdata.shootinginfo.FocusMode =
        (unsigned)table_buf[lid] << 24 | (unsigned)table_buf[lid + 1] << 16 |
        (unsigned)table_buf[lid + 2] << 8 | (unsigned)table_buf[lid + 3];

    free(table_buf);
  }
  else if ((tag == 0x0004) && // Minolta CameraSettings7D, big endian
           (len >= 227))
  {
    table_buf = (uchar *)malloc(len);
    fread(table_buf, len, 1, ifp);

    lid = 0x0;
    imgdata.shootinginfo.ExposureMode =
        (ushort)table_buf[lid] << 8 | (ushort)table_buf[lid + 1];

    lid = 0x0e << 1;
    imgdata.shootinginfo.FocusMode =
        (ushort)table_buf[lid] << 8 | (ushort)table_buf[lid + 1];

    lid = 0x10 << 1;
    imgdata.shootinginfo.AFPoint =
        (ushort)table_buf[lid] << 8 | (ushort)table_buf[lid + 1];

    lid = 0x71 << 1;
    imgdata.shootinginfo.ImageStabilization =
        (ushort)table_buf[lid] << 8 | (ushort)table_buf[lid + 1];

    free(table_buf);
  }
  else if ((tag == 0x0010) && // CameraInfo
           strncasecmp(model, "DSLR-A100", 9) &&
           !strncasecmp(make, "SONY", 4) &&
           ((len == 368) ||  // a700                         : CameraInfo
            (len == 5478) || // a850, a900                   : CameraInfo
            (len == 5506) || // a200, a300, a350             : CameraInfo2
            (len == 6118) || // a230, a290, a330, a380, a390 : CameraInfo2
            (len == 15360))  // a450, a500, a550, a560, a580 : CameraInfo3
                             // a33, a35, a55
                             // NEX-3, NEX-5, NEX-5C, NEX-C3, NEX-VG10E

  )
  {
    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))
    {
      LensDataValid = 1;
    }
    switch (len)
    {
    case 368:  // a700: CameraInfo
    case 5478: // 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 (LensDataValid)
        {
          if (table_buf[0] | table_buf[3])
            ilm.MinFocal = bcd2dec(table_buf[0]) * 100 + bcd2dec(table_buf[3]);
          if (table_buf[2] | table_buf[5])
            ilm.MaxFocal = bcd2dec(table_buf[2]) * 100 + bcd2dec(table_buf[5]);
          if (table_buf[4])
            ilm.MaxAp4MinFocal = bcd2dec(table_buf[4]) / 10.0f;
          if (table_buf[4])
            ilm.MaxAp4MaxFocal = bcd2dec(table_buf[7]) / 10.0f;
          parseSonyLensFeatures(table_buf[1], table_buf[6]);
        }

        imSony.AFPointSelected = table_buf[21];
        imgdata.shootinginfo.AFPoint = (ushort)table_buf[25];

        if (len == 5478)
        {
          imSony.AFMicroAdjValue = table_buf[304] - 20;
          imSony.AFMicroAdjOn = (((table_buf[305] & 0x80) == 0x80) ? 1 : 0);
          imSony.AFMicroAdjRegisteredLenses = table_buf[305] & 0x7f;
        }
      }
      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 ((LensDataValid) && strncasecmp(model, "NEX-5C", 6))
        {
          if (table_buf[1] | table_buf[2])
            ilm.MinFocal = bcd2dec(table_buf[1]) * 100 + bcd2dec(table_buf[2]);
          if (table_buf[3] | table_buf[4])
            ilm.MaxFocal = bcd2dec(table_buf[3]) * 100 + bcd2dec(table_buf[4]);
          if (table_buf[5])
            ilm.MaxAp4MinFocal = bcd2dec(table_buf[5]) / 10.0f;
          if (table_buf[6])
            ilm.MaxAp4MaxFocal = bcd2dec(table_buf[6]) / 10.0f;
          parseSonyLensFeatures(table_buf[0], table_buf[7]);
        }

        if (!strncasecmp(model, "DSLR-A450", 9) ||
            !strncasecmp(model, "DSLR-A500", 9) ||
            !strncasecmp(model, "DSLR-A550", 9))
        {
          imSony.AFPointSelected = table_buf[0x14];
          imgdata.shootinginfo.FocusMode = table_buf[0x15];
          imgdata.shootinginfo.AFPoint = (ushort)table_buf[0x18];
        }
        else if (!strncasecmp(model, "SLT-", 4) ||
                 !strncasecmp(model, "DSLR-A560", 9) ||
                 !strncasecmp(model, "DSLR-A580", 9))
        {
          imSony.AFPointSelected = table_buf[0x1c];
          imgdata.shootinginfo.FocusMode = table_buf[0x1d];
          imgdata.shootinginfo.AFPoint = (ushort)table_buf[0x20];
        }
      }
    }
    free(table_buf);
  }
  else if ((!dng_writer) && ((tag == 0x0020) || (tag == 0xb0280020)))
  {
    if (!strncasecmp(model, "DSLR-A100", 9))
    { // WBInfoA100
      fseek(ifp, 0x49dc, SEEK_CUR);
      stmread(imgdata.shootinginfo.InternalBodySerial, 13, ifp);
    }
    else if ((len ==
              19154) || // a200 a230 a290 a300 a330 a350 a380 a390 : FocusInfo
             (len == 19148))
    { // a700 a850 a900                          : FocusInfo
      table_buf = (uchar *)malloc(128);
      fread(table_buf, 128, 1, ifp);
      imgdata.shootinginfo.DriveMode = table_buf[14];
      imgdata.shootinginfo.ExposureProgram = table_buf[63];
      free(table_buf);
    }
    else if (len == 20480) // a450 a500 a550 a560 a580 a33 a35 a55 : MoreInfo
                           // NEX-3 NEX-5 NEX-C3 NEX-VG10E         : MoreInfo
    {
      a = get2();
      b = get2();
      c = get2();
      d = get2();
      if ((a) && (c == 1))
      {
        fseek(ifp, d - 8, SEEK_CUR);
        table_buf = (uchar *)malloc(256);
        fread(table_buf, 256, 1, ifp);
        imgdata.shootinginfo.DriveMode = table_buf[1];
        imgdata.shootinginfo.ExposureProgram = table_buf[2];
        imgdata.shootinginfo.MeteringMode = table_buf[3];
        if (strncasecmp(model, "DSLR-A450", 9) &&
            strncasecmp(model, "DSLR-A500", 9) &&
            strncasecmp(model, "DSLR-A550", 9))
          imgdata.shootinginfo.FocusMode = table_buf[0x13];
        else
          imgdata.shootinginfo.FocusMode = table_buf[0x2c];
        free(table_buf);
      }
    }
  }
  else if (tag == 0x0102)
  {
    imSony.Quality = get4();
  }
  else if (tag == 0x0104)
  {
    imgdata.makernotes.common.FlashEC = getreal(type);
  }
  else if (tag == 0x0105)
  { // Teleconverter
    ilm.TeleconverterID = get4();
  }
  else if (tag == 0x0107)
  {
    uitemp = get4();
    if (uitemp == 1)
      imgdata.shootinginfo.ImageStabilization = 0;
    else if (uitemp == 5)
      imgdata.shootinginfo.ImageStabilization = 1;
    else
      imgdata.shootinginfo.ImageStabilization = uitemp;
  }
  else if ((tag == 0xb0280088) && (dng_writer == nonDNG))
  {
    thumb_offset = get4() + base;
  }
  else if ((tag == 0xb0280089) && (dng_writer == nonDNG))
  {
    thumb_length = get4();
  }
  else if (((tag == 0x0114) || // CameraSettings
            (tag == 0xb0280114)) &&
           (len < 256000))
  {
    table_buf = (uchar *)malloc(len);
    fread(table_buf, len, 1, ifp);
    switch (len)
    {
    case 260: // Sony a100, big endian
      imgdata.shootinginfo.ExposureMode =
          ((ushort)table_buf[0]) << 8 | ((ushort)table_buf[1]);
      lid = 0x0a << 1;
      imgdata.shootinginfo.DriveMode =
          ((ushort)table_buf[lid]) << 8 | ((ushort)table_buf[lid + 1]);
      lid = 0x0c << 1;
      imgdata.shootinginfo.FocusMode =
          ((ushort)table_buf[lid]) << 8 | ((ushort)table_buf[lid + 1]);
      lid = 0x0d << 1;
      imSony.AFPointSelected = table_buf[lid + 1];
      lid = 0x0e << 1;
      imSony.AFAreaModeSetting = table_buf[lid + 1];
      lid = 0x12 << 1;
      imgdata.shootinginfo.MeteringMode =
          ((ushort)table_buf[lid]) << 8 | ((ushort)table_buf[lid + 1]);
      break;
    case 448: // Minolta "DYNAX 5D" and its aliases, big endian
      lid = 0x0a << 1;
      imgdata.shootinginfo.ExposureMode =
          ((ushort)table_buf[lid]) << 8 | ((ushort)table_buf[lid + 1]);
      lid = 0x25 << 1;
      imgdata.shootinginfo.MeteringMode =
          ((ushort)table_buf[lid]) << 8 | ((ushort)table_buf[lid + 1]);
      lid = 0xbd << 1;
      imgdata.shootinginfo.ImageStabilization =
          ((ushort)table_buf[lid]) << 8 | ((ushort)table_buf[lid + 1]);
      break;
    case 280: // a200 a300 a350 a700
    case 364: // a850 a900
      // CameraSettings and CameraSettings2 are big endian
      if (table_buf[2] | table_buf[3])
      {
        lid = (((ushort)table_buf[2]) << 8) | ((ushort)table_buf[3]);
        ilm.CurAp = libraw_powf64l(2.0f, ((float)lid / 8.0f - 1.0f) / 2.0f);
      }
      lid = 0x04 << 1;
      imgdata.shootinginfo.DriveMode = table_buf[lid + 1];
      lid = 0x4d << 1;
      imgdata.shootinginfo.FocusMode =
          ((ushort)table_buf[lid]) << 8 | ((ushort)table_buf[lid + 1]);
      break;
    case 332: // a230 a290 a330 a380 a390
      // CameraSettings and CameraSettings2 are big endian
      if (table_buf[2] | table_buf[3])
      {
        lid = (((ushort)table_buf[2]) << 8) | ((ushort)table_buf[3]);
        ilm.CurAp = libraw_powf64l(2.0f, ((float)lid / 8.0f - 1.0f) / 2.0f);
      }
      lid = 0x4d << 1;
      imgdata.shootinginfo.FocusMode =
          ((ushort)table_buf[lid]) << 8 | ((ushort)table_buf[lid + 1]);
      lid = 0x7e << 1;
      imgdata.shootinginfo.DriveMode = table_buf[lid + 1];
      break;
    case 1536: // a560 a580 a33 a35 a55 NEX-3 NEX-5 NEX-5C NEX-C3 NEX-VG10E
    case 2048: // a450 a500 a550
      // CameraSettings3 are little endian
      imgdata.shootinginfo.DriveMode = table_buf[0x34];
      parseSonyLensType2(table_buf[1016], table_buf[1015]);
      if (ilm.LensMount != LIBRAW_MOUNT_Canon_EF)
      {
        switch (table_buf[153])
        {
        case 16:
          ilm.LensMount = LIBRAW_MOUNT_Minolta_A;
          break;
        case 17:
          ilm.LensMount = LIBRAW_MOUNT_Sony_E;
          break;
        }
      }
      break;
    }
    free(table_buf);
  }
  else if ((tag == 0x3000) && (len < 256000))
  {
    table_buf = (uchar *)malloc(len);
    fread(table_buf, len, 1, ifp);
    for (int i = 0; i < 20; i++)
      imSony.SonyDateTime[i] = table_buf[6 + i];
    free(table_buf);
  }
  else if (tag == 0x0116 && len < 256000)
  {
    table_buf_0x0116 = (uchar *)malloc(len);
    table_buf_0x0116_len = len;
    fread(table_buf_0x0116, len, 1, ifp);
    if (ilm.CamID)
    {
      process_Sony_0x0116(table_buf_0x0116, table_buf_0x0116_len, ilm.CamID);
      free(table_buf_0x0116);
      table_buf_0x0116_len = 0;
    }
  }
  else if (tag == 0x2008)
  {
    imSony.LongExposureNoiseReduction = get4();
  }
  else if (tag == 0x2009)
  {
    imSony.HighISONoiseReduction = get2();
  }
  else if (tag == 0x200a)
  {
    imSony.HDR[0] = get2();
    imSony.HDR[1] = get2();
  }
  else if (tag == 0x2010 && len < 256000)
  {
    table_buf_0x2010 = (uchar *)malloc(len);
    table_buf_0x2010_len = len;
    fread(table_buf_0x2010, len, 1, ifp);
    if (ilm.CamID)
    {
      process_Sony_0x2010(table_buf_0x2010, table_buf_0x2010_len);
      free(table_buf_0x2010);
      table_buf_0x2010_len = 0;
    }
  }
  else if (tag == 0x201a)
  {
    imSony.ElectronicFrontCurtainShutter = get4();
  }
  else if (tag == 0x201b)
  {
    if ((imSony.CameraType != LIBRAW_SONY_DSC) ||
        (ilm.CamID == 0x16dULL) || // DSC-RX10M4
        (ilm.CamID == 0x16eULL) || // DSC-RX100M6
        (ilm.CamID == 0x171ULL) || // DSC-RX100M5A
        (ilm.CamID == 0x174ULL) || // DSC-RX0M2
        (ilm.CamID == 0x176ULL))
    { // DSC-RX100M7
      fread(&uc, 1, 1, ifp);
      imgdata.shootinginfo.FocusMode = (short)uc;
    }
  }
  else if (tag == 0x201c)
  {
    if ((imSony.CameraType != LIBRAW_SONY_DSC) ||
        (ilm.CamID == 0x16dULL) || // DSC-RX10M4
        (ilm.CamID == 0x16eULL) || // DSC-RX100M6
        (ilm.CamID == 0x171ULL) || // DSC-RX100M5A
        (ilm.CamID == 0x174ULL) || // DSC-RX0M2
        (ilm.CamID == 0x176ULL))
    { // DSC-RX100M7
      imSony.AFAreaModeSetting = fgetc(ifp);
    }
  }
  else if (tag == 0x201d)
  {
    if (((imSony.AFAreaModeSetting == 3) &&
         ((imSony.CameraType == LIBRAW_SONY_ILCE) ||
          (imSony.CameraType == LIBRAW_SONY_NEX) ||
          (ilm.CamID == 0x16dULL) ||   // DSC-RX10M4
          (ilm.CamID == 0x16eULL) ||   // DSC-RX100M6
          (ilm.CamID == 0x171ULL) ||   // DSC-RX100M5A
          (ilm.CamID == 0x174ULL) ||   // DSC-RX0M2
          (ilm.CamID == 0x176ULL))) || // DSC-RX100M7
        ((imSony.AFAreaModeSetting == 4) &&
         (imSony.CameraType == LIBRAW_SONY_ILCA)))
    {
      imSony.FlexibleSpotPosition[0] = get2();
      imSony.FlexibleSpotPosition[1] = get2();
    }
  }
  else if (tag == 0x201e)
  {
    if (imSony.CameraType != LIBRAW_SONY_DSC)
    {
      imSony.AFPointSelected = fgetc(ifp);
    }
  }
  else if (tag == 0x2020)
  {
    if (imSony.CameraType != LIBRAW_SONY_DSC)
    {
      fread(imSony.AFPointsUsed, 1, 10, ifp);
    }
  }
  else if (tag == 0x2021)
  {
    if ((imSony.CameraType != LIBRAW_SONY_DSC) ||
        (ilm.CamID == 0x16dULL) || // DSC-RX10M4
        (ilm.CamID == 0x16eULL) || // DSC-RX100M6
        (ilm.CamID == 0x171ULL) || // DSC-RX100M5A
        (ilm.CamID == 0x174ULL) || // DSC-RX0M2
        (ilm.CamID == 0x176ULL))
    { // DSC-RX100M7
      imSony.AFTracking = fgetc(ifp);
    }
  }
  else if (tag == 0x2027)
  {
    FORC4 imSony.FocusLocation[c] = get2();
  }
  else if (tag == 0x2028)
  {
    if (get2())
    {
      imSony.VariableLowPassFilter = get2();
    }
  }
  else if (tag == 0x2029)
  {
    imSony.RAWFileType = get2();
  }
  else if (tag == 0x202c)
  {
    imSony.MeteringMode2 = get2();
  }
  else if (tag == 0x202f)
  {
    imSony.PixelShiftGroupID = get4();
    imSony.PixelShiftGroupPrefix = imSony.PixelShiftGroupID >> 22;
    imSony.PixelShiftGroupID =
        ((imSony.PixelShiftGroupID >> 17) & (unsigned)0x1f) *
            (unsigned)1000000 +
        ((imSony.PixelShiftGroupID >> 12) & (unsigned)0x1f) * (unsigned)10000 +
        ((imSony.PixelShiftGroupID >> 6) & (unsigned)0x3f) * (unsigned)100 +
        (imSony.PixelShiftGroupID & (unsigned)0x3f);

    imSony.numInPixelShiftGroup = fgetc(ifp);
    imSony.nShotsInPixelShiftGroup = fgetc(ifp);
  }
  else if (tag == 0x9050 && len < 256000)
  { // little endian
    table_buf_0x9050 = (uchar *)malloc(len);
    table_buf_0x9050_len = len;
    fread(table_buf_0x9050, len, 1, ifp);

    if (ilm.CamID)
    {
      process_Sony_0x9050(table_buf_0x9050, table_buf_0x9050_len, ilm.CamID);
      free(table_buf_0x9050);
      table_buf_0x9050_len = 0;
    }
  }
  else if (tag == 0x9400 && len < 256000)
  {
    table_buf_0x9400 = (uchar *)malloc(len);
    table_buf_0x9400_len = len;
    fread(table_buf_0x9400, len, 1, ifp);
    if (ilm.CamID)
    {
      process_Sony_0x9400(table_buf_0x9400, table_buf_0x9400_len, unique_id);
      free(table_buf_0x9400);
      table_buf_0x9400_len = 0;
    }
  }
  else if (tag == 0x9402 && len < 256000)
  {
    table_buf_0x9402 = (uchar *)malloc(len);
    table_buf_0x9402_len = len;
    fread(table_buf_0x9402, len, 1, ifp);
    if (ilm.CamID)
    {
      process_Sony_0x9402(table_buf_0x9402, table_buf_0x9402_len);
      free(table_buf_0x9402);
      table_buf_0x9402_len = 0;
    }
  }
  else if (tag == 0x9403 && len < 256000)
  {
    table_buf_0x9403 = (uchar *)malloc(len);
    table_buf_0x9403_len = len;
    fread(table_buf_0x9403, len, 1, ifp);
    if (ilm.CamID)
    {
      process_Sony_0x9403(table_buf_0x9403, table_buf_0x9403_len);
      free(table_buf_0x9403);
      table_buf_0x9403_len = 0;
    }
  }
  else if ((tag == 0x9405) && (len < 256000) && (len > 0x64))
  {
    table_buf = (uchar *)malloc(len);
    fread(table_buf, len, 1, ifp);
    uc = table_buf[0x0];
    if (imgdata.makernotes.common.real_ISO < 0.1f)
    {
      if ((uc == 0x25) || (uc == 0x3a) || (uc == 0x76) || (uc == 0x7e) ||
          (uc == 0x8b) || (uc == 0x9a) || (uc == 0xb3) || (uc == 0xe1))
      {
        s[0] = SonySubstitution[table_buf[0x04]];
        s[1] = SonySubstitution[table_buf[0x05]];
        imgdata.makernotes.common.real_ISO =
            100.0f * libraw_powf64l(2.0f, (16 - ((float)sget2(s)) / 256.0f));
      }
    }
    free(table_buf);
  }
  else if (tag == 0x9406 && len < 256000)
  {
    table_buf_0x9406 = (uchar *)malloc(len);
    table_buf_0x9406_len = len;
    fread(table_buf_0x9406, len, 1, ifp);
    if (ilm.CamID)
    {
      process_Sony_0x9406(table_buf_0x9406, table_buf_0x9406_len);
      free(table_buf_0x9406);
      table_buf_0x9406_len = 0;
    }
  }
  else if (tag == 0x940c && len < 256000)
  {
    table_buf_0x940c = (uchar *)malloc(len);
    table_buf_0x940c_len = len;
    fread(table_buf_0x940c, len, 1, ifp);
    if (ilm.CamID)
    {
      process_Sony_0x940c(table_buf_0x940c, table_buf_0x940c_len);
      free(table_buf_0x940c);
      table_buf_0x940c_len = 0;
    }
  }
  else if (tag == 0x940e && len < 256000)
  {
    table_buf_0x940e = (uchar *)malloc(len);
    table_buf_0x940e_len = len;
    fread(table_buf_0x940e, len, 1, ifp);
    if (ilm.CamID)
    {
      process_Sony_0x940e(table_buf_0x940e, table_buf_0x940e_len, ilm.CamID);
      free(table_buf_0x940e);
      table_buf_0x940e_len = 0;
    }
  }
  else if (((tag == 0xb027) || (tag == 0x010c)) && (ilm.LensID == -1))
  {
    ilm.LensID = get4();
    if ((ilm.LensID > 0x4900) && (ilm.LensID <= 0x5900))
    {
      ilm.AdapterID = 0x4900;
      ilm.LensID -= ilm.AdapterID;
      ilm.LensMount = LIBRAW_MOUNT_Sigma_X3F;
      strcpy(ilm.Adapter, "MC-11");
    }

    else if ((ilm.LensID > 0xef00) && (ilm.LensID < 0xffff) &&
             (ilm.LensID != 0xff00))
    {
      ilm.AdapterID = 0xef00;
      ilm.LensID -= ilm.AdapterID;
      ilm.LensMount = LIBRAW_MOUNT_Canon_EF;
    }

    else if (((ilm.LensID != -1) && (ilm.LensID < 0xef00)) ||
             (ilm.LensID == 0xff00))
      ilm.LensMount = LIBRAW_MOUNT_Minolta_A;
    /*
        if (tag == 0x010c)
          ilm.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])
        ilm.MinFocal = bcd2dec(table_buf[1]) * 100 + bcd2dec(table_buf[2]);
      if (table_buf[3] | table_buf[4])
        ilm.MaxFocal = bcd2dec(table_buf[3]) * 100 + bcd2dec(table_buf[4]);
      if (table_buf[5])
        ilm.MaxAp4MinFocal = bcd2dec(table_buf[5]) / 10.0f;
      if (table_buf[6])
        ilm.MaxAp4MaxFocal = bcd2dec(table_buf[6]) / 10.0f;
      parseSonyLensFeatures(table_buf[0], table_buf[7]);
    }
    free(table_buf);
  }
  else if ((tag == 0xb02b) && !imgdata.sizes.raw_inset_crop.cwidth &&
           (len == 2))
  {
    imgdata.sizes.raw_inset_crop.cheight = get4();
    imgdata.sizes.raw_inset_crop.cwidth = get4();
  }
  else if (tag == 0xb041)
  {
    imgdata.shootinginfo.ExposureMode = get2();
  }

  // MetaVersion: (unique_id >= 286)
}

Project: LibRaw

void *LibRaw::memmem(char *haystack, size_t haystacklen, char *needle,
                     size_t needlelen)
{
#if !defined(__GLIBC__) && !defined(__FreeBSD__) && !defined(__OpenBSD__)
  char *c;
  for (c = haystack; c <= haystack + haystacklen - needlelen; c++)
    if (!memcmp(c, needle, needlelen))
      return c;
  return 0;
#else
  return ::memmem(haystack, haystacklen, needle, needlelen);
#endif
}

Project: LibRaw

void LibRaw::copy_bayer(unsigned short cblack[4], unsigned short *dmaxp)
{
  // Both cropped and uncropped
  int row;

#if defined(LIBRAW_USE_OPENMP)
#pragma omp parallel for default(shared)
#endif
  for (row = 0; row < S.height && row + S.top_margin < S.raw_height; row++)
  {
    int col;
    unsigned short ldmax = 0;
    for (col = 0; col < S.width && col + S.left_margin < S.raw_width; col++)
    {
      unsigned short val =
          imgdata.rawdata.raw_image[(row + S.top_margin) * S.raw_pitch / 2 +
                                    (col + S.left_margin)];
      int cc = fcol(row, col);
      if (val > cblack[cc])
      {
        val -= cblack[cc];
        if (val > ldmax)
          ldmax = val;
      }
      else
        val = 0;
      imgdata
          .image[((row) >> IO.shrink) * S.iwidth + ((col) >> IO.shrink)][cc] =
          val;
    }
#if defined(LIBRAW_USE_OPENMP)
#pragma omp critical(dataupdate)
#endif
    {
      if (*dmaxp < ldmax)
        *dmaxp = ldmax;
    }
  }
}

Project: LibRaw

int LibRaw::open_datastream(LibRaw_abstract_datastream *stream)
{

  if (!stream)
    return ENOENT;
  if (!stream->valid())
    return LIBRAW_IO_ERROR;
  recycle();
  if (callbacks.pre_identify_cb)
  {
    int r = (callbacks.pre_identify_cb)(this);
    if (r == 1)
      goto final;
  }

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

    identify();
    if (callbacks.post_identify_cb)
      (callbacks.post_identify_cb)(this);

    if (load_raw == &LibRaw::nikon_load_raw)
      nikon_read_curve();

    if (load_raw == &LibRaw::panasonic_load_raw)
    {
      if (libraw_internal_data.unpacker_data.pana_encoding == 6 ||
          libraw_internal_data.unpacker_data.pana_encoding == 7)
      {
        for (int i = 0; i < 3; i++)
          imgdata.color.cblack[i] =
              libraw_internal_data.internal_data.pana_black[i];
        imgdata.color.cblack[3] = imgdata.color.cblack[1];
        imgdata.color.cblack[4] = imgdata.color.cblack[5] = 0;
        imgdata.color.black = 0;
        imgdata.color.maximum =
            MAX(imgdata.color.linear_max[0],
                MAX(imgdata.color.linear_max[1], imgdata.color.linear_max[2]));
      }

      if (libraw_internal_data.unpacker_data.pana_encoding == 6)
      {
        int rowbytes = imgdata.sizes.raw_width / 11 * 16;
        if ((imgdata.sizes.raw_width % 11) == 0 &&
            (imgdata.sizes.raw_height * rowbytes ==
             libraw_internal_data.unpacker_data.data_size))
          load_raw = &LibRaw::panasonicC6_load_raw;
        else
          imgdata.idata.raw_count = 0; // incorrect size
      }
      else if (libraw_internal_data.unpacker_data.pana_encoding == 7)
      {
        int pixperblock =
            libraw_internal_data.unpacker_data.pana_bpp == 14 ? 9 : 10;
        int rowbytes = imgdata.sizes.raw_width / pixperblock * 16;
        if ((imgdata.sizes.raw_width % pixperblock) == 0 &&
            (imgdata.sizes.raw_height * rowbytes ==
             libraw_internal_data.unpacker_data.data_size))
          load_raw = &LibRaw::panasonicC7_load_raw;
        else
          imgdata.idata.raw_count = 0; // incorrect size
      }
    }

#define NIKON_14BIT_SIZE(rw, rh)                                               \
  (((unsigned)(ceilf((float)(rw * 7 / 4) / 16.0)) * 16) * rh)

    // Ugly hack, replace with proper data/line size for different
    // cameras/format when available
    if (makeIs(LIBRAW_CAMERAMAKER_Nikon)
		&& !strncasecmp(imgdata.idata.model, "Z", 1) &&
        NIKON_14BIT_SIZE(imgdata.sizes.raw_width, imgdata.sizes.raw_height) ==
            libraw_internal_data.unpacker_data.data_size)
    {
      load_raw = &LibRaw::nikon_14bit_load_raw;
    }
#undef NIKON_14BIT_SIZE

    // Linear max from 14-bit camera, but on 12-bit data?
	if (makeIs(LIBRAW_CAMERAMAKER_Sony) &&
        imgdata.color.maximum > 0 &&
        imgdata.color.linear_max[0] > imgdata.color.maximum &&
        imgdata.color.linear_max[0] <= imgdata.color.maximum * 4)
      for (int c = 0; c < 4; c++)
        imgdata.color.linear_max[c] /= 4;

	if (makeIs(LIBRAW_CAMERAMAKER_Canon) )
    {
#define imC imgdata.makernotes.canon
#define isRIC imgdata.sizes.raw_inset_crop
      if (imC.SensorLeftBorder != -1)
      { // tag 0x00e0 SensorInfo was parsed
        if (isRIC.aspect != LIBRAW_IMAGE_ASPECT_UNKNOWN)
        { // tag 0x009a AspectInfo was parsed
          isRIC.cleft += imC.SensorLeftBorder;
          isRIC.ctop += imC.SensorTopBorder;
        }
        else
        {
          isRIC.cleft = imC.SensorLeftBorder;
          isRIC.ctop = imC.SensorTopBorder;
          isRIC.cwidth = imC.SensorRightBorder - imC.SensorLeftBorder + 1;
          isRIC.cheight = imC.SensorBottomBorder - imC.SensorTopBorder + 1;
        }
      }
      else
      {
        if (isRIC.aspect != LIBRAW_IMAGE_ASPECT_UNKNOWN)
        {
        }
        else
        { // Canon PowerShot S2 IS
        }
      }
#undef isRIC
#undef imC
    }

	if (makeIs(LIBRAW_CAMERAMAKER_Canon) &&
        (load_raw == &LibRaw::canon_sraw_load_raw) &&
        imgdata.sizes.raw_width > 0)
    {
      float ratio =
          float(imgdata.sizes.raw_height) / float(imgdata.sizes.raw_width);
      if ((ratio < 0.57 || ratio > 0.75) &&
          imgdata.makernotes.canon.SensorHeight > 1 &&
          imgdata.makernotes.canon.SensorWidth > 1)
      {
        imgdata.sizes.raw_width = imgdata.makernotes.canon.SensorWidth;
        imgdata.sizes.left_margin = imgdata.makernotes.canon.SensorLeftBorder;
        imgdata.sizes.iwidth = imgdata.sizes.width =
            imgdata.makernotes.canon.SensorRightBorder -
            imgdata.makernotes.canon.SensorLeftBorder + 1;
        imgdata.sizes.raw_height = imgdata.makernotes.canon.SensorHeight;
        imgdata.sizes.top_margin = imgdata.makernotes.canon.SensorTopBorder;
        imgdata.sizes.iheight = imgdata.sizes.height =
            imgdata.makernotes.canon.SensorBottomBorder -
            imgdata.makernotes.canon.SensorTopBorder + 1;
        libraw_internal_data.unpacker_data.load_flags |=
            256; // reset width/height in canon_sraw_load_raw()
        imgdata.sizes.raw_pitch = 8 * imgdata.sizes.raw_width;
      }
      else if (imgdata.sizes.raw_width == 4032 &&
               imgdata.sizes.raw_height == 3402 &&
               !strcasecmp(imgdata.idata.model, "EOS 80D")) // 80D hardcoded
      {
        imgdata.sizes.raw_width = 4536;
        imgdata.sizes.left_margin = 28;
        imgdata.sizes.iwidth = imgdata.sizes.width =
            imgdata.sizes.raw_width - imgdata.sizes.left_margin;
        imgdata.sizes.raw_height = 3024;
        imgdata.sizes.top_margin = 8;
        imgdata.sizes.iheight = imgdata.sizes.height =
            imgdata.sizes.raw_height - imgdata.sizes.top_margin;
        libraw_internal_data.unpacker_data.load_flags |= 256;
        imgdata.sizes.raw_pitch = 8 * imgdata.sizes.raw_width;
      }
    }

    // XTrans Compressed?
    if (!imgdata.idata.dng_version &&
		makeIs(LIBRAW_CAMERAMAKER_Fujifilm) &&
        (load_raw == &LibRaw::unpacked_load_raw))
    {
      if (imgdata.sizes.raw_width * imgdata.sizes.raw_height * 2 !=
          libraw_internal_data.unpacker_data.data_size)
      {
        if (imgdata.sizes.raw_width * imgdata.sizes.raw_height * 7 / 4 ==
            libraw_internal_data.unpacker_data.data_size)
          load_raw = &LibRaw::fuji_14bit_load_raw;
        else
          parse_fuji_compressed_header();
      }
      if (imgdata.idata.filters == 9)
      {
        // Adjust top/left margins for X-Trans
        int newtm = imgdata.sizes.top_margin % 6
                        ? (imgdata.sizes.top_margin / 6 + 1) * 6
                        : imgdata.sizes.top_margin;
        int newlm = imgdata.sizes.left_margin % 6
                        ? (imgdata.sizes.left_margin / 6 + 1) * 6
                        : imgdata.sizes.left_margin;
        if (newtm != imgdata.sizes.top_margin ||
            newlm != imgdata.sizes.left_margin)
        {
          imgdata.sizes.height -= (newtm - imgdata.sizes.top_margin);
          imgdata.sizes.top_margin = newtm;
          imgdata.sizes.width -= (newlm - imgdata.sizes.left_margin);
          imgdata.sizes.left_margin = newlm;
          for (int c1 = 0; c1 < 6; c1++)
            for (int c2 = 0; c2 < 6; c2++)
              imgdata.idata.xtrans[c1][c2] = imgdata.idata.xtrans_abs[c1][c2];
        }
      }
    }
    if (!libraw_internal_data.internal_output_params.fuji_width
        && imgdata.idata.filters >= 1000
        && ((imgdata.sizes.top_margin % 2) || (imgdata.sizes.left_margin%2)))
    {
        int crop[2] = {0,0};
        unsigned filt;
        int c;
        if(imgdata.sizes.top_margin % 2)
        {
            imgdata.sizes.top_margin+=1;
            imgdata.sizes.height-=1;
            crop[1] = 1;
        }
        if(imgdata.sizes.left_margin % 2)
        {
            imgdata.sizes.left_margin+=1;
            imgdata.sizes.width-=1;
            crop[0] = 1;
        }
        for (filt = c = 0; c < 16; c++)
            filt |= FC((c >> 1) + (crop[1]), (c & 1) + (crop[0])) << c * 2;
        imgdata.idata.filters = filt;
    }


    // Fix DNG white balance if needed
    if (imgdata.idata.dng_version && (imgdata.idata.filters == 0) &&
        imgdata.idata.colors > 1 && imgdata.idata.colors < 5)
    {
      float delta[4] = {0.f, 0.f, 0.f, 0.f};
      int black[4];
      for (int c = 0; c < 4; c++)
        black[c] = imgdata.color.dng_levels.dng_black +
                   imgdata.color.dng_levels.dng_cblack[c];
      for (int c = 0; c < imgdata.idata.colors; c++)
        delta[c] = imgdata.color.dng_levels.dng_whitelevel[c] - black[c];
      float mindelta = delta[0], maxdelta = delta[0];
      for (int c = 1; c < imgdata.idata.colors; c++)
      {
        if (mindelta > delta[c])
          mindelta = delta[c];
        if (maxdelta < delta[c])
          maxdelta = delta[c];
      }
      if (mindelta > 1 && maxdelta < (mindelta * 20)) // safety
      {
        for (int c = 0; c < imgdata.idata.colors; c++)
        {
          imgdata.color.cam_mul[c] /= (delta[c] / maxdelta);
          imgdata.color.pre_mul[c] /= (delta[c] / maxdelta);
        }
        imgdata.color.maximum = imgdata.color.cblack[0] + maxdelta;
      }
    }

    if (imgdata.idata.dng_version &&
        !(imgdata.params.raw_processing_options &
        LIBRAW_PROCESSING_USE_DNG_DEFAULT_CROP) &&
		makeIs(LIBRAW_CAMERAMAKER_Panasonic)
          && !strcasecmp(imgdata.idata.normalized_model, "DMC-LX100"))
      imgdata.sizes.width = 4288;

	if (makeIs(LIBRAW_CAMERAMAKER_Sony) &&
        imgdata.idata.dng_version &&
        !(imgdata.params.raw_processing_options &
          LIBRAW_PROCESSING_USE_DNG_DEFAULT_CROP))
    {
      if (S.raw_width == 3984)
        S.width = 3925;
      else if (S.raw_width == 4288)
        S.width = S.raw_width - 32;
      else if (S.raw_width == 4928 && S.height < 3280)
        S.width = S.raw_width - 8;
      else if (S.raw_width == 5504)
        S.width = S.raw_width - (S.height > 3664 ? 8 : 32);
    }

	if (makeIs(LIBRAW_CAMERAMAKER_Sony) &&
        !imgdata.idata.dng_version)
    {
        if(load_raw ==&LibRaw::sony_arq_load_raw)
        {
            if(S.raw_width > 12000) // A7RM4 16x, both APS-C and APS
                S.width = S.raw_width - 64;
            else // A7RM3/M4 4x merge
                S.width = S.raw_width - 32;
        }

      if (((!strncasecmp(imgdata.idata.model, "ILCE-7RM", 8) ||
            !strcasecmp(imgdata.idata.model, "ILCA-99M2")) &&
           (S.raw_width == 5216 || S.raw_width == 6304)) // A7RM2/M3/A99M2 in APS mode; A7RM4 in APS-C
          ||
          (!strcasecmp(imgdata.idata.model, "ILCE-7R") && S.raw_width >= 4580 &&
           S.raw_width < 5020) // A7R in crop mode, no samples, so size est.
          || (!strcasecmp(imgdata.idata.model, "ILCE-7") &&
              S.raw_width == 3968) // A7 in crop mode
          ||
          ((!strncasecmp(imgdata.idata.model, "ILCE-7M", 7) ||
            !strcasecmp(imgdata.idata.model, "ILCE-9") ||
            !strcasecmp(imgdata.idata.model,
                        "SLT-A99V")) // Is SLT-A99 also has APS-C mode??
           && S.raw_width > 3750 &&
           S.raw_width < 4120) // A7M2, A7M3, AA9, most likely APS-C raw_width
                               // is 3968 (same w/ A7), but no samples, so guess
          || (!strncasecmp(imgdata.idata.model, "ILCE-7S", 7) &&
              S.raw_width == 2816) // A7S2=> exact, hope it works for A7S-I too
      )
        S.width = S.raw_width - 32;
    }


    // FIXME: it is possible that DNG contains 4x main frames + some previews; in this case imgdata.idata.raw_count will be greater than 4
	if (makeIs(LIBRAW_CAMERAMAKER_Pentax) &&
        /*!strcasecmp(imgdata.idata.model,"K-3 II")  &&*/
            imgdata.idata.raw_count == 4 &&
        (imgdata.params.raw_processing_options &
         LIBRAW_PROCESSING_PENTAX_PS_ALLFRAMES))
    {
      imgdata.idata.raw_count = 1;
      imgdata.idata.filters = 0;
      imgdata.idata.colors = 4;
      imgdata.sizes.top_margin+=2;
      imgdata.sizes.left_margin+=2;
      imgdata.sizes.width-=4;
      imgdata.sizes.height-=4;
      IO.mix_green = 1;
      pentax_component_load_raw = load_raw;
      load_raw = &LibRaw::pentax_4shot_load_raw;
    }

	if (!imgdata.idata.dng_version && makeIs(LIBRAW_CAMERAMAKER_Leaf) &&
        !strcmp(imgdata.idata.model, "Credo 50"))
    {
      imgdata.color.pre_mul[0] = 1.f / 0.3984f;
      imgdata.color.pre_mul[2] = 1.f / 0.7666f;
      imgdata.color.pre_mul[1] = imgdata.color.pre_mul[3] = 1.0;
    }

    // S5/S3Pro DNG patch
	if (imgdata.idata.dng_version &&  makeIs(LIBRAW_CAMERAMAKER_Fujifilm))

	{
		if ((!strcmp(imgdata.idata.model, "S3Pro") || !strcmp(imgdata.idata.model, "S5Pro")) &&
			imgdata.sizes.raw_width == 4288)
		{
			imgdata.sizes.left_margin++;
			imgdata.sizes.width--;
		}
	}

	if (!imgdata.idata.dng_version && makeIs(LIBRAW_CAMERAMAKER_Fujifilm) &&
        (!strncmp(imgdata.idata.model, "S20Pro", 6) ||
         !strncmp(imgdata.idata.model, "F700", 4)))
    {
      imgdata.sizes.raw_width /= 2;
      load_raw = &LibRaw::unpacked_load_raw_fuji_f700s20;
    }

    if (load_raw == &LibRaw::packed_load_raw &&
		makeIs(LIBRAW_CAMERAMAKER_Nikon) &&
        !libraw_internal_data.unpacker_data.load_flags &&
        (!strncasecmp(imgdata.idata.model, "D810", 4) ||
         !strcasecmp(imgdata.idata.model, "D4S")) &&
        libraw_internal_data.unpacker_data.data_size * 2 ==
            imgdata.sizes.raw_height * imgdata.sizes.raw_width * 3)
    {
      libraw_internal_data.unpacker_data.load_flags = 80;
    }
    // Adjust BL for Sony A900/A850
    if (load_raw == &LibRaw::packed_load_raw &&
		makeIs(LIBRAW_CAMERAMAKER_Sony)) // 12 bit sony, but metadata may be for 14-bit range
    {
      if (C.maximum > 4095)
        C.maximum = 4095;
      if (C.black > 256 || C.cblack[0] > 256)
      {
        C.black /= 4;
        for (int c = 0; c < 4; c++)
          C.cblack[c] /= 4;
        for (int c = 0; c < C.cblack[4] * C.cblack[5]; c++)
          C.cblack[6 + c] /= 4;
      }
    }

	if (load_raw == &LibRaw::nikon_yuv_load_raw) // Is it Nikon sRAW?
    {
      load_raw = &LibRaw::nikon_load_sraw;
      C.black = 0;
      memset(C.cblack, 0, sizeof(C.cblack));
      imgdata.idata.filters = 0;
      libraw_internal_data.unpacker_data.tiff_samples = 3;
      imgdata.idata.colors = 3;
      double beta_1 = -5.79342238397656E-02;
      double beta_2 = 3.28163551282665;
      double beta_3 = -8.43136004842678;
      double beta_4 = 1.03533181861023E+01;
      for (int i = 0; i <= 3072; i++)
      {
        double x = (double)i / 3072.;
        double y = (1. - exp(-beta_1 * x - beta_2 * x * x - beta_3 * x * x * x -
                             beta_4 * x * x * x * x));
        if (y < 0.)
          y = 0.;
        imgdata.color.curve[i] = (y * 16383.);
      }
      for (int i = 0; i < 3; i++)
        for (int j = 0; j < 4; j++)
          imgdata.color.rgb_cam[i][j] = float(i == j);
    }
    // Adjust BL for Nikon 12bit
    if ((load_raw == &LibRaw::nikon_load_raw ||
         load_raw == &LibRaw::packed_load_raw ||
         load_raw == &LibRaw::nikon_load_padded_packed_raw) &&
		 makeIs(LIBRAW_CAMERAMAKER_Nikon) &&
        strncmp(imgdata.idata.model, "COOLPIX", 7) &&
        libraw_internal_data.unpacker_data.tiff_bps == 12)
    {
      C.maximum = 4095;
      C.black /= 4;
      for (int c = 0; c < 4; c++)
        C.cblack[c] /= 4;
      for (int c = 0; c < C.cblack[4] * C.cblack[5]; c++)
        C.cblack[6 + c] /= 4;
    }

    // Adjust wb_already_applied
    if (load_raw == &LibRaw::nikon_load_sraw)
      imgdata.color.as_shot_wb_applied =
          LIBRAW_ASWB_APPLIED | LIBRAW_ASWB_NIKON_SRAW;
    else if (makeIs(LIBRAW_CAMERAMAKER_Canon) &&
             imgdata.makernotes.canon.multishot[0] >= 8 &&
             imgdata.makernotes.canon.multishot[1] > 0)
      imgdata.color.as_shot_wb_applied =
          LIBRAW_ASWB_APPLIED | LIBRAW_ASWB_CANON;
    else if (makeIs(LIBRAW_CAMERAMAKER_Nikon) &&
             imgdata.makernotes.nikon.ExposureMode == 1)
      imgdata.color.as_shot_wb_applied =
          LIBRAW_ASWB_APPLIED | LIBRAW_ASWB_NIKON;
	else if (makeIs(LIBRAW_CAMERAMAKER_Pentax) &&
             ((imgdata.makernotes.pentax.MultiExposure & 0x01) == 1))
      imgdata.color.as_shot_wb_applied =
          LIBRAW_ASWB_APPLIED | LIBRAW_ASWB_PENTAX;
    else
      imgdata.color.as_shot_wb_applied = 0;

    // Adjust Highlight Linearity limit
    if (C.linear_max[0] < 0)
    {
      if (imgdata.idata.dng_version)
      {
        for (int c = 0; c < 4; c++)
          C.linear_max[c] = -1 * C.linear_max[c] + imgdata.color.cblack[c + 6];
      }
      else
      {
        for (int c = 0; c < 4; c++)
          C.linear_max[c] = -1 * C.linear_max[c] + imgdata.color.cblack[c];
      }
    }

	if (makeIs(LIBRAW_CAMERAMAKER_Nikon) &&
		(!C.linear_max[0]) && (C.maximum > 1024) && (load_raw != &LibRaw::nikon_load_sraw))
    {
      C.linear_max[0] = C.linear_max[1] = C.linear_max[2] = C.linear_max[3] =
          (long)((float)(C.maximum) / 1.07f);
    }

    // Correct WB for Samsung GX20
	if (
#if 0
        /* GX20 should be corrected, but K20 is not */
        makeIs(LIBRAW_CAMERAMAKER_Pentax) &&
		!strcasecmp(imgdata.idata.normalized_model, "K20D")
#endif
		!strcasecmp(imgdata.idata.make, "Samsung") &&
        !strcasecmp(imgdata.idata.model, "GX20")
		)
    {
      for (int cnt = LIBRAW_WBI_Unknown; cnt <= LIBRAW_WBI_StudioTungsten; cnt++) {
        if (C.WB_Coeffs[cnt][1]) {
          C.WB_Coeffs[cnt][0] =
            (int)((float)(C.WB_Coeffs[cnt][0]) * 1.0503f);
          C.WB_Coeffs[cnt][2] =
            (int)((float)(C.WB_Coeffs[cnt][2]) * 2.2867f);
        }
      }
      for (int cnt = 0; cnt < 64; cnt++) {
        if (imgdata.color.WBCT_Coeffs[cnt][0] > 0.0f) {
          imgdata.color.WBCT_Coeffs[cnt][1] *= 1.0503f;
          imgdata.color.WBCT_Coeffs[cnt][3] *= 2.2867f;
        }
      }
      for(int cnt = 0; cnt < 4; cnt++)
        imgdata.color.pre_mul[cnt] =
          C.WB_Coeffs[LIBRAW_WBI_Daylight][cnt];
    }

    // Adjust BL for Panasonic
    if (load_raw == &LibRaw::panasonic_load_raw &&
		makeIs(LIBRAW_CAMERAMAKER_Panasonic) &&
        ID.pana_black[0] && ID.pana_black[1] && ID.pana_black[2])
    {
      if (libraw_internal_data.unpacker_data.pana_encoding == 5)
        libraw_internal_data.internal_output_params.zero_is_bad = 0;
      C.black = 0;
      int add = libraw_internal_data.unpacker_data.pana_encoding == 4 ? 15 : 0;
      C.cblack[0] = ID.pana_black[0] + add;
      C.cblack[1] = C.cblack[3] = ID.pana_black[1] + add;
      C.cblack[2] = ID.pana_black[2] + add;
      int i = C.cblack[3];
      for (int c = 0; c < 3; c++)
        if (i > C.cblack[c])
          i = C.cblack[c];
      for (int c = 0; c < 4; c++)
        C.cblack[c] -= i;
      C.black = i;
    }

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

    SET_PROC_FLAG(LIBRAW_PROGRESS_IDENTIFY);
  }
  catch (LibRaw_exceptions err)
  {
    EXCEPTION_HANDLER(err);
  }
  catch (std::exception ee)
  {
    EXCEPTION_HANDLER(LIBRAW_EXCEPTION_IO_CORRUPT);
  }

final:;

  if (P1.raw_count < 1)
    return LIBRAW_FILE_UNSUPPORTED;

  write_fun = &LibRaw::write_ppm_tiff;

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

  IO.shrink =
      P1.filters &&
      (O.half_size || ((O.threshold || O.aber[0] != 1 || O.aber[2] != 1)));
  if (IO.shrink && P1.filters >= 1000)
  {
    S.width &= 65534;
    S.height &= 65534;
  }

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

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

  SET_PROC_FLAG(LIBRAW_PROGRESS_SIZE_ADJUST);

  return LIBRAW_SUCCESS;
}

Project: LibRaw

void LibRaw::kodak_thumb_loader()
{
  INT64 est_datasize =
      T.theight * T.twidth / 3; // is 0.3 bytes per pixel good estimate?
  if (ID.toffset < 0)
    throw LIBRAW_EXCEPTION_IO_CORRUPT;

  if (ID.toffset + est_datasize > ID.input->size() + THUMB_READ_BEYOND)
    throw LIBRAW_EXCEPTION_IO_EOF;

  // some kodak cameras
  ushort s_height = S.height, s_width = S.width, s_iwidth = S.iwidth,
         s_iheight = S.iheight;
  ushort s_flags = libraw_internal_data.unpacker_data.load_flags;
  libraw_internal_data.unpacker_data.load_flags = 12;
  int s_colors = P1.colors;
  unsigned s_filters = P1.filters;
  ushort(*s_image)[4] = imgdata.image;

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

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

  imgdata.image =
      (ushort(*)[4])calloc(S.iheight * S.iwidth, sizeof(*imgdata.image));
  merror(imgdata.image, "LibRaw::kodak_thumb_loader()");

  ID.input->seek(ID.toffset, SEEK_SET);
  // read kodak thumbnail into T.image[]
  try
  {
    (this->*thumb_load_raw)();
  }
  catch (...)
  {
    free(imgdata.image);
    imgdata.image = s_image;

    T.twidth = 0;
    S.width = s_width;

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

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

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

    P1.filters = s_filters;
    T.tlength = 0;
    libraw_internal_data.unpacker_data.load_flags = s_flags;
    return;
  }

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

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

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

  // from convert_to_rgb
  ushort *img;
  int row, col;

  int(*t_hist)[LIBRAW_HISTOGRAM_SIZE] =
      (int(*)[LIBRAW_HISTOGRAM_SIZE])calloc(sizeof(*t_hist), 4);
  merror(t_hist, "LibRaw::kodak_thumb_loader()");

  float out[3], out_cam[3][4] = {{2.81761312, -1.98369181, 0.166078627, 0},
                                 {-0.111855984, 1.73688626, -0.625030339, 0},
                                 {-0.0379119813, -0.891268849, 1.92918086, 0}};

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

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

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

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

  libraw_internal_data.output_data.histogram = save_hist;
  free(t_hist);

  // from write_ppm_tiff - copy pixels into bitmap

  int s_flip = imgdata.sizes.flip;
  if (imgdata.params.raw_processing_options &
      LIBRAW_PROCESSING_NO_ROTATE_FOR_KODAK_THUMBNAILS)
    imgdata.sizes.flip = 0;

  S.iheight = S.height;
  S.iwidth = S.width;
  if (S.flip & 4)
    SWAP(S.height, S.width);

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

  // from write_tiff_ppm
  {
    int soff = flip_index(0, 0);
    int cstep = flip_index(0, 1) - soff;
    int rstep = flip_index(1, 0) - flip_index(0, S.width);

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

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

  // restore variables
  free(imgdata.image);
  imgdata.image = s_image;

  if (imgdata.params.raw_processing_options &
      LIBRAW_PROCESSING_NO_ROTATE_FOR_KODAK_THUMBNAILS)
    imgdata.sizes.flip = s_flip;

  T.twidth = S.width;
  S.width = s_width;

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

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

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

  P1.filters = s_filters;
  libraw_internal_data.unpacker_data.load_flags = s_flags;
}

Project: LibRaw

void LibRaw::lin_interpolate_loop(int code[16][16][32], int size)
{
  int row;
  for (row = 1; row < height - 1; row++)
  {
    int col, *ip;
    ushort *pix;
    for (col = 1; col < width - 1; col++)
    {
      int i;
      int sum[4];
      pix = image[row * width + col];
      ip = code[row % size][col % size];
      memset(sum, 0, sizeof sum);
      for (i = *ip++; i--; ip += 3)
        sum[ip[2]] += pix[ip[0]] << ip[1];
      for (i = colors; --i; ip += 2)
        pix[ip[0]] = sum[ip[0]] * ip[1] >> 8;
    }
  }
}

Project: LibRaw

  libraw_processed_image_t *libraw_dcraw_make_mem_thumb(libraw_data_t *lr,
                                                        int *errc)
  {
    if (!lr)
    {
      if (errc)
        *errc = EINVAL;
      return NULL;
    }
    LibRaw *ip = (LibRaw *)lr->parent_class;
    return ip->dcraw_make_mem_thumb(errc);
  }

Project: LibRaw

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

Project: LibRaw

void LibRaw::write_ppm_tiff()
{
  struct tiff_hdr th;
  uchar *ppm;
  ushort *ppm2;
  int c, row, col, soff, rstep, cstep;
  int perc, val, total, t_white = 0x2000;

  perc = width * height * auto_bright_thr;

  if (fuji_width)
    perc /= 2;
  if (!((highlight & ~2) || no_auto_bright))
    for (t_white = c = 0; c < colors; c++)
    {
      for (val = 0x2000, total = 0; --val > 32;)
        if ((total += histogram[c][val]) > perc)
          break;
      if (t_white < val)
        t_white = val;
    }
  gamma_curve(gamm[0], gamm[1], 2, (t_white << 3) / bright);
  iheight = height;
  iwidth = width;
  if (flip & 4)
    SWAP(height, width);
  ppm = (uchar *)calloc(width, colors * output_bps / 8);
  ppm2 = (ushort *)ppm;
  merror(ppm, "write_ppm_tiff()");
  if (output_tiff)
  {
    tiff_head(&th, 1);
    fwrite(&th, sizeof th, 1, ofp);
    if (oprof)
      fwrite(oprof, ntohl(oprof[0]), 1, ofp);
  }
  else if (colors > 3)
    fprintf(
        ofp,
        "P7\nWIDTH %d\nHEIGHT %d\nDEPTH %d\nMAXVAL %d\nTUPLTYPE %s\nENDHDR\n",
        width, height, colors, (1 << output_bps) - 1, cdesc);
  else
    fprintf(ofp, "P%d\n%d %d\n%d\n", colors / 2 + 5, width, height,
            (1 << output_bps) - 1);
  soff = flip_index(0, 0);
  cstep = flip_index(0, 1) - soff;
  rstep = flip_index(1, 0) - flip_index(0, width);
  for (row = 0; row < height; row++, soff += rstep)
  {
    for (col = 0; col < width; col++, soff += cstep)
      if (output_bps == 8)
        FORCC ppm[col * colors + c] = curve[image[soff][c]] >> 8;
      else
        FORCC ppm2[col * colors + c] = curve[image[soff][c]];
    if (output_bps == 16 && !output_tiff && htons(0x55aa) != 0x55aa)
      swab((char *)ppm2, (char *)ppm2, width * colors * 2);
    fwrite(ppm, colors * output_bps / 8, width, ofp);
  }
  free(ppm);
}

Project: LibRaw

int LibRaw_file_datastream::jpeg_src(void *jpegdata)
{
#ifdef NO_JPEG
  return -1; // not supported
#else
  if (jas_file)
  {
    fclose(jas_file);
    jas_file = NULL;
  }
#ifdef LIBRAW_WIN32_UNICODEPATHS
  if (wfname())
  {
    jas_file = _wfopen(wfname(), L"rb");
  }
  else
#endif
  {
    jas_file = fopen(fname(), "rb");
  }
  if (jas_file)
  {
    fseek(jas_file, tell(), SEEK_SET);
    j_decompress_ptr cinfo = (j_decompress_ptr)jpegdata;
    jpeg_stdio_src(cinfo, jas_file);
    return 0; // OK
  }
  return -1;
#endif
}

Project: LibRaw

void LibRaw_windows_datastream::Open(HANDLE hFile)
{
  // create a file mapping handle on the file handle
  hMap_ = ::CreateFileMapping(hFile, 0, PAGE_READONLY, 0, 0, 0);
  if (hMap_ == NULL)
    throw std::runtime_error("failed to create file mapping");

  // now map the whole file base view
  if (!::GetFileSizeEx(hFile, (PLARGE_INTEGER)&cbView_))
    throw std::runtime_error("failed to get the file size");

  pView_ = ::MapViewOfFile(hMap_, FILE_MAP_READ, 0, 0, (size_t)cbView_);
  if (pView_ == NULL)
    throw std::runtime_error("failed to map the file");
}

Project: LibRaw

  void free(void *ptr)
  {
    forget_ptr(ptr);
    ::free(ptr);
  }

Project: LibRaw

void LibRaw::canon_600_fixed_wb(int temp)
{
  static const short mul[4][5] = {{667, 358, 397, 565, 452},
                                  {731, 390, 367, 499, 517},
                                  {1119, 396, 348, 448, 537},
                                  {1399, 485, 431, 508, 688}};
  int lo, hi, i;
  float frac = 0;

  for (lo = 4; --lo;)
    if (*mul[lo] <= temp)
      break;
  for (hi = 0; hi < 3; hi++)
    if (*mul[hi] >= temp)
      break;
  if (lo != hi)
    frac = (float)(temp - *mul[lo]) / (*mul[hi] - *mul[lo]);
  for (i = 1; i < 5; i++)
    pre_mul[i - 1] = 1 / (frac * mul[hi][i] + (1 - frac) * mul[lo][i]);
}

Project: LibRaw

void DHT::hide_hots()
{
  int iwidth = libraw.imgdata.sizes.iwidth;
#if defined(LIBRAW_USE_OPENMP)
#pragma omp parallel for schedule(guided) firstprivate(iwidth)
#endif
  for (int i = 0; i < libraw.imgdata.sizes.iheight; ++i)
  {
    int js = libraw.COLOR(i, 0) & 1;
    int kc = libraw.COLOR(i, js);
    /*
     * js -- начальная х-координата, которая попадает мимо известного зелёного
     * kc -- известный цвет в точке интерполирования
     */
    for (int j = js; j < iwidth; j += 2)
    {
      int x = j + nr_leftmargin;
      int y = i + nr_topmargin;
      float c = nraw[nr_offset(y, x)][kc];
      if ((c > nraw[nr_offset(y, x + 2)][kc] &&
           c > nraw[nr_offset(y, x - 2)][kc] &&
           c > nraw[nr_offset(y - 2, x)][kc] &&
           c > nraw[nr_offset(y + 2, x)][kc] &&
           c > nraw[nr_offset(y, x + 1)][1] &&
           c > nraw[nr_offset(y, x - 1)][1] &&
           c > nraw[nr_offset(y - 1, x)][1] &&
           c > nraw[nr_offset(y + 1, x)][1]) ||
          (c < nraw[nr_offset(y, x + 2)][kc] &&
           c < nraw[nr_offset(y, x - 2)][kc] &&
           c < nraw[nr_offset(y - 2, x)][kc] &&
           c < nraw[nr_offset(y + 2, x)][kc] &&
           c < nraw[nr_offset(y, x + 1)][1] &&
           c < nraw[nr_offset(y, x - 1)][1] &&
           c < nraw[nr_offset(y - 1, x)][1] &&
           c < nraw[nr_offset(y + 1, x)][1]))
      {
        float avg = 0;
        for (int k = -2; k < 3; k += 2)
          for (int m = -2; m < 3; m += 2)
            if (m == 0 && k == 0)
              continue;
            else
              avg += nraw[nr_offset(y + k, x + m)][kc];
        avg /= 8;
        //				float dev = 0;
        //				for (int k = -2; k < 3; k += 2)
        //					for (int l = -2; l < 3; l += 2)
        //						if (k == 0 && l == 0)
        //							continue;
        //						else {
        //							float t = nraw[nr_offset(y + k, x + l)][kc] -
        //avg; 							dev += t * t;
        //						}
        //				dev /= 8;
        //				dev = sqrt(dev);
        if (calc_dist(c, avg) > Thot())
        {
          ndir[nr_offset(y, x)] |= HOT;
          float dv = calc_dist(
              nraw[nr_offset(y - 2, x)][kc] * nraw[nr_offset(y - 1, x)][1],
              nraw[nr_offset(y + 2, x)][kc] * nraw[nr_offset(y + 1, x)][1]);
          float dh = calc_dist(
              nraw[nr_offset(y, x - 2)][kc] * nraw[nr_offset(y, x - 1)][1],
              nraw[nr_offset(y, x + 2)][kc] * nraw[nr_offset(y, x + 1)][1]);
          if (dv > dh)
            nraw[nr_offset(y, x)][kc] = (nraw[nr_offset(y, x + 2)][kc] +
                                         nraw[nr_offset(y, x - 2)][kc]) /
                                        2;
          else
            nraw[nr_offset(y, x)][kc] = (nraw[nr_offset(y - 2, x)][kc] +
                                         nraw[nr_offset(y + 2, x)][kc]) /
                                        2;
        }
      }
    }
    for (int j = js ^ 1; j < iwidth; j += 2)
    {
      int x = j + nr_leftmargin;
      int y = i + nr_topmargin;
      float c = nraw[nr_offset(y, x)][1];
      if ((c > nraw[nr_offset(y, x + 2)][1] &&
           c > nraw[nr_offset(y, x - 2)][1] &&
           c > nraw[nr_offset(y - 2, x)][1] &&
           c > nraw[nr_offset(y + 2, x)][1] &&
           c > nraw[nr_offset(y, x + 1)][kc] &&
           c > nraw[nr_offset(y, x - 1)][kc] &&
           c > nraw[nr_offset(y - 1, x)][kc ^ 2] &&
           c > nraw[nr_offset(y + 1, x)][kc ^ 2]) ||
          (c < nraw[nr_offset(y, x + 2)][1] &&
           c < nraw[nr_offset(y, x - 2)][1] &&
           c < nraw[nr_offset(y - 2, x)][1] &&
           c < nraw[nr_offset(y + 2, x)][1] &&
           c < nraw[nr_offset(y, x + 1)][kc] &&
           c < nraw[nr_offset(y, x - 1)][kc] &&
           c < nraw[nr_offset(y - 1, x)][kc ^ 2] &&
           c < nraw[nr_offset(y + 1, x)][kc ^ 2]))
      {
        float avg = 0;
        for (int k = -2; k < 3; k += 2)
          for (int m = -2; m < 3; m += 2)
            if (k == 0 && m == 0)
              continue;
            else
              avg += nraw[nr_offset(y + k, x + m)][1];
        avg /= 8;
        //				float dev = 0;
        //				for (int k = -2; k < 3; k += 2)
        //					for (int l = -2; l < 3; l += 2)
        //						if (k == 0 && l == 0)
        //							continue;
        //						else {
        //							float t = nraw[nr_offset(y + k, x + l)][1] -
        //avg; 							dev += t * t;
        //						}
        //				dev /= 8;
        //				dev = sqrt(dev);
        if (calc_dist(c, avg) > Thot())
        {
          ndir[nr_offset(y, x)] |= HOT;
          float dv = calc_dist(
              nraw[nr_offset(y - 2, x)][1] * nraw[nr_offset(y - 1, x)][kc ^ 2],
              nraw[nr_offset(y + 2, x)][1] * nraw[nr_offset(y + 1, x)][kc ^ 2]);
          float dh = calc_dist(
              nraw[nr_offset(y, x - 2)][1] * nraw[nr_offset(y, x - 1)][kc],
              nraw[nr_offset(y, x + 2)][1] * nraw[nr_offset(y, x + 1)][kc]);
          if (dv > dh)
            nraw[nr_offset(y, x)][1] =
                (nraw[nr_offset(y, x + 2)][1] + nraw[nr_offset(y, x - 2)][1]) /
                2;
          else
            nraw[nr_offset(y, x)][1] =
                (nraw[nr_offset(y - 2, x)][1] + nraw[nr_offset(y + 2, x)][1]) /
                2;
        }
      }
    }
  }
}

Project: LibRaw

  const char **libraw_cameraList() { return LibRaw::cameraList(); }

Project: LibRaw

int LibRaw::median4(int *p)
{
  int min, max, sum, i;

  min = max = sum = p[0];
  for (i = 1; i < 4; i++)
  {
    sum += p[i];
    if (min > p[i])
      min = p[i];
    if (max < p[i])
      max = p[i];
  }
  return (sum - min - max) >> 1;
}

Project: LibRaw

void LibRaw::phase_one_flat_field(int is_float, int nc)
{
  ushort head[8];
  unsigned wide, high, y, x, c, rend, cend, row, col;
  float *mrow, num, mult[4];

  read_shorts(head, 8);
  if (head[2] * head[3] * head[4] * head[5] == 0)
    return;
  wide = head[2] / head[4] + (head[2] % head[4] != 0);
  high = head[3] / head[5] + (head[3] % head[5] != 0);
  mrow = (float *)calloc(nc * wide, sizeof *mrow);
  merror(mrow, "phase_one_flat_field()");
  for (y = 0; y < high; y++)
  {
    checkCancel();
    for (x = 0; x < wide; x++)
      for (c = 0; c < nc; c += 2)
      {
        num = is_float ? getreal(11) : get2() / 32768.0;
        if (y == 0)
          mrow[c * wide + x] = num;
        else
          mrow[(c + 1) * wide + x] = (num - mrow[c * wide + x]) / head[5];
      }
    if (y == 0)
      continue;
    rend = head[1] + y * head[5];
    for (row = rend - head[5];
         row < raw_height && row < rend && row < head[1] + head[3] - head[5];
         row++)
    {
      for (x = 1; x < wide; x++)
      {
        for (c = 0; c < nc; c += 2)
        {
          mult[c] = mrow[c * wide + x - 1];
          mult[c + 1] = (mrow[c * wide + x] - mult[c]) / head[4];
        }
        cend = head[0] + x * head[4];
        for (col = cend - head[4];
             col < raw_width && col < cend && col < head[0] + head[2] - head[4];
             col++)
        {
          c = nc > 2 ? FC(row - top_margin, col - left_margin) : 0;
          if (!(c & 1))
          {
            c = RAW(row, col) * mult[c];
            RAW(row, col) = LIM(c, 0, 65535);
          }
          for (c = 0; c < nc; c += 2)
            mult[c] += mult[c + 1];
        }
      }
      for (x = 0; x < wide; x++)
        for (c = 0; c < nc; c += 2)
          mrow[c * wide + x] += mrow[(c + 1) * wide + x];
    }
  }
  free(mrow);
}

Project: LibRaw

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

Project: LibRaw

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

  fseek(ifp, base, SEEK_SET);
  if (fgetc(ifp) || fgetc(ifp) - 'M' || fgetc(ifp) - 'R')
    return;
  order = fgetc(ifp) * 0x101;
  offset = base + get4() + 8;
  INT64 fsize = ifp->size();
  if (offset > fsize - 8) // At least 8 bytes for tag/len
    offset = fsize - 8;

  while ((save = ftell(ifp)) < offset)
  {
    for (tag = i = 0; i < 4; i++)
      tag = tag << 8 | fgetc(ifp);
    len = get4();
    if (len < 0)
      return; // just ignore wrong len?? or raise bad file exception?
    if ((INT64)len + save + 8ULL > fsize)
      return; // just ignore out of file metadata, stop parse
    switch (tag)
    {
    case 0x505244: /* PRD */
      fseek(ifp, 8, SEEK_CUR);
      high = get2();
      wide = get2();
      imSony.prd_ImageHeight = get2();
      imSony.prd_ImageWidth = get2();
      fseek(ifp, 1L, SEEK_CUR);
      imSony.prd_RawBitDepth = (ushort)fgetc(ifp);
      imSony.prd_StorageMethod = (ushort)fgetc(ifp);
      fseek(ifp, 4L, SEEK_CUR);
      imSony.prd_BayerPattern = (ushort)fgetc(ifp);
      break;
#define icWBC imgdata.color.WB_Coeffs
    case 0x524946: /* RIF */
      if (!strncasecmp(model, "DSLR-A100", 9))
      {
        fseek(ifp, 8, SEEK_CUR);
        icWBC[LIBRAW_WBI_Tungsten][0] = get2();
        icWBC[LIBRAW_WBI_Tungsten][2] = get2();
        icWBC[LIBRAW_WBI_Daylight][0] = get2();
        icWBC[LIBRAW_WBI_Daylight][2] = get2();
        icWBC[LIBRAW_WBI_Cloudy][0] = get2();
        icWBC[LIBRAW_WBI_Cloudy][2] = get2();
        icWBC[LIBRAW_WBI_FL_W][0] = get2();
        icWBC[LIBRAW_WBI_FL_W][2] = get2();
        icWBC[LIBRAW_WBI_Flash][0] = get2();
        icWBC[LIBRAW_WBI_Flash][2] = get2();
        get4();
        icWBC[LIBRAW_WBI_Shade][0] = get2();
        icWBC[LIBRAW_WBI_Shade][2] = get2();
        icWBC[LIBRAW_WBI_FL_D][0] = get2();
        icWBC[LIBRAW_WBI_FL_D][2] = get2();
        icWBC[LIBRAW_WBI_FL_N][0] = get2();
        icWBC[LIBRAW_WBI_FL_N][2] = get2();
        icWBC[LIBRAW_WBI_FL_WW][0] = get2();
        icWBC[LIBRAW_WBI_FL_WW][2] = get2();
        icWBC[LIBRAW_WBI_Daylight][1] = icWBC[LIBRAW_WBI_Daylight][3] = icWBC
            [LIBRAW_WBI_Tungsten]
            [1] = icWBC[LIBRAW_WBI_Tungsten][3] = icWBC[LIBRAW_WBI_Flash][1] =
                icWBC[LIBRAW_WBI_Flash][3] = icWBC[LIBRAW_WBI_Cloudy][1] =
                    icWBC[LIBRAW_WBI_Cloudy][3] = icWBC[LIBRAW_WBI_Shade][1] =
                        icWBC[LIBRAW_WBI_Shade][3] = icWBC[LIBRAW_WBI_FL_D][1] =
                            icWBC[LIBRAW_WBI_FL_D][3] =
                                icWBC[LIBRAW_WBI_FL_N][1] =
                                    icWBC[LIBRAW_WBI_FL_N][3] =
                                        icWBC[LIBRAW_WBI_FL_W][1] =
                                            icWBC[LIBRAW_WBI_FL_W][3] =
                                                icWBC[LIBRAW_WBI_FL_WW][1] =
                                                    icWBC[LIBRAW_WBI_FL_WW][3] =
                                                        0x100;
      }
      break;
#undef icWBC
    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

void AAHD::illustrate_dirs()
{
  for (int i = 0; i < libraw.imgdata.sizes.iheight; ++i)
  {
    illustrate_dline(i);
  }
}

Project: LibRaw

int LibRaw_bigfile_datastream::valid() { return f ? 1 : 0; }

Project: LibRaw

void LibRaw::lossless_dng_load_raw()
{
  unsigned save, trow = 0, tcol = 0, jwide, jrow, jcol, row, col, i, j;
  struct jhead jh;
  ushort *rp;

  int ss = shot_select;
  shot_select = libraw_internal_data.unpacker_data.dng_frames[LIM(ss,0,(LIBRAW_IFD_MAXCOUNT*2-1))] & 0xff;

  while (trow < raw_height)
  {
    checkCancel();
    save = ftell(ifp);
    if (tile_length < INT_MAX)
      fseek(ifp, get4(), SEEK_SET);
    if (!ljpeg_start(&jh, 0))
      break;
    jwide = jh.wide;
    if (filters)
      jwide *= jh.clrs;

    if(filters && (tiff_samples == 2)) // Fuji Super CCD
        jwide /= 2;
    try
    {
      switch (jh.algo)
      {
      case 0xc1:
        jh.vpred[0] = 16384;
        getbits(-1);
        for (jrow = 0; jrow + 7 < jh.high; jrow += 8)
        {
          checkCancel();
          for (jcol = 0; jcol + 7 < jh.wide; jcol += 8)
          {
            ljpeg_idct(&jh);
            rp = jh.idct;
            row = trow + jcol / tile_width + jrow * 2;
            col = tcol + jcol % tile_width;
            for (i = 0; i < 16; i += 2)
              for (j = 0; j < 8; j++)
                adobe_copy_pixel(row + i, col + j, &rp);
          }
        }
        break;
      case 0xc3:
        for (row = col = jrow = 0; jrow < jh.high; jrow++)
        {
          checkCancel();
          rp = ljpeg_row(jrow, &jh);
          if (tiff_samples == 1 && jh.clrs > 1 && jh.clrs * jwide == raw_width)
            for (jcol = 0; jcol < jwide * jh.clrs; jcol++)
            {
              adobe_copy_pixel(trow + row, tcol + col, &rp);
              if (++col >= tile_width || col >= raw_width)
                row += 1 + (col = 0);
            }
          else
            for (jcol = 0; jcol < jwide; jcol++)
            {
              adobe_copy_pixel(trow + row, tcol + col, &rp);
              if (++col >= tile_width || col >= raw_width)
                row += 1 + (col = 0);
            }
        }
      }
    }
    catch (...)
    {
      ljpeg_end(&jh);
      shot_select = ss;
      throw;
    }
    fseek(ifp, save + 4, SEEK_SET);
    if ((tcol += tile_width) >= raw_width)
      trow += tile_length + (tcol = 0);
    ljpeg_end(&jh);
  }
  shot_select = ss;
}

Project: LibRaw

void LibRaw::dht_interpolate()
{
  DHT dht(*this);
  dht.hide_hots();
  dht.make_hv_dirs();
  //	dht.illustrate_dirs();
  dht.make_greens();
  dht.make_diag_dirs();
  //	dht.illustrate_dirs();
  dht.make_rb();
  dht.restore_hots();
  dht.copy_to_image();
}

Project: LibRaw

void AAHD::hide_hots()
{
  int iwidth = libraw.imgdata.sizes.iwidth;
  for (int i = 0; i < libraw.imgdata.sizes.iheight; ++i)
  {
    int js = libraw.COLOR(i, 0) & 1;
    int kc = libraw.COLOR(i, js);
    /*
     * js -- начальная х-координата, которая попадает мимо известного зелёного
     * kc -- известный цвет в точке интерполирования
     */
    int moff = nr_offset(i + nr_margin, nr_margin + js);
    for (int j = js; j < iwidth; j += 2, moff += 2)
    {
      ushort3 *rgb = &rgb_ahd[0][moff];
      int c = rgb[0][kc];
      if ((c > rgb[2 * Pe][kc] && c > rgb[2 * Pw][kc] && c > rgb[2 * Pn][kc] &&
           c > rgb[2 * Ps][kc] && c > rgb[Pe][1] && c > rgb[Pw][1] &&
           c > rgb[Pn][1] && c > rgb[Ps][1]) ||
          (c < rgb[2 * Pe][kc] && c < rgb[2 * Pw][kc] && c < rgb[2 * Pn][kc] &&
           c < rgb[2 * Ps][kc] && c < rgb[Pe][1] && c < rgb[Pw][1] &&
           c < rgb[Pn][1] && c < rgb[Ps][1]))
      {
        int chot = c >> Thot;
        int cdead = c << Tdead;
        int avg = 0;
        for (int k = -2; k < 3; k += 2)
          for (int m = -2; m < 3; m += 2)
            if (m == 0 && k == 0)
              continue;
            else
              avg += rgb[nr_offset(k, m)][kc];
        avg /= 8;
        if (chot > avg || cdead < avg)
        {
          ndir[moff] |= HOT;
          int dh =
              ABS(rgb[2 * Pw][kc] - rgb[2 * Pe][kc]) +
              ABS(rgb[Pw][1] - rgb[Pe][1]) +
              ABS(rgb[Pw][1] - rgb[Pe][1] + rgb[2 * Pe][kc] - rgb[2 * Pw][kc]);
          int dv =
              ABS(rgb[2 * Pn][kc] - rgb[2 * Ps][kc]) +
              ABS(rgb[Pn][1] - rgb[Ps][1]) +
              ABS(rgb[Pn][1] - rgb[Ps][1] + rgb[2 * Ps][kc] - rgb[2 * Pn][kc]);
          int d;
          if (dv > dh)
            d = Pw;
          else
            d = Pn;
          rgb_ahd[1][moff][kc] = rgb[0][kc] =
              (rgb[+2 * d][kc] + rgb[-2 * d][kc]) / 2;
        }
      }
    }
    js ^= 1;
    moff = nr_offset(i + nr_margin, nr_margin + js);
    for (int j = js; j < iwidth; j += 2, moff += 2)
    {
      ushort3 *rgb = &rgb_ahd[0][moff];
      int c = rgb[0][1];
      if ((c > rgb[2 * Pe][1] && c > rgb[2 * Pw][1] && c > rgb[2 * Pn][1] &&
           c > rgb[2 * Ps][1] && c > rgb[Pe][kc] && c > rgb[Pw][kc] &&
           c > rgb[Pn][kc ^ 2] && c > rgb[Ps][kc ^ 2]) ||
          (c < rgb[2 * Pe][1] && c < rgb[2 * Pw][1] && c < rgb[2 * Pn][1] &&
           c < rgb[2 * Ps][1] && c < rgb[Pe][kc] && c < rgb[Pw][kc] &&
           c < rgb[Pn][kc ^ 2] && c < rgb[Ps][kc ^ 2]))
      {
        int chot = c >> Thot;
        int cdead = c << Tdead;
        int avg = 0;
        for (int k = -2; k < 3; k += 2)
          for (int m = -2; m < 3; m += 2)
            if (k == 0 && m == 0)
              continue;
            else
              avg += rgb[nr_offset(k, m)][1];
        avg /= 8;
        if (chot > avg || cdead < avg)
        {
          ndir[moff] |= HOT;
          int dh =
              ABS(rgb[2 * Pw][1] - rgb[2 * Pe][1]) +
              ABS(rgb[Pw][kc] - rgb[Pe][kc]) +
              ABS(rgb[Pw][kc] - rgb[Pe][kc] + rgb[2 * Pe][1] - rgb[2 * Pw][1]);
          int dv = ABS(rgb[2 * Pn][1] - rgb[2 * Ps][1]) +
                   ABS(rgb[Pn][kc ^ 2] - rgb[Ps][kc ^ 2]) +
                   ABS(rgb[Pn][kc ^ 2] - rgb[Ps][kc ^ 2] + rgb[2 * Ps][1] -
                       rgb[2 * Pn][1]);
          int d;
          if (dv > dh)
            d = Pw;
          else
            d = Pn;
          rgb_ahd[1][moff][1] = rgb[0][1] =
              (rgb[+2 * d][1] + rgb[-2 * d][1]) / 2;
        }
      }
    }
  }
}

Project: LibRaw

void LibRaw::smal_v6_load_raw()
{
  unsigned seg[2][2];

  fseek(ifp, 16, SEEK_SET);
  seg[0][0] = 0;
  seg[0][1] = get2();
  seg[1][0] = raw_width * raw_height;
  seg[1][1] = INT_MAX;
  smal_decode_segment(seg, 0);
}

Project: LibRaw

LibRaw_buffer_datastream::LibRaw_buffer_datastream(void *buffer, size_t bsize)
{
  buf = (unsigned char *)buffer;
  streampos = 0;
  streamsize = bsize;
}

Project: LibRaw

static void jpegErrorExit_d(j_common_ptr cinfo)
{
  throw LIBRAW_EXCEPTION_DECODE_JPEG;
}

Project: LibRaw

float timerend(void)
{
  gettimeofday(&end, NULL);
  float msec = (end.tv_sec - start.tv_sec) * 1000.0f +
               (end.tv_usec - start.tv_usec) / 1000.0f;
  return msec;
}

Project: LibRaw

void LibRaw::parse_qt(int end)
{
  unsigned save, size;
  char tag[4];

  order = 0x4d4d;
  while (ftell(ifp) + 7 < end)
  {
    save = ftell(ifp);
    if ((size = get4()) < 8)
      return;
    if ((int)size < 0)
      return; // 2+GB is too much
    if (save + size < save)
      return; // 32bit overflow
    fread(tag, 4, 1, ifp);
    if (!memcmp(tag, "moov", 4) || !memcmp(tag, "udta", 4) ||
        !memcmp(tag, "CNTH", 4))
      parse_qt(save + size);
    if (!memcmp(tag, "CNDA", 4))
      parse_jpeg(ftell(ifp));
    fseek(ifp, save + size, SEEK_SET);
  }
}

Project: LibRaw

void AAHD::refine_hv_dirs(int i, int js)
{
  int iwidth = libraw.imgdata.sizes.iwidth;
  int moff = nr_offset(i + nr_margin, nr_margin + js);
  for (int j = js; j < iwidth; j += 2, moff += 2)
  {
    int nv = (ndir[moff + Pn] & VER) + (ndir[moff + Ps] & VER) +
             (ndir[moff + Pw] & VER) + (ndir[moff + Pe] & VER);
    int nh = (ndir[moff + Pn] & HOR) + (ndir[moff + Ps] & HOR) +
             (ndir[moff + Pw] & HOR) + (ndir[moff + Pe] & HOR);
    bool codir = (ndir[moff] & VER)
                     ? ((ndir[moff + Pn] & VER) || (ndir[moff + Ps] & VER))
                     : ((ndir[moff + Pw] & HOR) || (ndir[moff + Pe] & HOR));
    nv /= VER;
    nh /= HOR;
    if ((ndir[moff] & VER) && (nh > 2 && !codir))
    {
      ndir[moff] &= ~VER;
      ndir[moff] |= HOR;
    }
    if ((ndir[moff] & HOR) && (nv > 2 && !codir))
    {
      ndir[moff] &= ~HOR;
      ndir[moff] |= VER;
    }
  }
}

Project: LibRaw

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

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

    RUN_CALLBACK(LIBRAW_PROGRESS_LOAD_RAW, 0, 2);
    if (O.shot_select >= P1.raw_count)
      return LIBRAW_REQUEST_FOR_NONEXISTENT_IMAGE;

    if (!load_raw)
      return LIBRAW_UNSPECIFIED_ERROR;

    // already allocated ?
    if (imgdata.image)
    {
      free(imgdata.image);
      imgdata.image = 0;
    }
    if (imgdata.rawdata.raw_alloc)
    {
      free(imgdata.rawdata.raw_alloc);
      imgdata.rawdata.raw_alloc = 0;
    }
    if (libraw_internal_data.unpacker_data.meta_length)
    {
      libraw_internal_data.internal_data.meta_data =
          (char *)malloc(libraw_internal_data.unpacker_data.meta_length);
      merror(libraw_internal_data.internal_data.meta_data, "LibRaw::unpack()");
    }

    libraw_decoder_info_t decoder_info;
    get_decoder_info(&decoder_info);

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

    int rwidth = S.raw_width, rheight = S.raw_height;
    if (!IO.fuji_width)
    {
      // adjust non-Fuji allocation
      if (rwidth < S.width + S.left_margin)
        rwidth = S.width + S.left_margin;
      if (rheight < S.height + S.top_margin)
        rheight = S.height + S.top_margin;
    }
    if (rwidth > 65535 ||
        rheight > 65535) // No way to make image larger than 64k pix
      throw LIBRAW_EXCEPTION_IO_CORRUPT;

    imgdata.rawdata.raw_image = 0;
    imgdata.rawdata.color4_image = 0;
    imgdata.rawdata.color3_image = 0;
    imgdata.rawdata.float_image = 0;
    imgdata.rawdata.float3_image = 0;

#ifdef USE_DNGSDK
    if (imgdata.idata.dng_version && dnghost 
        && libraw_internal_data.unpacker_data.tiff_samples != 2  // Fuji SuperCCD; it is better to detect is more rigid way
        && valid_for_dngsdk() && load_raw != &LibRaw::pentax_4shot_load_raw)
    {
      // Data size check
      INT64 pixcount =
          INT64(MAX(S.width, S.raw_width)) * INT64(MAX(S.height, S.raw_height));
      INT64 planecount =
          (imgdata.idata.filters || P1.colors == 1) ? 1 : LIM(P1.colors, 3, 4);
      INT64 samplesize = is_floating_point() ? 4 : 2;
      INT64 bytes = pixcount * planecount * samplesize;
      if (bytes > INT64(imgdata.params.max_raw_memory_mb) * INT64(1024 * 1024))
        throw LIBRAW_EXCEPTION_TOOBIG;

      // find ifd to check sample
      int rr = try_dngsdk();
      if (raw_was_read())
        imgdata.process_warnings |= LIBRAW_WARN_DNGSDK_PROCESSED;
    }
#endif

#ifdef USE_RAWSPEED
    if (!raw_was_read())
    {
      int rawspeed_enabled = 1;

      if (imgdata.idata.dng_version && (libraw_internal_data.unpacker_data.tiff_samples == 2 || imgdata.idata.raw_count > 1))
        rawspeed_enabled = 0;

      if (libraw_internal_data.unpacker_data.is_NikonTransfer)
        rawspeed_enabled = 0;

      if (libraw_internal_data.unpacker_data.pana_encoding == 5)
        rawspeed_enabled = 0;

      if (imgdata.idata.raw_count > 1)
        rawspeed_enabled = 0;
      if (!strncasecmp(imgdata.idata.software, "Magic", 5))
        rawspeed_enabled = 0;
      // Disable rawspeed for double-sized Oly files
      if (!strncasecmp(imgdata.idata.make, "Olympus", 7) &&
          ((imgdata.sizes.raw_width > 6000) ||
           !strncasecmp(imgdata.idata.model, "SH-2", 4) ||
           !strncasecmp(imgdata.idata.model, "SH-3", 4) ||
           !strncasecmp(imgdata.idata.model, "TG-4", 4) ||
           !strncasecmp(imgdata.idata.model, "TG-5", 4) ||
           !strncasecmp(imgdata.idata.model, "TG-6", 4)))
        rawspeed_enabled = 0;

      if (!strncasecmp(imgdata.idata.make, "Canon", 5) &&
          !strcasecmp(imgdata.idata.model, "EOS 6D Mark II"))
        rawspeed_enabled = 0;

      if (imgdata.idata.dng_version && imgdata.idata.filters == 0 &&
          libraw_internal_data.unpacker_data.tiff_bps == 8) // Disable for 8 bit
        rawspeed_enabled = 0;

      if (load_raw == &LibRaw::packed_load_raw &&
          !strncasecmp(imgdata.idata.make, "Nikon", 5) &&
          (!strncasecmp(imgdata.idata.model, "E", 1) ||
           !strncasecmp(imgdata.idata.model, "COOLPIX B", 9) ||
           !strncasecmp(imgdata.idata.model, "COOLPIX P1000", 13)))
        rawspeed_enabled = 0;

      if (load_raw == &LibRaw::nikon_load_raw &&
          !strncasecmp(imgdata.idata.make, "Nikon", 5) &&
          !strncasecmp(imgdata.idata.model, "Z", 1))
        rawspeed_enabled = 0;

      if (load_raw == &LibRaw::panasonic_load_raw &&
          libraw_internal_data.unpacker_data.pana_encoding > 4)
        rawspeed_enabled = 0;

      // RawSpeed Supported,
      if (O.use_rawspeed && rawspeed_enabled &&
          !(is_sraw() && (O.raw_processing_options &
                          (LIBRAW_PROCESSING_SRAW_NO_RGB |
                           LIBRAW_PROCESSING_SRAW_NO_INTERPOLATE))) &&
          (decoder_info.decoder_flags & LIBRAW_DECODER_TRYRAWSPEED) &&
          _rawspeed_camerameta)
      {
        INT64 pixcount = INT64(MAX(S.width, S.raw_width)) *
                         INT64(MAX(S.height, S.raw_height));
        INT64 planecount = (imgdata.idata.filters || P1.colors == 1)
                               ? 1
                               : LIM(P1.colors, 3, 4);
        INT64 bytes =
            pixcount * planecount * 2; // sample size is always 2 for rawspeed
        if (bytes >
            INT64(imgdata.params.max_raw_memory_mb) * INT64(1024 * 1024))
          throw LIBRAW_EXCEPTION_TOOBIG;

        int rr = try_rawspeed();
      }
    }
#endif
    if (!raw_was_read()) // RawSpeed failed or not run
    {
      // Not allocated on RawSpeed call, try call LibRaow
      int zero_rawimage = 0;
      if (decoder_info.decoder_flags & LIBRAW_DECODER_OWNALLOC)
      {
        // x3f foveon decoder and DNG float
        // Do nothing! Decoder will allocate data internally
      }
      if (decoder_info.decoder_flags & LIBRAW_DECODER_SINAR4SHOT)
      {
        if (imgdata.params.shot_select) // single image extract
        {
          if (INT64(rwidth) * INT64(rheight + 8) *
                  sizeof(imgdata.rawdata.raw_image[0]) >
              INT64(imgdata.params.max_raw_memory_mb) * INT64(1024 * 1024))
            throw LIBRAW_EXCEPTION_TOOBIG;
          imgdata.rawdata.raw_alloc = malloc(
              rwidth * (rheight + 8) * sizeof(imgdata.rawdata.raw_image[0]));
          imgdata.rawdata.raw_image = (ushort *)imgdata.rawdata.raw_alloc;
          if (!S.raw_pitch)
            S.raw_pitch = S.raw_width * 2; // Bayer case, not set before
        }
        else // Full image extract
        {
          if (INT64(rwidth) * INT64(rheight + 8) *
                  sizeof(imgdata.rawdata.raw_image[0]) * 4 >
              INT64(imgdata.params.max_raw_memory_mb) * INT64(1024 * 1024))
            throw LIBRAW_EXCEPTION_TOOBIG;
          S.raw_pitch = S.raw_width * 8;
          imgdata.rawdata.raw_alloc = 0;
          imgdata.image = (ushort(*)[4])calloc(
              unsigned(MAX(S.width, S.raw_width)) *
                  unsigned(MAX(S.height, S.raw_height) + 8),
              sizeof(*imgdata.image));
        }
      }
      else if (decoder_info.decoder_flags & LIBRAW_DECODER_3CHANNEL)
      {
        if (INT64(rwidth) * INT64(rheight + 8) *
                sizeof(imgdata.rawdata.raw_image[0]) * 3 >
            INT64(imgdata.params.max_raw_memory_mb) * INT64(1024 * 1024))
          throw LIBRAW_EXCEPTION_TOOBIG;

        imgdata.rawdata.raw_alloc = malloc(
            rwidth * (rheight + 8) * sizeof(imgdata.rawdata.raw_image[0]) * 3);
        imgdata.rawdata.color3_image = (ushort(*)[3])imgdata.rawdata.raw_alloc;
        if (!S.raw_pitch)
          S.raw_pitch = S.raw_width * 6;
      }
      else if (imgdata.idata.filters ||
               P1.colors ==
                   1) // Bayer image or single color -> decode to raw_image
      {
        if (INT64(rwidth) * INT64(rheight + 8) *
                sizeof(imgdata.rawdata.raw_image[0]) >
            INT64(imgdata.params.max_raw_memory_mb) * INT64(1024 * 1024))
          throw LIBRAW_EXCEPTION_TOOBIG;
        imgdata.rawdata.raw_alloc = malloc(
            rwidth * (rheight + 8) * sizeof(imgdata.rawdata.raw_image[0]));
        imgdata.rawdata.raw_image = (ushort *)imgdata.rawdata.raw_alloc;
        if (!S.raw_pitch)
          S.raw_pitch = S.raw_width * 2; // Bayer case, not set before
      }
      else // NO LEGACY FLAG if (decoder_info.decoder_flags &
           // LIBRAW_DECODER_LEGACY)
      {
        if (decoder_info.decoder_flags & LIBRAW_DECODER_ADOBECOPYPIXEL)
        {
          S.raw_pitch = S.raw_width * 8;
        }
        else
        {
          S.iwidth = S.width;
          S.iheight = S.height;
          IO.shrink = 0;
          if (!S.raw_pitch)
            S.raw_pitch = (decoder_info.decoder_flags &
                           LIBRAW_DECODER_LEGACY_WITH_MARGINS)
                              ? S.raw_width * 8
                              : S.width * 8;
        }
        // sRAW and old Foveon decoders only, so extra buffer size is just 1/4
        // allocate image as temporary buffer, size
        if (INT64(MAX(S.width, S.raw_width)) *
                INT64(MAX(S.height, S.raw_height) + 8) *
                sizeof(*imgdata.image) >
            INT64(imgdata.params.max_raw_memory_mb) * INT64(1024 * 1024))
          throw LIBRAW_EXCEPTION_TOOBIG;

        imgdata.rawdata.raw_alloc = 0;
        imgdata.image =
            (ushort(*)[4])calloc(unsigned(MAX(S.width, S.raw_width)) *
                                     unsigned(MAX(S.height, S.raw_height) + 8),
                                 sizeof(*imgdata.image));
        if (!(decoder_info.decoder_flags & LIBRAW_DECODER_ADOBECOPYPIXEL))
        {
          imgdata.rawdata.raw_image = (ushort *)imgdata.image;
          zero_rawimage = 1;
        }
      }
      ID.input->seek(libraw_internal_data.unpacker_data.data_offset, SEEK_SET);

      unsigned m_save = C.maximum;
      if (load_raw == &LibRaw::unpacked_load_raw &&
          (!strcasecmp(imgdata.idata.make, "Nikon") || !strcasecmp(imgdata.idata.make, "Hasselblad"))
          )
        C.maximum = 65535;
      (this->*load_raw)();
      if (zero_rawimage)
        imgdata.rawdata.raw_image = 0;
      if (load_raw == &LibRaw::unpacked_load_raw &&
          (!strcasecmp(imgdata.idata.make, "Nikon") || !strcasecmp(imgdata.idata.make, "Hasselblad"))
          )
        C.maximum = m_save;
      if (decoder_info.decoder_flags & LIBRAW_DECODER_OWNALLOC)
      {
        // x3f foveon decoder only: do nothing
      }
      else if (decoder_info.decoder_flags & LIBRAW_DECODER_SINAR4SHOT &&
               imgdata.params.shot_select == 0)
      {
        imgdata.rawdata.raw_alloc = imgdata.image;
        imgdata.rawdata.color4_image = (ushort(*)[4])imgdata.rawdata.raw_alloc;
        imgdata.image = 0;
      }
      else if (!(imgdata.idata.filters ||
                 P1.colors == 1)) // legacy decoder, ownalloc handled above
      {
        // successfully decoded legacy image, attach image to raw_alloc
        imgdata.rawdata.raw_alloc = imgdata.image;
        imgdata.rawdata.color4_image = (ushort(*)[4])imgdata.rawdata.raw_alloc;
        imgdata.image = 0;
        // Restore saved values. Note: Foveon have masked frame
        // Other 4-color legacy data: no borders
        if (!(libraw_internal_data.unpacker_data.load_flags & 256) &&
            !(decoder_info.decoder_flags & LIBRAW_DECODER_ADOBECOPYPIXEL) &&
            !(decoder_info.decoder_flags & LIBRAW_DECODER_LEGACY_WITH_MARGINS))
        {
          S.raw_width = S.width;
          S.left_margin = 0;
          S.raw_height = S.height;
          S.top_margin = 0;
        }
      }
    }

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

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

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

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

    SET_PROC_FLAG(LIBRAW_PROGRESS_LOAD_RAW);
    RUN_CALLBACK(LIBRAW_PROGRESS_LOAD_RAW, 1, 2);

    return 0;
  }
  catch (LibRaw_exceptions err)
  {
    EXCEPTION_HANDLER(err);
  }
  catch (std::exception ee)
  {
    EXCEPTION_HANDLER(LIBRAW_EXCEPTION_IO_CORRUPT);
  }
}

Project: LibRaw
File: libraw_cxx.cpp

void LibRaw::merror(void *ptr, const char *where)
{
  if (ptr)
    return;
  if (callbacks.mem_cb)
    (*callbacks.mem_cb)(callbacks.memcb_data,
                        libraw_internal_data.internal_data.input
                            ? libraw_internal_data.internal_data.input->fname()
                            : NULL,
                        where);
  throw LIBRAW_EXCEPTION_ALLOC;
}

Project: LibRaw

void LibRaw::parseOlympus_Equipment(unsigned tag, unsigned type, unsigned len,
                                    unsigned dng_writer)
{
  // uptag 2010

  int i;

  switch (tag)
  {
  case 0x0100:
    getOlympus_CameraType2();
    break;
  case 0x0101:
    if ((!imgdata.shootinginfo.BodySerial[0]) && (dng_writer == nonDNG))
      stmread(imgdata.shootinginfo.BodySerial, len, ifp);
    break;
  case 0x0102:
    stmread(imgdata.shootinginfo.InternalBodySerial, len, ifp);
    break;
  case 0x0201:
  {
    unsigned char bits[4];
    fread(bits, 1, 4, ifp);
    ilm.LensID = (unsigned long long)bits[0] << 16 |
                 (unsigned long long)bits[2] << 8 | (unsigned long long)bits[3];
    ilm.LensMount = LIBRAW_MOUNT_FT;
    ilm.LensFormat = LIBRAW_FORMAT_FT;
    if (((ilm.LensID < 0x20000) || (ilm.LensID > 0x4ffff)) &&
        (ilm.LensID & 0x10))
      ilm.LensMount = LIBRAW_MOUNT_mFT;
  }
  break;
  case 0x0202:
    if ((!imgdata.lens.LensSerial[0]))
      stmread(imgdata.lens.LensSerial, len, ifp);
    break;
  case 0x0203:
    stmread(ilm.Lens, len, ifp);
    break;
  case 0x0205:
    ilm.MaxAp4MinFocal = libraw_powf64l(sqrt(2.0f), get2() / 256.0f);
    break;
  case 0x0206:
    ilm.MaxAp4MaxFocal = libraw_powf64l(sqrt(2.0f), get2() / 256.0f);
    break;
  case 0x0207:
    ilm.MinFocal = (float)get2();
    break;
  case 0x0208:
    ilm.MaxFocal = (float)get2();
    if (ilm.MaxFocal > 1000.0f)
      ilm.MaxFocal = ilm.MinFocal;
    break;
  case 0x020a:
    ilm.MaxAp4CurFocal = libraw_powf64l(sqrt(2.0f), get2() / 256.0f);
    break;
  case 0x0301:
    ilm.TeleconverterID = fgetc(ifp) << 8;
    fgetc(ifp);
    ilm.TeleconverterID = ilm.TeleconverterID | fgetc(ifp);
    break;
  case 0x0303:
    stmread(ilm.Teleconverter, len, ifp);
    break;
  case 0x0403:
    stmread(ilm.Attachment, len, ifp);
    break;
  }

  return;
}

Project: LibRaw

void timer_start(starttime_t& r)
{
#ifdef LIBRAW_WIN32_CALLS
	QueryPerformanceCounter(&r.started);
#else
	gettimeofday(&r.started,NULL);
#endif
}

Project: LibRaw

void LibRaw::fuji_bayer_decode_block(
    struct fuji_compressed_block *info,
    const struct fuji_compressed_params *params, int cur_line)
{
  int r_even_pos = 0, r_odd_pos = 1;
  int g_even_pos = 0, g_odd_pos = 1;
  int b_even_pos = 0, b_odd_pos = 1;

  int errcnt = 0;

  const int line_width = params->line_width;

  while (g_even_pos < line_width || g_odd_pos < line_width)
  {
    if (g_even_pos < line_width)
    {
      errcnt += fuji_decode_sample_even(info, params, info->linebuf[_R2] + 1,
                                        r_even_pos, info->grad_even[0]);
      r_even_pos += 2;
      errcnt += fuji_decode_sample_even(info, params, info->linebuf[_G2] + 1,
                                        g_even_pos, info->grad_even[0]);
      g_even_pos += 2;
    }
    if (g_even_pos > 8)
    {
      errcnt += fuji_decode_sample_odd(info, params, info->linebuf[_R2] + 1,
                                       r_odd_pos, info->grad_odd[0]);
      r_odd_pos += 2;
      errcnt += fuji_decode_sample_odd(info, params, info->linebuf[_G2] + 1,
                                       g_odd_pos, info->grad_odd[0]);
      g_odd_pos += 2;
    }
  }

  fuji_extend_red(info->linebuf, line_width);
  fuji_extend_green(info->linebuf, line_width);

  g_even_pos = 0, g_odd_pos = 1;

  while (g_even_pos < line_width || g_odd_pos < line_width)
  {
    if (g_even_pos < line_width)
    {
      errcnt += fuji_decode_sample_even(info, params, info->linebuf[_G3] + 1,
                                        g_even_pos, info->grad_even[1]);
      g_even_pos += 2;
      errcnt += fuji_decode_sample_even(info, params, info->linebuf[_B2] + 1,
                                        b_even_pos, info->grad_even[1]);
      b_even_pos += 2;
    }
    if (g_even_pos > 8)
    {
      errcnt += fuji_decode_sample_odd(info, params, info->linebuf[_G3] + 1,
                                       g_odd_pos, info->grad_odd[1]);
      g_odd_pos += 2;
      errcnt += fuji_decode_sample_odd(info, params, info->linebuf[_B2] + 1,
                                       b_odd_pos, info->grad_odd[1]);
      b_odd_pos += 2;
    }
  }

  fuji_extend_green(info->linebuf, line_width);
  fuji_extend_blue(info->linebuf, line_width);

  r_even_pos = 0, r_odd_pos = 1;
  g_even_pos = 0, g_odd_pos = 1;

  while (g_even_pos < line_width || g_odd_pos < line_width)
  {
    if (g_even_pos < line_width)
    {
      errcnt += fuji_decode_sample_even(info, params, info->linebuf[_R3] + 1,
                                        r_even_pos, info->grad_even[2]);
      r_even_pos += 2;
      errcnt += fuji_decode_sample_even(info, params, info->linebuf[_G4] + 1,
                                        g_even_pos, info->grad_even[2]);
      g_even_pos += 2;
    }
    if (g_even_pos > 8)
    {
      errcnt += fuji_decode_sample_odd(info, params, info->linebuf[_R3] + 1,
                                       r_odd_pos, info->grad_odd[2]);
      r_odd_pos += 2;
      errcnt += fuji_decode_sample_odd(info, params, info->linebuf[_G4] + 1,
                                       g_odd_pos, info->grad_odd[2]);
      g_odd_pos += 2;
    }
  }

  fuji_extend_red(info->linebuf, line_width);
  fuji_extend_green(info->linebuf, line_width);

  g_even_pos = 0, g_odd_pos = 1;
  b_even_pos = 0, b_odd_pos = 1;

  while (g_even_pos < line_width || g_odd_pos < line_width)
  {
    if (g_even_pos < line_width)
    {
      errcnt += fuji_decode_sample_even(info, params, info->linebuf[_G5] + 1,
                                        g_even_pos, info->grad_even[0]);
      g_even_pos += 2;
      errcnt += fuji_decode_sample_even(info, params, info->linebuf[_B3] + 1,
                                        b_even_pos, info->grad_even[0]);
      b_even_pos += 2;
    }
    if (g_even_pos > 8)
    {
      errcnt += fuji_decode_sample_odd(info, params, info->linebuf[_G5] + 1,
                                       g_odd_pos, info->grad_odd[0]);
      g_odd_pos += 2;
      errcnt += fuji_decode_sample_odd(info, params, info->linebuf[_B3] + 1,
                                       b_odd_pos, info->grad_odd[0]);
      b_odd_pos += 2;
    }
  }

  fuji_extend_green(info->linebuf, line_width);
  fuji_extend_blue(info->linebuf, line_width);

  r_even_pos = 0, r_odd_pos = 1;
  g_even_pos = 0, g_odd_pos = 1;

  while (g_even_pos < line_width || g_odd_pos < line_width)
  {
    if (g_even_pos < line_width)
    {
      errcnt += fuji_decode_sample_even(info, params, info->linebuf[_R4] + 1,
                                        r_even_pos, info->grad_even[1]);
      r_even_pos += 2;
      errcnt += fuji_decode_sample_even(info, params, info->linebuf[_G6] + 1,
                                        g_even_pos, info->grad_even[1]);
      g_even_pos += 2;
    }
    if (g_even_pos > 8)
    {
      errcnt += fuji_decode_sample_odd(info, params, info->linebuf[_R4] + 1,
                                       r_odd_pos, info->grad_odd[1]);
      r_odd_pos += 2;
      errcnt += fuji_decode_sample_odd(info, params, info->linebuf[_G6] + 1,
                                       g_odd_pos, info->grad_odd[1]);
      g_odd_pos += 2;
    }
  }

  fuji_extend_red(info->linebuf, line_width);
  fuji_extend_green(info->linebuf, line_width);

  g_even_pos = 0, g_odd_pos = 1;
  b_even_pos = 0, b_odd_pos = 1;

  while (g_even_pos < line_width || g_odd_pos < line_width)
  {
    if (g_even_pos < line_width)
    {
      errcnt += fuji_decode_sample_even(info, params, info->linebuf[_G7] + 1,
                                        g_even_pos, info->grad_even[2]);
      g_even_pos += 2;
      errcnt += fuji_decode_sample_even(info, params, info->linebuf[_B4] + 1,
                                        b_even_pos, info->grad_even[2]);
      b_even_pos += 2;
    }
    if (g_even_pos > 8)
    {
      errcnt += fuji_decode_sample_odd(info, params, info->linebuf[_G7] + 1,
                                       g_odd_pos, info->grad_odd[2]);
      g_odd_pos += 2;
      errcnt += fuji_decode_sample_odd(info, params, info->linebuf[_B4] + 1,
                                       b_odd_pos, info->grad_odd[2]);
      b_odd_pos += 2;
    }
  }

  fuji_extend_green(info->linebuf, line_width);
  fuji_extend_blue(info->linebuf, line_width);

  if (errcnt)
    derror();
}

Project: LibRaw

int main(int ac, char *av[])
{
  int i;
  libraw_data_t *iprc = libraw_init(0);

  if (!iprc)
  {
    fprintf(stderr, "Cannot create libraw handle\n");
    exit(1);
  }

  iprc->params.half_size = 1; /* dcraw -h */

  for (i = 1; i < ac; i++)
  {
    char outfn[1024];
    int ret = libraw_open_file(iprc, av[i]);
    HANDLE_ALL_ERRORS(ret);

    printf("Processing %s (%s %s)\n", av[i], iprc->idata.make,
           iprc->idata.model);

    ret = libraw_unpack(iprc);
    HANDLE_ALL_ERRORS(ret);

    ret = libraw_dcraw_process(iprc);
    HANDLE_ALL_ERRORS(ret);

    strcpy(outfn, av[i]);
    strcat(outfn, ".ppm");
    printf("Writing to %s\n", outfn);

    ret = libraw_dcraw_ppm_tiff_writer(iprc, outfn);
    HANDLE_FATAL_ERROR(ret);
  }
  libraw_close(iprc);
  return 0;
}

Project: LibRaw

void DHT::refine_idiag_dirs(int i)
{
  int iwidth = libraw.imgdata.sizes.iwidth;
  for (int j = 0; j < iwidth; j++)
  {
    int x = j + nr_leftmargin;
    int y = i + nr_topmargin;
    if (ndir[nr_offset(y, x)] & DIASH)
      continue;
    int nv = (ndir[nr_offset(y - 1, x)] & LURD) +
             (ndir[nr_offset(y + 1, x)] & LURD) +
             (ndir[nr_offset(y, x - 1)] & LURD) +
             (ndir[nr_offset(y, x + 1)] & LURD) +
             (ndir[nr_offset(y - 1, x - 1)] & LURD) +
             (ndir[nr_offset(y - 1, x + 1)] & LURD) +
             (ndir[nr_offset(y + 1, x - 1)] & LURD) +
             (ndir[nr_offset(y + 1, x + 1)] & LURD);
    int nh = (ndir[nr_offset(y - 1, x)] & RULD) +
             (ndir[nr_offset(y + 1, x)] & RULD) +
             (ndir[nr_offset(y, x - 1)] & RULD) +
             (ndir[nr_offset(y, x + 1)] & RULD) +
             (ndir[nr_offset(y - 1, x - 1)] & RULD) +
             (ndir[nr_offset(y - 1, x + 1)] & RULD) +
             (ndir[nr_offset(y + 1, x - 1)] & RULD) +
             (ndir[nr_offset(y + 1, x + 1)] & RULD);
    bool codir = (ndir[nr_offset(y, x)] & LURD)
                     ? ((ndir[nr_offset(y - 1, x - 1)] & LURD) ||
                        (ndir[nr_offset(y + 1, x + 1)] & LURD))
                     : ((ndir[nr_offset(y - 1, x + 1)] & RULD) ||
                        (ndir[nr_offset(y + 1, x - 1)] & RULD));
    nv /= LURD;
    nh /= RULD;
    if ((ndir[nr_offset(y, x)] & LURD) && nh > 7)
    {
      ndir[nr_offset(y, x)] &= ~LURD;
      ndir[nr_offset(y, x)] |= RULD;
    }
    if ((ndir[nr_offset(y, x)] & RULD) && nv > 7)
    {
      ndir[nr_offset(y, x)] &= ~RULD;
      ndir[nr_offset(y, x)] |= LURD;
    }
  }
}

Project: LibRaw

static inline float calc_dist(float c1, float c2)
{
  return c1 > c2 ? c1 / c2 : c2 / c1;
}

Project: LibRaw

void LibRaw::phase_one_load_raw()
{
  int a, b, i;
  ushort akey, bkey, t_mask;

  fseek(ifp, ph1.key_off, SEEK_SET);
  akey = get2();
  bkey = get2();
  t_mask = ph1.format == 1 ? 0x5555 : 0x1354;
  if (ph1.black_col || ph1.black_row)
  {
    imgdata.rawdata.ph1_cblack =
        (short(*)[2])calloc(raw_height * 2, sizeof(ushort));
    merror(imgdata.rawdata.ph1_cblack, "phase_one_load_raw()");
    imgdata.rawdata.ph1_rblack =
        (short(*)[2])calloc(raw_width * 2, sizeof(ushort));
    merror(imgdata.rawdata.ph1_rblack, "phase_one_load_raw()");
    if (ph1.black_col)
    {
      fseek(ifp, ph1.black_col, SEEK_SET);
      read_shorts((ushort *)imgdata.rawdata.ph1_cblack[0], raw_height * 2);
    }
    if (ph1.black_row)
    {
      fseek(ifp, ph1.black_row, SEEK_SET);
      read_shorts((ushort *)imgdata.rawdata.ph1_rblack[0], raw_width * 2);
    }
  }
  fseek(ifp, data_offset, SEEK_SET);
  read_shorts(raw_image, raw_width * raw_height);
  if (ph1.format)
    for (i = 0; i < raw_width * raw_height; i += 2)
    {
      a = raw_image[i + 0] ^ akey;
      b = raw_image[i + 1] ^ bkey;
      raw_image[i + 0] = (a & t_mask) | (b & ~t_mask);
      raw_image[i + 1] = (b & t_mask) | (a & ~t_mask);
    }
}

Project: LibRaw

void LibRaw::ppg_interpolate()
{
  int dir[5] = {1, width, -1, -width, 1};
  int row, col, diff[2], guess[2], c, d, i;
  ushort(*pix)[4];

  border_interpolate(3);

  /*  Fill in the green layer with gradients and pattern recognition: */
  RUN_CALLBACK(LIBRAW_PROGRESS_INTERPOLATE, 0, 3);
#ifdef LIBRAW_USE_OPENMP
#pragma omp parallel for default(shared) private(guess, diff, row, col, d, c,  \
                                                 i, pix) schedule(static)
#endif
  for (row = 3; row < height - 3; row++)
    for (col = 3 + (FC(row, 3) & 1), c = FC(row, col); col < width - 3;
         col += 2)
    {
      pix = image + row * width + col;
      for (i = 0; (d = dir[i]) > 0; i++)
      {
        guess[i] = (pix[-d][1] + pix[0][c] + pix[d][1]) * 2 - pix[-2 * d][c] -
                   pix[2 * d][c];
        diff[i] =
            (ABS(pix[-2 * d][c] - pix[0][c]) + ABS(pix[2 * d][c] - pix[0][c]) +
             ABS(pix[-d][1] - pix[d][1])) *
                3 +
            (ABS(pix[3 * d][1] - pix[d][1]) +
             ABS(pix[-3 * d][1] - pix[-d][1])) *
                2;
      }
      d = dir[i = diff[0] > diff[1]];
      pix[0][1] = ULIM(guess[i] >> 2, pix[d][1], pix[-d][1]);
    }
  /*  Calculate red and blue for each green pixel:		*/
  RUN_CALLBACK(LIBRAW_PROGRESS_INTERPOLATE, 1, 3);
#ifdef LIBRAW_USE_OPENMP
#pragma omp parallel for default(shared) private(guess, diff, row, col, d, c,  \
                                                 i, pix) schedule(static)
#endif
  for (row = 1; row < height - 1; row++)
    for (col = 1 + (FC(row, 2) & 1), c = FC(row, col + 1); col < width - 1;
         col += 2)
    {
      pix = image + row * width + col;
      for (i = 0; (d = dir[i]) > 0; c = 2 - c, i++)
        pix[0][c] = CLIP(
            (pix[-d][c] + pix[d][c] + 2 * pix[0][1] - pix[-d][1] - pix[d][1]) >>
            1);
    }
  /*  Calculate blue for red pixels and vice versa:		*/
  RUN_CALLBACK(LIBRAW_PROGRESS_INTERPOLATE, 2, 3);
#ifdef LIBRAW_USE_OPENMP
#pragma omp parallel for default(shared) private(guess, diff, row, col, d, c,  \
                                                 i, pix) schedule(static)
#endif
  for (row = 1; row < height - 1; row++)
    for (col = 1 + (FC(row, 1) & 1), c = 2 - FC(row, col); col < width - 1;
         col += 2)
    {
      pix = image + row * width + col;
      for (i = 0; (d = dir[i] + dir[i + 1]) > 0; i++)
      {
        diff[i] = ABS(pix[-d][c] - pix[d][c]) + ABS(pix[-d][1] - pix[0][1]) +
                  ABS(pix[d][1] - pix[0][1]);
        guess[i] =
            pix[-d][c] + pix[d][c] + 2 * pix[0][1] - pix[-d][1] - pix[d][1];
      }
      if (diff[0] != diff[1])
        pix[0][c] = CLIP(guess[diff[0] > diff[1]] >> 1);
      else
        pix[0][c] = CLIP((guess[0] + guess[1]) >> 2);
    }
}

Project: LibRaw
File: libraw_cxx.cpp

void LibRaw::unpacked_load_raw_fuji_f700s20()
{
  int base_offset = 0;
  int row_size = imgdata.sizes.raw_width * 2; // in bytes
  if (imgdata.idata.raw_count == 2 && imgdata.params.shot_select)
  {
    libraw_internal_data.internal_data.input->seek(-row_size, SEEK_CUR);
    base_offset = row_size; // in bytes
  }
  unsigned char *buffer = (unsigned char *)malloc(row_size * 2);
  for (int row = 0; row < imgdata.sizes.raw_height; row++)
  {
    read_shorts((ushort *)buffer, imgdata.sizes.raw_width * 2);
    memmove(&imgdata.rawdata.raw_image[row * imgdata.sizes.raw_pitch / 2],
            buffer + base_offset, row_size);
  }
  free(buffer);
}

Project: LibRaw

void LibRaw::nikon_14bit_load_raw()
{
  const unsigned linelen =
      (unsigned)(ceilf((float)(S.raw_width * 7 / 4) / 16.0)) *
      16; // 14512; // S.raw_width * 7 / 4;
  const unsigned pitch = S.raw_pitch ? S.raw_pitch / 2 : S.raw_width;
  unsigned char *buf = (unsigned char *)malloc(linelen);
  merror(buf, "nikon_14bit_load_raw()");
  for (int row = 0; row < S.raw_height; row++)
  {
    unsigned bytesread =
        libraw_internal_data.internal_data.input->read(buf, 1, linelen);
    unsigned short *dest = &imgdata.rawdata.raw_image[pitch * row];
    // swab32arr((unsigned *)buf, bytesread / 4);
    for (int sp = 0, dp = 0;
         dp < pitch - 3 && sp < linelen - 6 && sp < bytesread - 6;
         sp += 7, dp += 4)
      unpack7bytesto4x16_nikon(buf + sp, dest + dp);
  }
  free(buf);
}

Project: LibRaw

  int libraw_dcraw_ppm_tiff_writer(libraw_data_t *lr, const char *filename)
  {
    if (!lr)
      return EINVAL;
    LibRaw *ip = (LibRaw *)lr->parent_class;
    return ip->dcraw_ppm_tiff_writer(filename);
  }

Project: LibRaw

INT64 LibRaw_buffer_datastream::tell()
{
  return INT64(streampos);
}

Project: LibRaw

void write_ppm(libraw_processed_image_t *img, const char *basename)
{
  if (!img)
    return;
  // type SHOULD be LIBRAW_IMAGE_BITMAP, but we'll check
  if (img->type != LIBRAW_IMAGE_BITMAP)
    return;
  // only 3-color images supported...
  if (img->colors != 3)
    return;

  char fn[1024];
  snprintf(fn, 1024, "%s.ppm", basename);
  FILE *f = fopen(fn, "wb");
  if (!f)
    return;
  fprintf(f, "P6\n%d %d\n%d\n", img->width, img->height, (1 << img->bits) - 1);
/*
  NOTE:
  data in img->data is not converted to network byte order.
  So, we should swap values on some architectures for dcraw compatibility
  (unfortunately, xv cannot display 16-bit PPMs with network byte order data
*/
#define SWAP(a, b)                                                             \
  {                                                                            \
    a ^= b;                                                                    \
    a ^= (b ^= a);                                                             \
  }
  if (img->bits == 16 && htons(0x55aa) != 0x55aa)
    for (unsigned i = 0; i < img->data_size; i += 2)
      SWAP(img->data[i], img->data[i + 1]);
#undef SWAP

  fwrite(img->data, img->data_size, 1, f);
  fclose(f);
}

Project: LibRaw

  void *calloc(size_t n, size_t sz)
  {
    void *ptr = ::calloc(n + (extra_bytes + sz - 1) / (sz ? sz : 1), sz);
    mem_ptr(ptr);
    return ptr;
  }

Project: LibRaw

void usage(const char *av)
{
	printf(
		"Dump (small) selecton of RAW file as tab-separated text file\n"
		"Usage: %s inputfile COL ROW [CHANNEL] [width] [height]\n"
		"  COL - start column\n"
		"  ROW - start row\n"
		"  CHANNEL - raw channel to dump, default is 0 (red for rggb)\n"
		"  width - area width to dump, default is 16\n"
		"  height - area height to dump, default is 4\n"
		, av);
}

Project: LibRaw

void LibRaw::unpacked_load_raw_reversed()
{
  int row, col, bits = 0;
  while (1 << ++bits < maximum)
    ;
  for (row = raw_height - 1; row >= 0; row--)
  {
    checkCancel();
    read_shorts(&raw_image[row * raw_width], raw_width);
    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

  DllDef void libraw_set_gamma(libraw_data_t *lr, int index, float value)
  {
    if (!lr)
      return;
    LibRaw *ip = (LibRaw *)lr->parent_class;
    ip->imgdata.params.gamm[LIM(index, 0, 5)] = value;
  }

Project: LibRaw

void LibRaw::cam_xyz_coeff(float _rgb_cam[3][4], double cam_xyz[4][3])
{
  double cam_rgb[4][3], inverse[4][3], num;
  int i, j, k;

  for (i = 0; i < colors; i++) /* Multiply out XYZ colorspace */
    for (j = 0; j < 3; j++)
      for (cam_rgb[i][j] = k = 0; k < 3; k++)
        cam_rgb[i][j] += cam_xyz[i][k] * LibRaw_constants::xyz_rgb[k][j];

  for (i = 0; i < colors; i++)
  {                               /* Normalize cam_rgb so that */
    for (num = j = 0; j < 3; j++) /* cam_rgb * (1,1,1) is (1,1,1,1) */
      num += cam_rgb[i][j];
    if (num > 0.00001)
    {
      for (j = 0; j < 3; j++)
        cam_rgb[i][j] /= num;
      pre_mul[i] = 1 / num;
    }
    else
    {
      for (j = 0; j < 3; j++)
        cam_rgb[i][j] = 0.0;
      pre_mul[i] = 1.0;
    }
  }
  pseudoinverse(cam_rgb, inverse, colors);
  for (i = 0; i < 3; i++)
    for (j = 0; j < colors; j++)
      _rgb_cam[i][j] = inverse[j][i];
}

Project: LibRaw

void LibRaw::fuji_rotate()
{
  int i, row, col;
  double step;
  float r, c, fr, fc;
  unsigned ur, uc;
  ushort wide, high, (*img)[4], (*pix)[4];

  if (!fuji_width)
    return;
  fuji_width = (fuji_width - 1 + shrink) >> shrink;
  step = sqrt(0.5);
  wide = fuji_width / step;
  high = (height - fuji_width) / step;
  img = (ushort(*)[4])calloc(high, wide * sizeof *img);
  merror(img, "fuji_rotate()");

  RUN_CALLBACK(LIBRAW_PROGRESS_FUJI_ROTATE, 0, 2);

  for (row = 0; row < high; row++)
    for (col = 0; col < wide; col++)
    {
      ur = r = fuji_width + (row - col) * step;
      uc = c = (row + col) * step;
      if (ur > height - 2 || uc > width - 2)
        continue;
      fr = r - ur;
      fc = c - uc;
      pix = image + ur * width + uc;
      for (i = 0; i < colors; i++)
        img[row * wide + col][i] =
            (pix[0][i] * (1 - fc) + pix[1][i] * fc) * (1 - fr) +
            (pix[width][i] * (1 - fc) + pix[width + 1][i] * fc) * fr;
    }

  free(image);
  width = wide;
  height = high;
  image = img;
  fuji_width = 0;
  RUN_CALLBACK(LIBRAW_PROGRESS_FUJI_ROTATE, 1, 2);
}

Project: LibRaw

void LibRaw::linear_table(unsigned len)
{
  int i;
  if (len > 0x10000)
    len = 0x10000;
  else if (len < 1)
    return;
  read_shorts(curve, len);
  for (i = len; i < 0x10000; i++)
    curve[i] = curve[i - 1];
  maximum = curve[len < 0x1000 ? 0xfff : len - 1];
}

Project: LibRaw

void LibRaw::cubic_spline(const int *x_, const int *y_, const int len)
{
  float **A, *b, *c, *d, *x, *y;
  int i, j;

  A = (float **)calloc(((2 * len + 4) * sizeof **A + sizeof *A), 2 * len);
  if (!A)
    return;
  A[0] = (float *)(A + 2 * len);
  for (i = 1; i < 2 * len; i++)
    A[i] = A[0] + 2 * len * i;
  y = len + (x = i + (d = i + (c = i + (b = A[0] + i * i))));
  for (i = 0; i < len; i++)
  {
    x[i] = x_[i] / 65535.0;
    y[i] = y_[i] / 65535.0;
  }
  for (i = len - 1; i > 0; i--)
  {
    b[i] = (y[i] - y[i - 1]) / (x[i] - x[i - 1]);
    d[i - 1] = x[i] - x[i - 1];
  }
  for (i = 1; i < len - 1; i++)
  {
    A[i][i] = 2 * (d[i - 1] + d[i]);
    if (i > 1)
    {
      A[i][i - 1] = d[i - 1];
      A[i - 1][i] = d[i - 1];
    }
    A[i][len - 1] = 6 * (b[i + 1] - b[i]);
  }
  for (i = 1; i < len - 2; i++)
  {
    float v = A[i + 1][i] / A[i][i];
    for (j = 1; j <= len - 1; j++)
      A[i + 1][j] -= v * A[i][j];
  }
  for (i = len - 2; i > 0; i--)
  {
    float acc = 0;
    for (j = i; j <= len - 2; j++)
      acc += A[i][j] * c[j];
    c[i] = (A[i][len - 1] - acc) / A[i][i];
  }
  for (i = 0; i < 0x10000; i++)
  {
    float x_out = (float)(i / 65535.0);
    float y_out = 0;
    for (j = 0; j < len - 1; j++)
    {
      if (x[j] <= x_out && x_out <= x[j + 1])
      {
        float v = x_out - x[j];
        y_out = y[j] +
                ((y[j + 1] - y[j]) / d[j] -
                 (2 * d[j] * c[j] + c[j + 1] * d[j]) / 6) *
                    v +
                (c[j] * 0.5) * v * v +
                ((c[j + 1] - c[j]) / (6 * d[j])) * v * v * v;
      }
    }
    curve[i] = y_out < 0.0
                   ? 0
                   : (y_out >= 1.0 ? 65535 : (ushort)(y_out * 65535.0 + 0.5));
  }
  free(A);
}

Project: LibRaw

void AAHD::make_ahd_rb_hv(int i)
{
  int iwidth = libraw.imgdata.sizes.iwidth;
  int js = libraw.COLOR(i, 0) & 1;
  int kc = libraw.COLOR(i, js);
  js ^= 1; // начальная координата зелёного
  int hvdir[2] = {Pe, Ps};
  // интерполяция вертикальных вертикально и горизонтальных горизонтально
  for (int j = js; j < iwidth; j += 2)
  {
    int x = j + nr_margin;
    int y = i + nr_margin;
    int moff = nr_offset(y, x);
    for (int d = 0; d < 2; ++d)
    {
      ushort3 *cnr;
      cnr = &rgb_ahd[d][moff];
      int c = kc ^ (d << 1); // цвет соответсвенного направления, для
                             // горизонтального c = kc, для вертикального c=kc^2
      int h1 = cnr[-hvdir[d]][c] - cnr[-hvdir[d]][1];
      int h2 = cnr[+hvdir[d]][c] - cnr[+hvdir[d]][1];
      int h0 = (h1 + h2) / 2;
      int eg = cnr[0][1] + h0;
      //			int min = MIN(cnr[-hvdir[d]][c], cnr[+hvdir[d]][c]);
      //			int max = MAX(cnr[-hvdir[d]][c], cnr[+hvdir[d]][c]);
      //			min -= min / OverFraction;
      //			max += max / OverFraction;
      //			if (eg < min)
      //				eg = min - sqrt(min - eg);
      //			else if (eg > max)
      //				eg = max + sqrt(eg - max);
      if (eg > channel_maximum[c])
        eg = channel_maximum[c];
      else if (eg < channel_minimum[c])
        eg = channel_minimum[c];
      cnr[0][c] = eg;
    }
  }
}

Project: LibRaw

void LibRaw::parseLeicaMakernote(int base, int uptag, unsigned MakernoteTagType)
{
  int c;
  uchar ci, cj;
  unsigned offset = 0, entries, tag, type, len, save;
  short morder, sorder = order;
  char buf[10];
  int LeicaMakernoteSignature = -1;
  INT64 fsize = ifp->size();
  fread(buf, 1, 10, ifp);
  if (strncmp(buf, "LEICA", 5))
  {
    fseek(ifp, -10, SEEK_CUR);
    if (uptag == 0x3400)
      LeicaMakernoteSignature = 0x3400;
    else
      LeicaMakernoteSignature = -2; // DMR
  }
  else
  {
    fseek(ifp, -2, SEEK_CUR);
    LeicaMakernoteSignature = ((uchar)buf[6] << 8) | (uchar)buf[7];
    if (!LeicaMakernoteSignature &&
        (!strncmp(model, "M8", 2) || !strncmp(model + 6, "M8", 2)))
      LeicaMakernoteSignature = -3;
    if ((LeicaMakernoteSignature != 0x0000) &&
        (LeicaMakernoteSignature != 0x0800) &&
        (LeicaMakernoteSignature != 0x0900) &&
        (LeicaMakernoteSignature != 0x02ff))
      base = ftell(ifp) - 8;
  }
  setLeicaBodyFeatures(LeicaMakernoteSignature);

  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)
    {
      fseek(ifp, save, SEEK_SET); // Recover tiff-read position!!
      continue;
    }
    tag |= uptag << 16;
    if (len > 100 * 1024 * 1024)
      goto next; // 100Mb tag? No!

    if (LeicaMakernoteSignature == -3)
    { // M8
      if (tag == 0x0310)
      {
        parseLeicaLensID();
      }
      else if ((tag == 0x0313) && (fabs(ilm.CurAp) < 0.17f))
      {
        ilm.CurAp = getreal(type);
        if (ilm.CurAp > 126.3)
        {
          ilm.CurAp = 0.0f;
        }
      }
      else if (tag == 0x0320)
      {
        imgdata.makernotes.common.CameraTemperature = getreal(type);
      }
    }
    else if (LeicaMakernoteSignature == -2)
    { // DMR
      if (tag == 0x000d)
      {
        FORC3 cam_mul[c] = get2();
        cam_mul[3] = cam_mul[1];
      }
    }
    else if (LeicaMakernoteSignature == 0)
    { // DIGILUX 2
      if (tag == 0x0007)
      {
        imgdata.shootinginfo.FocusMode = get2();
      }
      else if (tag == 0x001a)
      {
        imgdata.shootinginfo.ImageStabilization = get2();
      }
    }
    else if ((LeicaMakernoteSignature == 0x0100) || // X1
             (LeicaMakernoteSignature == 0x0400) || // X VARIO
             (LeicaMakernoteSignature == 0x0500) || // X2, X-E (Typ 102)
             (LeicaMakernoteSignature == 0x0700) || // X (Typ 113)
             (LeicaMakernoteSignature == 0x1000))
    { // X-U (Typ 113)
      if (tag == 0x040d)
      {
        ci = fgetc(ifp);
        cj = fgetc(ifp);
        imgdata.shootinginfo.ExposureMode = ((ushort)ci << 8) | cj;
      }
    }
    else if ((LeicaMakernoteSignature == 0x0600) || // TL, T (Typ 701)
             (LeicaMakernoteSignature == 0x1a00))
    { // TL2
      if (tag == 0x040d)
      {
        ci = fgetc(ifp);
        cj = fgetc(ifp);
        imgdata.shootinginfo.ExposureMode = ((ushort)ci << 8) | cj;
      }
      else if (tag == 0x0303)
      {
        parseLeicaLensName(len);
      }
    }
    else if (LeicaMakernoteSignature == 0x0200)
    { // M10, M10-D, S (Typ 007)
    }
    else if (LeicaMakernoteSignature == 0x02ff)
    { // M (Typ 240), M (Typ 262), M-D (Typ 262), M Monochrom (Typ 246), S (Typ
      // 006), S-E (Typ 006), S2, S3
      if (tag == 0x0303)
      {
        if (parseLeicaLensName(len))
        {
          ilm.LensMount = ilm.CameraMount;
          ilm.LensFormat = ilm.CameraFormat;
        }
      }
    }
    else if (LeicaMakernoteSignature == 0x0300)
    { // M9, M9 Monochrom, M Monochrom, M-E
      if (tag == 0x3400)
      {
        parseLeicaMakernote(base, 0x3400, MakernoteTagType);
      }
    }
    else if ((LeicaMakernoteSignature == 0x0800) || // Q (Typ 116)
             (LeicaMakernoteSignature == 0x0900))
    { // SL (Typ 601), CL
      if ((tag == 0x0304) && (len == 1) && ((c = fgetc(ifp)) != 0) &&
          (ilm.CameraMount == LIBRAW_MOUNT_Leica_L))
      {
        strcpy(ilm.Adapter, "M-Adapter L");
        ilm.LensMount = LIBRAW_MOUNT_Leica_M;
        ilm.LensFormat = LIBRAW_FORMAT_FF;
        ilm.LensID = c * 256;
      }
      else if (tag == 0x0500)
      {
        parseLeicaInternalBodySerial(len);
      }
    }
    else if (LeicaMakernoteSignature == 0x3400)
    { // tag 0x3400 in M9, M9 Monochrom, M Monochrom
      if (tag == 0x34003402)
      {
        imgdata.makernotes.common.CameraTemperature = getreal(type);
      }
      else if (tag == 0x34003405)
      {
        parseLeicaLensID();
      }
      else if ((tag == 0x34003406) && (fabs(ilm.CurAp) < 0.17f))
      {
        ilm.CurAp = getreal(type);
        if (ilm.CurAp > 126.3)
        {
          ilm.CurAp = 0.0f;
        }
      }
    }

  next:
    fseek(ifp, save, SEEK_SET);
  }
quit:
  order = sorder;
}

Project: LibRaw

LibRaw_windows_datastream::~LibRaw_windows_datastream()
{
  if (pView_ != NULL)
    ::UnmapViewOfFile(pView_);

  if (hMap_ != 0)
    ::CloseHandle(hMap_);
}

Project: LibRaw

int LibRaw::valid_for_dngsdk()
{
#ifndef USE_DNGSDK
  return 0;
#else
  if (!imgdata.idata.dng_version)
    return 0;
#ifdef USE_GPRSDK
  if (load_raw == &LibRaw::vc5_dng_load_raw_placeholder) // regardless of flags or use_dngsdk value!
      return 1;
#endif
  if (!imgdata.params.use_dngsdk)
    return 0;
  if (load_raw == &LibRaw::lossy_dng_load_raw) // WHY??
    return 0;
  if (load_raw ==
      &LibRaw::float_dng_load_raw_placeholder) // regardless of flags!
    return 1;
  if (is_floating_point() && (imgdata.params.use_dngsdk & LIBRAW_DNG_FLOAT))
    return 1;
  if (!imgdata.idata.filters && (imgdata.params.use_dngsdk & LIBRAW_DNG_LINEAR))
    return 1;
  if (libraw_internal_data.unpacker_data.tiff_bps == 8 &&
      (imgdata.params.use_dngsdk & LIBRAW_DNG_8BIT))
    return 1;
  if (libraw_internal_data.unpacker_data.tiff_compress == 8 &&
      (imgdata.params.use_dngsdk & LIBRAW_DNG_DEFLATE))
    return 1;
  if (libraw_internal_data.unpacker_data.tiff_samples == 2)
    return 0; // Always deny 2-samples (old fuji superccd)
  if (imgdata.idata.filters == 9 &&
      (imgdata.params.use_dngsdk & LIBRAW_DNG_XTRANS))
    return 1;
  if (is_fuji_rotated())
    return 0; // refuse
  if (imgdata.params.use_dngsdk & LIBRAW_DNG_OTHER)
    return 1;
  return 0;
#endif
}

Project: LibRaw

void LibRaw::aRGB_coeff(double aRGB_cam[3][3])
{
  static const double rgb_aRGB[3][3] = {
      {1.39828313770000, -0.3982830047, 9.64980900741708E-8},
      {6.09219200572997E-8, 0.9999999809, 1.33230799934103E-8},
      {2.17237099975343E-8, -0.0429383201, 1.04293828050000}};

  double cmatrix_tmp[3][3] = {
      {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}};
  int i, j, k;

  for (i = 0; i < 3; i++)
    for (j = 0; j < 3; j++)
    {
      for (k = 0; k < 3; k++)
        cmatrix_tmp[i][j] += rgb_aRGB[i][k] * aRGB_cam[k][j];
      cmatrix[i][j] = (float)cmatrix_tmp[i][j];
    }
}

Project: LibRaw

  virtual int jpeg_src(void *) { return -1; }

Project: LibRaw

void usage(const char *p)
{
  printf("Options:\n"
         "-J n  - set parallel job count (default 2)\n"
         "-v    - verbose\n"
         "-w    - use camera white balance\n"
         "-T    - output TIFF instead of PPM\n"
         "-a    - average image for white balance\n");
  exit(1);
}

Project: LibRaw

void LibRaw::parse_makernote_0xc634(int base, int uptag, unsigned dng_writer)
{

  if (imgdata.params.raw_processing_options & LIBRAW_PROCESSING_SKIP_MAKERNOTES)
    return;

  if (metadata_blocks++ > LIBRAW_MAX_METADATA_BLOCKS)
    throw LIBRAW_EXCEPTION_IO_CORRUPT;

  if (!strncmp(make, "NIKON", 5))
  {
    parseNikonMakernote(base, uptag, AdobeDNG);
    return;
  }
  else if (!strncasecmp(make, "LEICA", 5))
  {
    parseLeicaMakernote(base, uptag, is_0xc634);
    return;
  }

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

  fread(buf, 1, 10, ifp);

  if (!strcmp(buf, "EPSON"))
  {
    parseEpsonMakernote(base, uptag, AdobeDNG);
    return;
  }

  unsigned offset = 0, entries, tag, type, len, save, c;
  unsigned i;

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

  int LeicaMakernoteSignature = -1;

  uchar *table_buf;
  uchar *table_buf_0x0116;
  ushort table_buf_0x0116_len = 0;
  uchar *table_buf_0x2010;
  ushort table_buf_0x2010_len = 0;
  uchar *table_buf_0x9050;
  ushort table_buf_0x9050_len = 0;
  uchar *table_buf_0x9400;
  ushort table_buf_0x9400_len = 0;
  uchar *table_buf_0x9402;
  ushort table_buf_0x9402_len = 0;
  uchar *table_buf_0x9403;
  ushort table_buf_0x9403_len = 0;
  uchar *table_buf_0x9406;
  ushort table_buf_0x9406_len = 0;
  uchar *table_buf_0x940c;
  ushort table_buf_0x940c_len = 0;
  uchar *table_buf_0x940e;
  ushort table_buf_0x940e_len = 0;

  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 (is_PentaxRicohMakernotes && (dng_writer == CameraDNG))
  {
    base = ftell(ifp) - 10;
    fseek(ifp, -4, SEEK_CUR);
    order = get2();
    is_PentaxRicohMakernotes = 1;
  }
  else if (!strncmp(buf, "SONY", 4) ||
           !strcmp(buf, "Panasonic"))
  {
    order = 0x4949;
    fseek(ifp, 2, SEEK_CUR);
  }
  else if (!strncmp(buf, "FUJIFILM", 8))
  {
    base = ftell(ifp) - 10;
    order = 0x4949;
    fseek(ifp, 2, SEEK_CUR);
  }
  else if (!strcmp(buf, "OLYMP") ||
           !strcmp(buf, "Ricoh"))
  {
    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;

  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))))
    is_Sony = 1;

  morder = order;
  while (entries--)
  {
    order = morder;

    tiff_get(base, &tag, &type, &len, &save);

    INT64 pos = ifp->tell();
    if (len > 8 && pos + len > 2 * fsize)
    {
      fseek(ifp, save, SEEK_SET); // Recover tiff-read position!!
      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 == 0x0010)
      { // Canon ModelID
        unique_id = get4();
        setCanonBodyFeatures(unique_id);
        if (lenCanonCameraInfo)
        {
          processCanonCameraInfo(unique_id, CanonCameraInfo, lenCanonCameraInfo,
                                 typeCanonCameraInfo, AdobeDNG);
          free(CanonCameraInfo);
          CanonCameraInfo = 0;
          lenCanonCameraInfo = 0;
        }
      }

      else
        parseCanonMakernotes(tag, type, len, AdobeDNG);
    }

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

    } else if (!strncasecmp(make, "Hasselblad", 10) && !is_Sony) {
      if (tag == 0x0011) {
        imHassy.SensorCode = getint(type);
      } else if ((tag == 0x0015) && (type == 2)) {
        stmread (imHassy.SensorUnitConnector, len, ifp);
      } else if (tag == 0x0016) {
        imHassy.CoatingCode = getint(type);
      } else if ((tag == 0x002a) && (type == 10) && (len == 12)) {
        FORC4 for (int i = 0; i < 3; i++)
                imHassy.mnColorMatrix[c][i] = getreal(type);

      } else if (tag == 0x0031) {
        imHassy.RecommendedCrop[0] = getint(type);
        imHassy.RecommendedCrop[1] = getint(type);
      }

    } else if (!strncmp(make, "OLYMPUS", 7) ||
             (!strncasecmp(make, "CLAUSS", 6) &&
              !strncasecmp(model, "piX 5oo", 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) || (tag == 0x2030) ||
          (tag == 0x2031) || (tag == 0x2040) || (tag == 0x2050) ||
          (tag == 0x3000))
      {
        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;

      else if ((tag >= 0x20100000) && (tag <= 0x2010ffff))
        parseOlympus_Equipment((tag & 0x0000ffff), type, len, AdobeDNG);

      else if ((tag >= 0x20200000) && (tag <= 0x2020ffff))
        parseOlympus_CameraSettings(base, (tag & 0x0000ffff), type, len,
                                    AdobeDNG);

      else if ((tag == 0x20300108) || (tag == 0x20310109))
        imOly.ColorSpace = get2();

      else if ((tag >= 0x20400000) && (tag <= 0x2040ffff))
        parseOlympus_ImageProcessing((tag & 0x0000ffff), type, len, AdobeDNG);

      else if ((tag >= 0x30000000) && (tag <= 0x3000ffff))
        parseOlympus_RawInfo((tag & 0x0000ffff), type, len, AdobeDNG);

      else
        switch (tag)
        {
        case 0x0207:
          getOlympus_CameraType2();
          break;
        case 0x1002:
          ilm.CurAp = libraw_powf64l(2.0f, getreal(type) / 2);
          break;
        case 0x1007:
          imgdata.makernotes.common.SensorTemperature = (float)get2();
          break;
        case 0x1008:
          imgdata.makernotes.common.LensTemperature = (float)get2();
          break;
        case 0x20501500:
          getOlympus_SensorTemperature(len);
          break;
        }

    skip_Oly_broken_tags:;
    }

    else if (!strncmp(make, "PENTAX", 6) || !strncmp(model, "PENTAX", 6) ||
             is_PentaxRicohMakernotes)
    {
      parsePentaxMakernotes(base, tag, type, len, dng_writer);
    }
    else if (!strncmp(make, "SAMSUNG", 7))
    {
      if (dng_writer == AdobeDNG)
        parseSamsungMakernotes(base, tag, type, len, dng_writer);
      else
        parsePentaxMakernotes(base, tag, type, len, dng_writer);
    }
    else if (is_Sony)
    {
      parseSonyMakernotes(
          base, tag, type, len, AdobeDNG, table_buf_0x0116,
          table_buf_0x0116_len, table_buf_0x2010, table_buf_0x2010_len,
          table_buf_0x9050, table_buf_0x9050_len, table_buf_0x9400,
          table_buf_0x9400_len, table_buf_0x9402, table_buf_0x9402_len,
          table_buf_0x9403, table_buf_0x9403_len, table_buf_0x9406,
          table_buf_0x9406_len, table_buf_0x940c, table_buf_0x940c_len,
          table_buf_0x940e, table_buf_0x940e_len);
    }
  next:
    fseek(ifp, save, SEEK_SET);
  }
quit:

  order = sorder;
}

Project: LibRaw

  virtual int lock() { return 1; } /* success */

Project: LibRaw

void LibRaw::android_tight_load_raw()
{
  uchar *data, *dp;
  int bwide, row, col, c;

  bwide = -(-5 * raw_width >> 5) << 3;
  data = (uchar *)malloc(bwide);
  merror(data, "android_tight_load_raw()");
  for (row = 0; row < raw_height; row++)
  {
    if (fread(data, 1, bwide, ifp) < bwide)
      derror();
    for (dp = data, col = 0; col < raw_width; dp += 5, col += 4)
      FORC4 RAW(row, col + c) = (dp[c] << 2) | (dp[4] >> (c << 1) & 3);
  }
  free(data);
}

Project: LibRaw

static void fuji_extend_generic(ushort *linebuf[_ltotal], int line_width,
                                int start, int end)
{
  for (int i = start; i <= end; i++)
  {
    linebuf[i][0] = linebuf[i - 1][1];
    linebuf[i][line_width + 1] = linebuf[i - 1][line_width];
  }
}

Project: LibRaw

void LibRaw::cielab(ushort rgb[3], short lab[3])
{
  int c, i, j, k;
  float r, xyz[3];
#ifdef LIBRAW_NOTHREADS
  static float cbrt[0x10000], xyz_cam[3][4];
#else
#define cbrt tls->ahd_data.cbrt
#define xyz_cam tls->ahd_data.xyz_cam
#endif

  if (!rgb)
  {
#ifndef LIBRAW_NOTHREADS
    if (cbrt[0] < -1.0f)
#endif
      for (i = 0; i < 0x10000; i++)
      {
        r = i / 65535.0;
        cbrt[i] =
            r > 0.008856 ? pow(r, 1.f / 3.0f) : 7.787f * r + 16.f / 116.0f;
      }
    for (i = 0; i < 3; i++)
      for (j = 0; j < colors; j++)
        for (xyz_cam[i][j] = k = 0; k < 3; k++)
          xyz_cam[i][j] += LibRaw_constants::xyz_rgb[i][k] * rgb_cam[k][j] /
                           LibRaw_constants::d65_white[i];
    return;
  }
  xyz[0] = xyz[1] = xyz[2] = 0.5;
  FORCC
  {
    xyz[0] += xyz_cam[0][c] * rgb[c];
    xyz[1] += xyz_cam[1][c] * rgb[c];
    xyz[2] += xyz_cam[2][c] * rgb[c];
  }
  xyz[0] = cbrt[CLIP((int)xyz[0])];
  xyz[1] = cbrt[CLIP((int)xyz[1])];
  xyz[2] = cbrt[CLIP((int)xyz[2])];
  lab[0] = 64 * (116 * xyz[1] - 16);
  lab[1] = 64 * 500 * (xyz[0] - xyz[1]);
  lab[2] = 64 * 200 * (xyz[1] - xyz[2]);
#ifndef LIBRAW_NOTHREADS
#undef cbrt
#undef xyz_cam
#endif
}

Project: LibRaw

static dng_ifd* search_single_ifd(const std::vector <dng_ifd *>& v, uint64 offset)
{
    for(int i = 0; i < v.size(); i++)
    {
        if(!v[i]) continue;;
        if(v[i]->fTileOffsetsOffset == offset) return v[i];
        if(v[i]->fTileOffsetsCount == 1 && v[i]->fTileOffset[0] == offset) return v[i];
    }
    return NULL;
}

Project: LibRaw

char *LibRaw_bigfile_datastream::gets(char *str, int sz)
{
  LR_BF_CHK();
  return fgets(str, sz, f);
}

Project: LibRaw

void LibRaw::ahd_interpolate_combine_homogeneous_pixels(
    int top, int left, ushort (*rgb)[LIBRAW_AHD_TILE][LIBRAW_AHD_TILE][3],
    char (*homogeneity_map)[LIBRAW_AHD_TILE][2])
{
  int row, col;
  int tr, tc;
  int i, j;
  int direction;
  int hm[2];
  int c;
  const int rowlimit = MIN(top + LIBRAW_AHD_TILE - 3, height - 5);
  const int collimit = MIN(left + LIBRAW_AHD_TILE - 3, width - 5);

  ushort(*pix)[4];
  ushort(*rix[2])[3];

  for (row = top + 3; row < rowlimit; row++)
  {
    tr = row - top;
    pix = &image[row * width + left + 2];
    for (direction = 0; direction < 2; direction++)
    {
      rix[direction] = &rgb[direction][tr][2];
    }

    for (col = left + 3; col < collimit; col++)
    {
      tc = col - left;
      pix++;
      for (direction = 0; direction < 2; direction++)
      {
        rix[direction]++;
      }

      for (direction = 0; direction < 2; direction++)
      {
        hm[direction] = 0;
        for (i = tr - 1; i <= tr + 1; i++)
        {
          for (j = tc - 1; j <= tc + 1; j++)
          {
            hm[direction] += homogeneity_map[i][j][direction];
          }
        }
      }
      if (hm[0] != hm[1])
      {
        memcpy(pix[0], rix[hm[1] > hm[0]][0], 3 * sizeof(ushort));
      }
      else
      {
        FORC3 { pix[0][c] = (rix[0][0][c] + rix[1][0][c]) >> 1; }
      }
    }
  }
}

Project: LibRaw

int LibRaw::raw2image(void)
{

  CHECK_ORDER_LOW(LIBRAW_PROGRESS_LOAD_RAW);

  try
  {
    raw2image_start();

    if (is_phaseone_compressed() && imgdata.rawdata.raw_alloc)
    {
      phase_one_allocate_tempbuffer();
      int rc = phase_one_subtract_black((ushort *)imgdata.rawdata.raw_alloc,
                                        imgdata.rawdata.raw_image);
      if (rc == 0)
        rc = phase_one_correct();
      if (rc != 0)
      {
        phase_one_free_tempbuffer();
        return rc;
      }
    }

    // free and re-allocate image bitmap
    if (imgdata.image)
    {
      imgdata.image = (ushort(*)[4])realloc(
          imgdata.image, S.iheight * S.iwidth * sizeof(*imgdata.image));
      memset(imgdata.image, 0, S.iheight * S.iwidth * sizeof(*imgdata.image));
    }
    else
      imgdata.image =
          (ushort(*)[4])calloc(S.iheight * S.iwidth, sizeof(*imgdata.image));

    merror(imgdata.image, "raw2image()");

    libraw_decoder_info_t decoder_info;
    get_decoder_info(&decoder_info);

    // Move saved bitmap to imgdata.image
    if ((imgdata.idata.filters || P1.colors == 1) && imgdata.rawdata.raw_image)
    {
      if (IO.fuji_width)
      {
        unsigned r, c;
        int row, col;
        for (row = 0; row < S.raw_height - S.top_margin * 2; row++)
        {
          for (col = 0;
               col < IO.fuji_width
                         << !libraw_internal_data.unpacker_data.fuji_layout;
               col++)
          {
            if (libraw_internal_data.unpacker_data.fuji_layout)
            {
              r = IO.fuji_width - 1 - col + (row >> 1);
              c = col + ((row + 1) >> 1);
            }
            else
            {
              r = IO.fuji_width - 1 + row - (col >> 1);
              c = row + ((col + 1) >> 1);
            }
            if (r < S.height && c < S.width)
              imgdata.image[((r) >> IO.shrink) * S.iwidth + ((c) >> IO.shrink)]
                           [FC(r, c)] =
                  imgdata.rawdata
                      .raw_image[(row + S.top_margin) * S.raw_pitch / 2 +
                                 (col + S.left_margin)];
          }
        }
      }
      else
      {
        int row, col;
        for (row = 0; row < S.height; row++)
          for (col = 0; col < S.width; col++)
            imgdata.image[((row) >> IO.shrink) * S.iwidth +
                          ((col) >> IO.shrink)][fcol(row, col)] =
                imgdata.rawdata
                    .raw_image[(row + S.top_margin) * S.raw_pitch / 2 +
                               (col + S.left_margin)];
      }
    }
    else // if(decoder_info.decoder_flags & LIBRAW_DECODER_LEGACY)
    {
      if (imgdata.rawdata.color4_image)
      {
        if (S.width * 8 == S.raw_pitch)
          memmove(imgdata.image, imgdata.rawdata.color4_image,
                  S.width * S.height * sizeof(*imgdata.image));
        else
        {
          for (int row = 0; row < S.height; row++)
            memmove(&imgdata.image[row * S.width],
                    &imgdata.rawdata
                         .color4_image[(row + S.top_margin) * S.raw_pitch / 8 +
                                       S.left_margin],
                    S.width * sizeof(*imgdata.image));
        }
      }
      else if (imgdata.rawdata.color3_image)
      {
        unsigned char *c3image = (unsigned char *)imgdata.rawdata.color3_image;
        for (int row = 0; row < S.height; row++)
        {
          ushort(*srcrow)[3] =
              (ushort(*)[3]) & c3image[(row + S.top_margin) * S.raw_pitch];
          ushort(*dstrow)[4] = (ushort(*)[4]) & imgdata.image[row * S.width];
          for (int col = 0; col < S.width; col++)
          {
            for (int c = 0; c < 3; c++)
              dstrow[col][c] = srcrow[S.left_margin + col][c];
            dstrow[col][3] = 0;
          }
        }
      }
      else
      {
        // legacy decoder, but no data?
        throw LIBRAW_EXCEPTION_DECODE_RAW;
      }
    }

    // Free PhaseOne separate copy allocated at function start
    if (is_phaseone_compressed())
    {
      phase_one_free_tempbuffer();
    }
    // hack - clear later flags!

    if (load_raw == &LibRaw::canon_600_load_raw && S.width < S.raw_width)
    {
      canon_600_correct();
    }

    imgdata.progress_flags =
        LIBRAW_PROGRESS_START | LIBRAW_PROGRESS_OPEN |
        LIBRAW_PROGRESS_RAW2_IMAGE | LIBRAW_PROGRESS_IDENTIFY |
        LIBRAW_PROGRESS_SIZE_ADJUST | LIBRAW_PROGRESS_LOAD_RAW;
    return 0;
  }
  catch (LibRaw_exceptions err)
  {
    EXCEPTION_HANDLER(err);
  }
}

Project: LibRaw

int LibRaw_file_datastream::scanf_one(const char *fmt, void *val)
{
  LR_STREAM_CHK();

  std::istream is(f.get());

  /* HUGE ASSUMPTION: *fmt is either "%d" or "%f" */
  if (strcmp(fmt, "%d") == 0)
  {
    int d;
    is >> d;
    if (is.fail())
      return EOF;
    *(static_cast<int *>(val)) = d;
  }
  else
  {
    float f;
    is >> f;
    if (is.fail())
      return EOF;
    *(static_cast<float *>(val)) = f;
  }

  return 1;
}

Project: LibRaw

  void set_exifparser_handler(exif_parser_callback cb, void *data)
  {
    callbacks.exifparser_data = data;
    callbacks.exif_cb = cb;
  }

Project: LibRaw

void LibRaw::lin_interpolate_loop(int code[16][16][32], int size) {}

Project: LibRaw

  void libraw_set_progress_handler(libraw_data_t *lr, progress_callback cb,
                                   void *data)
  {
    if (!lr)
      return;
    LibRaw *ip = (LibRaw *)lr->parent_class;
    ip->set_progress_handler(cb, data);
  }

Project: LibRaw

void LibRaw::getOlympus_SensorTemperature(unsigned len)
{
  if (OlyID != 0x0ULL)
  {
    short temp = get2();
    if ((OlyID == 0x4434303430ULL) || // E-1
        (OlyID == 0x5330303336ULL) || // E-M5
        (len != 1))
      imgdata.makernotes.common.SensorTemperature = (float)temp;
    else if ((temp != -32768) && (temp != 0))
    {
      if (temp > 199)
        imgdata.makernotes.common.SensorTemperature = 86.474958f - 0.120228f * (float)temp;
      else
        imgdata.makernotes.common.SensorTemperature = (float)temp;
    }
  }
  return;
}

Project: LibRaw

void LibRaw::parseOlympus_RawInfo(unsigned tag, unsigned type, unsigned len,
                                  unsigned dng_writer)
{
  // uptag 0x3000

  int wb_ind, c, i;

  if ((tag == 0x0110) && strcmp(software, "v757-71"))
  {
    imgdata.color.WB_Coeffs[LIBRAW_WBI_Auto][0] = get2();
    imgdata.color.WB_Coeffs[LIBRAW_WBI_Auto][2] = get2();
    if (len == 2)
    {
      for (i = 0; i < 256; i++)
        imgdata.color.WB_Coeffs[i][1] = imgdata.color.WB_Coeffs[i][3] = 0x100;
    }
  }
  else if ((((tag >= 0x0120) && (tag <= 0x0124)) ||
            ((tag >= 0x0130) && (tag <= 0x0133))) &&
           strcmp(software, "v757-71"))
  {
    if (tag <= 0x0124)
      wb_ind = tag - 0x0120;
    else
      wb_ind = tag - 0x0130 + 5;

    imgdata.color.WB_Coeffs[Oly_wb_list1[wb_ind]][0] = get2();
    imgdata.color.WB_Coeffs[Oly_wb_list1[wb_ind]][2] = get2();
  }
  else if ((tag == 0x0200) && (dng_writer == nonDNG))
  {
    for (i = 0; i < 3; i++)
    {
      if (!imOly.ColorSpace)
      {
        FORC3 cmatrix[i][c] = ((short)get2()) / 256.0;
      }
      else
      {
        FORC3 imgdata.color.ccm[i][c] = ((short)get2()) / 256.0;
      }
    }
  }
  else if ((tag == 0x0600) && (dng_writer == nonDNG))
  {
    FORC4 cblack[c ^ c >> 1] = get2();
  }
  else if ((tag == 0x0612) && (dng_writer == nonDNG))
  {
    imgdata.sizes.raw_inset_crop.cleft = get2();
  }
  else if ((tag == 0x0613) && (dng_writer == nonDNG))
  {
    imgdata.sizes.raw_inset_crop.ctop = get2();
  }
  else if ((tag == 0x0614) && (dng_writer == nonDNG))
  {
    imgdata.sizes.raw_inset_crop.cwidth = get2();
  }
  else if ((tag == 0x0615) && (dng_writer == nonDNG))
  {
    imgdata.sizes.raw_inset_crop.cheight = get2();
  }
  return;
}

Project: LibRaw

void LibRaw::x3f_dpq_interpolate_af(int xstep, int ystep, int scale)
{
  unsigned short *image = (ushort *)imgdata.rawdata.color3_image;
  unsigned int rowpitch =
      imgdata.rawdata.sizes.raw_pitch / 2; // in 16-bit words
                                           // Interpolate single pixel
  for (int y = 0;
       y < imgdata.rawdata.sizes.height + imgdata.rawdata.sizes.top_margin;
       y += ystep)
  {
    if (y < imgdata.rawdata.sizes.top_margin)
      continue;
    if (y < scale)
      continue;
    if (y > imgdata.rawdata.sizes.raw_height - scale)
      break;
    uint16_t *row0 = &image[imgdata.sizes.raw_width * 3 * y]; // Наша строка
    uint16_t *row_minus =
        &image[imgdata.sizes.raw_width * 3 * (y - scale)]; // Строка выше
    uint16_t *row_plus =
        &image[imgdata.sizes.raw_width * 3 * (y + scale)]; // Строка ниже
    for (int x = 0;
         x < imgdata.rawdata.sizes.width + imgdata.rawdata.sizes.left_margin;
         x += xstep)
    {
      if (x < imgdata.rawdata.sizes.left_margin)
        continue;
      if (x < scale)
        continue;
      if (x > imgdata.rawdata.sizes.raw_width - scale)
        break;
      uint16_t *pixel0 = &row0[x * 3];
      uint16_t *pixel_top = &row_minus[x * 3];
      uint16_t *pixel_bottom = &row_plus[x * 3];
      uint16_t *pixel_left = &row0[(x - scale) * 3];
      uint16_t *pixel_right = &row0[(x + scale) * 3];
      uint16_t *pixf = pixel_top;
      if (_ABS(pixf[2] - pixel0[2]) > _ABS(pixel_bottom[2] - pixel0[2]))
        pixf = pixel_bottom;
      if (_ABS(pixf[2] - pixel0[2]) > _ABS(pixel_left[2] - pixel0[2]))
        pixf = pixel_left;
      if (_ABS(pixf[2] - pixel0[2]) > _ABS(pixel_right[2] - pixel0[2]))
        pixf = pixel_right;
      int blocal = pixel0[2], bnear = pixf[2];
      if (blocal < imgdata.color.black + 16 || bnear < imgdata.color.black + 16)
      {
        if (pixel0[0] < imgdata.color.black)
          pixel0[0] = imgdata.color.black;
        if (pixel0[1] < imgdata.color.black)
          pixel0[1] = imgdata.color.black;
        pixel0[0] = CLIP(
            (pixel0[0] - imgdata.color.black) * 4 + imgdata.color.black, 16383);
        pixel0[1] = CLIP(
            (pixel0[1] - imgdata.color.black) * 4 + imgdata.color.black, 16383);
      }
      else
      {
        float multip = float(bnear - imgdata.color.black) /
                       float(blocal - imgdata.color.black);
        if (pixel0[0] < imgdata.color.black)
          pixel0[0] = imgdata.color.black;
        if (pixel0[1] < imgdata.color.black)
          pixel0[1] = imgdata.color.black;
        float pixf0 = pixf[0];
        if (pixf0 < imgdata.color.black)
          pixf0 = imgdata.color.black;
        float pixf1 = pixf[1];
        if (pixf1 < imgdata.color.black)
          pixf1 = imgdata.color.black;

        pixel0[0] = CLIP(
            ((float(pixf0 - imgdata.color.black) * multip +
              imgdata.color.black) +
             ((pixel0[0] - imgdata.color.black) * 3.75 + imgdata.color.black)) /
                2,
            16383);
        pixel0[1] = CLIP(
            ((float(pixf1 - imgdata.color.black) * multip +
              imgdata.color.black) +
             ((pixel0[1] - imgdata.color.black) * 3.75 + imgdata.color.black)) /
                2,
            16383);
        // pixel0[1] = float(pixf[1]-imgdata.color.black)*multip +
        // imgdata.color.black;
      }
    }
  }
}

Project: LibRaw

  DllDef void libraw_set_bright(libraw_data_t *lr, float value)
  {
    if (!lr)
      return;
    LibRaw *ip = (LibRaw *)lr->parent_class;
    ip->imgdata.params.bright = value;
  }

Project: LibRaw

void LibRaw::convertFloatToInt(float dmin /* =4096.f */,
                               float dmax /* =32767.f */,
                               float dtarget /*= 16383.f */)
{
  int samples = 0;
  float *data = 0;
  if (imgdata.rawdata.float_image)
  {
    samples = 1;
    data = imgdata.rawdata.float_image;
  }
  else if (imgdata.rawdata.float3_image)
  {
    samples = 3;
    data = (float *)imgdata.rawdata.float3_image;
  }
  else if (imgdata.rawdata.float4_image)
  {
    samples = 4;
    data = (float *)imgdata.rawdata.float4_image;
  }
  else
    return;

  ushort *raw_alloc = (ushort *)malloc(
      imgdata.sizes.raw_height * imgdata.sizes.raw_width *
      libraw_internal_data.unpacker_data.tiff_samples * sizeof(ushort));
  float tmax = MAX(imgdata.color.maximum, 1);
  float datamax = imgdata.color.fmaximum;

  tmax = MAX(tmax, datamax);
  tmax = MAX(tmax, 1.f);

  float multip = 1.f;
  if (tmax < dmin || tmax > dmax)
  {
    imgdata.rawdata.color.fnorm = imgdata.color.fnorm = multip = dtarget / tmax;
    imgdata.rawdata.color.maximum = imgdata.color.maximum = dtarget;
    imgdata.rawdata.color.black = imgdata.color.black =
        (float)imgdata.color.black * multip;
    for (int i = 0;
         i < sizeof(imgdata.color.cblack) / sizeof(imgdata.color.cblack[0]);
         i++)
      if (i != 4 && i != 5)
        imgdata.rawdata.color.cblack[i] = imgdata.color.cblack[i] =
            (float)imgdata.color.cblack[i] * multip;
  }
  else
    imgdata.rawdata.color.fnorm = imgdata.color.fnorm = 0.f;

  for (size_t i = 0; i < imgdata.sizes.raw_height * imgdata.sizes.raw_width *
                             libraw_internal_data.unpacker_data.tiff_samples;
       ++i)
  {
    float val = MAX(data[i], 0.f);
    raw_alloc[i] = (ushort)(val * multip);
  }

  if (samples == 1)
  {
    imgdata.rawdata.raw_alloc = imgdata.rawdata.raw_image = raw_alloc;
    imgdata.rawdata.sizes.raw_pitch = imgdata.sizes.raw_pitch =
        imgdata.sizes.raw_width * 2;
  }
  else if (samples == 3)
  {
    imgdata.rawdata.raw_alloc = imgdata.rawdata.color3_image =
        (ushort(*)[3])raw_alloc;
    imgdata.rawdata.sizes.raw_pitch = imgdata.sizes.raw_pitch =
        imgdata.sizes.raw_width * 6;
  }
  else if (samples == 4)
  {
    imgdata.rawdata.raw_alloc = imgdata.rawdata.color4_image =
        (ushort(*)[4])raw_alloc;
    imgdata.rawdata.sizes.raw_pitch = imgdata.sizes.raw_pitch =
        imgdata.sizes.raw_width * 8;
  }
  free(data); // remove old allocation
  imgdata.rawdata.float_image = 0;
  imgdata.rawdata.float3_image = 0;
  imgdata.rawdata.float4_image = 0;
}

Project: LibRaw

  virtual ~LibRaw_abstract_datastream(void) { }

Project: LibRaw

  unsigned libraw_capabilities() { return LibRaw::capabilities(); }

Project: LibRaw

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

  if (!filters || !raw_image)
  {
    if (!image)
      throw LIBRAW_EXCEPTION_IO_CORRUPT;
    pixel = (ushort *)calloc(raw_width, sizeof *pixel);
    merror(pixel, "leaf_hdr_load_raw()");
  }
  try
  {
    FORC(tiff_samples)
    for (r = 0; r < raw_height; r++)
    {
      checkCancel();
      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];
    }
  }
  catch (...)
  {
    if (!filters)
      free(pixel);
    throw;
  }
  if (!filters)
  {
    maximum = 0xffff;
    raw_color = 1;
    free(pixel);
  }
}

Project: LibRaw

void LibRaw::remove_caseSubstr(char *string, char *subStr) // replace a substring with an equal length of spaces
{
  char *found;
  while ((found = strcasestr(string,subStr))) {
    if (!found) return;
    int fill_len = strlen(subStr);
    int p = found - string;
    for (int i=p; i<p+fill_len; i++) {
      string[i] = 32;
    }
  }
  trimSpaces (string);
}

Project: LibRaw

void LibRaw::kodak_ycbcr_load_raw()
{
  if (!image)
    throw LIBRAW_EXCEPTION_IO_CORRUPT;
  short buf[384], *bp;
  int row, col, len, c, i, j, k, y[2][2], cb, cr, rgb[3];
  ushort *ip;

  unsigned int bits =
      (load_flags && load_flags > 9 && load_flags < 17) ? load_flags : 10;
  for (row = 0; row < height; row += 2)
  {
    checkCancel();
    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

void DHT::illustrate_dline(int i)
{
  int iwidth = libraw.imgdata.sizes.iwidth;
  for (int j = 0; j < iwidth; j++)
  {
    int x = j + nr_leftmargin;
    int y = i + nr_topmargin;
    nraw[nr_offset(y, x)][0] = nraw[nr_offset(y, x)][1] =
        nraw[nr_offset(y, x)][2] = 0.5;
    int l = ndir[nr_offset(y, x)] & 8;
    // l >>= 3; // WTF?
    l = 1;
    if (ndir[nr_offset(y, x)] & HOT)
      nraw[nr_offset(y, x)][0] =
          l * channel_maximum[0] / 4 + channel_maximum[0] / 4;
    else
      nraw[nr_offset(y, x)][2] =
          l * channel_maximum[2] / 4 + channel_maximum[2] / 4;
  }
}

Project: LibRaw

void AAHD::make_ahd_rb_last(int i)
{
  int iwidth = libraw.imgdata.sizes.iwidth;
  int js = libraw.COLOR(i, 0) & 1;
  int kc = libraw.COLOR(i, js);
  /*
   * js -- начальная х-координата, которая попадает мимо известного зелёного
   * kc -- известный цвет в точке интерполирования
   */
  int dirs[2][3] = {{Pnw, Pn, Pne}, {Pnw, Pw, Psw}};
  int moff = nr_offset(i + nr_margin, nr_margin);
  for (int j = 0; j < iwidth; j++)
  {
    for (int d = 0; d < 2; ++d)
    {
      ushort3 *cnr;
      cnr = &rgb_ahd[d][moff + j];
      int c = kc ^ 2;
      if ((j & 1) != js)
      {
        // точка зелёного, для вертикального направления нужен альтернативный
        // строчному цвет
        c ^= d << 1;
      }
      int bh, bk;
      int bgd = 0;
      for (int k = 0; k < 3; ++k)
        for (int h = 0; h < 3; ++h)
        {
          // градиент зелёного плюс градиент {r,b}
          int gd =
              ABS(2 * cnr[0][1] - (cnr[+dirs[d][k]][1] + cnr[-dirs[d][h]][1])) +
              ABS(cnr[+dirs[d][k]][c] - cnr[-dirs[d][h]][c]) / 4 +
              ABS(cnr[+dirs[d][k]][c] - cnr[+dirs[d][k]][1] +
                  cnr[-dirs[d][h]][1] - cnr[-dirs[d][h]][c]) /
                  4;
          if (bgd == 0 || gd < bgd)
          {
            bgd = gd;
            bh = h;
            bk = k;
          }
        }
      int h1 = cnr[+dirs[d][bk]][c] - cnr[+dirs[d][bk]][1];
      int h2 = cnr[-dirs[d][bh]][c] - cnr[-dirs[d][bh]][1];
      int eg = cnr[0][1] + (h1 + h2) / 2;
      //			int min = MIN(cnr[+dirs[d][bk]][c], cnr[-dirs[d][bh]][c]);
      //			int max = MAX(cnr[+dirs[d][bk]][c], cnr[-dirs[d][bh]][c]);
      //			min -= min / OverFraction;
      //			max += max / OverFraction;
      //			if (eg < min)
      //				eg = min - sqrt(min - eg);
      //			else if (eg > max)
      //				eg = max + sqrt(eg - max);
      if (eg > channel_maximum[c])
        eg = channel_maximum[c];
      else if (eg < channel_minimum[c])
        eg = channel_minimum[c];
      cnr[0][c] = eg;
    }
  }
}

Project: LibRaw

void LibRaw::green_matching()
{
  int i, j;
  double m1, m2, c1, c2;
  int o1_1, o1_2, o1_3, o1_4;
  int o2_1, o2_2, o2_3, o2_4;
  ushort(*img)[4];
  const int margin = 3;
  int oj = 2, oi = 2;
  float f;
  const float thr = 0.01f;
  if (half_size || shrink)
    return;
  if (FC(oj, oi) != 3)
    oj++;
  if (FC(oj, oi) != 3)
    oi++;
  if (FC(oj, oi) != 3)
    oj--;

  img = (ushort(*)[4])calloc(height * width, sizeof *image);
  merror(img, "green_matching()");
  memcpy(img, image, height * width * sizeof *image);

  for (j = oj; j < height - margin; j += 2)
    for (i = oi; i < width - margin; i += 2)
    {
      o1_1 = img[(j - 1) * width + i - 1][1];
      o1_2 = img[(j - 1) * width + i + 1][1];
      o1_3 = img[(j + 1) * width + i - 1][1];
      o1_4 = img[(j + 1) * width + i + 1][1];
      o2_1 = img[(j - 2) * width + i][3];
      o2_2 = img[(j + 2) * width + i][3];
      o2_3 = img[j * width + i - 2][3];
      o2_4 = img[j * width + i + 2][3];

      m1 = (o1_1 + o1_2 + o1_3 + o1_4) / 4.0;
      m2 = (o2_1 + o2_2 + o2_3 + o2_4) / 4.0;

      c1 = (abs(o1_1 - o1_2) + abs(o1_1 - o1_3) + abs(o1_1 - o1_4) +
            abs(o1_2 - o1_3) + abs(o1_3 - o1_4) + abs(o1_2 - o1_4)) /
           6.0;
      c2 = (abs(o2_1 - o2_2) + abs(o2_1 - o2_3) + abs(o2_1 - o2_4) +
            abs(o2_2 - o2_3) + abs(o2_3 - o2_4) + abs(o2_2 - o2_4)) /
           6.0;
      if ((img[j * width + i][3] < maximum * 0.95) && (c1 < maximum * thr) &&
          (c2 < maximum * thr))
      {
        f = image[j * width + i][3] * m1 / m2;
        image[j * width + i][3] = f > 0xffff ? 0xffff : f;
      }
    }
  free(img);
}

Project: LibRaw

void LibRaw::parse_mos(int offset)
{
  char data[40];
  int skip, from, i, c, neut[4], planes = 0, frot = 0;
  static const char *mod[] = {
      /* DM22, DM28, DM40, DM56 are somewhere here too */
      "",             //  0
      "DCB2",         //  1
      "Volare",       //  2
      "Cantare",      //  3
      "CMost",        //  4
      "Valeo 6",      //  5
      "Valeo 11",     //  6
      "Valeo 22",     //  7
      "Valeo 11p",    //  8
      "Valeo 17",     //  9
      "",             // 10
      "Aptus 17",     // 11
      "Aptus 22",     // 12
      "Aptus 75",     // 13
      "Aptus 65",     // 14
      "Aptus 54S",    // 15
      "Aptus 65S",    // 16
      "Aptus 75S",    // 17
      "AFi 5",        // 18
      "AFi 6",        // 19
      "AFi 7",        // 20
      "AFi-II 7",     // 21
      "Aptus-II 7",   // 22 (same CMs as Mamiya DM33)
      "",             // 23
      "Aptus-II 6",   // 24 (same CMs as Mamiya DM28)
      "AFi-II 10",    // 25
      "",             // 26
      "Aptus-II 10",  // 27 (same CMs as Mamiya DM56)
      "Aptus-II 5",   // 28 (same CMs as Mamiya DM22)
      "",             // 29
      "DM33",         // 30, make is Mamiya
      "",             // 31
      "",             // 32
      "Aptus-II 10R", // 33
      "Aptus-II 8",   // 34 (same CMs as Mamiya DM40)
      "",             // 35
      "Aptus-II 12",  // 36
      "",             // 37
      "AFi-II 12"     // 38
  };
  float romm_cam[3][3];

  fseek(ifp, offset, SEEK_SET);
  while (1)
  {
    if (get4() != 0x504b5453)
      break;
    get4();
    fread(data, 1, 40, ifp);
    skip = get4();
    from = ftell(ifp);

    if (!strcmp(data, "CameraObj_camera_type"))
    {
      stmread(ilm.body, skip, ifp);
      if (ilm.body[0])
      {
        if (!strncmp(ilm.body, "Mamiya R", 8))
        {
          ilm.CameraMount = LIBRAW_MOUNT_Mamiya67;
          ilm.CameraFormat = LIBRAW_FORMAT_67;
        }
        else if (!strncmp(ilm.body, "Hasselblad 5", 12))
        {
          ilm.CameraFormat = LIBRAW_FORMAT_66;
          ilm.CameraMount = LIBRAW_MOUNT_Hasselblad_V;
        }
        else if (!strncmp(ilm.body, "Hasselblad H", 12))
        {
          ilm.CameraMount = LIBRAW_MOUNT_Hasselblad_H;
          ilm.CameraFormat = LIBRAW_FORMAT_645;
        }
        else if (!strncmp(ilm.body, "Mamiya 6", 8) ||
                 !strncmp(ilm.body, "Phase One 6", 11))
        {
          ilm.CameraMount = LIBRAW_MOUNT_Mamiya645;
          ilm.CameraFormat = LIBRAW_FORMAT_645;
        }
        else if (!strncmp(ilm.body, "Large F", 7))
        {
          ilm.CameraMount = LIBRAW_MOUNT_LF;
          ilm.CameraFormat = LIBRAW_FORMAT_LF;
        }
        else if (!strncmp(model, "Leaf AFi", 8))
        {
          ilm.CameraMount = LIBRAW_MOUNT_Rollei_bayonet;
          ilm.CameraFormat = LIBRAW_FORMAT_66;
        }
      }
    }
    if (!strcmp(data, "back_serial_number"))
    {
      char buffer[sizeof(imgdata.shootinginfo.BodySerial)];
      char *words[4];
      int nwords;
      stmread(buffer, skip, ifp);
      nwords =
          getwords(buffer, words, 4, sizeof(imgdata.shootinginfo.BodySerial));
      strcpy(imgdata.shootinginfo.BodySerial, words[0]);
    }
    if (!strcmp(data, "CaptProf_serial_number"))
    {
      char buffer[sizeof(imgdata.shootinginfo.InternalBodySerial)];
      char *words[4];
      int nwords;
      stmread(buffer, skip, ifp);
      nwords = getwords(buffer, words, 4,
                        sizeof(imgdata.shootinginfo.InternalBodySerial));
      strcpy(imgdata.shootinginfo.InternalBodySerial, words[0]);
    }

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

Project: LibRaw
File: mem_image.cpp

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

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

  if (libraw_internal_data.output_data.histogram)
  {
    int perc, val, total, t_white = 0x2000, c;
    perc = S.width * S.height * O.auto_bright_thr;
    if (IO.fuji_width)
      perc /= 2;
    if (!((O.highlight & ~2) || O.no_auto_bright))
      for (t_white = c = 0; c < P1.colors; c++)
      {
        for (val = 0x2000, total = 0; --val > 32;)
          if ((total += libraw_internal_data.output_data.histogram[c][val]) >
              perc)
            break;
        if (t_white < val)
          t_white = val;
      }
    gamma_curve(O.gamm[0], O.gamm[1], 2, (t_white << 3) / O.bright);
  }

  int s_iheight = S.iheight;
  int s_iwidth = S.iwidth;
  int s_width = S.width;
  int s_hwight = S.height;

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

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

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

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

    //            bufp += stride;           // go to the next line
  }

  S.iheight = s_iheight;
  S.iwidth = s_iwidth;
  S.width = s_width;
  S.height = s_hwight;

  return 0;
}

Project: LibRaw

void DHT::make_hv_dline(int i)
{
  int iwidth = libraw.imgdata.sizes.iwidth;
  int js = libraw.COLOR(i, 0) & 1;
  int kc = libraw.COLOR(i, js);
  /*
   * js -- начальная х-координата, которая попадает мимо известного зелёного
   * kc -- известный цвет в точке интерполирования
   */
  for (int j = 0; j < iwidth; j++)
  {
    int x = j + nr_leftmargin;
    int y = i + nr_topmargin;
    char d = 0;
    if ((j & 1) == js)
    {
      d = get_hv_grb(x, y, kc);
    }
    else
    {
      d = get_hv_rbg(x, y, kc);
    }
    ndir[nr_offset(y, x)] |= d;
  }
}

Project: LibRaw

void LibRaw::dcb_pp()
{
  int g1, r1, b1, u = width, indx, row, col;

  for (row = 2; row < height - 2; row++)
    for (col = 2, indx = row * u + col; col < width - 2; col++, indx++)
    {

      r1 = (image[indx - 1][0] + image[indx + 1][0] + image[indx - u][0] +
            image[indx + u][0] + image[indx - u - 1][0] +
            image[indx + u + 1][0] + image[indx - u + 1][0] +
            image[indx + u - 1][0]) /
           8.0;
      g1 = (image[indx - 1][1] + image[indx + 1][1] + image[indx - u][1] +
            image[indx + u][1] + image[indx - u - 1][1] +
            image[indx + u + 1][1] + image[indx - u + 1][1] +
            image[indx + u - 1][1]) /
           8.0;
      b1 = (image[indx - 1][2] + image[indx + 1][2] + image[indx - u][2] +
            image[indx + u][2] + image[indx - u - 1][2] +
            image[indx + u + 1][2] + image[indx - u + 1][2] +
            image[indx + u - 1][2]) /
           8.0;

      image[indx][0] = CLIP(r1 + (image[indx][1] - g1));
      image[indx][2] = CLIP(b1 + (image[indx][1] - g1));
    }
}

Project: LibRaw
File: dcraw.c

  static float powf_lim(float a, float b, float limup)
  {
    return (b > limup || b < -limup) ? 0.f : powf(a, b);
  }

Project: LibRaw

void LibRaw::dcb(int iterations, int dcb_enhance)
{

  int i = 1;

  float(*image2)[3];
  image2 = (float(*)[3])calloc(width * height, sizeof *image2);

  float(*image3)[3];
  image3 = (float(*)[3])calloc(width * height, sizeof *image3);

  border_interpolate(6);

  dcb_hor(image2);
  dcb_color2(image2);

  dcb_ver(image3);
  dcb_color3(image3);

  dcb_decide(image2, image3);

  free(image3);

  dcb_copy_to_buffer(image2);

  while (i <= iterations)
  {
    dcb_nyquist();
    dcb_nyquist();
    dcb_nyquist();
    dcb_map();
    dcb_correction();
    i++;
  }

  dcb_color();
  dcb_pp();

  dcb_map();
  dcb_correction2();

  dcb_map();
  dcb_correction();

  dcb_map();
  dcb_correction();

  dcb_map();
  dcb_correction();

  dcb_map();
  dcb_restore_from_buffer(image2);
  dcb_color();

  if (dcb_enhance)
  {
    dcb_refinement();
    // dcb_color_full(image2);
    dcb_color_full();
  }

  free(image2);
}

Project: LibRaw

  void *malloc(size_t sz)
  {
#ifdef LIBRAW_USE_CALLOC_INSTEAD_OF_MALLOC
    void *ptr = ::calloc(sz + extra_bytes, 1);
#else
    void *ptr = ::malloc(sz + extra_bytes);
#endif
    mem_ptr(ptr);
    return ptr;
  }

Project: LibRaw

void LibRaw::process_Sony_0x0116(uchar *buf, ushort len, unsigned long long id)
{
  int i = 0;

  if (((id == 0x101ULL) || // DSLR-A900
       (id == 0x106ULL) || // DSLR-A900
       (id == 0x10dULL) || // DSLR-A850
       (id == 0x10eULL)    // DSLR-A850
       ) &&
      (len >= 2))
    i = 1;
  else if ((id >= 0x111ULL) && (len >= 3))
    i = 2;
  else
    return;

  imgdata.makernotes.common.BatteryTemperature = (float)(buf[i] - 32) / 1.8f;
}

Project: LibRaw

  int libraw_open_file_ex(libraw_data_t *lr, const char *file, INT64 sz)
  {
    if (!lr)
      return EINVAL;
    LibRaw *ip = (LibRaw *)lr->parent_class;
    return ip->open_file(file, sz);
  }

Project: LibRaw

int LibRaw::kodak_65000_decode(short *out, int bsize)
{
  uchar c, blen[768];
  ushort raw[6];
  INT64 bitbuf = 0;
  int save, bits = 0, i, j, len, diff;

  save = ftell(ifp);
  bsize = (bsize + 3) & -4;
  for (i = 0; i < bsize; i += 2)
  {
    c = fgetc(ifp);
    if ((blen[i] = c & 15) > 12 || (blen[i + 1] = c >> 4) > 12)
    {
      fseek(ifp, save, SEEK_SET);
      for (i = 0; i < bsize; i += 8)
      {
        read_shorts(raw, 6);
        out[i] = raw[0] >> 12 << 8 | raw[2] >> 12 << 4 | raw[4] >> 12;
        out[i + 1] = raw[1] >> 12 << 8 | raw[3] >> 12 << 4 | raw[5] >> 12;
        for (j = 0; j < 6; j++)
          out[i + 2 + j] = raw[j] & 0xfff;
      }
      return 1;
    }
  }
  if ((bsize & 7) == 4)
  {
    bitbuf = fgetc(ifp) << 8;
    bitbuf += fgetc(ifp);
    bits = 16;
  }
  for (i = 0; i < bsize; i++)
  {
    len = blen[i];
    if (bits < len)
    {
      for (j = 0; j < 32; j += 8)
        bitbuf += (INT64)fgetc(ifp) << (bits + (j ^ 8));
      bits += 32;
    }
    diff = bitbuf & (0xffff >> (16 - len));
    bitbuf >>= len;
    bits -= len;
    if ((diff & (1 << (len - 1))) == 0)
      diff -= (1 << len) - 1;
    out[i] = diff;
  }
  return 0;
}