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::apply_tiff()
{
  int max_samp = 0, ties = 0, raw = -1, thm = -1, i;
  unsigned long long ns, os;
  struct jhead jh;

  thumb_misc = 16;
  if (thumb_offset)
  {
    fseek(ifp, thumb_offset, SEEK_SET);
    if (ljpeg_start(&jh, 1))
    {
      if ((unsigned)jh.bits < 17 && (unsigned)jh.wide < 0x10000 &&
          (unsigned)jh.high < 0x10000)
      {
        thumb_misc = jh.bits;
        thumb_width = jh.wide;
        thumb_height = jh.high;
      }
    }
  }
  for (i = tiff_nifds; i--;)
  {
    if (tiff_ifd[i].t_shutter)
      shutter = tiff_ifd[i].t_shutter;
    tiff_ifd[i].t_shutter = shutter;
  }

  if(dng_version)
  {
      int ifdc = 0;
      for (i = 0; i < tiff_nifds; i++)
      {
          if (tiff_ifd[i].t_width < 1 || tiff_ifd[i].t_width > 65535 ||
              tiff_ifd[i].t_height < 1 || tiff_ifd[i].t_height > 65535)
              continue; /* wrong image dimensions */

          int samp = tiff_ifd[i].samples;
          if(samp == 2) samp = 1; // Fuji 2-frame
          max_samp = LIM(MAX(max_samp,samp),1,3); // max_samp is needed for thumbnail selection below

          if(tiff_ifd[i].phint != 32803 && tiff_ifd[i].phint != 34892) continue;

          if(
              (tiff_ifd[i].newsubfiletype == 0) // main image
              // Enhanced demosaiced:
              || (tiff_ifd[i].newsubfiletype == 16 && (imgdata.params.raw_processing_options & LIBRAW_PROCESSING_DNG_ADD_ENHANCED))
              // Preview: 0x1 or 0x10001
              || ((tiff_ifd[i].newsubfiletype & 0xffff) == 1 && (imgdata.params.raw_processing_options & LIBRAW_PROCESSING_DNG_ADD_PREVIEWS))
             )
          {
              // Add this IFD to dng_frames
              libraw_internal_data.unpacker_data.dng_frames[ifdc] = ((tiff_ifd[i].newsubfiletype & 0xffff)<<16) | ((i<<8)&0xff00);
              ifdc++;
              // Fuji SuperCCD: second frame:
              if((tiff_ifd[i].newsubfiletype == 0) && tiff_ifd[i].samples == 2)
              {
                  libraw_internal_data.unpacker_data.dng_frames[ifdc] = ((tiff_ifd[i].newsubfiletype & 0xffff)<<16) | ((i<<8)&0xff00) | 1;
                  ifdc++;
              }
          }
      }
      if(ifdc)
      {
          if(ifdc>1 && (imgdata.params.raw_processing_options & LIBRAW_PROCESSING_DNG_PREFER_LARGEST_IMAGE))
          {
              ifd_size_t arr[LIBRAW_IFD_MAXCOUNT*2];
              memset(arr,0,sizeof(arr));
              for(int i = 0; i < ifdc && i < LIBRAW_IFD_MAXCOUNT*2; i++)
              {
                  int ifdidx = (libraw_internal_data.unpacker_data.dng_frames[i]>>8) & 0xff;
                  arr[i].ifdi = libraw_internal_data.unpacker_data.dng_frames[i];
                  arr[i].databits = tiff_ifd[ifdidx].t_width * tiff_ifd[ifdidx].t_height * tiff_ifd[ifdidx].samples * tiff_ifd[ifdidx].bps
                      + (0x100 - (arr[i].ifdi & 0xff)); // add inverted frame # to ensure same sort order for similar sized frames.
              }
              qsort(arr, MIN(ifdc,LIBRAW_IFD_MAXCOUNT*2) ,sizeof(arr[0]),ifd_size_t_cmp);
              for(int i = 0; i < ifdc && i < LIBRAW_IFD_MAXCOUNT*2; i++)
                  libraw_internal_data.unpacker_data.dng_frames[i] = arr[i].ifdi;
          }

          int idx = LIM(shot_select,0,ifdc-1);
          i = (libraw_internal_data.unpacker_data.dng_frames[idx]>>8) & 0xff; // extract frame# back

          raw_width = tiff_ifd[i].t_width;
          raw_height = tiff_ifd[i].t_height;
          tiff_bps = tiff_ifd[i].bps;
          tiff_compress = tiff_ifd[i].comp;
          tiff_sampleformat = tiff_ifd[i].sample_format;
          data_offset = tiff_ifd[i].offset;
          data_size = tiff_ifd[i].bytes;
          tiff_flip = tiff_ifd[i].t_flip;
          tiff_samples = tiff_ifd[i].samples;
          tile_width = tiff_ifd[i].t_tile_width;
          tile_length = tiff_ifd[i].t_tile_length;
          fuji_width = tiff_ifd[i].t_fuji_width;
          if(tiff_samples != 2) /* special case: Fuji SuperCCD */
          {
              if(tiff_ifd[i].phint == 34892)
                  filters = 0;
              else if(i > 0 && tiff_ifd[i].phint == 32803 && tiff_ifd[0].phint == 32803 && !tiff_ifd[i].t_filters && tiff_ifd[0].t_filters)
                  filters = tiff_ifd[0].t_filters;
              else
                  filters = tiff_ifd[i].t_filters;
              width = tiff_ifd[i].t_vwidth;
              height = tiff_ifd[i].t_vheight;
              top_margin = tiff_ifd[i].t_tm;
              left_margin = tiff_ifd[i].t_lm;
              shutter = tiff_ifd[i].t_shutter;
              if(tiff_ifd[i].dng_levels.dng_whitelevel[0])
                  maximum = tiff_ifd[i].dng_levels.dng_whitelevel[0];
              else if (tiff_ifd[i].sample_format <= 2  && tiff_bps > 0 && tiff_bps < 32) // SampleFormat: 0-default(1), 1 - Uint, 2 - Int
                  maximum = (1<<tiff_bps)-1;
              else if (tiff_ifd[i].sample_format == 3)
                  maximum = 1; // Defaults for FP
          }
          raw = i;
          is_raw = ifdc;
      }
      else
          is_raw = 0;
  }
  else
  {
      for (i = 0; i < tiff_nifds; i++)
      {
          if (tiff_ifd[i].t_width < 1 || tiff_ifd[i].t_width > 65535 ||
              tiff_ifd[i].t_height < 1 || tiff_ifd[i].t_height > 65535)
              continue; /* wrong image dimensions */
          if (max_samp < tiff_ifd[i].samples)
              max_samp = tiff_ifd[i].samples;
          if (max_samp > 3)
              max_samp = 3;

          os = raw_width * raw_height;
          ns = tiff_ifd[i].t_width * tiff_ifd[i].t_height;
          if (tiff_bps)
          {
              os *= tiff_bps;
              ns *= tiff_ifd[i].bps;
          }
          if ((tiff_ifd[i].comp != 6 || tiff_ifd[i].samples != 3) &&
              unsigned(tiff_ifd[i].t_width | tiff_ifd[i].t_height) < 0x10000 &&
              (unsigned)tiff_ifd[i].bps < 33 && (unsigned)tiff_ifd[i].samples < 13 &&
              ns && ((ns > os && (ties = 1)) || (ns == os && shot_select == ties++)))
          {
              raw_width = tiff_ifd[i].t_width;
              raw_height = tiff_ifd[i].t_height;
              tiff_bps = tiff_ifd[i].bps;
              tiff_compress = tiff_ifd[i].comp;
              tiff_sampleformat = tiff_ifd[i].sample_format;
              data_offset = tiff_ifd[i].offset;
              data_size = tiff_ifd[i].bytes;
              tiff_flip = tiff_ifd[i].t_flip;
              tiff_samples = tiff_ifd[i].samples;
              tile_width = tiff_ifd[i].t_tile_width;
              tile_length = tiff_ifd[i].t_tile_length;
              shutter = tiff_ifd[i].t_shutter;
              raw = i;
          }
      }
      if (is_raw == 1 && ties)
          is_raw = ties;
  }
  if (is_NikonTransfer && raw >= 0)
  {
    if (tiff_ifd[raw].bps == 16)
    {
      if (tiff_compress == 1)
      {
        if ((raw_width * raw_height * 3) == (tiff_ifd[raw].bytes << 1))
        {
          tiff_bps = tiff_ifd[raw].bps = 12;
        }
        else
        {
          tiff_bps = tiff_ifd[raw].bps = 14;
        }
      }
    }
    else if (tiff_ifd[raw].bps == 8)
    {
      if (tiff_compress == 1)
      {
        is_NikonTransfer = 2; // 8-bit debayered TIFF, like CoolScan NEFs
        imgdata.params.coolscan_nef_gamma = 2.2f;
      }
    }
  }

  if (!tile_width)
    tile_width = INT_MAX;
  if (!tile_length)
    tile_length = INT_MAX;
  for (i = tiff_nifds; i--;)
    if (tiff_ifd[i].t_flip)
      tiff_flip = tiff_ifd[i].t_flip;
  if (raw >= 0 && !load_raw)
    switch (tiff_compress)
    {
    case 32767:
      if (!dng_version &&
          INT64(tiff_ifd[raw].bytes) == INT64(raw_width) * INT64(raw_height))
      {
        tiff_bps = 14;
        load_raw = &LibRaw::sony_arw2_load_raw;
        break;
      }
      if (!dng_version && !strncasecmp(make, "Sony", 4) &&
          INT64(tiff_ifd[raw].bytes) ==
              INT64(raw_width) * INT64(raw_height) * 2ULL)
      {
        tiff_bps = 14;
        load_raw = &LibRaw::unpacked_load_raw;
        break;
      }
      if (INT64(tiff_ifd[raw].bytes) * 8ULL !=
          INT64(raw_width) * INT64(raw_height) * INT64(tiff_bps))
      {
        raw_height += 8;
        load_raw = &LibRaw::sony_arw_load_raw;
        break;
      }
      load_flags = 79;
    case 32769:
      load_flags++;
    case 32770:
    case 32773:
      goto slr;
    case 0:
    case 1:
#ifdef USE_DNGSDK
      if (dng_version && tiff_sampleformat == 3 &&
          (tiff_bps > 8 && (tiff_bps % 8 == 0))) // 16,24,32,48...
      {
        load_raw = &LibRaw::float_dng_load_raw_placeholder;
        break;
      }
#endif
      // Sony 14-bit uncompressed
      if (!dng_version && !strncasecmp(make, "Sony", 4) &&
          INT64(tiff_ifd[raw].bytes) ==
              INT64(raw_width) * INT64(raw_height) * 2ULL)
      {
        tiff_bps = 14;
        load_raw = &LibRaw::unpacked_load_raw;
        break;
      }
      if (!dng_version && !strncasecmp(make, "Sony", 4) &&
          tiff_ifd[raw].samples == 4 &&
          INT64(tiff_ifd[raw].bytes) ==
              INT64(raw_width) * INT64(raw_height) * 8ULL) // Sony ARQ
      {
        // maybe to detect ARQ with the following:
        // if (tiff_ifd[raw].phint == 32892)
        tiff_bps = 14;
        tiff_samples = 4;
        load_raw = &LibRaw::sony_arq_load_raw;
        filters = 0;
        strcpy(cdesc, "RGBG");
        break;
      }
      if (!strncasecmp(make, "Nikon", 5) &&
          (!strncmp(software, "Nikon Scan", 10) || (is_NikonTransfer == 2) || strcasestr(model,"COOLSCAN")))
      {
        load_raw = &LibRaw::nikon_coolscan_load_raw;
        raw_color = 1;
        filters = 0;
        break;
      }
      if ((!strncmp(make, "OLYMPUS", 7) ||
           (!strncasecmp(make, "CLAUSS", 6) &&
            !strncasecmp(model, "piX 5oo", 7))) && // 0x5330303539 works here
          (INT64(tiff_ifd[raw].bytes) * 2ULL ==
           INT64(raw_width) * INT64(raw_height) * 3ULL))
        load_flags = 24;
      if (!dng_version && INT64(tiff_ifd[raw].bytes) * 5ULL ==
                              INT64(raw_width) * INT64(raw_height) * 8ULL)
      {
        load_flags = 81;
        tiff_bps = 12;
      }
    slr:
      switch (tiff_bps)
      {
      case 8:
        load_raw = &LibRaw::eight_bit_load_raw;
        break;
      case 12:
        if (tiff_ifd[raw].phint == 2)
          load_flags = 6;
        if (!strncasecmp(make, "NIKON", 5) &&
            !strncasecmp(model, "COOLPIX A1000", 13) &&
            data_size == raw_width * raw_height * 2)
          load_raw = &LibRaw::unpacked_load_raw;
        else
          load_raw = &LibRaw::packed_load_raw;
        break;
      case 14:
        load_flags = 0;
      case 16:
        load_raw = &LibRaw::unpacked_load_raw;
        if ((!strncmp(make, "OLYMPUS", 7) ||
             (!strncasecmp(make, "CLAUSS", 6) &&
              !strncasecmp(model, "piX 5oo", 7))) && // 0x5330303539 works here
            (INT64(tiff_ifd[raw].bytes) * 7ULL >
             INT64(raw_width) * INT64(raw_height)))
          load_raw = &LibRaw::olympus_load_raw;
      }
      break;
    case 6:
    case 7:
    case 99:
      load_raw = &LibRaw::lossless_jpeg_load_raw;
      break;
    case 262:
      load_raw = &LibRaw::kodak_262_load_raw;
      break;
    case 34713:
      if ((INT64(raw_width) + 9ULL) / 10ULL * 16ULL * INT64(raw_height) ==
          INT64(tiff_ifd[raw].bytes))
      {
        load_raw = &LibRaw::packed_load_raw;
        load_flags = 1;
      }
      else if (INT64(raw_width) * INT64(raw_height) * 3ULL ==
               INT64(tiff_ifd[raw].bytes) * 2ULL)
      {
        load_raw = &LibRaw::packed_load_raw;
        if (model[0] == 'N')
          load_flags = 80;
      }
      else if (INT64(raw_width) * INT64(raw_height) * 3ULL ==
               INT64(tiff_ifd[raw].bytes))
      {
        load_raw = &LibRaw::nikon_yuv_load_raw;
        gamma_curve(1 / 2.4, 12.92, 1, 4095);
        memset(cblack, 0, sizeof cblack);
        filters = 0;
      }
      else if (INT64(raw_width) * INT64(raw_height) * 2ULL ==
               INT64(tiff_ifd[raw].bytes))
      {
        load_raw = &LibRaw::unpacked_load_raw;
        load_flags = 4;
        order = 0x4d4d;
      }
      else if (INT64(raw_width) * INT64(raw_height) * 3ULL ==
               INT64(tiff_ifd[raw].bytes) * 2ULL)
      {
        load_raw = &LibRaw::packed_load_raw;
        load_flags = 80;
      }
      else if (tiff_ifd[raw].rows_per_strip &&
               tiff_ifd[raw].strip_offsets_count &&
               tiff_ifd[raw].strip_offsets_count ==
                   tiff_ifd[raw].strip_byte_counts_count)
      {
        int fit = 1;
        for (int i = 0; i < tiff_ifd[raw].strip_byte_counts_count - 1;
             i++) // all but last
          if (INT64(tiff_ifd[raw].strip_byte_counts[i]) * 2ULL !=
              INT64(tiff_ifd[raw].rows_per_strip) * INT64(raw_width) * 3ULL)
          {
            fit = 0;
            break;
          }
        if (fit)
          load_raw = &LibRaw::nikon_load_striped_packed_raw;
        else
          load_raw = &LibRaw::nikon_load_raw; // fallback
      }
      else if ((((INT64(raw_width) * 3ULL / 2ULL) + 15ULL) / 16ULL) * 16ULL *
                   INT64(raw_height) ==
               INT64(tiff_ifd[raw].bytes))
      {
        load_raw = &LibRaw::nikon_load_padded_packed_raw;
        load_flags = (((INT64(raw_width) * 3ULL / 2ULL) + 15ULL) / 16ULL) *
                     16ULL; // bytes per row
      }
      else
        load_raw = &LibRaw::nikon_load_raw;
      break;
    case 65535:
      load_raw = &LibRaw::pentax_load_raw;
      break;
    case 65000:
      switch (tiff_ifd[raw].phint)
      {
      case 2:
        load_raw = &LibRaw::kodak_rgb_load_raw;
        filters = 0;
        break;
      case 6:
        load_raw = &LibRaw::kodak_ycbcr_load_raw;
        filters = 0;
        break;
      case 32803:
        load_raw = &LibRaw::kodak_65000_load_raw;
      }
    case 32867:
    case 34892:
      break;
    case 8:
      break;
#ifdef USE_GPRSDK
    case 9:
        if(dng_version)
            break; /* Compression=9 supported for dng if we compiled with GPR SDK */
        /* Else: fallthrough */
#endif
    default:
      is_raw = 0;
    }
  if (!dng_version)
    if (((tiff_samples == 3 && tiff_ifd[raw].bytes &&
          !(tiff_bps == 16 &&
            !strncmp(make, "Leaf", 4)) && // Allow Leaf/16bit/3color files
          tiff_bps != 14 &&
          (tiff_compress & -16) != 32768) ||
         (tiff_bps == 8 && strncmp(make, "Phase", 5) &&
          strncmp(make, "Leaf", 4) && !strcasestr(make, "Kodak") &&
          !strstr(model2, "DEBUG RAW"))) && !strcasestr(model,"COOLSCAN") &&
        strncmp(software, "Nikon Scan", 10) && is_NikonTransfer != 2)
      is_raw = 0;

  for (i = 0; i < tiff_nifds; i++)
    if (i != raw &&
        (tiff_ifd[i].samples == max_samp ||
         (tiff_ifd[i].comp == 7 &&
          tiff_ifd[i].samples == 1)) /* Allow 1-bps JPEGs */
        && tiff_ifd[i].bps > 0 && tiff_ifd[i].bps < 33 &&
        tiff_ifd[i].phint != 32803 && tiff_ifd[i].phint != 34892 &&
        unsigned(tiff_ifd[i].t_width | tiff_ifd[i].t_height) < 0x10000 &&
        tiff_ifd[i].t_width * tiff_ifd[i].t_height /
                (SQR(tiff_ifd[i].bps) + 1) >
            thumb_width * thumb_height / (SQR(thumb_misc) + 1) &&
        tiff_ifd[i].comp != 34892)
    {
      thumb_width = tiff_ifd[i].t_width;
      thumb_height = tiff_ifd[i].t_height;
      thumb_offset = tiff_ifd[i].offset;
      thumb_length = tiff_ifd[i].bytes;
      thumb_misc = tiff_ifd[i].bps;
      thm = i;
    }
  if (thm >= 0)
  {
    thumb_misc |= tiff_ifd[thm].samples << 5;
    switch (tiff_ifd[thm].comp)
    {
    case 0:
      write_thumb = &LibRaw::layer_thumb;
      break;
    case 1:
      if (tiff_ifd[thm].bps <= 8)
        write_thumb = &LibRaw::ppm_thumb;
      else if (!strncmp(make, "Imacon", 6))
        write_thumb = &LibRaw::ppm16_thumb;
      else
        thumb_load_raw = &LibRaw::kodak_thumb_load_raw;
      break;
    case 65000:
      thumb_load_raw = tiff_ifd[thm].phint == 6 ? &LibRaw::kodak_ycbcr_load_raw
                                                : &LibRaw::kodak_rgb_load_raw;
    }
  }
}

Project: LibRaw

  DllDef void libraw_set_user_mul(libraw_data_t *lr, int index, float val)
  {
    if (!lr)
      return;
    LibRaw *ip = (LibRaw *)lr->parent_class;
    ip->imgdata.params.user_mul[LIM(index, 0, 3)] = val;
  }

Project: LibRaw

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

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

    case 0x0102:
      stmread(imgdata.shootinginfo.BodySerial, len, ifp);
      if ((imgdata.shootinginfo.BodySerial[0] == 0x4c) &&
          (imgdata.shootinginfo.BodySerial[1] == 0x49))
      {
        unique_id = (((imgdata.shootinginfo.BodySerial[0] & 0x3f) << 5) |
                     (imgdata.shootinginfo.BodySerial[2] & 0x3f)) -
                    0x41;
      }
      else
      {
        unique_id = (((imgdata.shootinginfo.BodySerial[0] & 0x3f) << 5) |
                     (imgdata.shootinginfo.BodySerial[1] & 0x3f)) -
                    0x41;
      }
      setPhaseOneFeatures(unique_id);
      break;
    case 0x0203:
      stmread(imgdata.makernotes.phaseone.Software, len, ifp);
    case 0x0204:
      stmread(imgdata.makernotes.phaseone.SystemType, len, ifp);
    case 0x0211:
      imgdata.makernotes.common.SensorTemperature2 = int_to_float(data);
      break;
    case 0x0401:
      if (type == 4)
        ilm.CurAp = libraw_powf64l(2.0f, (int_to_float(data) / 2.0f));
      else
        ilm.CurAp = libraw_powf64l(2.0f, (getreal(type) / 2.0f));
      break;
    case 0x0403:
      if (type == 4)
        ilm.CurFocal = int_to_float(data);
      else
        ilm.CurFocal = getreal(type);
      break;
    case 0x0410:
      stmread(ilm.body, len, ifp);
      if (((unsigned char)ilm.body[0]) == 0xff)
        ilm.body[0] = 0;
      break;
    case 0x0412:
      stmread(ilm.Lens, len, ifp);
      if (((unsigned char)ilm.Lens[0]) == 0xff)
        ilm.Lens[0] = 0;
      break;
    case 0x0414:
      if (type == 4)
      {
        ilm.MaxAp4CurFocal = libraw_powf64l(2.0f, (int_to_float(data) / 2.0f));
      }
      else
      {
        ilm.MaxAp4CurFocal = libraw_powf64l(2.0f, (getreal(type) / 2.0f));
      }
      break;
    case 0x0415:
      if (type == 4)
      {
        ilm.MinAp4CurFocal = libraw_powf64l(2.0f, (int_to_float(data) / 2.0f));
      }
      else
      {
        ilm.MinAp4CurFocal = libraw_powf64l(2.0f, (getreal(type) / 2.0f));
      }
      break;
    case 0x0416:
      if (type == 4)
      {
        ilm.MinFocal = int_to_float(data);
      }
      else
      {
        ilm.MinFocal = getreal(type);
      }
      if (ilm.MinFocal > 1000.0f)
      {
        ilm.MinFocal = 0.0f;
      }
      break;
    case 0x0417:
      if (type == 4)
      {
        ilm.MaxFocal = int_to_float(data);
      }
      else
      {
        ilm.MaxFocal = getreal(type);
      }
      break;

    case 0x0100:
      flip = "0653"[data & 3] - '0';
      break;
    case 0x0106:
      for (i = 0; i < 9; i++)
        imgdata.color.P1_color[0].romm_cam[i] = ((float *)romm_cam)[i] =
            getreal(11);
      romm_coeff(romm_cam);
      break;
    case 0x0107:
      FORC3 cam_mul[c] = getreal(11);
      break;
    case 0x0108:
      raw_width = data;
      break;
    case 0x0109:
      raw_height = data;
      break;
    case 0x010a:
      left_margin = data;
      break;
    case 0x010b:
      top_margin = data;
      break;
    case 0x010c:
      width = data;
      break;
    case 0x010d:
      height = data;
      break;
    case 0x010e:
      ph1.format = data;
      break;
    case 0x010f:
      data_offset = data + base;
      break;
    case 0x0110:
      meta_offset = data + base;
      meta_length = len;
      break;
    case 0x0112:
      ph1.key_off = save - 4;
      break;
    case 0x0210:
      ph1.tag_210 = int_to_float(data);
      imgdata.makernotes.common.SensorTemperature = ph1.tag_210;
      break;
    case 0x021a:
      ph1.tag_21a = data;
      break;
    case 0x021c:
      strip_offset = data + base;
      break;
    case 0x021d:
      ph1.t_black = data;
      break;
    case 0x0222:
      ph1.split_col = data;
      break;
    case 0x0223:
      ph1.black_col = data + base;
      break;
    case 0x0224:
      ph1.split_row = data;
      break;
    case 0x0225:
      ph1.black_row = data + base;
      break;
    case 0x0226:
      for (i = 0; i < 9; i++)
        imgdata.color.P1_color[1].romm_cam[i] = getreal(11);
      break;
    case 0x0301:
      model[63] = 0;
      imgdata.makernotes.phaseone.FirmwareString[255] = 0;
      fread(imgdata.makernotes.phaseone.FirmwareString, 1, 255, ifp);
      memcpy(model, imgdata.makernotes.phaseone.FirmwareString, 63);
      if ((cp = strstr(model, " camera")))
        *cp = 0;
      else if ((cp = strchr(model, ',')))
        *cp = 0;
      /* minus and the letter after it are not always present
        if present, last letter means:
          C : Contax 645AF
          H : Hasselblad H1 / H2
          M : Mamiya
          V : Hasselblad 555ELD / 553ELX / 503CW / 501CM; not included below
        because of adapter conflicts (Mamiya RZ body) if not present, Phase One
        645 AF, Mamiya 645AFD Series, or anything
       */
      strcpy(imgdata.makernotes.phaseone.SystemModel, model);
      if ((cp = strchr(model, '-')))
      {
        if (cp[1] == 'C')
        {
          strcpy(ilm.body, "Contax 645AF");
          ilm.CameraMount = LIBRAW_MOUNT_Contax645;
          ilm.CameraFormat = LIBRAW_FORMAT_645;
        }
        else if (cp[1] == 'M')
        {
          strcpy(ilm.body, "Mamiya 645");
          ilm.CameraMount = LIBRAW_MOUNT_Mamiya645;
          ilm.CameraFormat = LIBRAW_FORMAT_645;
        }
        else if (cp[1] == 'H')
        {
          strcpy(ilm.body, "Hasselblad H1/H2");
          ilm.CameraMount = LIBRAW_MOUNT_Hasselblad_H;
          ilm.CameraFormat = LIBRAW_FORMAT_645;
        }
        *cp = 0;
      }
    }
    fseek(ifp, save, SEEK_SET);
  }

  if (!ilm.body[0] && !imgdata.shootinginfo.BodySerial[0])
  {
    fseek(ifp, meta_offset, SEEK_SET);
    order = get2();
    fseek(ifp, 6, SEEK_CUR);
    fseek(ifp, meta_offset + get4(), SEEK_SET);
    entries = get4();
    get4();
    while (entries--)
    {
      tag = get4();
      len = get4();
      data = get4();
      save = ftell(ifp);
      fseek(ifp, meta_offset + data, SEEK_SET);
      if (tag == 0x0407)
      {
        stmread(imgdata.shootinginfo.BodySerial, len, ifp);
        if ((imgdata.shootinginfo.BodySerial[0] == 0x4c) &&
            (imgdata.shootinginfo.BodySerial[1] == 0x49))
        {
          unique_id = (((imgdata.shootinginfo.BodySerial[0] & 0x3f) << 5) |
                       (imgdata.shootinginfo.BodySerial[2] & 0x3f)) -
                      0x41;
        }
        else
        {
          unique_id = (((imgdata.shootinginfo.BodySerial[0] & 0x3f) << 5) |
                       (imgdata.shootinginfo.BodySerial[1] & 0x3f)) -
                      0x41;
        }
        setPhaseOneFeatures(unique_id);
      }
      fseek(ifp, save, SEEK_SET);
    }
  }
  load_raw = ph1.format < 3 ? &LibRaw::phase_one_load_raw
                            : &LibRaw::phase_one_load_raw_c;
  maximum = 0xffff;
  strcpy(make, "Phase One");
  if (model[0])
    return;
  switch (raw_height)
  {
  case 2060:
    strcpy(model, "LightPhase");
    break;
  case 2682:
    strcpy(model, "H 10");
    break;
  case 4128:
    strcpy(model, "H 20");
    break;
  case 5488:
    strcpy(model, "H 25");
    break;
  }
}

Project: LibRaw

void LibRaw::rgb_to_lch(double (*image2)[3])
{
  int indx;
  for (indx = 0; indx < height * width; indx++)
  {

    image2[indx][0] = image[indx][0] + image[indx][1] + image[indx][2]; // L
    image2[indx][1] = 1.732050808 * (image[indx][0] - image[indx][1]);  // C
    image2[indx][2] =
        2.0 * image[indx][2] - image[indx][0] - image[indx][1]; // H
  }
}

Project: LibRaw

ushort LibRaw::sget2Rev(uchar *s) // specific to some Canon Makernotes fields,
                                  // where they have endian in reverse
{
  if (order == 0x4d4d) /* "II" means little-endian, and we reverse to "MM" - big
                          endian */
    return s[0] | s[1] << 8;
  else /* "MM" means big-endian... */
    return s[0] << 8 | s[1];
}

Project: LibRaw

  int FCF(int row, int col)
  {
    int rr, cc;
    if (libraw_internal_data.unpacker_data.fuji_layout)
    {
      rr = libraw_internal_data.internal_output_params.fuji_width - 1 - col +
           (row >> 1);
      cc = col + ((row + 1) >> 1);
    }
    else
    {
      rr = libraw_internal_data.internal_output_params.fuji_width - 1 + row -
           (col >> 1);
      cc = row + ((col + 1) >> 1);
    }
    return FC(rr, cc);
  }

Project: LibRaw

void LibRaw::dcb_color()
{
  int row, col, c, d, u = width, indx;

  for (row = 1; row < height - 1; row++)
    for (col = 1 + (FC(row, 1) & 1), indx = row * width + col,
        c = 2 - FC(row, col);
         col < u - 1; col += 2, indx += 2)
    {

      image[indx][c] = CLIP((4 * image[indx][1] - image[indx + u + 1][1] -
                             image[indx + u - 1][1] - image[indx - u + 1][1] -
                             image[indx - u - 1][1] + image[indx + u + 1][c] +
                             image[indx + u - 1][c] + image[indx - u + 1][c] +
                             image[indx - u - 1][c]) /
                            4.0);
    }

  for (row = 1; row < height - 1; row++)
    for (col = 1 + (FC(row, 2) & 1), indx = row * width + col,
        c = FC(row, col + 1), d = 2 - c;
         col < width - 1; col += 2, indx += 2)
    {

      image[indx][c] =
          CLIP((2 * image[indx][1] - image[indx + 1][1] - image[indx - 1][1] +
                image[indx + 1][c] + image[indx - 1][c]) /
               2.0);
      image[indx][d] =
          CLIP((2 * image[indx][1] - image[indx + u][1] - image[indx - u][1] +
                image[indx + u][d] + image[indx - u][d]) /
               2.0);
    }
}

Project: LibRaw

void DHT::make_gline(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 = js; j < iwidth; j += 2)
  {
    int x = j + nr_leftmargin;
    int y = i + nr_topmargin;
    int dx, dy, dx2, dy2;
    float h1, h2;
    if (ndir[nr_offset(y, x)] & VER)
    {
      dx = dx2 = 0;
      dy = -1;
      dy2 = 1;
      h1 = 2 * nraw[nr_offset(y - 1, x)][1] /
           (nraw[nr_offset(y - 2, x)][kc] + nraw[nr_offset(y, x)][kc]);
      h2 = 2 * nraw[nr_offset(y + 1, x)][1] /
           (nraw[nr_offset(y + 2, x)][kc] + nraw[nr_offset(y, x)][kc]);
    }
    else
    {
      dy = dy2 = 0;
      dx = 1;
      dx2 = -1;
      h1 = 2 * nraw[nr_offset(y, x + 1)][1] /
           (nraw[nr_offset(y, x + 2)][kc] + nraw[nr_offset(y, x)][kc]);
      h2 = 2 * nraw[nr_offset(y, x - 1)][1] /
           (nraw[nr_offset(y, x - 2)][kc] + nraw[nr_offset(y, x)][kc]);
    }
    float b1 = 1 / calc_dist(nraw[nr_offset(y, x)][kc],
                             nraw[nr_offset(y + dy * 2, x + dx * 2)][kc]);
    float b2 = 1 / calc_dist(nraw[nr_offset(y, x)][kc],
                             nraw[nr_offset(y + dy2 * 2, x + dx2 * 2)][kc]);
    b1 *= b1;
    b2 *= b2;
    float eg = nraw[nr_offset(y, x)][kc] * (b1 * h1 + b2 * h2) / (b1 + b2);
    float min, max;
    min = MIN(nraw[nr_offset(y + dy, x + dx)][1],
              nraw[nr_offset(y + dy2, x + dx2)][1]);
    max = MAX(nraw[nr_offset(y + dy, x + dx)][1],
              nraw[nr_offset(y + dy2, x + dx2)][1]);
    min /= 1.2;
    max *= 1.2;
    if (eg < min)
      eg = scale_under(eg, min);
    else if (eg > max)
      eg = scale_over(eg, max);
    if (eg > channel_maximum[1])
      eg = channel_maximum[1];
    else if (eg < channel_minimum[1])
      eg = channel_minimum[1];
    nraw[nr_offset(y, x)][1] = eg;
  }
}

Project: LibRaw

LibRaw_buffer_datastream::~LibRaw_buffer_datastream() {}

Project: LibRaw

float LibRaw::int_to_float(int i)
{
  union {
    int i;
    float f;
  } u;
  u.i = i;
  return u.f;
}

Project: LibRaw

void LibRaw::GetNormalizedModel()
{

  int i, j, c;
  char *ps;

  static const struct
  {
    unsigned long long id;
    char t_model[20];
  } unique[] =
// clang-format off
      {
      { CanonID_EOS_M50, "EOS M50" }, // Kiss M
      { CanonID_EOS_M3, "EOS M3" },
      { CanonID_EOS_M10, "EOS M10" },
      { CanonID_EOS_M5, "EOS M5" },
      { CanonID_EOS_M100, "EOS M100" },
      { CanonID_EOS_M200, "EOS M200" },
      { CanonID_EOS_1D, "EOS-1D" },
      { CanonID_EOS_1DS, "EOS-1DS" },
      { CanonID_EOS_10D, "EOS 10D" },
      { CanonID_EOS_1D_Mark_III, "EOS-1D Mark III" },
      { CanonID_EOS_300D, "EOS 300D" }, // Digital Rebel / Kiss Digital
      { CanonID_EOS_1D_Mark_II, "EOS-1D Mark II" },
      { CanonID_EOS_20D, "EOS 20D" },
      { CanonID_EOS_450D, "EOS 450D" }, // Digital Rebel XSi / Kiss X2
      { CanonID_EOS_1Ds_Mark_II, "EOS-1Ds Mark II" },
      { CanonID_EOS_350D, "EOS 350D" }, // Digital Rebel XT / Kiss Digital N
      { CanonID_EOS_40D, "EOS 40D" },
      { CanonID_EOS_5D, "EOS 5D" },
      { CanonID_EOS_1Ds_Mark_III, "EOS-1Ds Mark III" },
      { CanonID_EOS_5D_Mark_II, "EOS 5D Mark II" },
      { CanonID_EOS_1D_Mark_II_N, "EOS-1D Mark II N" },
      { CanonID_EOS_30D, "EOS 30D" },
      { CanonID_EOS_400D, "EOS 400D" }, // Digital Rebel XTi / Kiss Digital X
      { CanonID_EOS_7D, "EOS 7D" },
      { CanonID_EOS_500D, "EOS 500D" },   // Rebel T1i / Kiss X3
      { CanonID_EOS_1000D, "EOS 1000D" }, // Digital Rebel XS / Kiss F
      { CanonID_EOS_50D, "EOS 50D" },
      { CanonID_EOS_1D_X, "EOS-1D X" },
      { CanonID_EOS_550D, "EOS 550D" }, // Rebel T2i / Kiss X4
      { CanonID_EOS_1D_Mark_IV, "EOS-1D Mark IV" },
      { CanonID_EOS_5D_Mark_III, "EOS 5D Mark III" },
      { CanonID_EOS_600D, "EOS 600D" }, // Rebel T3i / Kiss X5
      { CanonID_EOS_60D, "EOS 60D" },
      { CanonID_EOS_1100D, "EOS 1100D" }, // Rebel T3 / Kiss X50
      { CanonID_EOS_7D_Mark_II, "EOS 7D Mark II" },
      { CanonID_EOS_650D, "EOS 650D" }, // Rebel T4i / Kiss X6i
      { CanonID_EOS_6D, "EOS 6D" },
      { CanonID_EOS_1D_C, "EOS-1D C" },
      { CanonID_EOS_70D, "EOS 70D" },
      { CanonID_EOS_700D, "EOS 700D" },   // Rebel T5i / Kiss X7i
      { CanonID_EOS_1200D, "EOS 1200D" }, // Rebel T5 / Kiss X70 / Hi
      { CanonID_EOS_1D_X_Mark_II, "EOS-1D X Mark II" },
      { CanonID_EOS_M, "EOS M" },
      { CanonID_EOS_M2, "EOS M2" },
      { CanonID_EOS_100D, "EOS 100D" }, // Rebel SL1 / Kiss X7
      { CanonID_EOS_760D, "EOS 760D" }, // Rebel T6s / 8000D
      { CanonID_EOS_5D_Mark_IV, "EOS 5D Mark IV" },
      { CanonID_EOS_80D, "EOS 80D" },
      { CanonID_EOS_5DS, "EOS 5DS" },
      { CanonID_EOS_750D, "EOS 750D" }, // Rebel T6i / Kiss X8i
      { CanonID_EOS_5DS_R, "EOS 5DS R" },
      { CanonID_EOS_1300D, "EOS 1300D" }, // Rebel T6 / Kiss X80
      { CanonID_EOS_800D, "EOS 800D" },   // Rebel T7i / Kiss X9i
      { CanonID_EOS_6D_Mark_II, "EOS 6D Mark II" },
      { CanonID_EOS_M6, "EOS M6" },
      { CanonID_EOS_77D, "EOS 77D" },     // 9000D
      { CanonID_EOS_200D, "EOS 200D" },   // Rebel SL2 / Kiss X9
      { CanonID_EOS_3000D, "EOS 3000D" }, // Rebel T100 / 4000D
      { CanonID_EOS_R, "EOS R" },
      { CanonID_EOS_1500D, "EOS 1500D" }, // Rebel T7 / 2000D / Kiss X90
      { CanonID_EOS_RP, "EOS RP" },
      { CanonID_EOS_250D, "EOS 250D" }, // Rebel SL3 / 200D II / Kiss X10
      { CanonID_EOS_90D, "EOS 90D" },
      { CanonID_EOS_M6_Mark_II, "EOS M6 Mark II" },
      },
    sonique[] = {
        {0x002ULL, "DSC-R1"},      {0x100ULL, "DSLR-A100"},
        {0x101ULL, "DSLR-A900"},   {0x102ULL, "DSLR-A700"},
        {0x103ULL, "DSLR-A200"},   {0x104ULL, "DSLR-A350"},
        {0x105ULL, "DSLR-A300"},   {0x106ULL, "DSLR-A900"},
        {0x107ULL, "DSLR-A380"},   {0x108ULL, "DSLR-A330"},
        {0x109ULL, "DSLR-A230"},   {0x10aULL, "DSLR-A290"},
        {0x10dULL, "DSLR-A850"},   {0x10eULL, "DSLR-A850"},
        {0x111ULL, "DSLR-A550"},   {0x112ULL, "DSLR-A500"},
        {0x113ULL, "DSLR-A450"},   {0x116ULL, "NEX-5"},
        {0x117ULL, "NEX-3"},       {0x118ULL, "SLT-A33"},
        {0x119ULL, "SLT-A55V"},    {0x11aULL, "DSLR-A560"},
        {0x11bULL, "DSLR-A580"},   {0x11cULL, "NEX-C3"},
        {0x11dULL, "SLT-A35"},     {0x11eULL, "SLT-A65"},
        {0x11fULL, "SLT-A77"},     {0x120ULL, "NEX-5N"},
        {0x121ULL, "NEX-7"},       {0x122ULL, "NEX-VG20"},
        {0x123ULL, "SLT-A37"},     {0x124ULL, "SLT-A57"},
        {0x125ULL, "NEX-F3"},      {0x126ULL, "SLT-A99V"},
        {0x127ULL, "NEX-6"},       {0x128ULL, "NEX-5R"},
        {0x129ULL, "DSC-RX100"},   {0x12aULL, "DSC-RX1"},
        {0x12bULL, "NEX-VG900"},   {0x12cULL, "NEX-VG30"},
        {0x12eULL, "ILCE-3000"},   {0x12fULL, "SLT-A58"},
        {0x131ULL, "NEX-3N"},      {0x132ULL, "ILCE-7"},
        {0x133ULL, "NEX-5T"},      {0x134ULL, "DSC-RX100M2"},
        {0x135ULL, "DSC-RX10"},    {0x136ULL, "DSC-RX1R"},
        {0x137ULL, "ILCE-7R"},     {0x138ULL, "ILCE-6000"},
        {0x139ULL, "ILCE-5000"},   {0x13dULL, "DSC-RX100M3"},
        {0x13eULL, "ILCE-7S"},     {0x13fULL, "ILCA-77M2"},
        {0x153ULL, "ILCE-5100"},   {0x154ULL, "ILCE-7M2"},
        {0x155ULL, "DSC-RX100M4"}, {0x156ULL, "DSC-RX10M2"},
        {0x158ULL, "DSC-RX1RM2"},  {0x15aULL, "ILCE-QX1"},
        {0x15bULL, "ILCE-7RM2"},   {0x15eULL, "ILCE-7SM2"},
        {0x161ULL, "ILCA-68"},     {0x162ULL, "ILCA-99M2"},
        {0x163ULL, "DSC-RX10M3"},  {0x164ULL, "DSC-RX100M5"},
        {0x165ULL, "ILCE-6300"},   {0x166ULL, "ILCE-9"},
        {0x168ULL, "ILCE-6500"},   {0x16aULL, "ILCE-7RM3"},
        {0x16bULL, "ILCE-7M3"},    {0x16cULL, "DSC-RX0"},
        {0x16dULL, "DSC-RX10M4"},  {0x16eULL, "DSC-RX100M6"},
        {0x16fULL, "DSC-HX99"},    {0x171ULL, "DSC-RX100M5A"},
        {0x173ULL, "ILCE-6400"},   {0x174ULL, "DSC-RX0M2"},
        {0x176ULL, "DSC-RX100M7"}, {0x177ULL, "ILCE-7RM4"},
        {0x17aULL, "ILCE-6600"},   {0x17bULL, "ILCE-6100"},
    };

  static const char *orig;

  static const char fujialias[][16] = {
    "@DBP for GX680", "DX-2000",
    "@F500EXR", "F505EXR",
    "@F600EXR", "F605EXR",
    "@F770EXR", "F775EXR",
    "@HS10", "HS10 HS11",
    "@HS20EXR", "HS22EXR",
    "@HS30EXR", "HS33EXR", "HS35EXR",
    "@S5100", "S5500",
    "@S5200", "S5600",
    "@S6000fd", "S6500fd",
    "@S9000", "S9500",
    "@S9100", "S9600",
    "@S200EXR", "S205EXR",
    "@X-T1 IR", "X-T1IR",
  };

  static const char kodakalias[][16] = {
    "@DCS Pro 14N", "Camerz ZDS 14", // Camerz rebadge make: "Photo Control"
    "@DCS720X", "SCS2000",
    "@DCS520C", "EOS D2000C", "EOS D2000", // EOS rebadge make: Canon
    "@DCS560C", "EOS D6000C", "EOS D6000", // EOS rebadge make: Canon
    "@DCS460M", "DCS460A", // 'A' was supposed to stand for 'achromatic', marketing changed it to 'M'
    "@DCS460",  "DCS460C", "DCS460D",
    "@DCS465",  "DCS465C", "DCS465D",
    "@EOSDCS1", "EOSDCS1B", "EOSDCS1C",
    "@EOSDCS3", "EOSDCS3B", "EOSDCS3C",
  };

  static const struct
  {
    const char *Kmodel;
    ushort mount;
  } Kodak_mounts[] = {
      {"DCS465", LIBRAW_MOUNT_DigitalBack},
      {"DCS5", LIBRAW_MOUNT_Canon_EF},
      {"DCS Pro SLR/c", LIBRAW_MOUNT_Canon_EF},
      {"DCS", LIBRAW_MOUNT_Nikon_F},
      {"EOS", LIBRAW_MOUNT_Canon_EF},
      {"NC2000", LIBRAW_MOUNT_Nikon_F}, // AP "News Camera"
      {"Pixpro S-1", LIBRAW_MOUNT_mFT},
      {"ProBack", LIBRAW_MOUNT_DigitalBack},
      {"SCS1000", LIBRAW_MOUNT_Canon_EF},
  };

  static const char *KodakMonochrome[] = {
      "DCS420M",    "DCS420A",  "DCS420I",
      "DCS460M",    "DCS460A",  "DCS460I",
      "DCS465M",    "DCS465A",  "DCS465I",
      "DCS560M",    "DCS660M",  "DCS760M", "EOS D2000M", "EOS D6000M",
      "EOSDCS1M",   "EOSDCS1I",
      "EOSDCS3M",   "EOSDCS3I",
      "EOSDCS5M",   "EOSDCS5I",
      "NC2000M",    "NC2000A",  "NC2000I",
  };

  static const char leafalias[][16] = {
      // Leaf re-badged to Mamiya
    "@Aptus-II 5",  "DM22",
    "@Aptus-II 6",  "DM28",
    "@Aptus-II 7",  "DM33",
    "@Aptus-II 8",  "DM40",
    "@Aptus-II 10", "DM56",
  };

  static const char KonicaMinolta_aliases[][24] = {
    "@Dynax 5D", "DYNAX 5D", "MAXXUM 5D", "ALPHA-5 DIGITAL", "Alpha-5 Digital", "Alpha Sweet Digital",
    "@Dynax 7D", "DYNAX 7D", "MAXXUM 7D", "Alpha-7 Digital",
  };

  static const char nikonalias[][16] = {
      "@COOLPIX 2100",  "E2100",         "@COOLPIX 2500",  "E2500",
      "@COOLPIX 3200",  "E3200",         "@COOLPIX 3700",  "E3700",
      "@COOLPIX 4300",  "E4300",         "@COOLPIX 4500",  "E4500",
      "@COOLPIX 5000",  "E5000",         "@COOLPIX 5400",  "E5400",
      "@COOLPIX 5700",  "E5700",         "@COOLPIX 8400",  "E8400",
      "@COOLPIX 8700",  "E8700",         "@COOLPIX 8800",  "E8800",
      "@COOLPIX 700",   "E700",          "@COOLPIX 800",   "E800",
      "@COOLPIX 880",   "E880",          "@COOLPIX 900",   "E900",
      "@COOLPIX 950",   "E950",          "@COOLPIX 990",   "E990",
      "@COOLPIX 995",   "E995",          "@COOLPIX P7700", "COOLPIX Deneb",
      "@COOLPIX P7800", "COOLPIX Kalon",
  };

  static const char olyalias[][32] = { // Olympus
    "@AIR A01", "AIR-A01",
    "@C-5050Z", "C5050Z",
    "@C-5060WZ", "C5060WZ",
    "@C-7000Z", "C7000Z", "C70Z,C7000Z", "C70Z",
    "@C-7070WZ", "C7070WZ",
    "@C-8080WZ", "C8080WZ",
    "@C350Z", "X200,D560Z,C350Z", "X200", "D560Z",
    "@E-20", "E-20,E-20N,E-20P", "E-20N", "E-20P",
    "@E-M10 Mark II", "E-M10MarkII", "E-M10_M2", "piX 5oo",
    "@E-M10 Mark III", "E-M10MarkIII", "E-M10_M3",
    "@E-M1 Mark II", "E-M1MarkII", "E-M1_M2",
    "@E-M5 Mark III", "E-M5MarkIII", "E-M5_M3",
    "@E-M5 Mark II", "E-M5MarkII", "E-M5_M2",
    "@SH-2", "SH-3",
    "@SP-310", "SP310",
    "@SP-320", "SP320",
    "@SP-350", "SP350",
    "@SP-500UZ", "SP500UZ",
    "@SP-510UZ", "SP510UZ",
    "@SP-550UZ", "SP550UZ",
    "@SP-560UZ", "SP560UZ",
    "@SP-565UZ", "SP565UZ",
    "@SP-570UZ", "SP570UZ",
    "@STYLUS 1s", "STYLUS1s", "STYLUS1,1s",
    "@STYLUS 1", "STYLUS1",
  };

  static const char panalias[][16] = { // Panasonic, PanaLeica
// fixed lens
    "@DMC-FX150", "DMC-FX180",
    "@DC-FZ1000M2", "DC-FZ10002", "V-Lux 5",
    "@DMC-FZ1000", "V-LUX (Typ 114)",
    "@DMC-FZ2500", "DMC-FZ2000", "DMC-FZH1",
    "@DMC-FZ100", "V-LUX 2",
    "@DMC-FZ150", "V-LUX 3",
    "@DMC-FZ200", "V-LUX 4",
    "@DMC-FZ300", "DMC-FZ330",
    "@DMC-FZ35", "DMC-FZ38",
    "@DMC-FZ40", "DMC-FZ42", "DMC-FZ45", "DC-FZ40", "DC-FZ42", "DC-FZ45",
    "@DMC-FZ50", "V-LUX 1", "V-LUX1",
    "@DMC-FZ70", "DMC-FZ72",
    "@DC-FZ80", "DC-FZ81", "DC-FZ82", "DC-FZ83", "DC-FZ85",
    "@DMC-LC1", "DIGILUX 2", "Digilux 2", "DIGILUX2",
    "@DMC-LF1", "C (Typ 112)",
    "@DC-LX100M2", "D-Lux 7",
    "@DMC-LX100", "D-LUX (Typ 109)", "D-Lux (Typ 109)",
    "@DMC-LX1", "D-Lux2", "D-LUX2", "D-LUX 2",
    "@DMC-LX2", "D-LUX 3", "D-LUX3",
    "@DMC-LX3", "D-LUX 4",
    "@DMC-LX5", "D-LUX 5",
    "@DMC-LX7", "D-LUX 6",
    "@DMC-LX9", "DMC-LX10", "DMC-LX15",
    "@DMC-ZS100", "DMC-ZS110", "DMC-TZ100", "DMC-TZ101", "DMC-TZ110", "DMC-TX1",
    "@DC-ZS200", "DC-ZS220", "DC-TZ200", "DC-TZ202", "DC-TZ220", "DC-TX2", "C-Lux", "CAM-DC25",
    "@DMC-ZS40", "DMC-TZ60", "DMC-TZ61",
    "@DMC-ZS50", "DMC-TZ70", "DMC-TZ71",
    "@DMC-ZS60", "DMC-TZ80", "DMC-TZ81", "DMC-TZ82", "DMC-TZ85",
    "@DC-ZS70", "DC-TZ90", "DC-TZ91", "DC-TZ92", "DC-TZ93",
    "@DC-ZS80", "DC-TZ95", "DC-TZ96", "DC-TZ97",

// interchangeable lens
    "@DC-G99", "DC-G90", "DC-G91", "DC-G95",
    "@DMC-G7", "DMC-G70",
    "@DMC-G8", "DMC-G80", "DMC-G81", "DMC-G85",
    "@DMC-GH4", "AG-GH4", "CGO4",
    "@DC-GF10", "DC-GF90", "DC-GX880",
    "@DC-GF9", "DC-GX850", "DC-GX800",
    "@DMC-GM1", "DMC-GM1S",
    "@DMC-GX85", "DMC-GX80", "DMC-GX7MK2",
    "@DC-GX9", "DC-GX7MK3",
    "@DMC-L1", "DIGILUX 3", "DIGILUX3", // full 4/3 mount, not m43
  };

  static const char phase1alias[][16] = {
    "@H20", "H 20",
    "@H25", "H 25",
    "@P20+", "P 20+",
    "@P20", "P 20",
    "@P21+", "P 21+", "M18", // "Mamiya M18"
    "@P21", "P 21",
    "@P25+", "P 25+", "M22", // "Mamiya M22"
    "@P25", "P 25",
    "@P30+", "P 30+", "M31", // "Mamiya M31"
    "@P30", "P 30",
    "@P40+", "P 40+",
    "@P40", "P 40",
    "@P45+", "P 45+",
    "@P45", "P 45",
    "@P65+", "P 65+",
    "@P65", "P 65",
  };

  static const char SamsungPentax_aliases[][16] = {
    "@*istDL2", "*ist DL2", "GX-1L",
    "@*istDS2", "*ist DS2", "GX-1S",
    "@*istDL",  "*ist DL",
    "@*istDS",  "*ist DS",
    "@*istD",   "*ist D",
    "@K10D", "GX10", "GX-10",
    "@K20D", "GX20", "GX-20",
    "@K-m", "K2000",
  };

  static const char samsungalias[][64] = {
    "@EX1", "TL500",
//    "@GX20", "GX-20",
    "@NX U", "EK-GN100", "EK-GN110", "EK-GN120", "EK-KN120", "Galaxy NX",
    "@NX mini", "NXF1",
    "@WB2000", "TL350",
      //    "@WB5000", "WB5000/HZ25W", // no spaces around the slash separating names
      //    "@WB5500", "WB5500 / VLUU WB5500 / SAMSUNG HZ50W",
      //    "@WB500", "WB510 / VLUU WB500 / SAMSUNG HZ10W",
      //    "@WB550", "WB560 / VLUU WB550 / SAMSUNG HZ15W",
  };

//clang-format on
  if (!strncasecmp(model, "KODAK PIXPRO S-1", 16))
  {
    setMakeFromIndex(LIBRAW_CAMERAMAKER_Kodak);
    strcpy(make, "Kodak");
    strcpy(model, "Pixpro S-1");
    ilm.CameraFormat = LIBRAW_FORMAT_FT;
  }

  if (strstr(make, "VLUU"))
  {
	  setMakeFromIndex(LIBRAW_CAMERAMAKER_Samsung);
  }
  else if (makeIs(LIBRAW_CAMERAMAKER_Unknown)) {
    if (strcasestr(model, "Google")) {
		setMakeFromIndex(LIBRAW_CAMERAMAKER_Google);
    }
  }
  else if (makeIs(LIBRAW_CAMERAMAKER_Hasselblad) && is_Sony)
  {
	  setMakeFromIndex(LIBRAW_CAMERAMAKER_Sony);
  }
  else if (makeIs(LIBRAW_CAMERAMAKER_Clauss) && (OlyID == 0x5330303539ULL))
  {
	  setMakeFromIndex(LIBRAW_CAMERAMAKER_Olympus);
  }
  else if (!strncmp(model, "EOS D2000", 9) || !strncmp(model, "EOS D6000", 9) ||
           !strncmp(model, "EOSDCS", 6) ||
           !strncasecmp(model, "Camerz ZDS 14", 13))
  {
	  setMakeFromIndex(LIBRAW_CAMERAMAKER_Kodak);
  }
  else
  {
    strcpy(normalized_make, make);
  }

  if (makeIs(LIBRAW_CAMERAMAKER_Apple)) {
    if ((imgdata.color.UniqueCameraModel[0]) &&
        (!strncmp(model, "iPad", 4) || !strncmp(model, "iPhone", 6)))
    strcpy(model, imgdata.color.UniqueCameraModel);

  } else if (makeIs(LIBRAW_CAMERAMAKER_Kodak)) {
    if ((model[6] == ' ') &&
        (!strncmp(model, "DCS4", 4) ||
        !strncmp(model, "NC2000", 6)))
    {
      model[6] = 0;
    }
    if ((model[6] != 'A') &&
        (model[6] != 'I') &&
        (model[6] != 'M') &&
        !strncmp(model, "NC2000", 6))
    {
      model[6] = 0;
    }
  }

  else if (makeIs(LIBRAW_CAMERAMAKER_Ricoh) &&
           !strncmp(model, "GXR", 3)) {
    strcpy(ilm.body, "Ricoh GXR");
    if (!imgdata.lens.Lens[0] && imgdata.color.UniqueCameraModel[0]) {
      strcpy (imgdata.lens.Lens, imgdata.color.UniqueCameraModel);
      remove_caseSubstr (imgdata.lens.Lens, (char *)"Ricoh");
      remove_caseSubstr (imgdata.lens.Lens, (char *)"Lens");
      removeExcessiveSpaces (imgdata.lens.Lens);
    }
    if (ilm.LensID == -1) {
      if (strstr(imgdata.lens.Lens, "50mm"))
        ilm.LensID = 1;
      else if (strstr(imgdata.lens.Lens, "S10"))
        ilm.LensID = 2;
      else if (strstr(imgdata.lens.Lens, "P10"))
        ilm.LensID = 3;
      else if (strstr(imgdata.lens.Lens, "28mm"))
        ilm.LensID = 5;
      else if (strstr(imgdata.lens.Lens, "A16"))
        ilm.LensID = 6;
    }
    switch (ilm.LensID) {
    case 1: // GR Lens A12 50mm F2.5 Macro
      strcpy(model, "GXR A12 50mm");
      ilm.CameraFormat = ilm.LensFormat = LIBRAW_FORMAT_APSC;
      ilm.CameraMount = LIBRAW_MOUNT_RicohModule;
      ilm.LensMount = LIBRAW_MOUNT_FixedLens;
      ilm.FocalType = LIBRAW_FT_PRIME_LENS;
      break;
    case 2:
      strcpy(model, "GXR S10");
      ilm.CameraFormat = ilm.LensFormat = LIBRAW_FORMAT_1div1p7INCH;
      ilm.CameraMount = LIBRAW_MOUNT_RicohModule;
      ilm.LensMount = LIBRAW_MOUNT_FixedLens;
      ilm.FocalType = LIBRAW_FT_ZOOM_LENS;
      break;
    case 3: // Ricoh Lens P10 28-300mm F3.5-5.6 VC
      strcpy(model, "GXR P10");
      ilm.CameraFormat = ilm.LensFormat = LIBRAW_FORMAT_1div2p3INCH;
      ilm.CameraMount = LIBRAW_MOUNT_RicohModule;
      ilm.LensMount = LIBRAW_MOUNT_FixedLens;
      ilm.FocalType = LIBRAW_FT_ZOOM_LENS;
      break;
    case 5: // GR Lens A12 28mm F2.5
      strcpy(model, "GXR A12 28mm");
      ilm.CameraFormat = ilm.LensFormat = LIBRAW_FORMAT_APSC;
      ilm.CameraMount = LIBRAW_MOUNT_RicohModule;
      ilm.LensMount = LIBRAW_MOUNT_FixedLens;
      ilm.FocalType = LIBRAW_FT_PRIME_LENS;
      break;
    case 6: // Ricoh Lens A16 24-85mm F3.5-5.5
      strcpy(model, "GXR A16");
      ilm.CameraFormat = ilm.LensFormat = LIBRAW_FORMAT_APSC;
      ilm.CameraMount = LIBRAW_MOUNT_RicohModule;
      ilm.LensMount = LIBRAW_MOUNT_FixedLens;
      ilm.FocalType = LIBRAW_FT_ZOOM_LENS;
      break;
    case 8: // Ricoh Mount A12 (Leica M lenses)
      strcpy(model, "GXR Mount A12");
      ilm.CameraFormat = LIBRAW_FORMAT_APSC;
      ilm.CameraMount = LIBRAW_MOUNT_Leica_M;
      ilm.LensID = -1;
      break;
    }
  }

  strcpy(normalized_model, model);

  if (makeIs(LIBRAW_CAMERAMAKER_Canon))
  {
    if (unique_id)
    {
      for (i = 0; i < sizeof unique / sizeof *unique; i++)
      {
        if (unique_id == unique[i].id)
        {
          strcpy(model, unique[i].t_model);
          strcpy(normalized_model, unique[i].t_model);
          break;
        }
      }
    }
  }
  else if (makeIs(LIBRAW_CAMERAMAKER_Fujifilm))
  {
    if (!strcmp(model + 7, "S2Pro"))
    {
      strcpy(model, "S2Pro");
      strcpy(normalized_model, model);
    }
    for (i = 0; i < sizeof fujialias / sizeof *fujialias; i++)
    {
      if (fujialias[i][0] == '@')
      {
        orig = fujialias[i] + 1;
        if (!strcmp(model, orig))
        {
          break;
        }
      }
      else if (!strcmp(model, fujialias[i]))
      {
        strcpy(normalized_model, orig);
        break;
      }
    }

  } else if (makeIs(LIBRAW_CAMERAMAKER_Hasselblad)) {
    parseHassyModel();
  }
  else if (makeIs(LIBRAW_CAMERAMAKER_Mamiya))
  {
    for (i = 0; i < sizeof phase1alias / sizeof *phase1alias; i++)
    { // re-badged Phase One backs
      if (phase1alias[i][0] == '@')
      {
        orig = phase1alias[i] + 1;
      }
      else if (!strcmp(model, phase1alias[i]))
      {
		setMakeFromIndex(LIBRAW_CAMERAMAKER_PhaseOne);
        strcpy(normalized_model, orig);
        break;
      }
    }
    for (i = 0; i < sizeof leafalias / sizeof *leafalias; i++)
    { // re-badged Leaf backs
      if (leafalias[i][0] == '@')
      {
        orig = leafalias[i] + 1;
      }
      else if (!strcmp(model, leafalias[i]))
      {
        setMakeFromIndex(LIBRAW_CAMERAMAKER_Leaf);
        strcpy(normalized_model, orig);
        break;
      }
    }

    /* repeating, because make for some Mamiya re-badged Leaf backs is set to
     * Leaf */
  }
  else if (makeIs(LIBRAW_CAMERAMAKER_Leaf))
  {
    for (i = 0; i < sizeof leafalias / sizeof *leafalias; i++)
    { // re-badged Leaf backs
      if (leafalias[i][0] == '@')
      {
        orig = leafalias[i] + 1;
        if (!strcmp(model, orig))
        {
          break;
        }
      }
      else if (!strcmp(model, leafalias[i]))
      { // maybe to change regular "make" to "Mamiya" too
        strcpy(normalized_model, orig);
        break;
      }
    }
    if ((ps = strchr(normalized_model, '(')))
      *ps = 0;
  }
  else if (makeIs(LIBRAW_CAMERAMAKER_Minolta) ||
           makeIs(LIBRAW_CAMERAMAKER_Konica))
  {
    if (makeIs(LIBRAW_CAMERAMAKER_Konica) && !strncasecmp(model, "DiMAGE", 6))
    {
	  setMakeFromIndex(LIBRAW_CAMERAMAKER_Minolta);
      strcpy(make, "Minolta");
    }
    else
    {
      for (i = 0;
           i < sizeof KonicaMinolta_aliases / sizeof *KonicaMinolta_aliases;
           i++)
      {
        if (KonicaMinolta_aliases[i][0] == '@')
        {
          orig = KonicaMinolta_aliases[i] + 1;
          if (!strcmp(model, orig))
          {
			setMakeFromIndex(LIBRAW_CAMERAMAKER_Minolta);
            strcpy(make, "Minolta");
            break;
          }
        }
        else if (!strcmp(model, KonicaMinolta_aliases[i]))
        {
		  setMakeFromIndex(LIBRAW_CAMERAMAKER_Minolta);
          strcpy(make, "Minolta");
          strcpy(normalized_model, orig);
          break;
        }
      }
    }
  }
  else if (makeIs(LIBRAW_CAMERAMAKER_Nikon))
  {
    for (i = 0; i < sizeof nikonalias / sizeof *nikonalias; i++)
    {
      if (nikonalias[i][0] == '@')
      {
        orig = nikonalias[i] + 1;
        if (!strcmp(model, orig))
        {
          break;
        }
      }
      else if (!strcmp(model, nikonalias[i]))
      {
        strcpy(normalized_model, orig);
        break;
      }
    }
  }
  else if (makeIs(LIBRAW_CAMERAMAKER_Olympus))
  {
    for (i = 0; i < sizeof olyalias / sizeof *olyalias; i++)
    {
      if (olyalias[i][0] == '@')
      {
        orig = olyalias[i] + 1;
        if (!strcmp(model, orig))
        {
          break;
        }
      }
      else if (!strcmp(model, olyalias[i]))
      {
        strcpy(normalized_model, orig);
        break;
      }
    }
  }
  else if (makeIs(LIBRAW_CAMERAMAKER_Panasonic) ||
           makeIs(LIBRAW_CAMERAMAKER_Leica) ||
           makeIs(LIBRAW_CAMERAMAKER_Yuneec))
  {
    for (i = 0; i < sizeof panalias / sizeof *panalias; i++)
    {
      if (panalias[i][0] == '@')
      {
        orig = panalias[i] + 1;
        if (!strcmp(model, orig))
        {
          break;
        }
      }
      else if (!strcmp(model, panalias[i]))
      {
   	    setMakeFromIndex(LIBRAW_CAMERAMAKER_Panasonic);
        strcpy(normalized_model, orig);
        break;
      }
    }
  } else if (makeIs(LIBRAW_CAMERAMAKER_Pentax)) {
    for (i = 0; i < sizeof SamsungPentax_aliases / sizeof *SamsungPentax_aliases; i++) {
      if (SamsungPentax_aliases[i][0] == '@') {
        orig = SamsungPentax_aliases[i] + 1;
        if (!strcmp(model, orig)) {
          break;
        }
      } else if (!strcmp(model, SamsungPentax_aliases[i])) {
        strcpy(normalized_model, orig);
        break;
      }
    }
    if (!strncmp(model, "GR", 2)) {
	  setMakeFromIndex(LIBRAW_CAMERAMAKER_Ricoh);
      strcpy(make, "Ricoh");
    }

  } else if (makeIs(LIBRAW_CAMERAMAKER_PhaseOne))
  {
    for (i = 0; i < sizeof phase1alias / sizeof *phase1alias; i++)
    {
      if (phase1alias[i][0] == '@')
      {
        orig = phase1alias[i] + 1;
        if (!strcmp(model, orig))
        {
          break;
        }
      }
      else if (!strcmp(model, phase1alias[i]))
      {
        strcpy(normalized_model, orig);
        break;
      }
    }
  }
  else if (makeIs(LIBRAW_CAMERAMAKER_Samsung))
  {
    j = 0;
    if (strstr(model, "WB5500"))
    {
      strcpy(model, "WB5500");
      j++;
    }
    else if (strstr(model, "WB5000"))
    {
      strcpy(model, "WB5000");
      j++;
    }
    else if (strstr(model, "WB550"))
    {
      strcpy(model, "WB550");
      j++;
    }
    else if (strstr(model, "WB500"))
    {
      strcpy(model, "WB500");
      j++;
    }
    if (j)
    {
      strcpy(normalized_model, model);
    }
    else
    {
      for (i = 0; i < sizeof samsungalias / sizeof *samsungalias; i++)
      {
        if (samsungalias[i][0] == '@')
        {
          orig = samsungalias[i] + 1;
          if (!strcmp(model, orig))
          {
            break;
          }
        }
        else if (!strcmp(model, samsungalias[i]))
        {
          strcpy(normalized_model, orig);
          break;
        }
      }
      // re-badged Pentax cameras, CamIDs differ from original Pentax models
      for (i = 0;
           i < sizeof SamsungPentax_aliases / sizeof *SamsungPentax_aliases;
           i++)
      {
        if (SamsungPentax_aliases[i][0] == '@')
        {
          orig = SamsungPentax_aliases[i] + 1;
        }
        else if (!strcmp(model, SamsungPentax_aliases[i]))
        {
		  setMakeFromIndex(LIBRAW_CAMERAMAKER_Pentax);
          strcpy(normalized_model, orig);
          break;
        }
      }
    }

  } else if (makeIs(LIBRAW_CAMERAMAKER_Sony)) {
    if (unique_id)
    {
      for (i = 0; i < sizeof sonique / sizeof *sonique; i++)
      {
        if (unique_id == sonique[i].id)
        {
          if (!strcmp(make, "Sony"))
            strcpy(model, sonique[i].t_model);
          strcpy(normalized_model, sonique[i].t_model);
          break;
        }
      }
    }

  } else if (makeIs(LIBRAW_CAMERAMAKER_Kodak)) {
    remove_caseSubstr (normalized_model, (char *)"EasyShare");
    remove_caseSubstr (normalized_model, (char *)"ZOOM");
    removeExcessiveSpaces (normalized_model);
    for (i = 0; i < sizeof kodakalias / sizeof *kodakalias; i++)
    {
      if (kodakalias[i][0] == '@')
      {
        orig = kodakalias[i] + 1;
        if (!strcmp(model, orig))
        {
          break;
        }
      }
      else if (!strcmp(model, kodakalias[i]))
      {
        strcpy(normalized_model, orig);
        break;
      }
    }

    if (strstr(model, "DC25"))
    {
      strcpy(model, "DC25");
      strcpy(normalized_model, model);
    }
    else if (!strcmp(model, "40"))
    {
      strcpy(model, "DC40");
      strcpy(normalized_model, model);
    }
    else if (strstr(model, "DC50"))
    {
      strcpy(model, "DC50");
      strcpy(normalized_model, model);
    }
    else if (strstr(model, "DC120"))
    {
      strcpy(model, "DC120");
      strcpy(normalized_model, model);
    }

    for (i = 0; i < sizeof KodakMonochrome / sizeof *KodakMonochrome; i++)
    {
      if (!strncmp(model, KodakMonochrome[i], strlen(KodakMonochrome[i])))
      {
        colors = 1;
        filters = 0;
      }
    }
  }

  if (ilm.body[0])
  {
    if ((ilm.CameraMount != LIBRAW_MOUNT_Hasselblad_V) &&
        !strncmp(ilm.body, "Hasselblad ", 11) &&
        ((ilm.body[11] == 'C') || (ilm.body[11] == '2') ||
         (ilm.body[11] == '5') || (ilm.body[11] == '9')))
    {
      ilm.CameraFormat = LIBRAW_FORMAT_66;
      ilm.CameraMount = LIBRAW_MOUNT_Hasselblad_V;
    }
    else if (!strncmp(ilm.body, "XF", 2) || !strncmp(ilm.body, "645DF", 5))
    {
      ilm.CameraMount = LIBRAW_MOUNT_Mamiya645;
      ilm.CameraFormat = LIBRAW_FORMAT_645;
    }
    else if (!strncmp(ilm.body, "Sinarcam", 2))
    {
      ilm.CameraMount = LIBRAW_MOUNT_LF;
      ilm.CameraFormat = LIBRAW_FORMAT_LF;
      strcat(ilm.body, " shutter system");
    }
  }

  if (makeIs(LIBRAW_CAMERAMAKER_Kodak))
  {
    if (((ilm.CameraMount == LIBRAW_MOUNT_DigitalBack) ||
         (ilm.CameraMount == LIBRAW_MOUNT_Unknown)) &&
        !strncmp(model2, "PB645", 5))
    {
      ilm.CameraFormat = LIBRAW_FORMAT_645;
      if (model2[5] == 'C')
      {
        ilm.CameraMount = LIBRAW_MOUNT_Contax645;
        strcpy(ilm.body, "Contax 645");
      }
      else if (model2[5] == 'H')
      {
        ilm.CameraMount = LIBRAW_MOUNT_Hasselblad_H;
        strcpy(ilm.body, "Hasselblad H1/H2");
      }
      else if (model2[5] == 'M')
      {
        ilm.CameraMount = LIBRAW_MOUNT_Mamiya645;
        strcpy(ilm.body, "Mamiya 645");
      }
    }
  }
  else if (makeIs(LIBRAW_CAMERAMAKER_Fujifilm))
  {
    if (!strncmp(normalized_model, "DBP", 3))
    {
      strcpy(ilm.body, "Fujifilm GX680");
    }
  }

  if ((ilm.CameraFormat == LIBRAW_FORMAT_Unknown) ||
      (ilm.CameraMount == LIBRAW_MOUNT_Unknown) ||
      (ilm.CameraMount == LIBRAW_MOUNT_IL_UM))
  {

    if (makeIs(LIBRAW_CAMERAMAKER_Canon))
    {
      if (strncmp(normalized_model, "EOS", 3))
      {
        ilm.CameraMount = LIBRAW_MOUNT_FixedLens;
      }
    }
    else if (makeIs(LIBRAW_CAMERAMAKER_Nikon))
    {
      if (normalized_model[0] == 'D')
      {
        ilm.CameraMount = LIBRAW_MOUNT_Nikon_F;
      }
      else
      {
        ilm.CameraMount = LIBRAW_MOUNT_FixedLens;
      }
    }
    else if (makeIs(LIBRAW_CAMERAMAKER_Panasonic))
    {
      if (!strncmp(normalized_model, "DC-S", 4))
      {
        ilm.CameraFormat = LIBRAW_FORMAT_FF;
        ilm.CameraMount = LIBRAW_MOUNT_Leica_L;
      }
      else if (!strncmp(normalized_model, "DMC-L1", 6) ||
               !strncmp(normalized_model, "DMC-L10", 7))
      {
        ilm.CameraFormat = ilm.CameraMount = LIBRAW_FORMAT_FT;
      }
      else if (!strncmp(normalized_model + 2, "-G", 2) ||
               !strncmp(normalized_model + 3, "-G", 2))
      {
        ilm.CameraFormat = LIBRAW_FORMAT_FT;
        ilm.CameraMount = LIBRAW_MOUNT_mFT;
      }
      else
      {
        ilm.CameraMount = LIBRAW_MOUNT_FixedLens;
        ilm.FocalType = LIBRAW_FT_ZOOM_LENS;
        if (!strncmp(normalized_model + 2, "-LX100", 6) || // DC-LX100M2
            !strncmp(normalized_model + 3, "-LX100", 6))
        { // DMC-LX100
          ilm.CameraFormat = ilm.LensFormat = LIBRAW_FORMAT_FT;
        }
        else if (!strncmp(normalized_model, "DMC-CM1", 7))
        {
          ilm.FocalType = LIBRAW_FT_PRIME_LENS;
        }
      }
    }
    else if (makeIs(LIBRAW_CAMERAMAKER_Fujifilm))
    {
      if (!strncmp(normalized_model, "GFX ", 4))
      {
        ilm.CameraFormat = LIBRAW_FORMAT_CROP645;
        ilm.CameraMount = LIBRAW_MOUNT_Fuji_GF;
      }
      else if (!strncmp(normalized_model, "X-", 2) &&
               strncmp(normalized_model, "X-S1", 4))
      {
        ilm.CameraFormat = LIBRAW_FORMAT_APSC;
        ilm.CameraMount = LIBRAW_MOUNT_Fuji_X;
      }
      else if (((normalized_model[0] == 'S') && // S2Pro, S3Pro, S5Pro
                (normalized_model[2] == 'P')) ||
               !strncasecmp(normalized_model, "IS Pro", 6))
      {
        ilm.CameraFormat = LIBRAW_FORMAT_APSC;
        ilm.CameraMount = LIBRAW_MOUNT_Nikon_F;
      }
      else if (!strncmp(normalized_model, "DBP", 3))
      {
        ilm.CameraFormat = LIBRAW_FORMAT_68;
        ilm.CameraMount = LIBRAW_MOUNT_Fuji_GX;
      }
      else
      {
        ilm.CameraMount = LIBRAW_MOUNT_FixedLens;
      }
    }
    else if (makeIs(LIBRAW_CAMERAMAKER_Samsung))
    {
      if ((normalized_model[0] == 'N') && (normalized_model[1] == 'X'))
      { // DNG converters delete makernotes
        if ((normalized_model[2] == 'F') && (normalized_model[3] == '1'))
        {
          ilm.CameraMount = LIBRAW_MOUNT_Samsung_NX_M;
          ilm.CameraFormat = LIBRAW_FORMAT_1INCH;
        }
        else
        {
          ilm.CameraMount = LIBRAW_MOUNT_Samsung_NX;
          ilm.CameraFormat = LIBRAW_FORMAT_APSC;
        }
      }
      else
      {
        ilm.CameraMount = LIBRAW_MOUNT_FixedLens;
      }
    }
    else if (makeIs(LIBRAW_CAMERAMAKER_Kodak))
    {
      ilm.CameraMount = LIBRAW_MOUNT_FixedLens;
      for (i = 0; i < sizeof Kodak_mounts / sizeof *Kodak_mounts; i++)
      {
        if (!strncmp(normalized_model, Kodak_mounts[i].Kmodel,
                     strlen(Kodak_mounts[i].Kmodel)))
        {
          ilm.CameraMount = Kodak_mounts[i].mount;
          break;
        }
      }
    }
    else if (makeIs(LIBRAW_CAMERAMAKER_Minolta))
    {
      if (!strcmp(normalized_model, "Dynax 5D") ||
          !strcmp(normalized_model, "Dynax 7D"))
      {
        ilm.CameraFormat = LIBRAW_FORMAT_APSC;
        ilm.CameraMount = LIBRAW_MOUNT_Minolta_A;
      }
      else if (!strncasecmp(normalized_model, "DiMAGE", 6))
      {
        ilm.CameraMount = LIBRAW_MOUNT_FixedLens;
      }
    }
    else if (makeIs(LIBRAW_CAMERAMAKER_Casio) ||
             makeIs(LIBRAW_CAMERAMAKER_Creative))
    {
      ilm.CameraMount = LIBRAW_MOUNT_FixedLens;
    }
    else if (makeIs(LIBRAW_CAMERAMAKER_Sigma))
    {
      if (!strncmp(normalized_model, "fp", 2))
      {
        ilm.CameraFormat = LIBRAW_FORMAT_FF;
        ilm.CameraMount = LIBRAW_MOUNT_Sigma_X3F;
      }
      else if (!strncasecmp(normalized_model, "SD", 2))
      {
        ilm.CameraMount = LIBRAW_MOUNT_Sigma_X3F;
        if (!strcmp(normalized_model, "SD1") || (normalized_model[4] == 'M'))
        {
          ilm.CameraFormat = LIBRAW_FORMAT_SigmaMerrill;
        }
        else if (normalized_model[11] == 'H')
        { // 'sd Quattro H'
          ilm.CameraFormat = LIBRAW_FORMAT_SigmaAPSH;
        }
        else if (normalized_model[4] == 'Q')
        { // 'sd Quattro'
          ilm.CameraFormat = LIBRAW_FORMAT_APSC;
        }
        else
        {
          ilm.CameraFormat = LIBRAW_FORMAT_SigmaAPSC;
        }
      }
      else if (!strncasecmp(normalized_model, "DP", 2))
      {
        ilm.CameraMount = LIBRAW_MOUNT_FixedLens;
        if (normalized_model[4] == 'M')
        {
          ilm.CameraFormat = LIBRAW_FORMAT_SigmaMerrill;
        }
        else if (normalized_model[4] == 'Q')
        {
          ilm.CameraFormat = LIBRAW_FORMAT_APSC;
        }
        else
        {
          ilm.CameraFormat = LIBRAW_FORMAT_SigmaAPSC;
        }
      }
    }
    else if (makeIs(LIBRAW_CAMERAMAKER_Konica))
    {
      if (!strncmp(model, "KD-", 3))
      { // Konica KD-400Z, KD-510Z
        ilm.CameraMount = LIBRAW_MOUNT_FixedLens;
      }
    }
    else if (makeIs(LIBRAW_CAMERAMAKER_Mamiya))
    {
      if (!strncmp(normalized_model, "ZD", 2))
      {
        ilm.CameraFormat = LIBRAW_FORMAT_3648;
        ilm.CameraMount = LIBRAW_MOUNT_Mamiya645;
      }
    }
    else if (makeIs(LIBRAW_CAMERAMAKER_Sony))
    {
      if (!strncmp(normalized_model, "XCD-", 4))
      {
        ilm.CameraMount = LIBRAW_MOUNT_C;
      }
      else if (!strncmp(normalized_model, "DSC-V3", 6) ||
               !strncmp(normalized_model, "DSC-F828", 8))
      {
        ilm.CameraMount = LIBRAW_MOUNT_FixedLens;
        imSony.CameraType = LIBRAW_SONY_DSC;
      }
    }
    else if (makeIs(LIBRAW_CAMERAMAKER_Polaroid) &&
             !strncmp(normalized_model, "x530", 4))
    {
      ilm.CameraMount = LIBRAW_MOUNT_FixedLens;
    }
    else if (makeIs(LIBRAW_CAMERAMAKER_Rollei) &&
             !strncmp(normalized_model, "d530flex", 8))
    {
      ilm.CameraMount = LIBRAW_MOUNT_FixedLens;
    }
    else if (makeIs(LIBRAW_CAMERAMAKER_Pentax) &&
             !strncmp(normalized_model, "Optio", 5)) {
        ilm.CameraMount = LIBRAW_MOUNT_FixedLens;
    }
    else if (makeIs(LIBRAW_CAMERAMAKER_Epson) &&
             !strncmp(normalized_model, "R-D1", 4))
    {
      ilm.CameraMount = LIBRAW_MOUNT_Leica_M;
      ilm.CameraFormat = LIBRAW_FORMAT_APSC;
    }
  }

  if (ilm.LensMount == LIBRAW_MOUNT_Unknown)
  {
    if (makeIs(LIBRAW_CAMERAMAKER_Samsung))
    {
      if ((imgdata.lens.Lens[0] == 'N') && (imgdata.lens.Lens[1] == 'X'))
      { // same DNG problem
        if (imgdata.lens.Lens[2] == '-')
        {
          ilm.LensMount = LIBRAW_MOUNT_Samsung_NX_M;
          ilm.LensFormat = LIBRAW_FORMAT_1INCH;
        }
        else
        {
          ilm.LensMount = LIBRAW_MOUNT_Samsung_NX;
          ilm.LensFormat = LIBRAW_FORMAT_APSC;
        }
      }
    }
  }

  if (ilm.LensID == -1)
  {
    if (makeIs(LIBRAW_CAMERAMAKER_Samsung))
    {
      if ((ilm.LensMount == LIBRAW_MOUNT_Samsung_NX) && (strlen(xmpdata) > 9) &&
          (ps = strstr(xmpdata, "LensID=\"(")))
      {
        ilm.LensID = atoi(ps + 9);
      }
    }
  }

  if (ilm.CameraMount == LIBRAW_MOUNT_FixedLens)
  {
    if (ilm.CameraFormat)
      ilm.LensFormat = ilm.CameraFormat;
    if (ilm.LensMount == LIBRAW_MOUNT_Unknown)
      ilm.LensMount = LIBRAW_MOUNT_FixedLens;
  }

  if ((ilm.CameraMount != LIBRAW_MOUNT_Unknown) &&
      (ilm.CameraMount != LIBRAW_MOUNT_FixedLens) &&
      (ilm.LensMount == LIBRAW_MOUNT_Unknown)) {
    if (ilm.LensID == -1) ilm.LensMount = LIBRAW_MOUNT_IL_UM;
    else ilm.LensMount = ilm.CameraMount;
    }

  if (normalized_model[0] && !CM_found)
    CM_found = adobe_coeff(maker_index, normalized_model);
}

Project: LibRaw

int my_progress_callback(void *d, enum LibRaw_progress p, int iteration,
                         int expected)
{
  char *passed = (char *)(d ? d : "default string"); // data passed to callback
                                                     // at set_callback stage

  if (verbosity > 2) // verbosity set by repeat -v switches
  {
    printf("CB: %s  pass %d of %d (data passed=%s)\n", libraw_strprogress(p),
           iteration, expected, passed);
  }
  else if (iteration == 0) // 1st iteration of each step
    printf("Starting %s (expecting %d iterations)\n", libraw_strprogress(p),
           expected);
  else if (iteration == expected - 1)
    printf("%s finished\n", libraw_strprogress(p));

  ///    if(++cnt>10) return 1; // emulate user termination on 10-th callback
  ///    call

  return 0; // always return 0 to continue processing
}

Project: LibRaw

void LibRaw::process_Sony_0x9050(uchar *buf, ushort len, unsigned long long id)
{
  ushort lid;
  uchar s[4];
  int c;

  if ((ilm.CameraMount != LIBRAW_MOUNT_Sony_E) &&
      (ilm.CameraMount != LIBRAW_MOUNT_FixedLens))
  {
    if (len < 2)
      return;
    if (buf[0])
      ilm.MaxAp4CurFocal =
          my_roundf(libraw_powf64l(
                        2.0f, ((float)SonySubstitution[buf[0]] / 8.0 - 1.06f) /
                                  2.0f) *
                    10.0f) /
          10.0f;

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

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

  if (ilm.CameraMount == LIBRAW_MOUNT_Sony_E)
  {
    if (len <= 0x108)
      return;
    parseSonyLensType2(
        SonySubstitution[buf[0x0108]], // LensType2 - Sony lens ids
        SonySubstitution[buf[0x0107]]);
  }

  if (len <= 0x10a)
    return;
  if ((ilm.LensID == -1) && (ilm.CameraMount == LIBRAW_MOUNT_Minolta_A) &&
      (buf[0x010a] | buf[0x0109]))
  {
    ilm.LensID = // LensType - Minolta/Sony lens ids
        SonySubstitution[buf[0x010a]] << 8 | SonySubstitution[buf[0x0109]];

    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;
    }
  }

  if ((id >= 0x11eULL) && (id <= 0x125ULL))
  {
    if (len <= 0x116)
      return;
    // "SLT-A65", "SLT-A77", "NEX-7", "NEX-VG20",
    // "SLT-A37", "SLT-A57", "NEX-F3", "Lunar"
    parseSonyLensFeatures(SonySubstitution[buf[0x115]],
                          SonySubstitution[buf[0x116]]);
  }
  else if (ilm.CameraMount != LIBRAW_MOUNT_FixedLens)
  {
    if (len <= 0x117)
      return;
    parseSonyLensFeatures(SonySubstitution[buf[0x116]],
                          SonySubstitution[buf[0x117]]);
  }

  if ((id == 0x15bULL) || // ILCE-7RM2
      (id == 0x15eULL) || // ILCE-7SM2
      (id == 0x162ULL) || // ILCA-99M2
      (id == 0x165ULL) || // ILCE-6300
      (id == 0x166ULL) || // ILCE-9
      (id == 0x168ULL) || // ILCE-6500
      (id == 0x16aULL) || // ILCE-7RM3
      (id == 0x16bULL) || // ILCE-7M3
      (id == 0x173ULL) || // ILCE-6400
      (id == 0x177ULL) || // ILCE-7RM4
      (id == 0x17aULL) || // ILCE-6600
      (id == 0x17bULL)    // ILCE-6100
  )
  {
    if (len <= 0x8d)
      return;
    unsigned long long b88 = SonySubstitution[buf[0x88]];
    unsigned long long b89 = SonySubstitution[buf[0x89]];
    unsigned long long b8a = SonySubstitution[buf[0x8a]];
    unsigned long long b8b = SonySubstitution[buf[0x8b]];
    unsigned long long b8c = SonySubstitution[buf[0x8c]];
    unsigned long long b8d = SonySubstitution[buf[0x8d]];
    sprintf(imgdata.shootinginfo.InternalBodySerial, "%06llx",
            (b88 << 40) + (b89 << 32) + (b8a << 24) + (b8b << 16) + (b8c << 8) +
                b8d);
  }
  else if (ilm.CameraMount == LIBRAW_MOUNT_Minolta_A)
  {
    if (len <= 0xf4)
      return;
    unsigned long long bf0 = SonySubstitution[buf[0xf0]];
    unsigned long long bf1 = SonySubstitution[buf[0xf1]];
    unsigned long long bf2 = SonySubstitution[buf[0xf2]];
    unsigned long long bf3 = SonySubstitution[buf[0xf3]];
    unsigned long long bf4 = SonySubstitution[buf[0xf4]];
    sprintf(imgdata.shootinginfo.InternalBodySerial, "%05llx",
            (bf0 << 32) + (bf1 << 24) + (bf2 << 16) + (bf3 << 8) + bf4);
  }
  else if ((ilm.CameraMount == LIBRAW_MOUNT_Sony_E) &&
           (id != 0x120ULL) && // not NEX-5N
           (id != 0x121ULL) && // not NEX-7
           (id != 0x122ULL)    // not NEX-VG20
  )
  {
    if (len <= 0x7f)
      return;
    unsigned b7c = SonySubstitution[buf[0x7c]];
    unsigned b7d = SonySubstitution[buf[0x7d]];
    unsigned b7e = SonySubstitution[buf[0x7e]];
    unsigned b7f = SonySubstitution[buf[0x7f]];
    sprintf(imgdata.shootinginfo.InternalBodySerial, "%04x",
            (b7c << 24) + (b7d << 16) + (b7e << 8) + b7f);
  }

  if ((imSony.ImageCount3_offset != 0xffff) &&
      (len >= (imSony.ImageCount3_offset + 4)))
  {
    FORC4 s[c] = SonySubstitution[buf[imSony.ImageCount3_offset + c]];
    imSony.ImageCount3 = sget4(s);
  }

  return;
}

Project: LibRaw

  int inline U(ushort3 &rgb) throw()
  {
    return yuv_cam[1][0] * rgb[0] + yuv_cam[1][1] * rgb[1] +
           yuv_cam[1][2] * rgb[2];
  }

Project: LibRaw

void print_1fun(FILE* outfile, LibRaw& MyCoolRawProcessor, std::string& fn)
{
	char frame[64] = "";
	snprintf(frame, 64, "rw %d rh %d lm %d tm %d", S.raw_width, S.raw_height,
		S.left_margin, S.top_margin);
	fprintf(outfile, "%s=%s=nFms %02d=%s=bps %02d=%s", P1.normalized_make, P1.normalized_model, P1.raw_count,
		MyCoolRawProcessor.unpack_function_name(), C.raw_bps, frame);
	fprintf(outfile, "\n");
}

Project: LibRaw

  void libraw_dcraw_clear_mem(libraw_processed_image_t *p)
  {
    LibRaw::dcraw_clear_mem(p);
  }

Project: LibRaw

void LibRaw::panasonicC7_load_raw()
{
  const int rowstep = 16;
  int pixperblock = libraw_internal_data.unpacker_data.pana_bpp == 14 ? 9 : 10;
  int rowbytes = imgdata.sizes.raw_width / pixperblock * 16;
  unsigned char *iobuf = (unsigned char *)malloc(rowbytes * rowstep);
  merror(iobuf, "panasonicC7_load_raw()");
  for (int row = 0; row < imgdata.sizes.raw_height - rowstep + 1;
       row += rowstep)
  {
    int rowstoread = MIN(rowstep, imgdata.sizes.raw_height - row);
    if (libraw_internal_data.internal_data.input->read(
            iobuf, rowbytes, rowstoread) != rowstoread)
      throw LIBRAW_EXCEPTION_IO_EOF;
    unsigned char *bytes = iobuf;
    for (int crow = 0; crow < rowstoread; crow++)
    {
      unsigned short *rowptr =
          &imgdata.rawdata
               .raw_image[(row + crow) * imgdata.sizes.raw_pitch / 2];
      for (int col = 0; col < imgdata.sizes.raw_width - pixperblock + 1;
           col += pixperblock, bytes += 16)
      {
        if (libraw_internal_data.unpacker_data.pana_bpp == 14)
        {
          rowptr[col] = bytes[0] + ((bytes[1] & 0x3F) << 8);
          rowptr[col + 1] =
              (bytes[1] >> 6) + 4 * (bytes[2]) + ((bytes[3] & 0xF) << 10);
          rowptr[col + 2] =
              (bytes[3] >> 4) + 16 * (bytes[4]) + ((bytes[5] & 3) << 12);
          rowptr[col + 3] = ((bytes[5] & 0xFC) >> 2) + (bytes[6] << 6);
          rowptr[col + 4] = bytes[7] + ((bytes[8] & 0x3F) << 8);
          rowptr[col + 5] =
              (bytes[8] >> 6) + 4 * bytes[9] + ((bytes[10] & 0xF) << 10);
          rowptr[col + 6] =
              (bytes[10] >> 4) + 16 * bytes[11] + ((bytes[12] & 3) << 12);
          rowptr[col + 7] = ((bytes[12] & 0xFC) >> 2) + (bytes[13] << 6);
          rowptr[col + 8] = bytes[14] + ((bytes[15] & 0x3F) << 8);
        }
        else if (libraw_internal_data.unpacker_data.pana_bpp ==
                 12) // have not seen in the wild yet
        {
          rowptr[col] = ((bytes[1] & 0xF) << 8) + bytes[0];
          rowptr[col + 1] = 16 * bytes[2] + (bytes[1] >> 4);
          rowptr[col + 2] = ((bytes[4] & 0xF) << 8) + bytes[3];
          rowptr[col + 3] = 16 * bytes[5] + (bytes[4] >> 4);
          rowptr[col + 4] = ((bytes[7] & 0xF) << 8) + bytes[6];
          rowptr[col + 5] = 16 * bytes[8] + (bytes[7] >> 4);
          rowptr[col + 6] = ((bytes[10] & 0xF) << 8) + bytes[9];
          rowptr[col + 7] = 16 * bytes[11] + (bytes[10] >> 4);
          rowptr[col + 8] = ((bytes[13] & 0xF) << 8) + bytes[12];
          rowptr[col + 9] = 16 * bytes[14] + (bytes[13] >> 4);
        }
      }
    }
  }
  free(iobuf);
}

Project: LibRaw

void timerprint(const char *msg, const char *filename)
{
  gettimeofday(&end, NULL);
  float msec = (end.tv_sec - start.tv_sec) * 1000.0f +
               (end.tv_usec - start.tv_usec) / 1000.0f;
  printf("Timing: %s/%s: %6.3f msec\n", filename, msg, msec);
}

Project: LibRaw

int LibRaw_file_datastream::seek(INT64 o, int whence)
{
  LR_STREAM_CHK();
  std::ios_base::seekdir dir;
  switch (whence)
  {
  case SEEK_SET:
    dir = std::ios_base::beg;
    break;
  case SEEK_CUR:
    dir = std::ios_base::cur;
    break;
  case SEEK_END:
    dir = std::ios_base::end;
    break;
  default:
    dir = std::ios_base::beg;
  }
  return f->pubseekoff((long)o, dir) < 0;
}

Project: LibRaw

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

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

Project: LibRaw

int main(int ac, char *av[])
{
	if (ac < 4)
	{
		usage(av[0]);
		exit(1);
	}
	int colstart = atoi(av[2]);
	int rowstart = atoi(av[3]);
	int channel = 0;
	if (ac > 4) channel = atoi(av[4]);
	int width = 16;
	if (ac > 5) width = atoi(av[5]);
	int height = 4;
	if (ac > 6) height = atoi(av[6]);
	if (width <1 || height<1)
	{
		usage(av[0]);
		exit(1);
	}

	LibRaw_bl lr;

	if (lr.open_file(av[1]) != LIBRAW_SUCCESS)
	{
		fprintf(stderr, "Unable to open file %s\n", av[1]);
		exit(1);
	}
	if ((lr.imgdata.idata.colors == 1 && channel>0) || (channel >3))
	{
		fprintf(stderr, "Incorrect CHANNEL specified: %d\n", channel);
		exit(1);
	}
	if (lr.unpack() != LIBRAW_SUCCESS)
	{
		fprintf(stderr, "Unable to unpack raw data from %s\n", av[1]);
		exit(1);
	}
	lr.adjust_blacklevel();
	printf("%s\t%d-%d-%dx%d\tchannel: %d\n", av[1], colstart, rowstart, width, height, channel);

	printf("%6s", "R\\C");
	for (int col = colstart; col < colstart + width && col < lr.imgdata.sizes.raw_width; col++)
		printf("%6u", col);
	printf("\n");

	if (lr.imgdata.rawdata.raw_image)
	{
		for (int row = rowstart; row < rowstart + height && row < lr.imgdata.sizes.raw_height; row++)
		{
			unsigned rcolors[48];
			if (lr.imgdata.idata.colors > 1)
				for (int c = 0; c < 48; c++)
					rcolors[c] = lr.COLOR(row, c);
			else
				memset(rcolors, 0, sizeof(rcolors));
			unsigned short *rowdata = &lr.imgdata.rawdata.raw_image[row * lr.imgdata.sizes.raw_pitch / 2];
			printf("%6u", row);
			for (int col = colstart; col < colstart + width && col < lr.imgdata.sizes.raw_width; col++)
				if (rcolors[col % 48] == channel) printf("%6u", subtract_bl(rowdata[col],lr.imgdata.color.cblack[channel]));
				else printf("     -");
			printf("\n");
		}
	}
	else if (lr.imgdata.rawdata.color4_image && channel < 4)
	{
		for (int row = rowstart; row < rowstart + height && row < lr.imgdata.sizes.raw_height; row++)
		{
			unsigned short(*rowdata)[4] = &lr.imgdata.rawdata.color4_image[row * lr.imgdata.sizes.raw_pitch / 8];
			printf("%6u", row);
			for (int col = colstart; col < colstart + width && col < lr.imgdata.sizes.raw_width; col++)
				printf("%6u", subtract_bl(rowdata[col][channel],lr.imgdata.color.cblack[channel]));
			printf("\n");
		}
	}
	else if (lr.imgdata.rawdata.color3_image && channel < 3)
	{
		for (int row = rowstart; row < rowstart + height && row < lr.imgdata.sizes.raw_height; row++)
		{
			unsigned short(*rowdata)[3] = &lr.imgdata.rawdata.color3_image[row * lr.imgdata.sizes.raw_pitch / 6];
			printf("%6u", row);
			for (int col = colstart; col < colstart + width && col < lr.imgdata.sizes.raw_width; col++)
				printf("%6u", subtract_bl(rowdata[col][channel],lr.imgdata.color.cblack[channel]));
			printf("\n");
		}
	}
	else
		printf("Unsupported file data (e.g. floating point format), or incorrect channel specified\n");
}

Project: LibRaw

  ~libraw_dng_stream()
  {
    if (parent_stream)
      parent_stream->seek(off, SEEK_SET);
  }

Project: LibRaw

  virtual const wchar_t *wfname() { return NULL; };

Project: LibRaw

int LibRaw_file_datastream::eof()
{
  LR_STREAM_CHK();
  return f->sgetc() == EOF;
}

Project: LibRaw
File: dcraw.c

static ushort saneSonyCameraInfo(uchar a, uchar b, uchar c, uchar d, uchar e,
                                 uchar f)
{
  if ((a >> 4) > 9)
    return 0;
  else if ((a & 0x0f) > 9)
    return 0;
  else if ((b >> 4) > 9)
    return 0;
  else if ((b & 0x0f) > 9)
    return 0;
  else if ((c >> 4) > 9)
    return 0;
  else if ((c & 0x0f) > 9)
    return 0;
  else if ((d >> 4) > 9)
    return 0;
  else if ((d & 0x0f) > 9)
    return 0;
  else if ((e >> 4) > 9)
    return 0;
  else if ((e & 0x0f) > 9)
    return 0;
  else if ((f >> 4) > 9)
    return 0;
  else if ((f & 0x0f) > 9)
    return 0;
  return 1;
}

Project: LibRaw

void DHT::restore_hots()
{
  int iwidth = libraw.imgdata.sizes.iwidth;
#if defined(LIBRAW_USE_OPENMP)
#ifdef _MSC_VER
#pragma omp parallel for firstprivate(iwidth)
#else
#pragma omp parallel for schedule(guided) firstprivate(iwidth) collapse(2)
#endif
#endif
  for (int i = 0; i < libraw.imgdata.sizes.iheight; ++i)
  {
    for (int j = 0; j < iwidth; ++j)
    {
      int x = j + nr_leftmargin;
      int y = i + nr_topmargin;
      if (ndir[nr_offset(y, x)] & HOT)
      {
        int l = libraw.COLOR(i, j);
        nraw[nr_offset(i + nr_topmargin, j + nr_leftmargin)][l] =
            libraw.imgdata.image[i * iwidth + j][l];
      }
    }
  }
}

Project: LibRaw

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

Project: LibRaw

void LibRaw::canon_600_correct()
{
  int row, col, val;
  static const short mul[4][2] = {
      {1141, 1145}, {1128, 1109}, {1178, 1149}, {1128, 1109}};

  for (row = 0; row < height; row++)
  {
    checkCancel();
    for (col = 0; col < width; col++)
    {
      if ((val = BAYER(row, col) - black) < 0)
        val = 0;
      val = val * mul[row & 3][col & 1] >> 9;
      BAYER(row, col) = val;
    }
  }
  canon_600_fixed_wb(1311);
  canon_600_auto_wb();
  canon_600_coeff();
  maximum = (0x3ff - black) * 1109 >> 9;
  black = 0;
}

Project: LibRaw

void AAHD::evaluate_ahd()
{
  int hvdir[4] = {Pw, Pe, Pn, Ps};
  /*
   * YUV
   *
   */
  for (int d = 0; d < 2; ++d)
  {
    for (int i = 0; i < nr_width * nr_height; ++i)
    {
      ushort3 rgb;
      for (int c = 0; c < 3; ++c)
      {
        rgb[c] = gammaLUT[rgb_ahd[d][i][c]];
      }
      yuv[d][i][0] = Y(rgb);
      yuv[d][i][1] = U(rgb);
      yuv[d][i][2] = V(rgb);
    }
  }
  /* */
  /*
   * Lab
   *
   float r, cbrt[0x10000], xyz[3], xyz_cam[3][4];
   for (int i = 0; i < 0x10000; i++) {
   r = i / 65535.0;
   cbrt[i] = r > 0.008856 ? pow((double) r, (double) (1 / 3.0)) : 7.787 * r + 16
   / 116.0;
   }
   for (int i = 0; i < 3; i++)
   for (int j = 0; j < 3; j++) {
   xyz_cam[i][j] = 0;
   for (int k = 0; k < 3; k++)
   xyz_cam[i][j] += xyz_rgb[i][k] * libraw.imgdata.color.rgb_cam[k][j] /
   d65_white[i];
   }
   for (int d = 0; d < 2; ++d)
   for (int i = 0; i < libraw.imgdata.sizes.iheight; ++i) {
   int moff = nr_offset(i + nr_margin, nr_margin);
   for (int j = 0; j < libraw.imgdata.sizes.iwidth; j++, ++moff) {
   xyz[0] = xyz[1] = xyz[2] = 0.5;
   for (int c = 0; c < 3; c++) {
   xyz[0] += xyz_cam[0][c] * rgb_ahd[d][moff][c];
   xyz[1] += xyz_cam[1][c] * rgb_ahd[d][moff][c];
   xyz[2] += xyz_cam[2][c] * rgb_ahd[d][moff][c];
   }
   xyz[0] = cbrt[CLIP((int) xyz[0])];
   xyz[1] = cbrt[CLIP((int) xyz[1])];
   xyz[2] = cbrt[CLIP((int) xyz[2])];
   yuv[d][moff][0] = 64 * (116 * xyz[1] - 16);
   yuv[d][moff][1] = 64 * 500 * (xyz[0] - xyz[1]);
   yuv[d][moff][2] = 64 * 200 * (xyz[1] - xyz[2]);
   }
   }
   * Lab */
  for (int i = 0; i < libraw.imgdata.sizes.iheight; ++i)
  {
    int moff = nr_offset(i + nr_margin, nr_margin);
    for (int j = 0; j < libraw.imgdata.sizes.iwidth; j++, ++moff)
    {
      int3 *ynr;
      float ydiff[2][4];
      int uvdiff[2][4];
      for (int d = 0; d < 2; ++d)
      {
        ynr = &yuv[d][moff];
        for (int k = 0; k < 4; k++)
        {
          ydiff[d][k] = ABS(ynr[0][0] - ynr[hvdir[k]][0]);
          uvdiff[d][k] = SQR(ynr[0][1] - ynr[hvdir[k]][1]) +
                         SQR(ynr[0][2] - ynr[hvdir[k]][2]);
        }
      }
      float yeps =
          MIN(MAX(ydiff[0][0], ydiff[0][1]), MAX(ydiff[1][2], ydiff[1][3]));
      int uveps =
          MIN(MAX(uvdiff[0][0], uvdiff[0][1]), MAX(uvdiff[1][2], uvdiff[1][3]));
      for (int d = 0; d < 2; d++)
      {
        ynr = &yuv[d][moff];
        for (int k = 0; k < 4; k++)
          if (ydiff[d][k] <= yeps && uvdiff[d][k] <= uveps)
          {
            homo[d][moff + hvdir[k]]++;
            if (k / 2 == d)
            {
              // если в сонаправленном направлении интеполяции следующие точки
              // так же гомогенны, учтём их тоже
              for (int m = 2; m < 4; ++m)
              {
                int hvd = m * hvdir[k];
                if (ABS(ynr[0][0] - ynr[hvd][0]) < yeps &&
                    SQR(ynr[0][1] - ynr[hvd][1]) +
                            SQR(ynr[0][2] - ynr[hvd][2]) <
                        uveps)
                {
                  homo[d][moff + hvd]++;
                }
                else
                  break;
              }
            }
          }
      }
    }
  }
  for (int i = 0; i < libraw.imgdata.sizes.iheight; ++i)
  {
    int moff = nr_offset(i + nr_margin, nr_margin);
    for (int j = 0; j < libraw.imgdata.sizes.iwidth; j++, ++moff)
    {
      char hm[2];
      for (int d = 0; d < 2; d++)
      {
        hm[d] = 0;
        char *hh = &homo[d][moff];
        for (int hx = -1; hx < 2; hx++)
          for (int hy = -1; hy < 2; hy++)
            hm[d] += hh[nr_offset(hy, hx)];
      }
      char d = 0;
      if (hm[0] != hm[1])
      {
        if (hm[1] > hm[0])
        {
          d = VERSH;
        }
        else
        {
          d = HORSH;
        }
      }
      else
      {
        int3 *ynr = &yuv[1][moff];
        int gv = SQR(2 * ynr[0][0] - ynr[Pn][0] - ynr[Ps][0]);
        gv += SQR(2 * ynr[0][1] - ynr[Pn][1] - ynr[Ps][1]) +
              SQR(2 * ynr[0][2] - ynr[Pn][2] - ynr[Ps][2]);
        ynr = &yuv[1][moff + Pn];
        gv += (SQR(2 * ynr[0][0] - ynr[Pn][0] - ynr[Ps][0]) +
               SQR(2 * ynr[0][1] - ynr[Pn][1] - ynr[Ps][1]) +
               SQR(2 * ynr[0][2] - ynr[Pn][2] - ynr[Ps][2])) /
              2;
        ynr = &yuv[1][moff + Ps];
        gv += (SQR(2 * ynr[0][0] - ynr[Pn][0] - ynr[Ps][0]) +
               SQR(2 * ynr[0][1] - ynr[Pn][1] - ynr[Ps][1]) +
               SQR(2 * ynr[0][2] - ynr[Pn][2] - ynr[Ps][2])) /
              2;
        ynr = &yuv[0][moff];
        int gh = SQR(2 * ynr[0][0] - ynr[Pw][0] - ynr[Pe][0]);
        gh += SQR(2 * ynr[0][1] - ynr[Pw][1] - ynr[Pe][1]) +
              SQR(2 * ynr[0][2] - ynr[Pw][2] - ynr[Pe][2]);
        ynr = &yuv[0][moff + Pw];
        gh += (SQR(2 * ynr[0][0] - ynr[Pw][0] - ynr[Pe][0]) +
               SQR(2 * ynr[0][1] - ynr[Pw][1] - ynr[Pe][1]) +
               SQR(2 * ynr[0][2] - ynr[Pw][2] - ynr[Pe][2])) /
              2;
        ynr = &yuv[0][moff + Pe];
        gh += (SQR(2 * ynr[0][0] - ynr[Pw][0] - ynr[Pe][0]) +
               SQR(2 * ynr[0][1] - ynr[Pw][1] - ynr[Pe][1]) +
               SQR(2 * ynr[0][2] - ynr[Pw][2] - ynr[Pe][2])) /
              2;
        if (gv > gh)
          d = HOR;
        else
          d = VER;
      }
      ndir[moff] |= d;
    }
  }
}

Project: LibRaw

int LibRaw::try_rawspeed()
{
#ifdef USE_RAWSPEED
  int ret = LIBRAW_SUCCESS;

  int rawspeed_ignore_errors = 0;
  if (imgdata.idata.dng_version && imgdata.idata.colors == 3 &&
      !strcasecmp(imgdata.idata.software,
                  "Adobe Photoshop Lightroom 6.1.1 (Windows)"))
    rawspeed_ignore_errors = 1;

  // RawSpeed Supported,
  INT64 spos = ID.input->tell();
  void *_rawspeed_buffer = 0;
  try
  {
    ID.input->seek(0, SEEK_SET);
    INT64 _rawspeed_buffer_sz = ID.input->size() + 32;
    _rawspeed_buffer = malloc(_rawspeed_buffer_sz);
    if (!_rawspeed_buffer)
      throw LIBRAW_EXCEPTION_ALLOC;
    ID.input->read(_rawspeed_buffer, _rawspeed_buffer_sz, 1);
    FileMap map((uchar8 *)_rawspeed_buffer, _rawspeed_buffer_sz);
    RawParser t(&map);
    RawDecoder *d = 0;
    CameraMetaDataLR *meta =
        static_cast<CameraMetaDataLR *>(_rawspeed_camerameta);
    d = t.getDecoder();
    if (!d)
      throw "Unable to find decoder";
    try
    {
      d->checkSupport(meta);
    }
    catch (const RawDecoderException &e)
    {
      imgdata.process_warnings |= LIBRAW_WARN_RAWSPEED_UNSUPPORTED;
      throw e;
    }
    d->interpolateBadPixels = FALSE;
    d->applyStage1DngOpcodes = FALSE;
    _rawspeed_decoder = static_cast<void *>(d);
    d->decodeRaw();
    d->decodeMetaData(meta);
    RawImage r = d->mRaw;
    if (r->errors.size() > 0 && !rawspeed_ignore_errors)
    {
      delete d;
      _rawspeed_decoder = 0;
      throw 1;
    }
    if (r->isCFA)
    {
      imgdata.rawdata.raw_image = (ushort *)r->getDataUncropped(0, 0);
    }
    else if (r->getCpp() == 4)
    {
      imgdata.rawdata.color4_image = (ushort(*)[4])r->getDataUncropped(0, 0);
      if (r->whitePoint > 0 && r->whitePoint < 65536)
        C.maximum = r->whitePoint;
    }
    else if (r->getCpp() == 3)
    {
      imgdata.rawdata.color3_image = (ushort(*)[3])r->getDataUncropped(0, 0);
      if (r->whitePoint > 0 && r->whitePoint < 65536)
        C.maximum = r->whitePoint;
    }
    else
    {
      delete d;
      _rawspeed_decoder = 0;
      ret = LIBRAW_UNSPECIFIED_ERROR;
    }
    if (_rawspeed_decoder)
    {
      // set sizes
      iPoint2D rsdim = r->getUncroppedDim();
      S.raw_pitch = r->pitch;
      S.raw_width = rsdim.x;
      S.raw_height = rsdim.y;
      // C.maximum = r->whitePoint;
      fix_after_rawspeed(r->blackLevel);
    }
    free(_rawspeed_buffer);
    _rawspeed_buffer = 0;
    imgdata.process_warnings |= LIBRAW_WARN_RAWSPEED_PROCESSED;
  }
  catch (const RawDecoderException &RDE)
  {
    imgdata.process_warnings |= LIBRAW_WARN_RAWSPEED_PROBLEM;
    if (_rawspeed_buffer)
    {
      free(_rawspeed_buffer);
      _rawspeed_buffer = 0;
    }
    const char *p = RDE.what();
    if (!strncmp(RDE.what(), "Decoder canceled", strlen("Decoder canceled")))
      throw LIBRAW_EXCEPTION_CANCELLED_BY_CALLBACK;
    ret = LIBRAW_UNSPECIFIED_ERROR;
  }
  catch (...)
  {
    // We may get here due to cancellation flag
    imgdata.process_warnings |= LIBRAW_WARN_RAWSPEED_PROBLEM;
    if (_rawspeed_buffer)
    {
      free(_rawspeed_buffer);
      _rawspeed_buffer = 0;
    }
    ret = LIBRAW_UNSPECIFIED_ERROR;
  }
  ID.input->seek(spos, SEEK_SET);

  return ret;
#else
  return LIBRAW_NOT_IMPLEMENTED;
#endif
}

Project: LibRaw

int main(int ac, char *av[])
{
  int i, ret;

  LibRaw RawProcessor;
  if (ac < 2)
  {
    printf("multirender_test - LibRaw %s sample. Performs 4 different "
           "renderings of one file\n"
           " %d cameras supported\n"
           "Usage: %s raw-files....\n",
           LibRaw::version(), LibRaw::cameraCount(), av[0]);
    return 0;
  }

  for (i = 1; i < ac; i++)
  {

    printf("Processing file %s\n", av[i]);

    if ((ret = RawProcessor.open_file(av[i])) != LIBRAW_SUCCESS)
    {
      fprintf(stderr, "Cannot open_file %s: %s\n", av[i], libraw_strerror(ret));
      continue; // no recycle b/c open file will recycle itself
    }

    if ((ret = RawProcessor.unpack()) != LIBRAW_SUCCESS)
    {
      fprintf(stderr, "Cannot unpack %s: %s\n", av[i], libraw_strerror(ret));
      continue;
    }
    process_once(RawProcessor, 0, 0, 0, 1, -1, av[i]); // default flip
    process_once(RawProcessor, 1, 0, 1, 2, -1, av[i]);
    process_once(RawProcessor, 1, 1, 0, 3, -1, av[i]); // default flip
    process_once(RawProcessor, 1, 1, 0, 4, 1, av[i]);  // flip 1
    process_once(RawProcessor, 1, 1, 0, 5, 3, av[i]);  // flip 3
    process_once(RawProcessor, 1, 1, 0, 6, 1, av[i]);  // 1 again same as 4
    process_once(RawProcessor, 1, 1, 0, 7, -1,
                 av[i]); // default again, same as 3
    process_once(RawProcessor, 0, 0, 0, 8, -1, av[i]); // same as 1

    RawProcessor.recycle(); // just for show this call
  }
  return 0;
}

Project: LibRaw

void LibRaw::panasonicC6_load_raw()
{
  const int rowstep = 16;
  const int blocksperrow = imgdata.sizes.raw_width / 11;
  const int rowbytes = blocksperrow * 16;
  unsigned char *iobuf = (unsigned char *)malloc(rowbytes * rowstep);
  merror(iobuf, "panasonicC6_load_raw()");

  for (int row = 0; row < imgdata.sizes.raw_height - rowstep + 1;
       row += rowstep)
  {
    int rowstoread = MIN(rowstep, imgdata.sizes.raw_height - row);
    if (libraw_internal_data.internal_data.input->read(
            iobuf, rowbytes, rowstoread) != rowstoread)
      throw LIBRAW_EXCEPTION_IO_EOF;
    pana_cs6_page_decoder page(iobuf, rowbytes * rowstoread);
    for (int crow = 0, col = 0; crow < rowstoread; crow++, col = 0)
    {
      unsigned short *rowptr =
          &imgdata.rawdata
               .raw_image[(row + crow) * imgdata.sizes.raw_pitch / 2];
      for (int rblock = 0; rblock < blocksperrow; rblock++)
      {
        page.read_page();
        unsigned oddeven[2] = {0, 0}, nonzero[2] = {0, 0};
        unsigned pmul = 0, pixel_base = 0;
        for (int pix = 0; pix < 11; pix++)
        {
          if (pix % 3 == 2)
          {
            unsigned base = page.nextpixel();
            if (base > 3)
              throw LIBRAW_EXCEPTION_IO_CORRUPT; // not possible b/c of 2-bit
                                                 // field, but....
            if (base == 3)
              base = 4;
            pixel_base = 0x200 << base;
            pmul = 1 << base;
          }
          unsigned epixel = page.nextpixel();
          if (oddeven[pix % 2])
          {
            epixel *= pmul;
            if (pixel_base < 0x2000 && nonzero[pix % 2] > pixel_base)
              epixel += nonzero[pix % 2] - pixel_base;
            nonzero[pix % 2] = epixel;
          }
          else
          {
            oddeven[pix % 2] = epixel;
            if (epixel)
              nonzero[pix % 2] = epixel;
            else
              epixel = nonzero[pix % 2];
          }
          unsigned spix = epixel - 0xf;
          if (spix <= 0xffff)
            rowptr[col++] = spix & 0xffff;
          else
          {
            epixel = (((signed int)(epixel + 0x7ffffff1)) >> 0x1f);
            rowptr[col++] = epixel & 0x3fff;
          }
        }
      }
    }
  }
  free(iobuf);
}

Project: LibRaw

void timerstart(void) { QueryPerformanceCounter(&start); }

Project: LibRaw

  int FC(int row, int col)
  {
    return (imgdata.idata.filters >> (((row << 1 & 14) | (col & 1)) << 1) & 3);
  }

Project: LibRaw

int main(int ac, char *av[])
{
  int i, ret, output_thumbs = 0;

  // don't use fixed size buffers in real apps!

  LibRaw RawProcessor;

  if (ac < 2)
  {
    printf("mem_image - LibRaw sample, to illustrate work for memory buffers. "
           "Emulates dcraw [-4] [-1] [-e] [-h]\n"
           "Usage: %s [-D] [-T] [-v] [-e] raw-files....\n"
           "\t-6 - output 16-bit PPM\n"
           "\t-4 - linear 16-bit data\n"
           "\t-e - extract thumbnails (same as dcraw -e in separate run)\n",
           "\t-h - use half_size\n");
    return 0;
  }

  putenv((char *)"TZ=UTC"); // dcraw compatibility, affects TIFF datestamp field

#define P1 RawProcessor.imgdata.idata
#define S RawProcessor.imgdata.sizes
#define C RawProcessor.imgdata.color
#define T RawProcessor.imgdata.thumbnail
#define P2 RawProcessor.imgdata.other
#define OUT RawProcessor.imgdata.params

  for (i = 1; i < ac; i++)
  {
    if (av[i][0] == '-')
    {
      if (av[i][1] == '6' && av[i][2] == 0)
        OUT.output_bps = 16;
      if (av[i][1] == '4' && av[i][2] == 0)
      {
        OUT.output_bps = 16;
        OUT.gamm[0] = OUT.gamm[1] = OUT.no_auto_bright = 1;
      }
      if (av[i][1] == 'e' && av[i][2] == 0)
        output_thumbs++;
      if (av[i][1] == 'h' && av[i][2] == 0)
        OUT.half_size = 1;
      continue;
    }
    printf("Processing %s\n", av[i]);
    if ((ret = RawProcessor.open_file(av[i])) != LIBRAW_SUCCESS)
    {
      fprintf(stderr, "Cannot open %s: %s\n", av[i], libraw_strerror(ret));
      continue; // no recycle b/c open file will recycle itself
    }

    if ((ret = RawProcessor.unpack()) != LIBRAW_SUCCESS)
    {
      fprintf(stderr, "Cannot unpack %s: %s\n", av[i], libraw_strerror(ret));
      continue;
    }

    // we should call dcraw_process before thumbnail extraction because for
    // some cameras (i.e. Kodak ones) white balance for thumbnal should be set
    // from main image settings

    ret = RawProcessor.dcraw_process();

    if (LIBRAW_SUCCESS != ret)
    {
      fprintf(stderr, "Cannot do postpocessing on %s: %s\n", av[i],
              libraw_strerror(ret));
      if (LIBRAW_FATAL_ERROR(ret))
        continue;
    }
    libraw_processed_image_t *image = RawProcessor.dcraw_make_mem_image(&ret);
    if (image)
    {
      write_ppm(image, av[i]);
      LibRaw::dcraw_clear_mem(image);
    }
    else
      fprintf(stderr, "Cannot unpack %s to memory buffer: %s\n", av[i],
              libraw_strerror(ret));

    if (output_thumbs)
    {

      if ((ret = RawProcessor.unpack_thumb()) != LIBRAW_SUCCESS)
      {
        fprintf(stderr, "Cannot unpack_thumb %s: %s\n", av[i],
                libraw_strerror(ret));
        if (LIBRAW_FATAL_ERROR(ret))
          continue; // skip to next file
      }
      else
      {
        libraw_processed_image_t *thumb =
            RawProcessor.dcraw_make_mem_thumb(&ret);
        if (thumb)
        {
          write_thumb(thumb, av[i]);
          LibRaw::dcraw_clear_mem(thumb);
        }
        else
          fprintf(stderr,
                  "Cannot unpack thumbnail of %s to memory buffer: %s\n", av[i],
                  libraw_strerror(ret));
      }
    }

    RawProcessor.recycle(); // just for show this call
  }
  return 0;
}

Project: LibRaw

void LibRaw::parse_makernote(int base, int uptag)
{

  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, nonDNG);
    return;
  }
  else if (!strncasecmp(make, "LEICA", 5))
  {
    parseLeicaMakernote(base, uptag, is_0x927c);
    return;
  }

  if (!strncmp(make, "Nokia", 5))
    return;

  char buf[10];
  char another_buf[128];

  fseek(ifp, -12, SEEK_CUR);
  fread (another_buf, 1, 12, ifp);
  if (!strncmp(another_buf, "SONY", 4) ||
      !strncmp(another_buf, "VHAB", 4)) {
    is_Sony = 1;
  }

  fread(buf, 1, 10, ifp);

  if (!strncmp(buf, "KDK", 3) || /* these aren't TIFF tables */
      !strncmp(buf, "VER", 3) || !strncmp(buf, "IIII", 4) ||
      !strncmp(buf, "MMMM", 4))
    return;

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

  unsigned offset = 0, entries, tag, type, len, save, c;
  unsigned serial = 0, i, wb[4] = {0, 0, 0, 0};
  short morder, sorder = order;

  uchar *CanonCameraInfo;
  unsigned lenCanonCameraInfo = 0;
  unsigned typeCanonCameraInfo = 0;
  imCanon.wbi = 0;

  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;

  INT64 fsize = ifp->size();

  /*
       The MakerNote might have its own TIFF header (possibly with
       its own byte-order!), or it might just be a table.
  */

  if (!strncmp(buf, "KC", 2) || /* Konica KD-400Z, KD-510Z */
      !strncmp(buf, "MLY", 3))  /* Minolta DiMAGE G series */
  {
    order = 0x4d4d;
    while ((i = ftell(ifp)) < data_offset && i < 16384)
    {
      wb[0] = wb[2];
      wb[2] = wb[1];
      wb[1] = wb[3];
      wb[3] = get2();
      if (wb[1] == 256 && wb[3] == 256 && wb[0] > 256 && wb[0] < 640 &&
          wb[2] > 256 && wb[2] < 640)
        FORC4 cam_mul[c] = wb[c];
    }
    goto quit;
  }

  if (!strcmp(buf, "OLYMPUS") ||
      !strcmp(buf, "PENTAX "))
  {
    base = ftell(ifp) - 10;
    fseek(ifp, -2, SEEK_CUR);
    order = get2();
    if (buf[0] == 'O')
      get2();
  }
  else if (!strncmp(buf, "SONY", 4) ||
           !strncmp(buf, "VHAB", 4)) {
    is_Sony = 1;
    goto nf;
  }
  else if (!strcmp(buf, "Panasonic"))
  {
    goto nf;
  }
  else if (!strncmp(buf, "FUJIFILM", 8))
  {
    base = ftell(ifp) - 10;
  nf:
    order = 0x4949;
    fseek(ifp, 2, SEEK_CUR);
  }
  else if (!strcmp(buf, "OLYMP") ||
           !strncmp(buf, "LEICA", 5) ||
           !strcmp(buf, "Ricoh"))
  {
    fseek(ifp, -2, SEEK_CUR);
  }
  else if (!strcmp(buf, "AOC") ||
           !strcmp(buf, "QVC"))
  {
    fseek(ifp, -4, SEEK_CUR);
  }
  else if (!strncmp(buf, "CMT3", 4))
  {
    order = sget2((uchar *)(buf + 4));
    fseek(ifp, 2L, SEEK_CUR);
  }
  else if (libraw_internal_data.unpacker_data.CR3_CTMDtag)
  {
    order = sget2((uchar *)buf);
    fseek(ifp, -2L, SEEK_CUR);
  }
  else
  {
    fseek(ifp, -10, SEEK_CUR);
    if (!strncmp(make, "SAMSUNG", 7))
      base = ftell(ifp);
  }

  if (!is_Sony &&
      (!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;

  if (strcasestr(make, "Kodak") &&
      (sget2((uchar *)buf) > 1) && // check number of entries
      (sget2((uchar *)buf) < 128) &&
      (sget2((uchar *)(buf + 4)) > 0) && // check type
      (sget2((uchar *)(buf + 4)) < 13) &&
      (sget4((uchar *)(buf + 6)) < 256) // check count
  )
    imKodak.MakerNoteKodak8a = 1; // Kodak P712 / P850 / P880

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

  morder = order;
  while (entries--)
  {
    order = morder;
    tiff_get(base, &tag, &type, &len, &save);
    tag |= uptag << 16;

    INT64 _pos = ftell(ifp);
    INT64 _pos2;
    if (len > 100 * 1024 * 1024)
	goto next; // 100Mb tag? No!
    if (len > 8 && _pos + len > 2 * fsize)
    {
      fseek(ifp, save, SEEK_SET); // Recover tiff-read position!!
      continue;
    }
    if (imKodak.MakerNoteKodak8a)
    {
      if ((tag == 0xff00) && (type == 4) && (len == 1))
      {
        INT64 _pos1 = get4();
        if ((_pos1 < fsize) && (_pos1 > 0))
        {
          fseek(ifp, _pos1, SEEK_SET);
          parse_makernote(base, tag);
        }
      }
      else if (tag == 0xff00f90b)
      {
        imKodak.clipBlack = get2();
      }
      else if (tag == 0xff00f90c)
      {
        imKodak.clipWhite = imgdata.color.linear_max[0] =
            imgdata.color.linear_max[1] = imgdata.color.linear_max[2] =
                imgdata.color.linear_max[3] = get2();
      }
    }
    else 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, nonDNG);
          free(CanonCameraInfo);
          CanonCameraInfo = 0;
          lenCanonCameraInfo = 0;
        }
      }

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

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

    else if (!strncasecmp(model, "Hasselblad X1D", 14) ||
             !strncasecmp(model, "Hasselblad H6D", 14) ||
             !strncasecmp(model, "Hasselblad A6D", 14))
    {
      if (tag == 0x0045)
      {
        imHassy.BaseISO = get4();
      }
      else if (tag == 0x0046)
      {
        imHassy.Gain = getreal(type);
      }
    }

    else if (!strncmp(make, "PENTAX", 6) ||
             !strncmp(make, "RICOH", 5) ||
             !strncmp(model, "PENTAX", 6))
    {
      if (!strncmp(model, "GR", 2) ||
          !strncmp(model, "GXR", 3))
      {
        parseRicohMakernotes(base, tag, type, len, CameraDNG);
      }
      else
      {
        parsePentaxMakernotes(base, tag, type, len, nonDNG);
      }
    }

    else if (!strncmp(make, "SAMSUNG", 7))
    {
      if (!dng_version)
        parseSamsungMakernotes(base, tag, type, len, nonDNG);
      else
        parsePentaxMakernotes(base, tag, type, len, CameraDNG);
    }

    else if (is_Sony)
    {
      if ((tag == 0xb028) && (len == 1) && (type == 4))
      { // DSLR-A100
        if ((c = get4()))
        {
          fseek(ifp, c, SEEK_SET);
          parse_makernote(base, tag);
        }
      }
      else
      {
        parseSonyMakernotes(
            base, tag, type, len, nonDNG, 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);
      }
    }
    fseek(ifp, _pos, SEEK_SET);

    if (!strncasecmp(make, "Hasselblad", 10) && !is_Sony) {
      if (tag == 0x0011)
        imHassy.SensorCode = getint(type);
      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);
      }
    }

    if ((tag == 0x0004 || tag == 0x0114) && !strncmp(make, "KONICA", 6))
    {
      fseek(ifp, tag == 0x0004 ? 140 : 160, SEEK_CUR);
      switch (get2())
      {
      case 72:
        flip = 0;
        break;
      case 76:
        flip = 6;
        break;
      case 82:
        flip = 5;
        break;
      }
    }

    _pos2 = ftell(ifp);
    if (!strncasecmp(make, "Olympus", 7) ||
        (!strncasecmp(make, "CLAUSS", 6) && !strncasecmp(model, "piX 5oo", 7)))
    {
      if ((tag == 0x2010) || (tag == 0x2020) || (tag == 0x2030) ||
          (tag == 0x2031) || (tag == 0x2040) || (tag == 0x2050) ||
          (tag == 0x3000))
      {
        if (type == 7)
        {
          parse_makernote(base, tag);
        }
        else if (type == 13)
        {
          fseek(ifp, base + get4(), SEEK_SET);
          parse_makernote(base, tag);
        }
      }
      else if (tag == 0x0207)
      {
        getOlympus_CameraType2();
      }
      else if ((tag == 0x0404) || (tag == 0x101a))
      {
        if (!imgdata.shootinginfo.BodySerial[0])
          stmread(imgdata.shootinginfo.BodySerial, len, ifp);
      }
      else if (tag == 0x1002)
      {
        ilm.CurAp = libraw_powf64l(2.0f, getreal(type) / 2);
      }
      else if (tag == 0x1007)
      {
        imgdata.makernotes.common.SensorTemperature = (float)get2();
      }
      else if (tag == 0x1008)
      {
        imgdata.makernotes.common.LensTemperature = (float)get2();
      }
      else if ((tag == 0x1011) && strcmp(software, "v757-71"))
      {
        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 == 0x1012)
      {
        FORC4 cblack[c ^ c >> 1] = get2();
      }
      else if (tag == 0x1017)
      {
        cam_mul[0] = get2() / 256.0;
      }
      else if (tag == 0x1018)
      {
        cam_mul[2] = get2() / 256.0;
      }
      else if ((tag >= 0x20100000) && (tag <= 0x2010ffff))
      {
        parseOlympus_Equipment((tag & 0x0000ffff), type, len, nonDNG);
      }
      else if ((tag >= 0x20200000) && (tag <= 0x2020ffff))
      {
        parseOlympus_CameraSettings(base, (tag & 0x0000ffff), type, len,
                                    nonDNG);
      }
      else if ((tag == 0x20300108) || (tag == 0x20310109))
      {
        imOly.ColorSpace = get2();
      }
      else if ((tag >= 0x20400000) && (tag <= 0x2040ffff))
      {
        parseOlympus_ImageProcessing((tag & 0x0000ffff), type, len, nonDNG);
      }
      else if (tag == 0x20501500)
      {
        getOlympus_SensorTemperature(len);
      }
      else if ((tag >= 0x30000000) && (tag <= 0x3000ffff))
      {
        parseOlympus_RawInfo((tag & 0x0000ffff), type, len, nonDNG);
      }
    }
    fseek(ifp, _pos2, SEEK_SET);

    if (tag == 0x0015 && type == 2 && is_raw)
    { // Hasselblad
      stmread (imHassy.SensorUnitConnector, len, ifp);
    }

    if ((tag == 0x0081 && type == 7) || // Minolta
        (tag == 0x0100 && type == 7))   // Olympus
    {
      thumb_offset = ftell(ifp);
      thumb_length = len;
    }
    if (tag == 0x0088 && type == 4 && (thumb_offset = get4())) // Minolta
      thumb_offset += base;

    if (tag == 0x0089 && type == 4) // Minolta
      thumb_length = get4();

    if ((type == 7) &&
        ((tag == 0x008c) ||
         (tag == 0x0096))) {
      meta_offset = ftell(ifp);
    }

    if ((tag == 0x00a1) && (type == 7) && strncasecmp(make, "Samsung", 7))
    {
      order = 0x4949;
      fseek(ifp, 140, SEEK_CUR);
      FORC3 cam_mul[c] = get4();
    }

    if (tag == 0xb001 && type == 3) // Sony ModelID
    {
      unique_id = get2();
    }
    if (tag == 0x0200 && len == 3) // Olympus
      shot_order = (get4(), get4());

    if (tag == 0x0f00 && type == 7)
    {
      if (len == 614)
        fseek(ifp, 176, SEEK_CUR);
      else if (len == 734 || len == 1502) // Kodak, Minolta, Olympus
        fseek(ifp, 148, SEEK_CUR);
      else
        goto next;
      goto get2_256;
    }

    if (tag == 0x2011 && len == 2) // Casio
    {
    get2_256:
      order = 0x4d4d;
      cam_mul[0] = get2() / 256.0;
      cam_mul[2] = get2() / 256.0;
    }

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

Project: LibRaw

int LibRaw_bigfile_datastream::read(void *ptr, size_t size, size_t nmemb)
{
  LR_BF_CHK();
  return int(fread(ptr, size, nmemb, f));
}

Project: LibRaw

void LibRaw::fuji_compressed_load_raw()
{
  struct fuji_compressed_params common_info;
  int cur_block;
  unsigned line_size, *block_sizes;
  INT64 raw_offset, *raw_block_offsets;
  // struct fuji_compressed_block info;

  init_fuji_compr(&common_info);
  line_size = sizeof(ushort) * (common_info.line_width + 2);

  // read block sizes
  block_sizes = (unsigned *)malloc(
      sizeof(unsigned) * libraw_internal_data.unpacker_data.fuji_total_blocks);
  merror(block_sizes, "fuji_compressed_load_raw()");
  raw_block_offsets = (INT64 *)malloc(
      sizeof(INT64) * libraw_internal_data.unpacker_data.fuji_total_blocks);
  merror(raw_block_offsets, "fuji_compressed_load_raw()");

  raw_offset =
      sizeof(unsigned) * libraw_internal_data.unpacker_data.fuji_total_blocks;
  if (raw_offset & 0xC)
    raw_offset += 0x10 - (raw_offset & 0xC);

  raw_offset += libraw_internal_data.unpacker_data.data_offset;

  libraw_internal_data.internal_data.input->seek(
      libraw_internal_data.unpacker_data.data_offset, SEEK_SET);
  libraw_internal_data.internal_data.input->read(
      block_sizes, 1,
      sizeof(unsigned) * libraw_internal_data.unpacker_data.fuji_total_blocks);

  raw_block_offsets[0] = raw_offset;
  // calculating raw block offsets
  for (cur_block = 0;
       cur_block < libraw_internal_data.unpacker_data.fuji_total_blocks;
       cur_block++)
  {
    unsigned bsize = sgetn(4, (uchar *)(block_sizes + cur_block));
    block_sizes[cur_block] = bsize;
  }

  for (cur_block = 1;
       cur_block < libraw_internal_data.unpacker_data.fuji_total_blocks;
       cur_block++)
    raw_block_offsets[cur_block] =
        raw_block_offsets[cur_block - 1] + block_sizes[cur_block - 1];

  fuji_decode_loop(&common_info,
                   libraw_internal_data.unpacker_data.fuji_total_blocks,
                   raw_block_offsets, block_sizes);

  free(block_sizes);
  free(raw_block_offsets);
  free(common_info.q_table);
}

Project: LibRaw

int LibRaw::open_file(const char *fname, INT64 max_buf_size)
{
#ifndef LIBRAW_WIN32_CALLS
  struct stat st;
  if (stat(fname, &st))
    return LIBRAW_IO_ERROR;
  int big = (st.st_size > max_buf_size) ? 1 : 0;
#else
  struct _stati64 st;
  if (_stati64(fname, &st))
    return LIBRAW_IO_ERROR;
  int big = (st.st_size > max_buf_size) ? 1 : 0;
#endif

  LibRaw_abstract_datastream *stream;
  try
  {
    if (big)
      stream = new LibRaw_bigfile_datastream(fname);
    else
      stream = new LibRaw_file_datastream(fname);
  }

  catch (std::bad_alloc)
  {
    recycle();
    return LIBRAW_UNSUFFICIENT_MEMORY;
  }
  if (!stream->valid())
  {
    delete stream;
    return LIBRAW_IO_ERROR;
  }
  ID.input_internal = 0; // preserve from deletion on error
  int ret = open_datastream(stream);
  if (ret == LIBRAW_SUCCESS)
  {
    ID.input_internal = 1; // flag to delete datastream on recycle
  }
  else
  {
    delete stream;
    ID.input_internal = 0;
  }
  return ret;
}

Project: LibRaw

LibRaw_bigfile_datastream::LibRaw_bigfile_datastream(const wchar_t *fname)
    : filename(), wfilename(fname)
{
  if (wfilename.size() > 0)
  {
    struct _stati64 st;
    if (!_wstati64(wfilename.c_str(), &st))
      _fsize = st.st_size;
#ifndef WIN32SECURECALLS
    f = _wfopen(wfilename.c_str(), L"rb");
#else
    if (_wfopen_s(&f, fname, L"rb"))
      f = 0;
#endif
  }
  else
  {
    wfilename = std::wstring();
    f = 0;
  }
}

Project: LibRaw

void LibRaw::scale_colors_loop(float scale_mul[4]) {}

Project: LibRaw

void LibRaw::smal_decode_segment(unsigned seg[2][2], int holes)
{
  uchar hist[3][13] = {{7, 7, 0, 0, 63, 55, 47, 39, 31, 23, 15, 7, 0},
                       {7, 7, 0, 0, 63, 55, 47, 39, 31, 23, 15, 7, 0},
                       {3, 3, 0, 0, 63, 47, 31, 15, 0}};
  int low, high = 0xff, carry = 0, nbits = 8;
  int pix, s, count, bin, next, i, sym[3];
  uchar diff, pred[] = {0, 0};
  ushort data = 0, range = 0;

  fseek(ifp, seg[0][1] + 1, SEEK_SET);
  getbits(-1);
  if (seg[1][0] > raw_width * raw_height)
    seg[1][0] = raw_width * raw_height;
  for (pix = seg[0][0]; pix < seg[1][0]; pix++)
  {
    for (s = 0; s < 3; s++)
    {
      data = data << nbits | getbits(nbits);
      if (carry < 0)
        carry = (nbits += carry + 1) < 1 ? nbits - 1 : 0;
      while (--nbits >= 0)
        if ((data >> nbits & 0xff) == 0xff)
          break;
      if (nbits > 0)
        data =
            ((data & ((1 << (nbits - 1)) - 1)) << 1) |
            ((data + (((data & (1 << (nbits - 1)))) << 1)) & ((~0u) << nbits));
      if (nbits >= 0)
      {
        data += getbits(1);
        carry = nbits - 8;
      }
      count = ((((data - range + 1) & 0xffff) << 2) - 1) / (high >> 4);
      for (bin = 0; hist[s][bin + 5] > count; bin++)
        ;
      low = hist[s][bin + 5] * (high >> 4) >> 2;
      if (bin)
        high = hist[s][bin + 4] * (high >> 4) >> 2;
      high -= low;
      for (nbits = 0; high << nbits < 128; nbits++)
        ;
      range = (range + low) << nbits;
      high <<= nbits;
      next = hist[s][1];
      if (++hist[s][2] > hist[s][3])
      {
        next = (next + 1) & hist[s][0];
        hist[s][3] = (hist[s][next + 4] - hist[s][next + 5]) >> 2;
        hist[s][2] = 1;
      }
      if (hist[s][hist[s][1] + 4] - hist[s][hist[s][1] + 5] > 1)
      {
        if (bin < hist[s][1])
          for (i = bin; i < hist[s][1]; i++)
            hist[s][i + 5]--;
        else if (next <= bin)
          for (i = hist[s][1]; i < bin; i++)
            hist[s][i + 5]++;
      }
      hist[s][1] = next;
      sym[s] = bin;
    }
    diff = sym[2] << 5 | sym[1] << 2 | (sym[0] & 3);
    if (sym[0] & 4)
      diff = diff ? -diff : 0x80;
    if (ftell(ifp) + 12 >= seg[1][1])
      diff = 0;
    if (pix >= raw_width * raw_height)
      throw LIBRAW_EXCEPTION_IO_CORRUPT;
    raw_image[pix] = pred[pix & 1] += diff;
    if (!(pix & 1) && HOLE(pix / raw_width))
      pix += 2;
  }
  maximum = 0xff;
}

Project: LibRaw

int LibRaw::find_ifd_by_offset(int o)
{
    for(int i = 0; i < libraw_internal_data.identify_data.tiff_nifds && i < LIBRAW_IFD_MAXCOUNT; i++)
        if(tiff_ifd[i].offset == o)
            return i;
    return -1;
}

Project: LibRaw

void LibRaw::selectCRXTrack(short maxTrack)
{
  if (maxTrack < 0)
    return;
  INT64 bitcounts[LIBRAW_CRXTRACKS_MAXCOUNT], maxbitcount = 0;
  uint32_t maxjpegbytes = 0;
  memset(bitcounts, 0, sizeof(bitcounts));
  for (int i = 0; i <= maxTrack && i < LIBRAW_CRXTRACKS_MAXCOUNT; i++)
  {
    crx_data_header_t *d = &libraw_internal_data.unpacker_data.crx_header[i];
    if (d->MediaType == 1) // RAW
    {
      bitcounts[i] = INT64(d->nBits) * INT64(d->f_width) * INT64(d->f_height);
      if (bitcounts[i] > maxbitcount)
        maxbitcount = bitcounts[i];
    }
    else if (d->MediaType == 2) // JPEG
    {
      if (d->MediaSize > maxjpegbytes)
      {
        maxjpegbytes = d->MediaSize;
        thumb_offset = d->MediaOffset;
        thumb_length = d->MediaSize;
      }
    }
  }
  if (maxbitcount < 8)
    return;
  int framei = -1, framecnt = 0;
  for (int i = 0; i <= maxTrack && i < LIBRAW_CRXTRACKS_MAXCOUNT; i++)
  {
    if (bitcounts[i] == maxbitcount)
    {
      if (framecnt <= shot_select)
        framei = i;
      framecnt++;
    }
  }
  is_raw = framecnt;
  if (framei >= 0 && framei < LIBRAW_CRXTRACKS_MAXCOUNT)
  {
    crx_data_header_t *d =
        &libraw_internal_data.unpacker_data.crx_header[framei];
    data_offset = d->MediaOffset;
    data_size = d->MediaSize;
    raw_width = d->f_width;
    raw_height = d->f_height;
    load_raw = &LibRaw::crxLoadRaw;
    switch (d->cfaLayout)
    {
    case 0:
      filters = 0x94949494;
      break;
    case 1:
      filters = 0x61616161;
      break;
    case 2:
      filters = 0x49494949;
      break;
    case 3:
      filters = 0x16161616;
      break;
    }

    libraw_internal_data.unpacker_data.crx_track_selected = framei;

    int tiff_idx = -1;
    INT64 tpixels = 0;
    for (int i = 0; i < tiff_nifds; i++)
      if (INT64(tiff_ifd[i].t_height) * INT64(tiff_ifd[i].t_height) > tpixels)
      {
        tpixels = INT64(tiff_ifd[i].t_height) * INT64(tiff_ifd[i].t_height);
        tiff_idx = i;
      }
    if (tiff_idx >= 0)
      flip = tiff_ifd[tiff_idx].t_flip;
  }
}

Project: LibRaw

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

Project: LibRaw

  libraw_lensinfo_t *libraw_get_lensinfo(libraw_data_t *lr)
  {
    if (!lr)
      return NULL;
    return &(lr->lens);
  }

Project: LibRaw

DHT::DHT(LibRaw &_libraw) : libraw(_libraw)
{
  nr_height = libraw.imgdata.sizes.iheight + nr_topmargin * 2;
  nr_width = libraw.imgdata.sizes.iwidth + nr_leftmargin * 2;
  nraw = (float3 *)malloc(nr_height * nr_width * sizeof(float3));
  int iwidth = libraw.imgdata.sizes.iwidth;
  ndir = (char *)calloc(nr_height * nr_width, 1);
  channel_maximum[0] = channel_maximum[1] = channel_maximum[2] = 0;
  channel_minimum[0] = libraw.imgdata.image[0][0];
  channel_minimum[1] = libraw.imgdata.image[0][1];
  channel_minimum[2] = libraw.imgdata.image[0][2];
  for (int i = 0; i < nr_height * nr_width; ++i)
    nraw[i][0] = nraw[i][1] = nraw[i][2] = 0.5;
  for (int i = 0; i < libraw.imgdata.sizes.iheight; ++i)
  {
    int col_cache[48];
    for (int j = 0; j < 48; ++j)
    {
      int l = libraw.COLOR(i, j);
      if (l == 3)
        l = 1;
      col_cache[j] = l;
    }
    for (int j = 0; j < iwidth; ++j)
    {
      int l = col_cache[j % 48];
      unsigned short c = libraw.imgdata.image[i * iwidth + j][l];
      if (c != 0)
      {
        if (channel_maximum[l] < c)
          channel_maximum[l] = c;
        if (channel_minimum[l] > c)
          channel_minimum[l] = c;
        nraw[nr_offset(i + nr_topmargin, j + nr_leftmargin)][l] = (float)c;
      }
    }
  }
  channel_minimum[0] += .5;
  channel_minimum[1] += .5;
  channel_minimum[2] += .5;
}

Project: LibRaw

void LibRaw::ahd_interpolate_r_and_b_in_rgb_and_convert_to_cielab(
    int top, int left, ushort (*inout_rgb)[LIBRAW_AHD_TILE][3],
    short (*out_lab)[LIBRAW_AHD_TILE][3])
{
  unsigned row, col;
  int c, val;
  ushort(*pix)[4];
  ushort(*rix)[3];
  short(*lix)[3];
  float xyz[3];
  const unsigned num_pix_per_row = 4 * width;
  const unsigned rowlimit = MIN(top + LIBRAW_AHD_TILE - 1, height - 3);
  const unsigned collimit = MIN(left + LIBRAW_AHD_TILE - 1, width - 3);
  ushort *pix_above;
  ushort *pix_below;
  int t1, t2;

  for (row = top + 1; row < rowlimit; row++)
  {
    pix = image + row * width + left;
    rix = &inout_rgb[row - top][0];
    lix = &out_lab[row - top][0];

    for (col = left + 1; col < collimit; col++)
    {
      pix++;
      pix_above = &pix[0][0] - num_pix_per_row;
      pix_below = &pix[0][0] + num_pix_per_row;
      rix++;
      lix++;

      c = 2 - FC(row, col);

      if (c == 1)
      {
        c = FC(row + 1, col);
        t1 = 2 - c;
        val = pix[0][1] +
              ((pix[-1][t1] + pix[1][t1] - rix[-1][1] - rix[1][1]) >> 1);
        rix[0][t1] = CLIP(val);
        val =
            pix[0][1] + ((pix_above[c] + pix_below[c] -
                          rix[-LIBRAW_AHD_TILE][1] - rix[LIBRAW_AHD_TILE][1]) >>
                         1);
      }
      else
      {
        t1 = -4 + c; /* -4+c: pixel of color c to the left */
        t2 = 4 + c;  /* 4+c: pixel of color c to the right */
        val = rix[0][1] +
              ((pix_above[t1] + pix_above[t2] + pix_below[t1] + pix_below[t2] -
                rix[-LIBRAW_AHD_TILE - 1][1] - rix[-LIBRAW_AHD_TILE + 1][1] -
                rix[+LIBRAW_AHD_TILE - 1][1] - rix[+LIBRAW_AHD_TILE + 1][1] +
                1) >>
               2);
      }
      rix[0][c] = CLIP(val);
      c = FC(row, col);
      rix[0][c] = pix[0][c];
      cielab(rix[0], lix[0]);
    }
  }
}

Project: LibRaw

int LibRaw::parse_tiff(int base)
{
  int doff;
  fseek(ifp, base, SEEK_SET);
  order = get2();
  if (order != 0x4949 && order != 0x4d4d)
    return 0;
  get2();
  while ((doff = get4()))
  {
    fseek(ifp, doff + base, SEEK_SET);
    if (parse_tiff_ifd(base))
      break;
  }
  return 1;
}

Project: LibRaw

void LibRaw::copy_line_to_xtrans(struct fuji_compressed_block *info,
                                 int cur_line, int cur_block,
                                 int cur_block_width)
{
  ushort *lineBufB[3];
  ushort *lineBufG[6];
  ushort *lineBufR[3];
  unsigned pixel_count;
  ushort *line_buf;
  int index;

  int offset = libraw_internal_data.unpacker_data.fuji_block_width * cur_block +
               6 * imgdata.sizes.raw_width * cur_line;
  ushort *raw_block_data = imgdata.rawdata.raw_image + offset;
  int row_count = 0;

  for (int i = 0; i < 3; i++)
  {
    lineBufR[i] = info->linebuf[_R2 + i] + 1;
    lineBufB[i] = info->linebuf[_B2 + i] + 1;
  }
  for (int i = 0; i < 6; i++)
    lineBufG[i] = info->linebuf[_G2 + i] + 1;

  while (row_count < 6)
  {
    pixel_count = 0;
    while (pixel_count < cur_block_width)
    {
      switch (imgdata.idata.xtrans_abs[row_count][(pixel_count % 6)])
      {
      case 0: // red
        line_buf = lineBufR[row_count >> 1];
        break;
      case 1:  // green
      default: // to make static analyzer happy
        line_buf = lineBufG[row_count];
        break;
      case 2: // blue
        line_buf = lineBufB[row_count >> 1];
        break;
      }

      index = (((pixel_count * 2 / 3) & 0x7FFFFFFE) | ((pixel_count % 3) & 1)) +
              ((pixel_count % 3) >> 1);
      raw_block_data[pixel_count] = line_buf[index];

      ++pixel_count;
    }
    ++row_count;
    raw_block_data += imgdata.sizes.raw_width;
  }
}

Project: LibRaw

void LibRaw::dcb_color_full()
{
  int row, col, c, d, i, j, u = width, v = 2 * u, w = 3 * u, indx, g1, g2;
  float f[4], g[4], (*chroma)[2];

  chroma = (float(*)[2])calloc(width * height, sizeof *chroma);
  merror(chroma, "dcb_color_full()");

  for (row = 1; row < height - 1; row++)
    for (col = 1 + (FC(row, 1) & 1), indx = row * width + col, c = FC(row, col),
        d = c / 2;
         col < u - 1; col += 2, indx += 2)
      chroma[indx][d] = image[indx][c] - image[indx][1];

  for (row = 3; row < height - 3; row++)
    for (col = 3 + (FC(row, 1) & 1), indx = row * width + col,
        c = 1 - FC(row, col) / 2, d = 1 - c;
         col < u - 3; col += 2, indx += 2)
    {
      f[0] = 1.0 /
             (float)(1.0 +
                     fabs(chroma[indx - u - 1][c] - chroma[indx + u + 1][c]) +
                     fabs(chroma[indx - u - 1][c] - chroma[indx - w - 3][c]) +
                     fabs(chroma[indx + u + 1][c] - chroma[indx - w - 3][c]));
      f[1] = 1.0 /
             (float)(1.0 +
                     fabs(chroma[indx - u + 1][c] - chroma[indx + u - 1][c]) +
                     fabs(chroma[indx - u + 1][c] - chroma[indx - w + 3][c]) +
                     fabs(chroma[indx + u - 1][c] - chroma[indx - w + 3][c]));
      f[2] = 1.0 /
             (float)(1.0 +
                     fabs(chroma[indx + u - 1][c] - chroma[indx - u + 1][c]) +
                     fabs(chroma[indx + u - 1][c] - chroma[indx + w + 3][c]) +
                     fabs(chroma[indx - u + 1][c] - chroma[indx + w - 3][c]));
      f[3] = 1.0 /
             (float)(1.0 +
                     fabs(chroma[indx + u + 1][c] - chroma[indx - u - 1][c]) +
                     fabs(chroma[indx + u + 1][c] - chroma[indx + w - 3][c]) +
                     fabs(chroma[indx - u - 1][c] - chroma[indx + w + 3][c]));
      g[0] = 1.325 * chroma[indx - u - 1][c] - 0.175 * chroma[indx - w - 3][c] -
             0.075 * chroma[indx - w - 1][c] - 0.075 * chroma[indx - u - 3][c];
      g[1] = 1.325 * chroma[indx - u + 1][c] - 0.175 * chroma[indx - w + 3][c] -
             0.075 * chroma[indx - w + 1][c] - 0.075 * chroma[indx - u + 3][c];
      g[2] = 1.325 * chroma[indx + u - 1][c] - 0.175 * chroma[indx + w - 3][c] -
             0.075 * chroma[indx + w - 1][c] - 0.075 * chroma[indx + u - 3][c];
      g[3] = 1.325 * chroma[indx + u + 1][c] - 0.175 * chroma[indx + w + 3][c] -
             0.075 * chroma[indx + w + 1][c] - 0.075 * chroma[indx + u + 3][c];
      chroma[indx][c] =
          (f[0] * g[0] + f[1] * g[1] + f[2] * g[2] + f[3] * g[3]) /
          (f[0] + f[1] + f[2] + f[3]);
    }
  for (row = 3; row < height - 3; row++)
    for (col = 3 + (FC(row, 2) & 1), indx = row * width + col,
        c = FC(row, col + 1) / 2;
         col < u - 3; col += 2, indx += 2)
      for (d = 0; d <= 1; c = 1 - c, d++)
      {
        f[0] = 1.0 /
               (float)(1.0 + fabs(chroma[indx - u][c] - chroma[indx + u][c]) +
                       fabs(chroma[indx - u][c] - chroma[indx - w][c]) +
                       fabs(chroma[indx + u][c] - chroma[indx - w][c]));
        f[1] = 1.0 /
               (float)(1.0 + fabs(chroma[indx + 1][c] - chroma[indx - 1][c]) +
                       fabs(chroma[indx + 1][c] - chroma[indx + 3][c]) +
                       fabs(chroma[indx - 1][c] - chroma[indx + 3][c]));
        f[2] = 1.0 /
               (float)(1.0 + fabs(chroma[indx - 1][c] - chroma[indx + 1][c]) +
                       fabs(chroma[indx - 1][c] - chroma[indx - 3][c]) +
                       fabs(chroma[indx + 1][c] - chroma[indx - 3][c]));
        f[3] = 1.0 /
               (float)(1.0 + fabs(chroma[indx + u][c] - chroma[indx - u][c]) +
                       fabs(chroma[indx + u][c] - chroma[indx + w][c]) +
                       fabs(chroma[indx - u][c] - chroma[indx + w][c]));

        g[0] = 0.875 * chroma[indx - u][c] + 0.125 * chroma[indx - w][c];
        g[1] = 0.875 * chroma[indx + 1][c] + 0.125 * chroma[indx + 3][c];
        g[2] = 0.875 * chroma[indx - 1][c] + 0.125 * chroma[indx - 3][c];
        g[3] = 0.875 * chroma[indx + u][c] + 0.125 * chroma[indx + w][c];

        chroma[indx][c] =
            (f[0] * g[0] + f[1] * g[1] + f[2] * g[2] + f[3] * g[3]) /
            (f[0] + f[1] + f[2] + f[3]);
      }

  for (row = 6; row < height - 6; row++)
    for (col = 6, indx = row * width + col; col < width - 6; col++, indx++)
    {
      image[indx][0] = CLIP(chroma[indx][0] + image[indx][1]);
      image[indx][2] = CLIP(chroma[indx][1] + image[indx][1]);

      g1 = MIN(
          image[indx + 1 + u][0],
          MIN(image[indx + 1 - u][0],
              MIN(image[indx - 1 + u][0],
                  MIN(image[indx - 1 - u][0],
                      MIN(image[indx - 1][0],
                          MIN(image[indx + 1][0],
                              MIN(image[indx - u][0], image[indx + u][0])))))));

      g2 = MAX(
          image[indx + 1 + u][0],
          MAX(image[indx + 1 - u][0],
              MAX(image[indx - 1 + u][0],
                  MAX(image[indx - 1 - u][0],
                      MAX(image[indx - 1][0],
                          MAX(image[indx + 1][0],
                              MAX(image[indx - u][0], image[indx + u][0])))))));

      image[indx][0] = ULIM(image[indx][0], g2, g1);

      g1 = MIN(
          image[indx + 1 + u][2],
          MIN(image[indx + 1 - u][2],
              MIN(image[indx - 1 + u][2],
                  MIN(image[indx - 1 - u][2],
                      MIN(image[indx - 1][2],
                          MIN(image[indx + 1][2],
                              MIN(image[indx - u][2], image[indx + u][2])))))));

      g2 = MAX(
          image[indx + 1 + u][2],
          MAX(image[indx + 1 - u][2],
              MAX(image[indx - 1 + u][2],
                  MAX(image[indx - 1 - u][2],
                      MAX(image[indx - 1][2],
                          MAX(image[indx + 1][2],
                              MAX(image[indx - u][2], image[indx + u][2])))))));

      image[indx][2] = ULIM(image[indx][2], g2, g1);
    }

  free(chroma);
}

Project: LibRaw

void DHT::refine_ihv_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)] & HVSH)
      continue;
    int nv =
        (ndir[nr_offset(y - 1, x)] & VER) + (ndir[nr_offset(y + 1, x)] & VER) +
        (ndir[nr_offset(y, x - 1)] & VER) + (ndir[nr_offset(y, x + 1)] & VER);
    int nh =
        (ndir[nr_offset(y - 1, x)] & HOR) + (ndir[nr_offset(y + 1, x)] & HOR) +
        (ndir[nr_offset(y, x - 1)] & HOR) + (ndir[nr_offset(y, x + 1)] & HOR);
    nv /= VER;
    nh /= HOR;
    if ((ndir[nr_offset(y, x)] & VER) && nh > 3)
    {
      ndir[nr_offset(y, x)] &= ~VER;
      ndir[nr_offset(y, x)] |= HOR;
    }
    if ((ndir[nr_offset(y, x)] & HOR) && nv > 3)
    {
      ndir[nr_offset(y, x)] &= ~HOR;
      ndir[nr_offset(y, x)] |= VER;
    }
  }
}

Project: LibRaw

int LibRaw_buffer_datastream::eof()
{
  return streampos >= streamsize;
}

Project: LibRaw

void AAHD::refine_ihv_dirs(int i)
{
  int iwidth = libraw.imgdata.sizes.iwidth;
  int moff = nr_offset(i + nr_margin, nr_margin);
  for (int j = 0; j < iwidth; j++, ++moff)
  {
    if (ndir[moff] & HVSH)
      continue;
    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);
    nv /= VER;
    nh /= HOR;
    if ((ndir[moff] & VER) && nh > 3)
    {
      ndir[moff] &= ~VER;
      ndir[moff] |= HOR;
    }
    if ((ndir[moff] & HOR) && nv > 3)
    {
      ndir[moff] &= ~HOR;
      ndir[moff] |= VER;
    }
  }
}

Project: LibRaw

  CameraMetaDataLR(char *filename) : RawSpeed::CameraMetaData(filename) {}

Project: LibRaw

void LibRaw::smal_v9_load_raw()
{
  unsigned seg[256][2], offset, nseg, holes, i;

  fseek(ifp, 67, SEEK_SET);
  offset = get4();
  nseg = (uchar)fgetc(ifp);
  fseek(ifp, offset, SEEK_SET);
  for (i = 0; i < nseg * 2; i++)
    ((unsigned *)seg)[i] = get4() + data_offset * (i & 1);
  fseek(ifp, 78, SEEK_SET);
  holes = fgetc(ifp);
  fseek(ifp, 88, SEEK_SET);
  seg[nseg][0] = raw_height * raw_width;
  seg[nseg][1] = get4() + data_offset;
  for (i = 0; i < nseg; i++)
    smal_decode_segment(seg + i, holes);
  if (holes)
    fill_holes(holes);
}

Project: LibRaw

  int is_fuji_rotated()
  {
    return libraw_internal_data.internal_output_params.fuji_width;
  }

Project: LibRaw

void LibRaw::parseSamsungMakernotes(int base, unsigned tag, unsigned type,
                                    unsigned len, unsigned dng_writer)
{
  int i, c;
  if (tag == 0x0002)
  {
    imSamsung.DeviceType = get4();
    if (imSamsung.DeviceType == 0x2000)
    {
      ilm.CameraMount = LIBRAW_MOUNT_Samsung_NX;
      ilm.CameraFormat = LIBRAW_FORMAT_APSC;
    }
    else if (!strncmp(model, "NX mini", 7))
    { // device type 0x1000: 'NX mini', EX2F, EX1, WB2000
      ilm.CameraMount = LIBRAW_MOUNT_Samsung_NX_M;
      ilm.CameraFormat = LIBRAW_FORMAT_1INCH;
    }
    else
    {
      ilm.CameraMount = LIBRAW_MOUNT_FixedLens;
      ilm.LensMount = LIBRAW_MOUNT_FixedLens;
    }
  }
  else if (tag == 0x0003)
  {
    ilm.CamID = unique_id = get4();
  }
  else if (tag == 0x0043)
  {
    if ((i = get4()))
    {
      imgdata.makernotes.common.CameraTemperature = (float)i;
      if (get4() == 10)
        imgdata.makernotes.common.CameraTemperature /= 10.0f;
    }
  }
  else if ((tag == 0xa002) && (dng_writer != AdobeDNG))
  {
    stmread(imgdata.shootinginfo.BodySerial, len, ifp);
  }
  else if (tag == 0xa003)
  {
    ilm.LensID = get2();
    if (ilm.LensID)
      ilm.LensMount = LIBRAW_MOUNT_Samsung_NX;
  }
  else if (tag == 0xa004)
  { // LensFirmware
    stmread(imSamsung.LensFirmware, len, ifp);
  }
  else if (tag == 0xa005)
  {
    stmread(imgdata.lens.InternalLensSerial, len, ifp);
  }
  else if (tag == 0xa010)
  {
    FORC4 imSamsung.ImageSizeFull[c] = get4();
    FORC4 imSamsung.ImageSizeCrop[c] = get4();
  }
  else if ((tag == 0xa011) && ((len == 1) || (len == 2)) && (type == 3))
  {
    imSamsung.ColorSpace[0] = (int)get2();
    if (len == 2)
      imSamsung.ColorSpace[1] = (int)get2();
  }
  else if (tag == 0xa019)
  {
    ilm.CurAp = getreal(type);
  }
  else if ((tag == 0xa01a) && (unique_id != 0x5000000) &&
           (!imgdata.lens.FocalLengthIn35mmFormat))
  {
    ilm.FocalLengthIn35mmFormat = get4();
    if (ilm.FocalLengthIn35mmFormat >= 160)
      ilm.FocalLengthIn35mmFormat /= 10.0f;
    if ((ilm.CameraMount == LIBRAW_MOUNT_Samsung_NX_M) &&
        (imSamsung.LensFirmware[10] < '6'))
      ilm.FocalLengthIn35mmFormat *= 1.6f;
  }
  else if (tag == 0xa020)
  {
    FORC(11) imSamsung.key[c] = get4();
  }
  else if ((tag == 0xa021) && (dng_writer == nonDNG))
  {
    FORC4 cam_mul[c ^ (c >> 1)] = get4() - imSamsung.key[c];
  }
  else if (tag == 0xa022)
  {
    FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_Auto][c ^ (c >> 1)] =
        get4() - imSamsung.key[c + 4];
    if (imgdata.color.WB_Coeffs[LIBRAW_WBI_Auto][0] <
        (imgdata.color.WB_Coeffs[LIBRAW_WBI_Auto][1] >> 1))
    {
      imgdata.color.WB_Coeffs[LIBRAW_WBI_Auto][1] =
          imgdata.color.WB_Coeffs[LIBRAW_WBI_Auto][1] >> 4;
      imgdata.color.WB_Coeffs[LIBRAW_WBI_Auto][3] =
          imgdata.color.WB_Coeffs[LIBRAW_WBI_Auto][3] >> 4;
    }
  }
  else if (tag == 0xa023)
  {
    imgdata.color.WB_Coeffs[LIBRAW_WBI_Ill_A][0] =
        get4() - imSamsung.key[8];
    imgdata.color.WB_Coeffs[LIBRAW_WBI_Ill_A][1] =
        get4() - imSamsung.key[9];
    imgdata.color.WB_Coeffs[LIBRAW_WBI_Ill_A][3] =
        get4() - imSamsung.key[10];
    imgdata.color.WB_Coeffs[LIBRAW_WBI_Ill_A][2] =
        get4() - imSamsung.key[0];
    if (imgdata.color.WB_Coeffs[LIBRAW_WBI_Ill_A][0] <
        (imgdata.color.WB_Coeffs[LIBRAW_WBI_Ill_A][1] >> 1))
    {
      imgdata.color.WB_Coeffs[LIBRAW_WBI_Ill_A][1] =
          imgdata.color.WB_Coeffs[LIBRAW_WBI_Ill_A][1] >> 4;
      imgdata.color.WB_Coeffs[LIBRAW_WBI_Ill_A][3] =
          imgdata.color.WB_Coeffs[LIBRAW_WBI_Ill_A][3] >> 4;
    }
  }
  else if (tag == 0xa024)
  {
    FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_D65][c ^ (c >> 1)] =
        get4() - imSamsung.key[c + 1];
    if (imgdata.color.WB_Coeffs[LIBRAW_WBI_D65][0] <
        (imgdata.color.WB_Coeffs[LIBRAW_WBI_D65][1] >> 1))
    {
      imgdata.color.WB_Coeffs[LIBRAW_WBI_D65][1] =
          imgdata.color.WB_Coeffs[LIBRAW_WBI_D65][1] >> 4;
      imgdata.color.WB_Coeffs[LIBRAW_WBI_D65][3] =
          imgdata.color.WB_Coeffs[LIBRAW_WBI_D65][3] >> 4;
    }
  }
  else if (tag == 0xa025)
  {
    unsigned t = get4() + imSamsung.key[0];
    if (t == 4096)
      imSamsung.DigitalGain = 1.0;
    else
      imSamsung.DigitalGain = ((double)t) / 4096.0;
  }
  else if ((tag == 0xa028) && (dng_writer == nonDNG))
  {
    FORC4 cblack[c ^ (c >> 1)] = get4() - imSamsung.key[c];
  }
  else if ((tag == 0xa030) && (len == 9))
  {
    for (i = 0; i < 3; i++)
      FORC3 imgdata.color.ccm[i][c] =
          (float)((short)((get4() + imSamsung.key[i * 3 + c]))) / 256.0;
  }
  else if ((tag == 0xa032) && (len == 9) && (dng_writer == nonDNG))
  {
    double aRGB_cam[3][3];
    FORC(9)
    ((double *)aRGB_cam)[c] =
        ((double)((short)((get4() + imSamsung.key[c])))) / 256.0;
    aRGB_coeff(aRGB_cam);
  }
}

Project: LibRaw

void LibRaw::convert_to_rgb()
{
  int i, j, k;
  float out_cam[3][4];
  double num, inverse[3][3];
  static const double(*out_rgb[])[3] = {
      LibRaw_constants::rgb_rgb,  LibRaw_constants::adobe_rgb,
      LibRaw_constants::wide_rgb, LibRaw_constants::prophoto_rgb,
      LibRaw_constants::xyz_rgb,  LibRaw_constants::aces_rgb};
  static const char *name[] = {"sRGB",          "Adobe RGB (1998)",
                               "WideGamut D65", "ProPhoto D65",
                               "XYZ",           "ACES"};
  static const unsigned phead[] = {
      1024, 0, 0x2100000,  0x6d6e7472, 0x52474220, 0x58595a20, 0,
      0,    0, 0x61637370, 0,          0,          0x6e6f6e65, 0,
      0,    0, 0,          0xf6d6,     0x10000,    0xd32d};
  unsigned pbody[] = {10,         0x63707274, 0,  36, /* cprt */
                      0x64657363, 0,          40,     /* desc */
                      0x77747074, 0,          20,     /* wtpt */
                      0x626b7074, 0,          20,     /* bkpt */
                      0x72545243, 0,          14,     /* rTRC */
                      0x67545243, 0,          14,     /* gTRC */
                      0x62545243, 0,          14,     /* bTRC */
                      0x7258595a, 0,          20,     /* rXYZ */
                      0x6758595a, 0,          20,     /* gXYZ */
                      0x6258595a, 0,          20};    /* bXYZ */
  static const unsigned pwhite[] = {0xf351, 0x10000, 0x116cc};
  unsigned pcurve[] = {0x63757276, 0, 1, 0x1000000};

  RUN_CALLBACK(LIBRAW_PROGRESS_CONVERT_RGB, 0, 2);

  gamma_curve(gamm[0], gamm[1], 0, 0);
  memcpy(out_cam, rgb_cam, sizeof out_cam);
  raw_color |= colors == 1 || output_color < 1 || output_color > 6;
  if (!raw_color)
  {
    oprof = (unsigned *)calloc(phead[0], 1);
    merror(oprof, "convert_to_rgb()");
    memcpy(oprof, phead, sizeof phead);
    if (output_color == 5)
      oprof[4] = oprof[5];
    oprof[0] = 132 + 12 * pbody[0];
    for (i = 0; i < pbody[0]; i++)
    {
      oprof[oprof[0] / 4] = i ? (i > 1 ? 0x58595a20 : 0x64657363) : 0x74657874;
      pbody[i * 3 + 2] = oprof[0];
      oprof[0] += (pbody[i * 3 + 3] + 3) & -4;
    }
    memcpy(oprof + 32, pbody, sizeof pbody);
    oprof[pbody[5] / 4 + 2] = strlen(name[output_color - 1]) + 1;
    memcpy((char *)oprof + pbody[8] + 8, pwhite, sizeof pwhite);
    pcurve[3] = (short)(256 / gamm[5] + 0.5) << 16;
    for (i = 4; i < 7; i++)
      memcpy((char *)oprof + pbody[i * 3 + 2], pcurve, sizeof pcurve);
    pseudoinverse((double(*)[3])out_rgb[output_color - 1], inverse, 3);
    for (i = 0; i < 3; i++)
      for (j = 0; j < 3; j++)
      {
        for (num = k = 0; k < 3; k++)
          num += LibRaw_constants::xyzd50_srgb[i][k] * inverse[j][k];
        oprof[pbody[j * 3 + 23] / 4 + i + 2] = num * 0x10000 + 0.5;
      }
    for (i = 0; i < phead[0] / 4; i++)
      oprof[i] = htonl(oprof[i]);
    strcpy((char *)oprof + pbody[2] + 8, "auto-generated by dcraw");
    strcpy((char *)oprof + pbody[5] + 12, name[output_color - 1]);
    for (i = 0; i < 3; i++)
      for (j = 0; j < colors; j++)
        for (out_cam[i][j] = k = 0; k < 3; k++)
          out_cam[i][j] += out_rgb[output_color - 1][i][k] * rgb_cam[k][j];
  }
  convert_to_rgb_loop(out_cam);

  if (colors == 4 && output_color)
    colors = 3;

  RUN_CALLBACK(LIBRAW_PROGRESS_CONVERT_RGB, 1, 2);
}

Project: LibRaw

  libraw_processed_image_t *libraw_dcraw_make_mem_image(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_image(errc);
  }

Project: LibRaw

  virtual uint64 DoGetLength()
  {
    if (parent_stream)
      return parent_stream->size();
    return 0;
  }

Project: LibRaw

  int libraw_get_decoder_info(libraw_data_t *lr, libraw_decoder_info_t *d)
  {
    if (!lr || !d)
      return EINVAL;
    LibRaw *ip = (LibRaw *)lr->parent_class;
    return ip->get_decoder_info(d);
  }

Project: LibRaw

void LibRaw::Kodak_DCR_WBtags(int wb, unsigned type, int wbi)
{
  float mul[3] = {1.0f, 1.0f, 1.0f}, num, mul2;
  int c;
  FORC3 mul[c] = (num = getreal(type)) <= 0.001f ? 1.0f : num;
  imgdata.color.WB_Coeffs[wb][1] = imgdata.color.WB_Coeffs[wb][3] = mul[1];
  mul2 = mul[1] * mul[1];
  imgdata.color.WB_Coeffs[wb][0] = mul2 / mul[0];
  imgdata.color.WB_Coeffs[wb][2] = mul2 / mul[2];
  if (wbi == wb)
    FORC4 cam_mul[c] = imgdata.color.WB_Coeffs[wb][c];
  return;
}

Project: LibRaw

LibRaw_bigfile_datastream::LibRaw_bigfile_datastream(const char *fname)
    : filename(fname)
#ifdef LIBRAW_WIN32_UNICODEPATHS
      ,
      wfilename()
#endif
{
  if (filename.size() > 0)
  {
#ifndef LIBRAW_WIN32_CALLS
    struct stat st;
    if (!stat(filename.c_str(), &st))
      _fsize = st.st_size;
#else
    struct _stati64 st;
    if (!_stati64(filename.c_str(), &st))
      _fsize = st.st_size;
#endif

#ifndef WIN32SECURECALLS
    f = fopen(fname, "rb");
#else
    if (fopen_s(&f, fname, "rb"))
      f = 0;
#endif
  }
  else
  {
    filename = std::string();
    f = 0;
  }
}

Project: LibRaw

void LibRaw::xtrans_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)
    {
      fuji_decode_interpolation_even(line_width, info->linebuf[_R2] + 1,
                                     r_even_pos);
      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;
      fuji_decode_interpolation_even(line_width, info->linebuf[_B2] + 1,
                                     b_even_pos);
      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)
    {
      if (r_even_pos & 3)
        errcnt += fuji_decode_sample_even(info, params, info->linebuf[_R3] + 1,
                                          r_even_pos, info->grad_even[2]);
      else
        fuji_decode_interpolation_even(line_width, info->linebuf[_R3] + 1,
                                       r_even_pos);
      r_even_pos += 2;
      fuji_decode_interpolation_even(line_width, info->linebuf[_G4] + 1,
                                     g_even_pos);
      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;
      if ((b_even_pos & 3) == 2)
        fuji_decode_interpolation_even(line_width, info->linebuf[_B3] + 1,
                                       b_even_pos);
      else
        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)
    {
      if ((r_even_pos & 3) == 2)
        fuji_decode_interpolation_even(line_width, info->linebuf[_R4] + 1,
                                       r_even_pos);
      else
        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)
    {
      fuji_decode_interpolation_even(line_width, info->linebuf[_G7] + 1,
                                     g_even_pos);
      g_even_pos += 2;
      if (b_even_pos & 3)
        errcnt += fuji_decode_sample_even(info, params, info->linebuf[_B4] + 1,
                                          b_even_pos, info->grad_even[2]);
      else
        fuji_decode_interpolation_even(line_width, info->linebuf[_B4] + 1,
                                       b_even_pos);
      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

void timerstart(void) { gettimeofday(&start, NULL); }

Project: LibRaw

inline unsigned int __DNG_FP24ToFloat(const unsigned char *input)
{
  int sign = (input[0] >> 7) & 0x01;
  int exponent = (input[0]) & 0x7F;
  int mantissa = (((int)input[1]) << 8) | input[2];
  if (exponent == 0)
  {
    if (mantissa == 0)
    {
      return (unsigned int)(sign << 31);
    }
    else
    {
      while (!(mantissa & 0x00010000))
      {
        mantissa <<= 1;
        exponent -= 1;
      }
      exponent += 1;
      mantissa &= ~0x00010000;
    }
  }
  else if (exponent == 127)
  {
    if (mantissa == 0)
    {
      return (unsigned int)((sign << 31) | ((0x7eL + 128 - 64) << 23) |
                            (0xffffL << 7));
    }
    else
    {
      // Nan -- Just set to zero.
      return 0;
    }
  }
  exponent += (128 - 64);
  mantissa <<= 7;
  return (uint32_t)((sign << 31) | (exponent << 23) | mantissa);
}

Project: LibRaw

void LibRaw::ppm_thumb()
{
  char *thumb;
  thumb_length = thumb_width * thumb_height * 3;
  thumb = (char *)malloc(thumb_length);
  merror(thumb, "ppm_thumb()");
  fprintf(ofp, "P6\n%d %d\n255\n", thumb_width, thumb_height);
  fread(thumb, 1, thumb_length, ifp);
  fwrite(thumb, 1, thumb_length, ofp);
  free(thumb);
}

Project: LibRaw

void LibRaw::parse_sinar_ia()
{
  int entries, off;
  char str[8], *cp;

  order = 0x4949;
  fseek(ifp, 4, SEEK_SET);
  entries = get4();
  if (entries < 1 || entries > 8192)
    return;
  fseek(ifp, get4(), SEEK_SET);
  while (entries--)
  {
    off = get4();
    get4();
    fread(str, 8, 1, ifp);
    str[7] = 0; // Ensure end of string
    if (!strcmp(str, "META"))
      meta_offset = off;
    if (!strcmp(str, "THUMB"))
      thumb_offset = off;
    if (!strcmp(str, "RAW0"))
      data_offset = off;
  }
  fseek(ifp, meta_offset + 20, SEEK_SET);
  fread(make, 64, 1, ifp);
  make[63] = 0;
  if ((cp = strchr(make, ' ')))
  {
    strcpy(model, cp + 1);
    *cp = 0;
  }
  raw_width = get2();
  raw_height = get2();
  load_raw = &LibRaw::unpacked_load_raw;
  thumb_width = (get4(), get2());
  thumb_height = get2();
  write_thumb = &LibRaw::ppm_thumb;
  maximum = 0x3fff;
}

Project: LibRaw

char *LibRaw::strcasestr(char *haystack, const char *needle)
{
  char *c;
  for (c = haystack; *c; c++)
    if (!strncasecmp(c, needle, strlen(needle)))
      return c;
  return 0;
}

Project: LibRaw

int process_files(void *q)
{
  int ret;
  int count = 0;
  char outfn[1024], *fn;
  libraw_data_t *iprc = libraw_init(0);

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

  while ((fn = get_next_file()))
  {

    iprc->params.half_size = 1; /* dcraw -h */
    iprc->params.use_camera_wb = use_camera_wb;
    iprc->params.use_auto_wb = use_auto_wb;
    iprc->params.output_tiff = tiff_mode;

    ret = libraw_open_file(iprc, fn);
    if (verbose)
      fprintf(stderr, "%s: %s/%s\n", fn, iprc->idata.make, iprc->idata.model);
    HANDLE_ERRORS(ret);

    ret = libraw_unpack(iprc);
    HANDLE_ERRORS(ret);

    ret = libraw_dcraw_process(iprc);
    HANDLE_ERRORS(ret);

    snprintf(outfn, 1023, "%s.%s", fn, tiff_mode ? "tif" : "ppm");

    if (verbose)
      fprintf(stderr, "Writing file %s\n", outfn);
    ret = libraw_dcraw_ppm_tiff_writer(iprc, outfn);
    HANDLE_ERRORS(ret);
    count++;
  }
  libraw_close(iprc);
  printf("Processed %d files\n", count);
  return 0;
}

Project: LibRaw

  void libraw_recycle(libraw_data_t *lr)
  {
    if (!lr)
      return;
    LibRaw *ip = (LibRaw *)lr->parent_class;
    ip->recycle();
  }

Project: LibRaw

void DHT::copy_to_image()
{
  int iwidth = libraw.imgdata.sizes.iwidth;
#if defined(LIBRAW_USE_OPENMP)
#ifdef _MSC_VER
#pragma omp parallel for
#else
#pragma omp parallel for schedule(guided) collapse(2)
#endif
#endif
  for (int i = 0; i < libraw.imgdata.sizes.iheight; ++i)
  {
    for (int j = 0; j < iwidth; ++j)
    {
      libraw.imgdata.image[i * iwidth + j][0] =
          (unsigned short)(nraw[nr_offset(i + nr_topmargin, j + nr_leftmargin)]
                               [0]);
      libraw.imgdata.image[i * iwidth + j][2] =
          (unsigned short)(nraw[nr_offset(i + nr_topmargin, j + nr_leftmargin)]
                               [2]);
      libraw.imgdata.image[i * iwidth + j][1] =
          libraw.imgdata.image[i * iwidth + j][3] =
              (unsigned short)(nraw[nr_offset(i + nr_topmargin,
                                              j + nr_leftmargin)][1]);
    }
  }
}

Project: LibRaw

void LibRaw::android_loose_load_raw()
{
  uchar *data, *dp;
  int bwide, row, col, c;
  UINT64 bitbuf = 0;

  bwide = (raw_width + 5) / 6 << 3;
  data = (uchar *)malloc(bwide);
  merror(data, "android_loose_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 += 8, col += 6)
    {
      FORC(8) bitbuf = (bitbuf << 8) | dp[c ^ 7];
      FORC(6) RAW(row, col + c) = (bitbuf >> c * 10) & 0x3ff;
    }
  }
  free(data);
}

Project: LibRaw

  ~libraw_memmgr()
  {
    cleanup();
    ::free(mems);
  }

Project: LibRaw

  int get_hv_rbg(int x, int y, int hc)
  {
    float hv1 = 2 * nraw[nr_offset(y - 1, x)][hc ^ 2] /
                (nraw[nr_offset(y - 2, x)][1] + nraw[nr_offset(y, x)][1]);
    float hv2 = 2 * nraw[nr_offset(y + 1, x)][hc ^ 2] /
                (nraw[nr_offset(y + 2, x)][1] + nraw[nr_offset(y, x)][1]);
    float kv = calc_dist(hv1, hv2) *
               calc_dist(nraw[nr_offset(y, x)][1] * nraw[nr_offset(y, x)][1],
                         (nraw[nr_offset(y - 2, x)][1] *
                          nraw[nr_offset(y + 2, x)][1]));
    kv *= kv;
    kv *= kv;
    kv *= kv;
    float dv = kv * calc_dist(nraw[nr_offset(y - 3, x)][hc ^ 2] *
                                  nraw[nr_offset(y + 3, x)][hc ^ 2],
                              nraw[nr_offset(y - 1, x)][hc ^ 2] *
                                  nraw[nr_offset(y + 1, x)][hc ^ 2]);
    float hh1 = 2 * nraw[nr_offset(y, x - 1)][hc] /
                (nraw[nr_offset(y, x - 2)][1] + nraw[nr_offset(y, x)][1]);
    float hh2 = 2 * nraw[nr_offset(y, x + 1)][hc] /
                (nraw[nr_offset(y, x + 2)][1] + nraw[nr_offset(y, x)][1]);
    float kh = calc_dist(hh1, hh2) *
               calc_dist(nraw[nr_offset(y, x)][1] * nraw[nr_offset(y, x)][1],
                         (nraw[nr_offset(y, x - 2)][1] *
                          nraw[nr_offset(y, x + 2)][1]));
    kh *= kh;
    kh *= kh;
    kh *= kh;
    float dh =
        kh * calc_dist(
                 nraw[nr_offset(y, x - 3)][hc] * nraw[nr_offset(y, x + 3)][hc],
                 nraw[nr_offset(y, x - 1)][hc] * nraw[nr_offset(y, x + 1)][hc]);
    float e = calc_dist(dh, dv);
    char d = dh < dv ? (e > Tg() ? HORSH : HOR) : (e > Tg() ? VERSH : VER);
    return d;
  }

Project: LibRaw

void LibRaw::Canon_CameraSettings(unsigned len)
{
  fseek(ifp, 10, SEEK_CUR);
  imgdata.shootinginfo.DriveMode = get2(); // 5
  get2();
  imgdata.shootinginfo.FocusMode = get2(); // 7
  fseek(ifp, 18, SEEK_CUR);
  imgdata.shootinginfo.MeteringMode = get2(); // 17
  get2();
  imgdata.shootinginfo.AFPoint = get2();      // 19
  imgdata.shootinginfo.ExposureMode = get2(); // 20
  get2();
  ilm.LensID = get2();          // 22
  ilm.MaxFocal = get2();        // 23
  ilm.MinFocal = get2();        // 24
  ilm.FocalUnits = get2(); // 25
  if (ilm.FocalUnits > 1)
  {
    ilm.MaxFocal /= (float)ilm.FocalUnits;
    ilm.MinFocal /= (float)ilm.FocalUnits;
  }
  ilm.MaxAp = _CanonConvertAperture(get2()); // 26
  ilm.MinAp = _CanonConvertAperture(get2()); // 27
  if (len >= 36)
  {
    fseek(ifp, 12, SEEK_CUR);
    imgdata.shootinginfo.ImageStabilization = get2(); // 34
  }
  else
    return;
  if (len >= 48)
  {
    fseek(ifp, 22, SEEK_CUR);
    imCanon.SRAWQuality = get2(); // 46
  }
}

Project: LibRaw

void LibRaw::crxLoadDecodeLoop(void *img, int nPlanes)
{
#ifdef LIBRAW_USE_OPENMP
  int results[4]; // nPlanes is always <= 4
#pragma omp parallel for
  for (int32_t plane = 0; plane < nPlanes; ++plane)
    results[i] = crxDecodePlane(img, plane);

  for (int32_t plane = 0; plane < nPlanes; ++plane)
    if (results[i])
      derror();
#else
  for (int32_t plane = 0; plane < nPlanes; ++plane)
    if (crxDecodePlane(img, plane))
      derror();
#endif
}

Project: LibRaw

int LibRaw::stread(char *buf, size_t len, LibRaw_abstract_datastream *fp)
{
  if (len > 0)
  {
    int r = fp->read(buf, len, 1);
    buf[len - 1] = 0;
    return r;
  }
  else
    return 0;
}

Project: LibRaw

int LibRaw::phase_one_correct()
{
  unsigned entries, tag, data, save, col, row, type;
  int len, i, j, k, cip, val[4], dev[4], sum, max;
  int head[9], diff, mindiff = INT_MAX, off_412 = 0;
  /* static */ const signed char dir[12][2] = {
      {-1, -1}, {-1, 1}, {1, -1},  {1, 1},  {-2, 0}, {0, -2},
      {0, 2},   {2, 0},  {-2, -2}, {-2, 2}, {2, -2}, {2, 2}};
  float poly[8], num, cfrac, frac, mult[2], *yval[2] = {NULL, NULL};
  ushort *xval[2];
  int qmult_applied = 0, qlin_applied = 0;

  if (!meta_length)
    return 0;
  fseek(ifp, meta_offset, SEEK_SET);
  order = get2();
  fseek(ifp, 6, SEEK_CUR);
  fseek(ifp, meta_offset + get4(), SEEK_SET);
  entries = get4();
  get4();

  try
  {
    while (entries--)
    {
      checkCancel();
      tag = get4();
      len = get4();
      data = get4();
      save = ftell(ifp);
      fseek(ifp, meta_offset + data, SEEK_SET);
      if (tag == 0x0419)
      { /* Polynomial curve */
        for (get4(), i = 0; i < 8; i++)
          poly[i] = getreal(11);
        poly[3] += (ph1.tag_210 - poly[7]) * poly[6] + 1;
        for (i = 0; i < 0x10000; i++)
        {
          num = (poly[5] * i + poly[3]) * i + poly[1];
          curve[i] = LIM(num, 0, 65535);
        }
        goto apply; /* apply to right half */
      }
      else if (tag == 0x041a)
      { /* Polynomial curve */
        for (i = 0; i < 4; i++)
          poly[i] = getreal(11);
        for (i = 0; i < 0x10000; i++)
        {
          for (num = 0, j = 4; j--;)
            num = num * i + poly[j];
          curve[i] = LIM(num + i, 0, 65535);
        }
      apply: /* apply to whole image */
        for (row = 0; row < raw_height; row++)
        {
          checkCancel();
          for (col = (tag & 1) * ph1.split_col; col < raw_width; col++)
            RAW(row, col) = curve[RAW(row, col)];
        }
      }
      else if (tag == 0x0400)
      { /* Sensor defects */
        while ((len -= 8) >= 0)
        {
          col = get2();
          row = get2();
          type = get2();
          get2();
          if (col >= raw_width)
            continue;
          if (type == 131 || type == 137) /* Bad column */
            for (row = 0; row < raw_height; row++)
              if (FC(row - top_margin, col - left_margin) == 1)
              {
                for (sum = i = 0; i < 4; i++)
                  sum += val[i] = p1raw(row + dir[i][0], col + dir[i][1]);
                for (max = i = 0; i < 4; i++)
                {
                  dev[i] = abs((val[i] << 2) - sum);
                  if (dev[max] < dev[i])
                    max = i;
                }
                RAW(row, col) = (sum - val[max]) / 3.0 + 0.5;
              }
              else
              {
                for (sum = 0, i = 8; i < 12; i++)
                  sum += p1raw(row + dir[i][0], col + dir[i][1]);
                RAW(row, col) =
                    0.5 + sum * 0.0732233 +
                    (p1raw(row, col - 2) + p1raw(row, col + 2)) * 0.3535534;
              }
          else if (type == 129)
          { /* Bad pixel */
            if (row >= raw_height)
              continue;
            j = (FC(row - top_margin, col - left_margin) != 1) * 4;
            for (sum = 0, i = j; i < j + 8; i++)
              sum += p1raw(row + dir[i][0], col + dir[i][1]);
            RAW(row, col) = (sum + 4) >> 3;
          }
        }
      }
      else if (tag == 0x0401)
      { /* All-color flat fields */
        phase_one_flat_field(1, 2);
      }
      else if (tag == 0x0416 || tag == 0x0410)
      {
        phase_one_flat_field(0, 2);
      }
      else if (tag == 0x040b)
      { /* Red+blue flat field */
        phase_one_flat_field(0, 4);
      }
      else if (tag == 0x0412)
      {
        fseek(ifp, 36, SEEK_CUR);
        diff = abs(get2() - ph1.tag_21a);
        if (mindiff > diff)
        {
          mindiff = diff;
          off_412 = ftell(ifp) - 38;
        }
      }
      else if (tag == 0x041f && !qlin_applied)
      { /* Quadrant linearization */
        ushort lc[2][2][16], ref[16];
        int qr, qc;
        for (qr = 0; qr < 2; qr++)
          for (qc = 0; qc < 2; qc++)
            for (i = 0; i < 16; i++)
              lc[qr][qc][i] = get4();
        for (i = 0; i < 16; i++)
        {
          int v = 0;
          for (qr = 0; qr < 2; qr++)
            for (qc = 0; qc < 2; qc++)
              v += lc[qr][qc][i];
          ref[i] = (v + 2) >> 2;
        }
        for (qr = 0; qr < 2; qr++)
        {
          for (qc = 0; qc < 2; qc++)
          {
            int cx[19], cf[19];
            for (i = 0; i < 16; i++)
            {
              cx[1 + i] = lc[qr][qc][i];
              cf[1 + i] = ref[i];
            }
            cx[0] = cf[0] = 0;
            cx[17] = cf[17] = ((unsigned int)ref[15] * 65535) / lc[qr][qc][15];
            cf[18] = cx[18] = 65535;
            cubic_spline(cx, cf, 19);

            for (row = (qr ? ph1.split_row : 0);
                 row < (qr ? raw_height : ph1.split_row); row++)
            {
              checkCancel();
              for (col = (qc ? ph1.split_col : 0);
                   col < (qc ? raw_width : ph1.split_col); col++)
                RAW(row, col) = curve[RAW(row, col)];
            }
          }
        }
        qlin_applied = 1;
      }
      else if (tag == 0x041e && !qmult_applied)
      { /* Quadrant multipliers */
        float qmult[2][2] = {{1, 1}, {1, 1}};
        get4();
        get4();
        get4();
        get4();
        qmult[0][0] = 1.0 + getreal(11);
        get4();
        get4();
        get4();
        get4();
        get4();
        qmult[0][1] = 1.0 + getreal(11);
        get4();
        get4();
        get4();
        qmult[1][0] = 1.0 + getreal(11);
        get4();
        get4();
        get4();
        qmult[1][1] = 1.0 + getreal(11);
        for (row = 0; row < raw_height; row++)
        {
          checkCancel();
          for (col = 0; col < raw_width; col++)
          {
            i = qmult[row >= ph1.split_row][col >= ph1.split_col] *
                RAW(row, col);
            RAW(row, col) = LIM(i, 0, 65535);
          }
        }
        qmult_applied = 1;
      }
      else if (tag == 0x0431 && !qmult_applied)
      { /* Quadrant combined */
        ushort lc[2][2][7], ref[7];
        int qr, qc;
        for (i = 0; i < 7; i++)
          ref[i] = get4();
        for (qr = 0; qr < 2; qr++)
          for (qc = 0; qc < 2; qc++)
            for (i = 0; i < 7; i++)
              lc[qr][qc][i] = get4();
        for (qr = 0; qr < 2; qr++)
        {
          for (qc = 0; qc < 2; qc++)
          {
            int cx[9], cf[9];
            for (i = 0; i < 7; i++)
            {
              cx[1 + i] = ref[i];
              cf[1 + i] = ((unsigned)ref[i] * lc[qr][qc][i]) / 10000;
            }
            cx[0] = cf[0] = 0;
            cx[8] = cf[8] = 65535;
            cubic_spline(cx, cf, 9);
            for (row = (qr ? ph1.split_row : 0);
                 row < (qr ? raw_height : ph1.split_row); row++)
            {
              checkCancel();
              for (col = (qc ? ph1.split_col : 0);
                   col < (qc ? raw_width : ph1.split_col); col++)
                RAW(row, col) = curve[RAW(row, col)];
            }
          }
        }
        qmult_applied = 1;
        qlin_applied = 1;
      }
      fseek(ifp, save, SEEK_SET);
    }
    if (off_412)
    {
      fseek(ifp, off_412, SEEK_SET);
      for (i = 0; i < 9; i++)
        head[i] = get4() & 0x7fff;
      yval[0] = (float *)calloc(head[1] * head[3] + head[2] * head[4], 6);
      merror(yval[0], "phase_one_correct()");
      yval[1] = (float *)(yval[0] + head[1] * head[3]);
      xval[0] = (ushort *)(yval[1] + head[2] * head[4]);
      xval[1] = (ushort *)(xval[0] + head[1] * head[3]);
      get2();
      for (i = 0; i < 2; i++)
        for (j = 0; j < head[i + 1] * head[i + 3]; j++)
          yval[i][j] = getreal(11);
      for (i = 0; i < 2; i++)
        for (j = 0; j < head[i + 1] * head[i + 3]; j++)
          xval[i][j] = get2();
      for (row = 0; row < raw_height; row++)
      {
        checkCancel();
        for (col = 0; col < raw_width; col++)
        {
          cfrac = (float)col * head[3] / raw_width;
          cfrac -= cip = cfrac;
          num = RAW(row, col) * 0.5;
          for (i = cip; i < cip + 2; i++)
          {
            for (k = j = 0; j < head[1]; j++)
              if (num < xval[0][k = head[1] * i + j])
                break;
            frac = (j == 0 || j == head[1])
                       ? 0
                       : (xval[0][k] - num) / (xval[0][k] - xval[0][k - 1]);
            mult[i - cip] = yval[0][k - 1] * frac + yval[0][k] * (1 - frac);
          }
          i = ((mult[0] * (1 - cfrac) + mult[1] * cfrac) * row + num) * 2;
          RAW(row, col) = LIM(i, 0, 65535);
        }
      }
      free(yval[0]);
    }
  }
  catch (...)
  {
    if (yval[0])
      free(yval[0]);
    return LIBRAW_CANCELLED_BY_CALLBACK;
  }
  return 0;
}

Project: LibRaw

  libraw_imgother_t *libraw_get_imgother(libraw_data_t *lr)
  {
    if (!lr)
      return NULL;
    return &(lr->other);
  }

Project: LibRaw

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

#define isRIC imgdata.sizes.raw_inset_crop

  unsigned offset = 0, entries, tag, type, len, save;
  short morder, sorder = order;
  ushort c;
  INT64 fsize = ifp->size();

  fseek(ifp, -2, SEEK_CUR);

  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 (tag == 0x020b)
    {
      if (type == 4)
        isRIC.cwidth = get4();
      else if (type == 3)
        isRIC.cwidth = get2();
    }
    else if (tag == 0x020c)
    {
      if (type == 4)
        isRIC.cheight = get4();
      else if (type == 3)
        isRIC.cheight = get2();
    }
    else if (tag == 0x0400)
    {                                 // sensor area
      ushort sdims[4] = {0, 0, 0, 0}; // left margin, top margin, width, height
      FORC4 sdims[c] = get2();
      isRIC.cleft = (sdims[2] - sdims[0] - isRIC.cwidth) / 2;
      isRIC.ctop = (sdims[3] - sdims[1] - isRIC.cheight) / 2;
    }

    if (dng_writer == nonDNG)
    {

      if (tag == 0x0280)
      {
        thumb_offset = ftell(ifp);
        thumb_length = len;
      }
      else if (tag == 0x0401)
      {
        FORC4 cblack[c ^ c >> 1] = get4();
      }
      else if (tag == 0x0e80)
      {
        fseek(ifp, 48, SEEK_CUR);
        cam_mul[0] = get2() * 567.0 / 0x10000;
        cam_mul[2] = get2() * 431.0 / 0x10000;
      }
    }

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

Project: LibRaw

void LibRaw::jpeg_thumb()
{
  char *thumb;

  thumb = (char *)malloc(thumb_length);
  merror(thumb, "jpeg_thumb()");
  fread(thumb, 1, thumb_length, ifp);
  jpeg_thumb_writer(ofp, thumb, thumb_length);
  free(thumb);
}

Project: LibRaw

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

  unsigned kodak = !strncmp(make, "EASTMAN", 7) && tiff_nifds < 3;

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

    INT64 savepos = ftell(ifp);
    if (len > 8 && savepos + len > fsize * 2)
    {
      fseek(ifp, save, SEEK_SET); // Recover tiff-read position!!
      continue;
    }
    if (callbacks.exif_cb)
    {
      callbacks.exif_cb(callbacks.exifparser_data, tag, type, len, order, ifp,
                        base);
      fseek(ifp, savepos, SEEK_SET);
    }

    switch (tag)
    {

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

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

        fgets(mn_text, MIN(len, 511), ifp);
        mn_text[511] = 0;

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

        pos = strstr(mn_text, "ccm=");
        if (pos)
        {
          pos += 4;
          char *pos2 = strstr(pos, " ");
          if (pos2)
          {
            l = pos2 - pos;
            memcpy(ccms, pos, l);
            ccms[l] = '\0';
#ifdef LIBRAW_WIN32_CALLS
            // Win32 strtok is already thread-safe
            pos = strtok(ccms, ",");
#else
            char *last = 0;
            pos = strtok_r(ccms, ",", &last);
#endif
            if (pos)
            {
              for (l = 0; l < 4; l++)
              {
                num = 0.0;
                for (c = 0; c < 3; c++)
                {
                  imgdata.color.ccm[l][c] = (float)atoi(pos);
                  num += imgdata.color.ccm[l][c];
#ifdef LIBRAW_WIN32_CALLS
                  pos = strtok(NULL, ",");
#else
                  pos = strtok_r(NULL, ",", &last);
#endif
                  if (!pos)
                    goto end; // broken
                }
                if (num > 0.01)
                  FORC3 imgdata.color.ccm[l][c] = imgdata.color.ccm[l][c] / num;
              }
            }
          }
        }
      end:;
      }
      else if (!strncmp(make, "SONY", 4) &&
               (!strncmp(model, "DSC-V3", 6) || !strncmp(model, "DSC-F828", 8)))
      {
        parseSonySRF(len);
        break;
      }
      else if ((len == 1) && !strncmp(make, "NIKON", 5))
      {
        c = get4();
        if (c)
          fseek(ifp, c, SEEK_SET);
        is_NikonTransfer = 1;
      }
      parse_makernote(base, 0);
      break;
    case 0xa002: // 40962
      if (kodak)
        raw_width = get4();
      break;
    case 0xa003: // 40963
      if (kodak)
        raw_height = get4();
      break;
    case 0xa302: // 41730
      if (get4() == 0x20002)
        for (exif_cfa = c = 0; c < 8; c += 2)
          exif_cfa |= fgetc(ifp) * 0x01010101U << c;
    }
    fseek(ifp, save, SEEK_SET);
  }
}

Project: LibRaw

void LibRaw::fuji_decode_strip(const struct fuji_compressed_params *info_common,
                               int cur_block, INT64 raw_offset, unsigned dsize)
{
  int cur_block_width, cur_line;
  unsigned line_size;
  struct fuji_compressed_block info;

  init_fuji_block(&info, info_common, raw_offset, dsize);
  line_size = sizeof(ushort) * (info_common->line_width + 2);

  cur_block_width = libraw_internal_data.unpacker_data.fuji_block_width;
  if (cur_block + 1 == libraw_internal_data.unpacker_data.fuji_total_blocks)
  {
    cur_block_width =
        imgdata.sizes.raw_width -
        (libraw_internal_data.unpacker_data.fuji_block_width * cur_block);
    /* Old code, may get incorrect results on GFX50, but luckily large optical
    black cur_block_width = imgdata.sizes.raw_width %
    libraw_internal_data.unpacker_data.fuji_block_width;
    */
  }

  struct i_pair
  {
    int a, b;
  };
  const i_pair mtable[6] = {{_R0, _R3}, {_R1, _R4}, {_G0, _G6},
                            {_G1, _G7}, {_B0, _B3}, {_B1, _B4}},
               ztable[3] = {{_R2, 3}, {_G2, 6}, {_B2, 3}};
  for (cur_line = 0;
       cur_line < libraw_internal_data.unpacker_data.fuji_total_lines;
       cur_line++)
  {
    if (libraw_internal_data.unpacker_data.fuji_raw_type == 16)
      xtrans_decode_block(&info, info_common, cur_line);
    else
      fuji_bayer_decode_block(&info, info_common, cur_line);

    // copy data from line buffers and advance
    for (int i = 0; i < 6; i++)
      memcpy(info.linebuf[mtable[i].a], info.linebuf[mtable[i].b], line_size);

    if (libraw_internal_data.unpacker_data.fuji_raw_type == 16)
      copy_line_to_xtrans(&info, cur_line, cur_block, cur_block_width);
    else
      copy_line_to_bayer(&info, cur_line, cur_block, cur_block_width);

    for (int i = 0; i < 3; i++)
    {
      memset(info.linebuf[ztable[i].a], 0, ztable[i].b * line_size);
      info.linebuf[ztable[i].a][0] = info.linebuf[ztable[i].a - 1][1];
      info.linebuf[ztable[i].a][info_common->line_width + 1] =
          info.linebuf[ztable[i].a - 1][info_common->line_width];
    }
  }

  // release data
  free(info.linealloc);
  free(info.cur_buf);
}

Project: LibRaw

int LibRaw::have_fpdata()
{
  return imgdata.rawdata.float_image || imgdata.rawdata.float3_image ||
         imgdata.rawdata.float4_image;
}

Project: LibRaw
File: exif_gps.cpp

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

  entries = get2();
  if (entries > 40)
    return;
  while (entries--)
  {
    tiff_get(base, &tag, &type, &len, &save);
    if (len > 1024)
    {
      fseek(ifp, save, SEEK_SET); // Recover tiff-read position!!
      continue;                   // no GPS tags are 1k or larger
    }
    switch (tag)
    {
    case 0x0001:
    case 0x0003:
    case 0x0005:
      gpsdata[29 + tag / 2] = getc(ifp);
      break;
    case 0x0002:
    case 0x0004:
    case 0x0007:
      FORC(6) gpsdata[tag / 3 * 6 + c] = get4();
      break;
    case 0x0006:
      FORC(2) gpsdata[18 + c] = get4();
      break;
    case 0x0012: // 18
    case 0x001d: // 29
      fgets((char *)(gpsdata + 14 + tag / 3), MIN(len, 12), ifp);
    }
    fseek(ifp, save, SEEK_SET);
  }
}

Project: LibRaw

AAHD::~AAHD() { free(rgb_ahd[0]); }

Project: LibRaw

void LibRaw::parse_ciff(int offset, int length, int depth)
{

  int tboff, nrecs, c, type, len, save, wbi = -1;
  ushort key[] = {0x410, 0x45f3};
  INT64 fsize = ifp->size();
  if (metadata_blocks++ > LIBRAW_MAX_METADATA_BLOCKS)
    throw LIBRAW_EXCEPTION_IO_CORRUPT;

  fseek(ifp, offset + length - 4, SEEK_SET);
  tboff = get4() + offset;
  fseek(ifp, tboff, SEEK_SET);
  nrecs = get2();
  if (nrecs < 1)
    return;
  if ((nrecs | depth) > 127)
    return;

  if (nrecs * 10 + offset > fsize)
    return;

  while (nrecs--)
  {
    type = get2();
    len = get4();
    INT64 see = offset + get4();
    save = ftell(ifp);

    /* the following tags are not sub-tables
     * they contain the value in the "len" field
     * for such tags skip the check against filesize
     */
    if ((type != 0x2007) && (type != 0x580b) && (type != 0x501c) &&
        (type != 0x5029) && (type != 0x5813) && (type != 0x5814) &&
        (type != 0x5817) && (type != 0x5834) && (type != 0x580e))
    {

      if (see >= fsize)
      { // At least one byte
        fseek(ifp, save, SEEK_SET);
        continue;
      }
      fseek(ifp, see, SEEK_SET);
      if ((((type >> 8) + 8) | 8) == 0x38)
      {
        parse_ciff(ftell(ifp), len, depth + 1); /* Parse a sub-table */
      }
    }

    if (type == 0x3004)
    {
      parse_ciff(ftell(ifp), len, depth + 1);
    }
    else if (type == 0x0810)
    {
      fread(artist, 64, 1, ifp);
    }
    else if (type == 0x080a)
    {
      fread(make, 64, 1, ifp);
      fseek(ifp, strbuflen(make) - 63, SEEK_CUR);
      fread(model, 64, 1, ifp);
    }
    else if (type == 0x1810)
    {
      width = get4();
      height = get4();
      pixel_aspect = int_to_float(get4());
      flip = get4();
    }
    else if (type == 0x1835)
    { /* Get the decoder table */
      tiff_compress = get4();
    }
    else if (type == 0x2007)
    {
      thumb_offset = see;
      thumb_length = len;
    }
    else if (type == 0x1818)
    {
      shutter = libraw_powf64l(2.0f, -int_to_float((get4(), get4())));
      ilm.CurAp = aperture = libraw_powf64l(2.0f, int_to_float(get4()) / 2);
    }
    else if (type == 0x102a)
    {
      //      iso_speed = pow (2.0, (get4(),get2())/32.0 - 4) * 50;
      get2(); // skip one
      iso_speed =
          libraw_powf64l(2.0f, (get2() + get2()) / 32.0f - 5.0f) * 100.0f;
      ilm.CurAp = aperture = _CanonConvertAperture((get2(), get2()));
      shutter = libraw_powf64l(2.0, -((short)get2()) / 32.0);
      wbi = (get2(), get2());
      if (wbi > 17)
        wbi = 0;
      fseek(ifp, 32, SEEK_CUR);
      if (shutter > 1e6)
        shutter = get2() / 10.0;
    }
    else if (type == 0x102c)
    {
      if (get2() > 512)
      { /* Pro90, G1 */
        fseek(ifp, 118, SEEK_CUR);
        FORC4 cam_mul[c ^ 2] = get2();
      }
      else
      { /* G2, S30, S40 */
        fseek(ifp, 98, SEEK_CUR);
        FORC4 cam_mul[c ^ (c >> 1) ^ 1] = get2();
      }
    }
    else if (type == 0x10a9)
    { /* Canon D60, 10D, 300D, and clones */

      int bls = 0;
      int table[] = {
          LIBRAW_WBI_Auto,     // 0
          LIBRAW_WBI_Daylight, // 1
          LIBRAW_WBI_Cloudy,   // 2
          LIBRAW_WBI_Tungsten, // 3
          LIBRAW_WBI_FL_W,     // 4
          LIBRAW_WBI_Flash,    // 5
          LIBRAW_WBI_Custom,   // 6, absent in Canon D60
          LIBRAW_WBI_Auto,     // 7, use this if camera is set to b/w JPEG
          LIBRAW_WBI_Shade,    // 8
          LIBRAW_WBI_Kelvin    // 9, absent in Canon D60
      };
      int nWB =
          ((get2() - 2) / 8) -
          1; // 2 bytes this, N recs 4*2bytes each, last rec is black level
      if (nWB)
        FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_Auto][c ^ (c >> 1)] = get2();
      if (nWB >= 7)
        Canon_WBpresets(0, 0);
      else
        FORC4 cam_mul[c] = imgdata.color.WB_Coeffs[LIBRAW_WBI_Auto][c];
      if (nWB == 7)
      { /* mostly Canon EOS D60 + some fw#s for 300D; check for 0x1668000 is
           unreliable */
        if ((wbi >= 0) && (wbi < 9) && (wbi != 6))
        {
          FORC4 cam_mul[c] = imgdata.color.WB_Coeffs[wbi][c];
        }
        else
        {
          FORC4 cam_mul[c] = imgdata.color.WB_Coeffs[LIBRAW_WBI_Auto][c];
        }
      }
      else if (nWB == 9)
      { /* Canon 10D, 300D */
        FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_Custom][c ^ (c >> 1)] = get2();
        FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_Kelvin][c ^ (c >> 1)] = get2();
        if ((wbi >= 0) && (wbi < 10))
        {
          FORC4 cam_mul[c] = imgdata.color.WB_Coeffs[wbi][c];
        }
        else
        {
          FORC4 cam_mul[c] = imgdata.color.WB_Coeffs[LIBRAW_WBI_Auto][c];
        }
      }
      FORC4
      bls += (imCanon.ChannelBlackLevel[c ^ (c >> 1)] = get2());
      imCanon.AverageBlackLevel = bls / 4;
    }
    else if (type == 0x102d)
    {
      Canon_CameraSettings(len >> 1);
    }
    else if (type == 0x580b)
    {
      if (strcmp(model, "Canon EOS D30"))
        sprintf(imgdata.shootinginfo.BodySerial, "%d", len);
      else
        sprintf(imgdata.shootinginfo.BodySerial, "%0x-%05d", len >> 16,
                len & 0xffff);
    }
    else if (type == 0x0032)
    {
      if (len == 768)
      { /* EOS D30 */
        fseek(ifp, 72, SEEK_CUR);
        FORC4
        {
          ushort q = get2();
          cam_mul[c ^ (c >> 1)] = 1024.0 / MAX(1, q);
        }
        if (!wbi)
          cam_mul[0] = -1; /* use my auto white balance */
      }
      else if (cam_mul[0] <= 0.001f)
      {
        if (get2() == key[0]) /* Pro1, G6, S60, S70 */
          c = (strstr(model, "Pro1") ? "012346000000000000"
                                     : "01345:000000006008")[LIM(0, wbi, 17)] -
              '0' + 2;
        else
        { /* G3, G5, S45, S50 */
          c = "023457000000006000"[LIM(0, wbi, 17)] - '0';
          key[0] = key[1] = 0;
        }
        fseek(ifp, 78 + c * 8, SEEK_CUR);
        FORC4 cam_mul[c ^ (c >> 1) ^ 1] = get2() ^ key[c & 1];
        if (!wbi)
          cam_mul[0] = -1;
      }
    }
    else if (type == 0x1030 && wbi >= 0 && (0x18040 >> wbi & 1))
    {
      ciff_block_1030(); /* all that don't have 0x10a9 */
    }
    else if (type == 0x1031)
    {
      raw_width = (get2(), get2());
      raw_height = get2();
    }
    else if (type == 0x501c)
    {
      iso_speed = len & 0xffff;
    }
    else if (type == 0x5029)
    {
      ilm.CurFocal = len >> 16;
      ilm.FocalType = len & 0xffff;
      if (ilm.FocalType == LIBRAW_FT_ZOOM_LENS)
      {
        ilm.FocalUnits = 32;
        if (ilm.FocalUnits > 1)
          ilm.CurFocal /= (float)ilm.FocalUnits;
      }
      focal_len = ilm.CurFocal;
    }
    else if (type == 0x5813)
    {
      flash_used = int_to_float(len);
    }
    else if (type == 0x5814)
    {
      canon_ev = int_to_float(len);
    }
    else if (type == 0x5817)
    {
      shot_order = len;
    }
    else if (type == 0x5834)
    {
      unique_id = ((unsigned long long)len << 32) >> 32;
      setCanonBodyFeatures(unique_id);
    }
    else if (type == 0x580e)
    {
      timestamp = len;
    }
    else if (type == 0x180e)
    {
      timestamp = get4();
    }

#ifdef LOCALTIME
    if ((type | 0x4000) == 0x580e)
      timestamp = mktime(gmtime(&timestamp));
#endif
    fseek(ifp, save, SEEK_SET);
  }
}

Project: LibRaw

void LibRaw::parseSonySR2(uchar *cbuf_SR2, unsigned SR2SubIFDOffset,
                          unsigned SR2SubIFDLength, unsigned dng_writer)
{
  unsigned c;
  unsigned entries, tag, type, len;
  unsigned icbuf_SR2;
  int ival;
  int TagProcessed;
  float num;
  int i;
  entries = sget2(cbuf_SR2);
  if (entries > 1000)
    return;
  icbuf_SR2 = 2;
  while (entries--)
  {
    tag = sget2(cbuf_SR2 + icbuf_SR2);
    icbuf_SR2 += 2;
    type = sget2(cbuf_SR2 + icbuf_SR2);
    icbuf_SR2 += 2;
    len = sget4(cbuf_SR2 + icbuf_SR2);
    icbuf_SR2 += 4;

    if (len * ("11124811248484"[type < 14 ? type : 0] - '0') > 4)
    {
      ival = sget4(cbuf_SR2 + icbuf_SR2) - SR2SubIFDOffset;
    }
    else
    {
      ival = icbuf_SR2;
    }
    if (ival > SR2SubIFDLength) // points out of orig. buffer size
      break; // END processing. Generally we should check against
             // SR2SubIFDLength minus 6 of 8, depending on tag, but we allocated
             // extra 1024b for buffer, so this does not matter

    icbuf_SR2 += 4;
    TagProcessed = 0;

    if (dng_writer == nonDNG)
    {
      switch (tag)
      {
      case 0x7300:
        for (c = 0; c < 4 && c < len; c++)
          cblack[c] = sget2(cbuf_SR2 + ival + 2 * c);
        TagProcessed = 1;
        break;
      case 0x7303:
        FORC4 cam_mul[c ^ (c < 2)] = sget2(cbuf_SR2 + ival + 2 * c);
        TagProcessed = 1;
        break;
      case 0x7310:
        FORC4 cblack[c ^ c >> 1] = sget2(cbuf_SR2 + ival + 2 * c);
        i = cblack[3];
        FORC3 if (i > cblack[c]) i = cblack[c];
        FORC4 cblack[c] -= i;
        black = i;
        TagProcessed = 1;
        break;
      case 0x7313:
        FORC4 cam_mul[c ^ (c >> 1)] = sget2(cbuf_SR2 + ival + 2 * c);
        TagProcessed = 1;
        break;
      case 0x74a0:
        c = sget4(cbuf_SR2 + ival + 4);
        if (c)
          ilm.MaxAp4MaxFocal = ((float)sget4(cbuf_SR2 + ival)) / ((float)c);
        TagProcessed = 1;
        break;
      case 0x74a1:
        c = sget4(cbuf_SR2 + ival + 4);
        if (c)
          ilm.MaxAp4MinFocal = ((float)sget4(cbuf_SR2 + ival)) / ((float)c);
        TagProcessed = 1;
        break;
      case 0x74a2:
        c = sget4(cbuf_SR2 + ival + 4);
        if (c)
          ilm.MaxFocal = ((float)sget4(cbuf_SR2 + ival)) / ((float)c);
        TagProcessed = 1;
        break;
      case 0x74a3:
        c = sget4(cbuf_SR2 + ival + 4);
        if (c)
          ilm.MinFocal = ((float)sget4(cbuf_SR2 + ival)) / ((float)c);
        TagProcessed = 1;
        break;
      case 0x7800:
        for (i = 0; i < 3; i++)
        {
          num = 0.0;
          for (c = 0; c < 3; c++)
          {
            imgdata.color.ccm[i][c] =
                (float)((short)sget2(cbuf_SR2 + ival + 2 * (i * 3 + c)));
            num += imgdata.color.ccm[i][c];
          }
          if (num > 0.01)
            FORC3 imgdata.color.ccm[i][c] = imgdata.color.ccm[i][c] / num;
        }
        TagProcessed = 1;
        break;
      case 0x787f:
        if (len == 3)
        {
          FORC3 imgdata.color.linear_max[c] = sget2(cbuf_SR2 + ival + 2 * c);
          imgdata.color.linear_max[3] = imgdata.color.linear_max[1];
        }
        else if (len == 1)
        {
          imgdata.color.linear_max[0] = imgdata.color.linear_max[1] =
              imgdata.color.linear_max[2] = imgdata.color.linear_max[3] =
                  sget2(cbuf_SR2 + ival);
        }
        TagProcessed = 1;
        break;
      }
    }

    if (!TagProcessed)
    {
      switch (tag)
      {
      case 0x7302:
        FORC4 icWBC[LIBRAW_WBI_Auto][c ^ (c < 2)] =
            sget2(cbuf_SR2 + ival + 2 * c);
        break;
      case 0x7312:
        FORC4 icWBC[LIBRAW_WBI_Auto][c ^ (c >> 1)] =
            sget2(cbuf_SR2 + ival + 2 * c);
        break;
      case 0x7480:
      case 0x7820:
        FORC3 icWBC[LIBRAW_WBI_Daylight][c] = sget2(cbuf_SR2 + ival + 2 * c);
        icWBC[LIBRAW_WBI_Daylight][3] = icWBC[LIBRAW_WBI_Daylight][1];
        break;
      case 0x7481:
      case 0x7821:
        FORC3 icWBC[LIBRAW_WBI_Cloudy][c] = sget2(cbuf_SR2 + ival + 2 * c);
        icWBC[LIBRAW_WBI_Cloudy][3] = icWBC[LIBRAW_WBI_Cloudy][1];
        break;
      case 0x7482:
      case 0x7822:
        FORC3 icWBC[LIBRAW_WBI_Tungsten][c] = sget2(cbuf_SR2 + ival + 2 * c);
        icWBC[LIBRAW_WBI_Tungsten][3] = icWBC[LIBRAW_WBI_Tungsten][1];
        break;
      case 0x7483:
      case 0x7823:
        FORC3 icWBC[LIBRAW_WBI_Flash][c] = sget2(cbuf_SR2 + ival + 2 * c);
        icWBC[LIBRAW_WBI_Flash][3] = icWBC[LIBRAW_WBI_Flash][1];
        break;
      case 0x7484:
      case 0x7824:
        icWBCTC[0][0] = 4500;
        FORC3 icWBCTC[0][c + 1] = sget2(cbuf_SR2 + ival + 2 * c);
        icWBCTC[0][4] = icWBCTC[0][2];
        break;
      case 0x7486:
        FORC3 icWBC[LIBRAW_WBI_Fluorescent][c] = sget2(cbuf_SR2 + ival + 2 * c);
        icWBC[LIBRAW_WBI_Fluorescent][3] = icWBC[LIBRAW_WBI_Fluorescent][1];
        break;
      case 0x7825:
        FORC3 icWBC[LIBRAW_WBI_Shade][c] = sget2(cbuf_SR2 + ival + 2 * c);
        icWBC[LIBRAW_WBI_Shade][3] = icWBC[LIBRAW_WBI_Shade][1];
        break;
      case 0x7826:
        FORC3 icWBC[LIBRAW_WBI_FL_W][c] = sget2(cbuf_SR2 + ival + 2 * c);
        icWBC[LIBRAW_WBI_FL_W][3] = icWBC[LIBRAW_WBI_FL_W][1];
        break;
      case 0x7827:
        FORC3 icWBC[LIBRAW_WBI_FL_N][c] = sget2(cbuf_SR2 + ival + 2 * c);
        icWBC[LIBRAW_WBI_FL_N][3] = icWBC[LIBRAW_WBI_FL_N][1];
        break;
      case 0x7828:
        FORC3 icWBC[LIBRAW_WBI_FL_D][c] = sget2(cbuf_SR2 + ival + 2 * c);
        icWBC[LIBRAW_WBI_FL_D][3] = icWBC[LIBRAW_WBI_FL_D][1];
        break;
      case 0x7829:
        FORC3 icWBC[LIBRAW_WBI_FL_L][c] = sget2(cbuf_SR2 + ival + 2 * c);
        icWBC[LIBRAW_WBI_FL_L][3] = icWBC[LIBRAW_WBI_FL_L][1];
        break;
      case 0x782a:
        icWBCTC[1][0] = 8500;
        FORC3 icWBCTC[1][c + 1] = sget2(cbuf_SR2 + ival + 2 * c);
        icWBCTC[1][4] = icWBCTC[1][2];
        break;
      case 0x782b:
        icWBCTC[2][0] = 6000;
        FORC3 icWBCTC[2][c + 1] = sget2(cbuf_SR2 + ival + 2 * c);
        icWBCTC[2][4] = icWBCTC[2][2];
        break;
      case 0x782c:
        icWBCTC[3][0] = 3200;
        FORC3 icWBC[LIBRAW_WBI_StudioTungsten][c] = icWBCTC[3][c + 1] =
            sget2(cbuf_SR2 + ival + 2 * c);
        icWBC[LIBRAW_WBI_StudioTungsten][3] = icWBCTC[3][4] = icWBCTC[3][2];
        ;
        break;
      case 0x782d:
        icWBCTC[4][0] = 2500;
        FORC3 icWBCTC[4][c + 1] = sget2(cbuf_SR2 + ival + 2 * c);
        icWBCTC[4][4] = icWBCTC[4][2];
        break;
      }
    }
  }
}

Project: LibRaw

void LibRaw::exp_bef(float shift, float smooth)
{
  // params limits
  if (shift > 8)
    shift = 8;
  if (shift < 0.25)
    shift = 0.25;
  if (smooth < 0.0)
    smooth = 0.0;
  if (smooth > 1.0)
    smooth = 1.0;

  unsigned short *lut = (ushort *)malloc((TBLN + 1) * sizeof(unsigned short));

  if (shift <= 1.0)
  {
    for (int i = 0; i <= TBLN; i++)
      lut[i] = (unsigned short)((float)i * shift);
  }
  else
  {
    float x1, x2, y1, y2;

    float cstops = log(shift) / log(2.0f);
    float room = cstops * 2;
    float roomlin = powf(2.0f, room);
    x2 = (float)TBLN;
    x1 = (x2 + 1) / roomlin - 1;
    y1 = x1 * shift;
    y2 = x2 * (1 + (1 - smooth) * (shift - 1));
    float sq3x = powf(x1 * x1 * x2, 1.0f / 3.0f);
    float B = (y2 - y1 + shift * (3 * x1 - 3.0f * sq3x)) /
              (x2 + 2.0f * x1 - 3.0f * sq3x);
    float A = (shift - B) * 3.0f * powf(x1 * x1, 1.0f / 3.0f);
    float CC = y2 - A * powf(x2, 1.0f / 3.0f) - B * x2;
    for (int i = 0; i <= TBLN; i++)
    {
      float X = (float)i;
      float Y = A * powf(X, 1.0f / 3.0f) + B * X + CC;
      if (i < x1)
        lut[i] = (unsigned short)((float)i * shift);
      else
        lut[i] = Y < 0 ? 0 : (Y > TBLN ? TBLN : (unsigned short)(Y));
    }
  }
  for (int i = 0; i < S.height * S.width; i++)
  {
    imgdata.image[i][0] = lut[imgdata.image[i][0]];
    imgdata.image[i][1] = lut[imgdata.image[i][1]];
    imgdata.image[i][2] = lut[imgdata.image[i][2]];
    imgdata.image[i][3] = lut[imgdata.image[i][3]];
  }

  if (C.data_maximum <= TBLN)
    C.data_maximum = lut[C.data_maximum];
  if (C.maximum <= TBLN)
    C.maximum = lut[C.maximum];
  free(lut);
}

Project: LibRaw

void LibRaw::copy_bayer(unsigned short cblack[4], unsigned short *dmaxp){}

Project: LibRaw

void LibRaw::removeExcessiveSpaces(char *string) // replace repeating spaces with one space
{
	int orig_len = strlen(string);
	int i = 0;   // counter for resulting string
	int j = -1;
	bool prev_char_is_space = false;
	while (++j < orig_len && string[j] == ' ');
	while (j < orig_len)  {
		if (string[j] != ' ')  {
				string[i++] = string[j++];
				prev_char_is_space = false;
		} else if (string[j++] == ' ') {
			if (!prev_char_is_space) {
				string[i++] = ' ';
				prev_char_is_space = true;
			}
		}
	}
	if (string[i-1] == ' ')
    string[i-1] = 0;
}

Project: LibRaw

int LibRaw::getwords(char *line, char *words[], int maxwords, int maxlen)
{
  line[maxlen - 1] = 0;
  char *p = line;
  int nwords = 0;

  while (1)
  {
    while (isspace(*p))
      p++;
    if (*p == '\0')
      return nwords;
    words[nwords++] = p;
    while (!isspace(*p) && *p != '\0')
      p++;
    if (*p == '\0')
      return nwords;
    *p++ = '\0';
    if (nwords >= maxwords)
      return nwords;
  }
}

Project: LibRaw

  void forget_ptr(void *ptr)
  {
    if (ptr)
      for (int i = 0; i < LIBRAW_MSIZE; i++)
        if (mems[i] == ptr)
        {
          mems[i] = NULL;
          break;
        }
  }