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::scale_colors()
{
  unsigned bottom, right, size, row, col, ur, uc, i, x, y, c, sum[8];
  int val, dark, sat;
  double dsum[8], dmin, dmax;
  float scale_mul[4], fr, fc;
  ushort *img = 0, *pix;

  RUN_CALLBACK(LIBRAW_PROGRESS_SCALE_COLORS, 0, 2);

  if (user_mul[0])
    memcpy(pre_mul, user_mul, sizeof pre_mul);
  if (use_auto_wb || (use_camera_wb && cam_mul[0] <= 0.00001f))
  {
    memset(dsum, 0, sizeof dsum);
    bottom = MIN(greybox[1] + greybox[3], height);
    right = MIN(greybox[0] + greybox[2], width);
    for (row = greybox[1]; row < bottom; row += 8)
      for (col = greybox[0]; col < right; col += 8)
      {
        memset(sum, 0, sizeof sum);
        for (y = row; y < row + 8 && y < bottom; y++)
          for (x = col; x < col + 8 && x < right; x++)
            FORC4
            {
              if (filters)
              {
                c = fcol(y, x);
                val = BAYER2(y, x);
              }
              else
                val = image[y * width + x][c];
              if (val > maximum - 25)
                goto skip_block;
              if ((val -= cblack[c]) < 0)
                val = 0;
              sum[c] += val;
              sum[c + 4]++;
              if (filters)
                break;
            }
        FORC(8) dsum[c] += sum[c];
      skip_block:;
      }
    FORC4 if (dsum[c]) pre_mul[c] = dsum[c + 4] / dsum[c];
  }
  if (use_camera_wb && cam_mul[0] > 0.00001f)
  {
    memset(sum, 0, sizeof sum);
    for (row = 0; row < 8; row++)
      for (col = 0; col < 8; col++)
      {
        c = FC(row, col);
        if ((val = white[row][col] - cblack[c]) > 0)
          sum[c] += val;
        sum[c + 4]++;
      }
    if (imgdata.color.as_shot_wb_applied)
    {
      // Nikon sRAW: camera WB already applied:
      pre_mul[0] = pre_mul[1] = pre_mul[2] = pre_mul[3] = 1.0;
    }
    else if (sum[0] && sum[1] && sum[2] && sum[3])
      FORC4 pre_mul[c] = (float)sum[c + 4] / sum[c];
    else if (cam_mul[0] > 0.00001f && cam_mul[2] > 0.00001f)
      memcpy(pre_mul, cam_mul, sizeof pre_mul);
    else
    {
      imgdata.process_warnings |= LIBRAW_WARN_BAD_CAMERA_WB;
    }
  }
  // Nikon sRAW, daylight
  if (imgdata.color.as_shot_wb_applied && !use_camera_wb && !use_auto_wb &&
      cam_mul[0] > 0.00001f && cam_mul[1] > 0.00001f && cam_mul[2] > 0.00001f)
  {
    for (c = 0; c < 3; c++)
      pre_mul[c] /= cam_mul[c];
  }
  if (pre_mul[1] == 0)
    pre_mul[1] = 1;
  if (pre_mul[3] == 0)
    pre_mul[3] = colors < 4 ? pre_mul[1] : 1;
  dark = black;
  sat = maximum;
  if (threshold)
    wavelet_denoise();
  maximum -= black;
  for (dmin = DBL_MAX, dmax = c = 0; c < 4; c++)
  {
    if (dmin > pre_mul[c])
      dmin = pre_mul[c];
    if (dmax < pre_mul[c])
      dmax = pre_mul[c];
  }
  if (!highlight)
    dmax = dmin;
  if (dmax > 0.00001 && maximum > 0)
    FORC4 scale_mul[c] = (pre_mul[c] /= dmax) * 65535.0 / maximum;
  else
    FORC4 scale_mul[c] = 1.0;

  if (filters > 1000 && (cblack[4] + 1) / 2 == 1 && (cblack[5] + 1) / 2 == 1)
  {
    FORC4 cblack[FC(c / 2, c % 2)] +=
        cblack[6 + c / 2 % cblack[4] * cblack[5] + c % 2 % cblack[5]];
    cblack[4] = cblack[5] = 0;
  }
  size = iheight * iwidth;
  scale_colors_loop(scale_mul);
  if ((aber[0] != 1 || aber[2] != 1) && colors == 3)
  {
    for (c = 0; c < 4; c += 2)
    {
      if (aber[c] == 1)
        continue;
      img = (ushort *)malloc(size * sizeof *img);
      merror(img, "scale_colors()");
      for (i = 0; i < size; i++)
        img[i] = image[i][c];
      for (row = 0; row < iheight; row++)
      {
        ur = fr = (row - iheight * 0.5) * aber[c] + iheight * 0.5;
        if (ur > iheight - 2)
          continue;
        fr -= ur;
        for (col = 0; col < iwidth; col++)
        {
          uc = fc = (col - iwidth * 0.5) * aber[c] + iwidth * 0.5;
          if (uc > iwidth - 2)
            continue;
          fc -= uc;
          pix = img + ur * iwidth + uc;
          image[row * iwidth + col][c] =
              (pix[0] * (1 - fc) + pix[1] * fc) * (1 - fr) +
              (pix[iwidth] * (1 - fc) + pix[iwidth + 1] * fc) * fr;
        }
      }
      free(img);
    }
  }
  RUN_CALLBACK(LIBRAW_PROGRESS_SCALE_COLORS, 1, 2);
}

Project: LibRaw

void LibRaw::parse_thumb_note(int base, unsigned toff, unsigned tlen)
{
  unsigned entries, tag, type, len, save;

  entries = get2();
  while (entries--)
  {
    tiff_get(base, &tag, &type, &len, &save);
    if (tag == toff)
      thumb_offset = get4() + base;
    if (tag == tlen)
      thumb_length = get4();
    fseek(ifp, save, SEEK_SET);
  }
}

Project: LibRaw
File: libraw_cxx.cpp

void LibRaw::get_mem_image_format(int *width, int *height, int *colors,
                                  int *bps) const

{
  if (S.flip & 4)
  {
    *width = S.height;
    *height = S.width;
  }
  else
  {
    *width = S.width;
    *height = S.height;
  }
  *colors = P1.colors;
  *bps = O.output_bps;
}

Project: LibRaw

const char *LibRaw_file_datastream::fname()
{
  return filename.size() > 0 ? filename.c_str() : NULL;
}

Project: LibRaw

void LibRaw::ppm_thumb(){}

Project: LibRaw

void LibRaw::parseOlympus_ImageProcessing(unsigned tag, unsigned type,
                                          unsigned len, unsigned dng_writer)
{
  // uptag 0x2040

  int i, c, wb[4], nWB, tWB, wbG;
  ushort CT;
  short sorder;

  if ((tag == 0x0100) && (dng_writer == nonDNG))
  {
    cam_mul[0] = get2() / 256.0;
    cam_mul[2] = get2() / 256.0;
  }
  else if ((tag == 0x0101) && (len == 2) &&
           (!strncasecmp(model, "E-410", 5) || !strncasecmp(model, "E-510", 5)))
  {
    for (i = 0; i < 64; i++)
    {
      imgdata.color.WBCT_Coeffs[i][2] = imgdata.color.WBCT_Coeffs[i][4] =
          imgdata.color.WB_Coeffs[i][1] = imgdata.color.WB_Coeffs[i][3] = 0x100;
    }
    for (i = 64; i < 256; i++)
    {
      imgdata.color.WB_Coeffs[i][1] = imgdata.color.WB_Coeffs[i][3] = 0x100;
    }
  }
  else if ((tag > 0x0101) && (tag <= 0x0111))
  {
    nWB = tag - 0x0101;
    tWB = Oly_wb_list2[nWB << 1];
    CT = Oly_wb_list2[(nWB << 1) | 1];
    wb[0] = get2();
    wb[2] = get2();
    if (tWB != 0x100)
    {
      imgdata.color.WB_Coeffs[tWB][0] = wb[0];
      imgdata.color.WB_Coeffs[tWB][2] = wb[2];
    }
    if (CT)
    {
      imgdata.color.WBCT_Coeffs[nWB - 1][0] = CT;
      imgdata.color.WBCT_Coeffs[nWB - 1][1] = wb[0];
      imgdata.color.WBCT_Coeffs[nWB - 1][3] = wb[2];
    }
    if (len == 4)
    {
      wb[1] = get2();
      wb[3] = get2();
      if (tWB != 0x100)
      {
        imgdata.color.WB_Coeffs[tWB][1] = wb[1];
        imgdata.color.WB_Coeffs[tWB][3] = wb[3];
      }
      if (CT)
      {
        imgdata.color.WBCT_Coeffs[nWB - 1][2] = wb[1];
        imgdata.color.WBCT_Coeffs[nWB - 1][4] = wb[3];
      }
    }
  }
  else if ((tag >= 0x0112) && (tag <= 0x011e))
  {
    nWB = tag - 0x0112;
    wbG = get2();
    tWB = Oly_wb_list2[nWB << 1];
    if (nWB)
      imgdata.color.WBCT_Coeffs[nWB - 1][2] =
          imgdata.color.WBCT_Coeffs[nWB - 1][4] = wbG;
    if (tWB != 0x100)
      imgdata.color.WB_Coeffs[tWB][1] = imgdata.color.WB_Coeffs[tWB][3] = wbG;
  }
  else if (tag == 0x011f)
  {
    wbG = get2();
    if (imgdata.color.WB_Coeffs[LIBRAW_WBI_Flash][0])
      imgdata.color.WB_Coeffs[LIBRAW_WBI_Flash][1] =
          imgdata.color.WB_Coeffs[LIBRAW_WBI_Flash][3] = wbG;
    FORC4 if (imgdata.color.WB_Coeffs[LIBRAW_WBI_Custom1 + c][0])
        imgdata.color.WB_Coeffs[LIBRAW_WBI_Custom1 + c][1] =
        imgdata.color.WB_Coeffs[LIBRAW_WBI_Custom1 + c][3] = wbG;
  }
  else if (tag == 0x0121)
  {
    imgdata.color.WB_Coeffs[LIBRAW_WBI_Flash][0] = get2();
    imgdata.color.WB_Coeffs[LIBRAW_WBI_Flash][2] = get2();
    if (len == 4)
    {
      imgdata.color.WB_Coeffs[LIBRAW_WBI_Flash][1] = get2();
      imgdata.color.WB_Coeffs[LIBRAW_WBI_Flash][3] = get2();
    }
  }
  else if ((tag == 0x0200) && (dng_writer == nonDNG) &&
           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 == 0x0600) && (dng_writer == nonDNG))
  {
    FORC4 cblack[c ^ c >> 1] = get2();
  }
  else if ((tag == 0x0612) && (dng_writer == nonDNG))
  {
    imgdata.sizes.raw_inset_crop.cleft = get2();
  }
  else if ((tag == 0x0613) && (dng_writer == nonDNG))
  {
    imgdata.sizes.raw_inset_crop.ctop = get2();
  }
  else if ((tag == 0x0614) && (dng_writer == nonDNG))
  {
    imgdata.sizes.raw_inset_crop.cwidth = get2();
  }
  else if ((tag == 0x0615) && (dng_writer == nonDNG))
  {
    imgdata.sizes.raw_inset_crop.cheight = get2();
  }
  else if ((tag == 0x0805) && (len == 2))
  {
    imOly.SensorCalibration[0] = getreal(type);
    imOly.SensorCalibration[1] = getreal(type);
    if (dng_writer == nonDNG)
      FORC4 imgdata.color.linear_max[c] = imOly.SensorCalibration[0];
  }
  else if (tag == 0x1112)
  {
    sorder = order;
    order = 0x4d4d;
    c = get2();
    order = sorder;
    switch (c)
    {
    case 0x21:
      imgdata.sizes.raw_inset_crop.aspect = LIBRAW_IMAGE_ASPECT_3to2;
      break;
    case 0x31:
      imgdata.sizes.raw_inset_crop.aspect = LIBRAW_IMAGE_ASPECT_16to9;
      break;
    case 0x41:
      imgdata.sizes.raw_inset_crop.aspect = LIBRAW_IMAGE_ASPECT_1to1;
      break;
    case 0x91:
      imgdata.sizes.raw_inset_crop.aspect = LIBRAW_IMAGE_ASPECT_4to3;
      break;
    }
  }
  else if (tag == 0x1113)
  {
    imgdata.sizes.raw_inset_crop.cleft = get2();
    imgdata.sizes.raw_inset_crop.ctop = get2();
    imgdata.sizes.raw_inset_crop.cwidth =
        get2() - imgdata.sizes.raw_inset_crop.cleft;
    imgdata.sizes.raw_inset_crop.cheight =
        get2() - imgdata.sizes.raw_inset_crop.ctop;
  }
  else if (tag == 0x1306)
  {
    c = get2();
    if ((c != 0) && (c != 100))
    {
      if (c < 61)
        imgdata.makernotes.common.CameraTemperature = (float)c;
      else
        imgdata.makernotes.common.CameraTemperature = (float)(c - 32) / 1.8f;
      if ((imgdata.makernotes.common.exifAmbientTemperature > -273.15f) &&
          ((OlyID == 0x4434353933ULL) || // TG-5
           (OlyID == 0x4434363033ULL))   // TG-6
      )
        imgdata.makernotes.common.CameraTemperature += imgdata.makernotes.common.exifAmbientTemperature;
    }
  }

  return;
}

Project: LibRaw

LibRaw_file_datastream::~LibRaw_file_datastream()
{
  if (jas_file)
    fclose(jas_file);
}

Project: LibRaw

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

Project: LibRaw

int LibRaw_buffer_datastream::valid() { return buf ? 1 : 0; }

Project: LibRaw

void LibRaw::ahd_interpolate_build_homogeneity_map(
    int top, int left, short (*lab)[LIBRAW_AHD_TILE][LIBRAW_AHD_TILE][3],
    char (*out_homogeneity_map)[LIBRAW_AHD_TILE][2])
{
  int row, col;
  int tr, tc;
  int direction;
  int i;
  short(*lix)[3];
  short(*lixs[2])[3];
  short *adjacent_lix;
  unsigned ldiff[2][4], abdiff[2][4], leps, abeps;
  static const int dir[4] = {-1, 1, -LIBRAW_AHD_TILE, LIBRAW_AHD_TILE};
  const int rowlimit = MIN(top + LIBRAW_AHD_TILE - 2, height - 4);
  const int collimit = MIN(left + LIBRAW_AHD_TILE - 2, width - 4);
  int homogeneity;
  char(*homogeneity_map_p)[2];

  memset(out_homogeneity_map, 0, 2 * LIBRAW_AHD_TILE * LIBRAW_AHD_TILE);

  for (row = top + 2; row < rowlimit; row++)
  {
    tr = row - top;
    homogeneity_map_p = &out_homogeneity_map[tr][1];
    for (direction = 0; direction < 2; direction++)
    {
      lixs[direction] = &lab[direction][tr][1];
    }

    for (col = left + 2; col < collimit; col++)
    {
      tc = col - left;
      homogeneity_map_p++;

      for (direction = 0; direction < 2; direction++)
      {
        lix = ++lixs[direction];
        for (i = 0; i < 4; i++)
        {
          adjacent_lix = lix[dir[i]];
          ldiff[direction][i] = ABS(lix[0][0] - adjacent_lix[0]);
          abdiff[direction][i] = SQR(lix[0][1] - adjacent_lix[1]) +
                                 SQR(lix[0][2] - adjacent_lix[2]);
        }
      }
      leps = MIN(MAX(ldiff[0][0], ldiff[0][1]), MAX(ldiff[1][2], ldiff[1][3]));
      abeps =
          MIN(MAX(abdiff[0][0], abdiff[0][1]), MAX(abdiff[1][2], abdiff[1][3]));
      for (direction = 0; direction < 2; direction++)
      {
        homogeneity = 0;
        for (i = 0; i < 4; i++)
        {
          if (ldiff[direction][i] <= leps && abdiff[direction][i] <= abeps)
          {
            homogeneity++;
          }
        }
        homogeneity_map_p[0][direction] = homogeneity;
      }
    }
  }
}

Project: LibRaw

void LibRaw::nikon_load_raw()
{
  static const uchar nikon_tree[][32] = {
      {0, 1, 5, 1, 1, 1, 1, 1, 1, 2, 0,  0,  0, 0, 0, 0, /* 12-bit lossy */
       5, 4, 3, 6, 2, 7, 1, 0, 8, 9, 11, 10, 12},
      {0,    1,    5,    1,    1,    1, 1, 1, 1, 2, 0, 0,  0,  0,
       0,    0, /* 12-bit lossy after split */
       0x39, 0x5a, 0x38, 0x27, 0x16, 5, 4, 3, 2, 1, 0, 11, 12, 12},

      {0, 1, 4, 2, 3, 1, 2, 0, 0, 0, 0,  0,  0, 0, 0, 0, /* 12-bit lossless */
       5, 4, 6, 3, 7, 2, 8, 1, 9, 0, 10, 11, 12},
      {0, 1, 4, 3, 1, 1, 1, 1, 1, 2, 0,  0,  0,  0,  0, 0, /* 14-bit lossy */
       5, 6, 4, 7, 8, 3, 9, 2, 1, 0, 10, 11, 12, 13, 14},
      {0, 1,    5,    1,    1,    1, 1, 1, 1, 1, 2, 0, 0, 0,  0,
       0, /* 14-bit lossy after split */
       8, 0x5c, 0x4b, 0x3a, 0x29, 7, 6, 5, 4, 3, 2, 1, 0, 13, 14},
      {0, 1, 4, 2, 2, 3, 1,  2, 0,  0,  0, 0, 0, 0,  0, 0, /* 14-bit lossless */
       7, 6, 8, 5, 9, 4, 10, 3, 11, 12, 2, 0, 1, 13, 14}};
  ushort *huff, ver0, ver1, vpred[2][2], hpred[2];
  int i, min, max, tree = 0, split = 0, row, col, len, shl, diff;

  fseek(ifp, meta_offset, SEEK_SET);
  ver0 = fgetc(ifp);
  ver1 = fgetc(ifp);
  if (ver0 == 0x49 || ver1 == 0x58)
    fseek(ifp, 2110, SEEK_CUR);
  if (ver0 == 0x46)
    tree = 2;
  if (tiff_bps == 14)
    tree += 3;
  read_shorts(vpred[0], 4);
  max = 1 << tiff_bps & 0x7fff;
  if (ver0 == 0x44 && (ver1 == 0x20 || ver1 == 0x40))
  {
    if (ver1 == 0x40)
      max /= 4;
    fseek(ifp, meta_offset + 562, SEEK_SET);
    split = get2();
  }

  while (curve[max - 2] == curve[max - 1])
    max--;
  huff = make_decoder(nikon_tree[tree]);
  fseek(ifp, data_offset, SEEK_SET);
  getbits(-1);
  try
  {
    for (min = row = 0; row < height; row++)
    {
      checkCancel();
      if (split && row == split)
      {
        free(huff);
        huff = make_decoder(nikon_tree[tree + 1]);
        max += (min = 16) << 1;
      }
      for (col = 0; col < raw_width; col++)
      {
        i = gethuff(huff);
        len = i & 15;
        shl = i >> 4;
        diff = ((getbits(len - shl) << 1) + 1) << shl >> 1;
        if ((diff & (1 << (len - 1))) == 0)
          diff -= (1 << len) - !shl;
        if (col < 2)
          hpred[col] = vpred[row & 1][col] += diff;
        else
          hpred[col & 1] += diff;
        if ((ushort)(hpred[col & 1] + min) >= max)
          derror();
        RAW(row, col) = curve[LIM((short)hpred[col & 1], 0, 0x3fff)];
      }
    }
  }
  catch (...)
  {
    free(huff);
    throw;
  }
  free(huff);
}

Project: LibRaw

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

Project: LibRaw

  libraw_output_params_t *output_params_ptr() { return &imgdata.params; }

Project: LibRaw

LibRaw_file_datastream::LibRaw_file_datastream(const wchar_t *fname)
    : filename(), wfilename(fname), jas_file(NULL), _fsize(0)
{
  if (wfilename.size() > 0)
  {
    struct _stati64 st;
    if (!_wstati64(wfilename.c_str(), &st))
      _fsize = st.st_size;
#ifdef LIBRAW_USE_AUTOPTR
    std::auto_ptr<std::filebuf> buf(new std::filebuf());
#else
    std::unique_ptr<std::filebuf> buf(new std::filebuf());
#endif
    buf->open(wfilename.c_str(), std::ios_base::in | std::ios_base::binary);
    if (buf->is_open())
    {
#ifdef LIBRAW_USE_AUTOPTR
      f = buf;
#else
      f = std::move(buf);
#endif
	}
  }
}

Project: LibRaw

void tiff_set(ushort *ntag, ushort tag, ushort type, int count, int val)
{
  struct libraw_tiff_tag *tt;
  int c;

  tt = (struct libraw_tiff_tag *)(ntag + 1) + (*ntag)++;
  tt->tag = tag;
  tt->type = type;
  tt->count = count;
  if (type < 3 && count <= 4)
    for (c = 0; c < 4; c++)
      tt->val.c[c] = val >> (c << 3);
  else if (type == 3 && count <= 2)
    for (c = 0; c < 2; c++)
      tt->val.s[c] = val >> (c << 4);
  else
    tt->val.i = val;
}

Project: LibRaw

void LibRaw::parse_redcine()
{
  unsigned i, len, rdvo;

  order = 0x4d4d;
  is_raw = 0;
  fseek(ifp, 52, SEEK_SET);
  width = get4();
  height = get4();
  fseek(ifp, 0, SEEK_END);
  fseek(ifp, -(i = ftello(ifp) & 511), SEEK_CUR);
  if (get4() != i || get4() != 0x52454f42)
  {
    fseek(ifp, 0, SEEK_SET);
    while ((len = get4()) != EOF)
    {
      if (get4() == 0x52454456)
        if (is_raw++ == shot_select)
          data_offset = ftello(ifp) - 8;
      fseek(ifp, len - 8, SEEK_CUR);
    }
  }
  else
  {
    rdvo = get4();
    fseek(ifp, 12, SEEK_CUR);
    is_raw = get4();
    fseeko(ifp, rdvo + 8 + shot_select * 4, SEEK_SET);
    data_offset = get4();
  }
}

Project: LibRaw

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

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

Project: LibRaw

void LibRaw::parseFujiMakernotes(unsigned tag, unsigned type, unsigned len,
                                 unsigned dng_writer)
{
  if ((dng_writer == nonDNG) && (tag == 0x0010))
  {
    char FujiSerial[sizeof(imgdata.shootinginfo.InternalBodySerial)];
    char *words[4];
    char yy[2], mm[3], dd[3], ystr[16], ynum[16];
    int year, nwords, ynum_len;
    unsigned c;
    memset(FujiSerial, 0, sizeof(imgdata.shootinginfo.InternalBodySerial));
    ifp->read(FujiSerial, MIN(len,sizeof(FujiSerial)), 1);
    nwords = getwords(FujiSerial, words, 4,
                      sizeof(imgdata.shootinginfo.InternalBodySerial));
    for (int i = 0; i < nwords; i++)
    {
      mm[2] = dd[2] = 0;
      if (strnlen(words[i],
                  sizeof(imgdata.shootinginfo.InternalBodySerial) - 1) < 18)
      {
        if (i == 0)
        {
          strncpy(imgdata.shootinginfo.InternalBodySerial, words[0],
                  sizeof(imgdata.shootinginfo.InternalBodySerial) - 1);
        }
        else
        {
          char tbuf[sizeof(imgdata.shootinginfo.InternalBodySerial)];
          snprintf(tbuf, sizeof(tbuf), "%s %s",
                   imgdata.shootinginfo.InternalBodySerial, words[i]);
          strncpy(imgdata.shootinginfo.InternalBodySerial, tbuf,
                  sizeof(imgdata.shootinginfo.InternalBodySerial) - 1);
        }
      }
      else
      {
        strncpy(
            dd,
            words[i] +
                strnlen(words[i],
                        sizeof(imgdata.shootinginfo.InternalBodySerial) - 1) -
                14,
            2);
        strncpy(
            mm,
            words[i] +
                strnlen(words[i],
                        sizeof(imgdata.shootinginfo.InternalBodySerial) - 1) -
                16,
            2);
        strncpy(
            yy,
            words[i] +
                strnlen(words[i],
                        sizeof(imgdata.shootinginfo.InternalBodySerial) - 1) -
                18,
            2);
        year = (yy[0] - '0') * 10 + (yy[1] - '0');
        if (year < 70)
          year += 2000;
        else
          year += 1900;

        ynum_len = MIN(
            (sizeof(ynum) - 1),
            (int)strnlen(words[i],
                         sizeof(imgdata.shootinginfo.InternalBodySerial) - 1) -
                18);
        strncpy(ynum, words[i], ynum_len);
        ynum[ynum_len] = 0;
        for (int j = 0; ynum[j] && ynum[j + 1] && sscanf(ynum + j, "%2x", &c);
             j += 2)
          ystr[j / 2] = c;
        ystr[ynum_len / 2 + 1] = 0;
        strcpy(model2, ystr);

        if (i == 0)
        {
          char tbuf[sizeof(imgdata.shootinginfo.InternalBodySerial)];

          if (nwords == 1)
          {
            snprintf(
                tbuf, sizeof(tbuf), "%s %s %d:%s:%s",
                words[0] +
                    strnlen(words[0],
                            sizeof(imgdata.shootinginfo.InternalBodySerial) -
                                1) -
                    12,
                ystr, year, mm, dd);
          }
          else
          {
            snprintf(
                tbuf, sizeof(tbuf), "%s %d:%s:%s %s", ystr, year, mm, dd,
                words[0] +
                    strnlen(words[0],
                            sizeof(imgdata.shootinginfo.InternalBodySerial) -
                                1) -
                    12);
          }
          strncpy(imgdata.shootinginfo.InternalBodySerial, tbuf,
                  sizeof(imgdata.shootinginfo.InternalBodySerial) - 1);
        }
        else
        {
          char tbuf[sizeof(imgdata.shootinginfo.InternalBodySerial)];
          snprintf(
              tbuf, sizeof(tbuf), "%s %s %d:%s:%s %s",
              imgdata.shootinginfo.InternalBodySerial, ystr, year, mm, dd,
              words[i] +
                  strnlen(words[i],
                          sizeof(imgdata.shootinginfo.InternalBodySerial) - 1) -
                  12);
          strncpy(imgdata.shootinginfo.InternalBodySerial, tbuf,
                  sizeof(imgdata.shootinginfo.InternalBodySerial) - 1);
        }
      }
    }
  }
  else
    switch (tag)
    {
    case 0x1002:
      imFuji.WB_Preset = get2();
      break;
    case 0x1011:
      imgdata.makernotes.common.FlashEC = getreal(type);
      break;
    case 0x1020:
      imFuji.Macro = get2();
      break;
    case 0x1021:
      imFuji.FocusMode = imgdata.shootinginfo.FocusMode = get2();
      break;
    case 0x1022:
      imFuji.AFMode = get2();
      break;
    case 0x1023:
      imFuji.FocusPixel[0] = get2();
      imFuji.FocusPixel[1] = get2();
      break;
    case 0x1034:
      imFuji.ExrMode = get2();
      break;
    case 0x104d:
      FujiCropMode = get2(); // odd: one of raw dimensions here can be lost
      break;
    case 0x1050:
      imFuji.ShutterType = get2();
      break;
    case 0x1103:
      imgdata.shootinginfo.DriveMode = get2();
      imFuji.DriveMode = imgdata.shootinginfo.DriveMode & 0xff;
      break;
    case 0x1400:
      imFuji.DynamicRange = get2();
      break;
    case 0x1401:
      imFuji.FilmMode = get2();
      break;
    case 0x1402:
      imFuji.DynamicRangeSetting = get2();
      break;
    case 0x1403:
      imFuji.DevelopmentDynamicRange = get2();
      break;
    case 0x140b:
      imFuji.AutoDynamicRange = get2();
      break;
    case 0x1404:
      ilm.MinFocal = getreal(type);
      break;
    case 0x1405:
      ilm.MaxFocal = getreal(type);
      break;
    case 0x1406:
      ilm.MaxAp4MinFocal = getreal(type);
      break;
    case 0x1407:
      ilm.MaxAp4MaxFocal = getreal(type);
      break;
    case 0x1422:
      imFuji.ImageStabilization[0] = get2();
      imFuji.ImageStabilization[1] = get2();
      imFuji.ImageStabilization[2] = get2();
      imgdata.shootinginfo.ImageStabilization =
          (imFuji.ImageStabilization[0] << 9) + imFuji.ImageStabilization[1];
      break;
    case 0x1431:
      imFuji.Rating = get4();
      break;
    case 0x3820:
      imFuji.FrameRate = get2();
      break;
    case 0x3821:
      imFuji.FrameWidth = get2();
      break;
    case 0x3822:
      imFuji.FrameHeight = get2();
      break;
    }
  return;
}

Project: LibRaw

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

Project: LibRaw

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

  while (maximum << scale < 0x10000)
    scale++;
  maximum <<= --scale;
  black <<= scale;
  FORC4 cblack[c] <<= scale;
  if ((size = iheight * iwidth) < 0x15550000)
    fimg = (float *)malloc((size * 3 + iheight + iwidth) * sizeof *fimg);
  merror(fimg, "wavelet_denoise()");
  temp = fimg + size * 3;
  if ((nc = colors) == 3 && filters)
    nc++;
  FORC(nc)
  { /* denoise R,G1,B,G3 individually */
    for (i = 0; i < size; i++)
      fimg[i] = 256 * sqrt((double)(image[i][c] << scale));
    for (hpass = lev = 0; lev < 5; lev++)
    {
      lpass = size * ((lev & 1) + 1);
      for (row = 0; row < iheight; row++)
      {
        hat_transform(temp, fimg + hpass + row * iwidth, 1, iwidth, 1 << lev);
        for (col = 0; col < iwidth; col++)
          fimg[lpass + row * iwidth + col] = temp[col] * 0.25;
      }
      for (col = 0; col < iwidth; col++)
      {
        hat_transform(temp, fimg + lpass + col, iwidth, iheight, 1 << lev);
        for (row = 0; row < iheight; row++)
          fimg[lpass + row * iwidth + col] = temp[row] * 0.25;
      }
      thold = threshold * noise[lev];
      for (i = 0; i < size; i++)
      {
        fimg[hpass + i] -= fimg[lpass + i];
        if (fimg[hpass + i] < -thold)
          fimg[hpass + i] += thold;
        else if (fimg[hpass + i] > thold)
          fimg[hpass + i] -= thold;
        else
          fimg[hpass + i] = 0;
        if (hpass)
          fimg[i] += fimg[hpass + i];
      }
      hpass = lpass;
    }
    for (i = 0; i < size; i++)
      image[i][c] = CLIP(SQR(fimg[i] + fimg[lpass + i]) / 0x10000);
  }
  if (filters && colors == 3)
  { /* pull G1 and G3 closer together */
    for (row = 0; row < 2; row++)
    {
      mul[row] = 0.125 * pre_mul[FC(row + 1, 0) | 1] / pre_mul[FC(row, 0) | 1];
      blk[row] = cblack[FC(row, 0) | 1];
    }
    for (i = 0; i < 4; i++)
      window[i] = (ushort *)fimg + width * i;
    for (wlast = -1, row = 1; row < height - 1; row++)
    {
      while (wlast < row + 1)
      {
        for (wlast++, i = 0; i < 4; i++)
          window[(i + 3) & 3] = window[i];
        for (col = FC(wlast, 1) & 1; col < width; col += 2)
          window[2][col] = BAYER(wlast, col);
      }
      thold = threshold / 512;
      for (col = (FC(row, 0) & 1) + 1; col < width - 1; col += 2)
      {
        avg = (window[0][col - 1] + window[0][col + 1] + window[2][col - 1] +
               window[2][col + 1] - blk[~row & 1] * 4) *
                  mul[row & 1] +
              (window[1][col] + blk[row & 1]) * 0.5;
        avg = avg < 0 ? 0 : sqrt(avg);
        diff = sqrt((double)BAYER(row, col)) - avg;
        if (diff < -thold)
          diff += thold;
        else if (diff > thold)
          diff -= thold;
        else
          diff = 0;
        BAYER(row, col) = CLIP(SQR(avg + diff) + 0.5);
      }
    }
  }
  free(fimg);
}

Project: LibRaw

ushort LibRaw::get2()
{
  uchar str[2] = {0xff, 0xff};
  fread(str, 1, 2, ifp);
  return sget2(str);
}

Project: LibRaw

INT64 LibRaw_file_datastream::tell()
{
  LR_STREAM_CHK();
  return f->pubseekoff(0, std::ios_base::cur);
}

Project: LibRaw

void usage(const char *prog)
{
  printf("dcraw_emu: almost complete dcraw emulator\n");
  printf("Usage:  %s [OPTION]... [FILE]...\n", prog);
  printf("-c float-num       Set adjust maximum threshold (default 0.75)\n"
         "-v        Verbose: print progress messages (repeated -v will add "
         "verbosity)\n"
         "-w        Use camera white balance, if possible\n"
         "-a        Average the whole image for white balance\n"
         "-A <x y w h> Average a grey box for white balance\n"
         "-r <r g b g> Set custom white balance\n"
         "+M/-M     Use/don't use an embedded color matrix\n"
         "-C <r b>  Correct chromatic aberration\n"
         "-P <file> Fix the dead pixels listed in this file\n"
         "-K <file> Subtract dark frame (16-bit raw PGM)\n"
         "-k <num>  Set the darkness level\n"
         "-S <num>  Set the saturation level\n"
         "-R <num>  Set raw processing options to num\n"
         "-n <num>  Set threshold for wavelet denoising\n"
         "-H [0-9]  Highlight mode (0=clip, 1=unclip, 2=blend, 3+=rebuild)\n"
         "-t [0-7]  Flip image (0=none, 3=180, 5=90CCW, 6=90CW)\n"
         "-o [0-6]  Output colorspace (raw,sRGB,Adobe,Wide,ProPhoto,XYZ,ACES)\n"
#ifndef NO_LCMS
         "-o file   Output ICC profile\n"
         "-p file   Camera input profile (use \'embed\' for embedded profile)\n"
#endif
         "-j        Don't stretch or rotate raw pixels\n"
         "-W        Don't automatically brighten the image\n"
         "-b <num>  Adjust brightness (default = 1.0)\n"
         "-q N      Set the interpolation quality:\n"
         "          0 - linear, 1 - VNG, 2 - PPG, 3 - AHD, 4 - DCB\n"
         "          11 - DHT, 12 - AAHD\n"
         "-h        Half-size color image (twice as fast as \"-q 0\")\n"
         "-f        Interpolate RGGB as four colors\n"
         "-m <num>  Apply a 3x3 median filter to R-G and B-G\n"
         "-s [0..N-1] Select one raw image from input file\n"
         "-4        Linear 16-bit, same as \"-6 -W -g 1 1\n"
         "-6        Write 16-bit linear instead of 8-bit with gamma\n"
         "-g pow ts Set gamma curve to gamma pow and toe slope ts (default = "
         "2.222 4.5)\n"
         "-T        Write TIFF instead of PPM\n"
         "-G        Use green_matching() filter\n"
         "-B <x y w h> use cropbox\n"
         "-F        Use FILE I/O instead of streambuf API\n"
         "-Z <suf>  Output filename generation rules\n"
         "          .suf => append .suf to input name, keeping existing suffix "
         "too\n"
         "           suf => replace input filename last extension\n"
         "          - => output to stdout\n"
         "          filename.suf => output to filename.suf\n"
         "-timing   Detailed timing report\n"
         "-fbdd N   0 - disable FBDD noise reduction (default), 1 - light "
         "FBDD, 2 - full\n"
         "-dcbi N   Number of extra DCD iterations (default - 0)\n"
         "-dcbe     DCB color enhance\n"
         "-aexpo <e p> exposure correction\n"
         "-apentax4shot enables merge of 4-shot pentax files\n"
         "-apentax4shotorder 3102 sets pentax 4-shot alignment order\n"
         "-mmap     Use memory mmaped buffer instead of plain FILE I/O\n"
         "-mem	   Use memory buffer instead of FILE I/O\n"
         "-disars   Do not use RawSpeed library\n"
         "-disinterp Do not run interpolation step\n"
         "-dsrawrgb1 Disable YCbCr to RGB conversion for sRAW (Cb/Cr "
         "interpolation enabled)\n"
         "-dsrawrgb2 Disable YCbCr to RGB conversion for sRAW (Cb/Cr "
         "interpolation disabled)\n"
#ifdef USE_DNGSDK
         "-dngsdk   Use Adobe DNG SDK for DNG decode\n"
         "-dngflags N set DNG decoding options to value N\n"
#endif
  );
  exit(1);
}

Project: LibRaw

void LibRaw::xtrans_interpolate(int passes)
{
  int c, d, f, g, h, i, v, ng, row, col, top, left, mrow, mcol;

  int cstat[4] = {0, 0, 0, 0};

  int val, ndir, pass, hm[8], avg[4], color[3][8];
  static const short orth[12] = {1, 0, 0, 1, -1, 0, 0, -1, 1, 0, 0, 1},
                     patt[2][16] = {{0, 1, 0, -1, 2, 0, -1, 0, 1, 1, 1, -1, 0,
                                     0, 0, 0},
                                    {0, 1, 0, -2, 1, 0, -2, 0, 1, 1, -2, -2, 1,
                                     -1, -1, 1}},
                     dir[4] = {1, LIBRAW_AHD_TILE, LIBRAW_AHD_TILE + 1,
                               LIBRAW_AHD_TILE - 1};
  short allhex[3][3][2][8], *hex;
  ushort min, max, sgrow, sgcol;
  ushort(*rgb)[LIBRAW_AHD_TILE][LIBRAW_AHD_TILE][3], (*rix)[3], (*pix)[4];
  short(*lab)[LIBRAW_AHD_TILE][3], (*lix)[3];
  float(*drv)[LIBRAW_AHD_TILE][LIBRAW_AHD_TILE], diff[6], tr;
  char(*homo)[LIBRAW_AHD_TILE][LIBRAW_AHD_TILE], *buffer;

  if (width < LIBRAW_AHD_TILE || height < LIBRAW_AHD_TILE)
    throw LIBRAW_EXCEPTION_IO_CORRUPT; // too small image
                                       /* Check against right pattern */
  for (row = 0; row < 6; row++)
    for (col = 0; col < 6; col++)
      cstat[fcol(row, col)]++;

  if (cstat[0] < 6 || cstat[0] > 10 || cstat[1] < 16 || cstat[1] > 24 ||
      cstat[2] < 6 || cstat[2] > 10 || cstat[3])
    throw LIBRAW_EXCEPTION_IO_CORRUPT;

  // Init allhex table to unreasonable values
  for (int i = 0; i < 3; i++)
    for (int j = 0; j < 3; j++)
      for (int k = 0; k < 2; k++)
        for (int l = 0; l < 8; l++)
          allhex[i][j][k][l] = 32700;

  cielab(0, 0);
  ndir = 4 << (passes > 1);
  buffer = (char *)malloc(LIBRAW_AHD_TILE * LIBRAW_AHD_TILE * (ndir * 11 + 6));
  merror(buffer, "xtrans_interpolate()");
  rgb = (ushort(*)[LIBRAW_AHD_TILE][LIBRAW_AHD_TILE][3])buffer;
  lab = (short(*)[LIBRAW_AHD_TILE][3])(
      buffer + LIBRAW_AHD_TILE * LIBRAW_AHD_TILE * (ndir * 6));
  drv = (float(*)[LIBRAW_AHD_TILE][LIBRAW_AHD_TILE])(
      buffer + LIBRAW_AHD_TILE * LIBRAW_AHD_TILE * (ndir * 6 + 6));
  homo = (char(*)[LIBRAW_AHD_TILE][LIBRAW_AHD_TILE])(
      buffer + LIBRAW_AHD_TILE * LIBRAW_AHD_TILE * (ndir * 10 + 6));

  int minv = 0, maxv = 0, minh = 0, maxh = 0;
  /* Map a green hexagon around each non-green pixel and vice versa:	*/
  for (row = 0; row < 3; row++)
    for (col = 0; col < 3; col++)
      for (ng = d = 0; d < 10; d += 2)
      {
        g = fcol(row, col) == 1;
        if (fcol(row + orth[d], col + orth[d + 2]) == 1)
          ng = 0;
        else
          ng++;
        if (ng == 4)
        {
          sgrow = row;
          sgcol = col;
        }
        if (ng == g + 1)
          FORC(8)
          {
            v = orth[d] * patt[g][c * 2] + orth[d + 1] * patt[g][c * 2 + 1];
            h = orth[d + 2] * patt[g][c * 2] + orth[d + 3] * patt[g][c * 2 + 1];
            minv = MIN(v, minv);
            maxv = MAX(v, maxv);
            minh = MIN(v, minh);
            maxh = MAX(v, maxh);
            allhex[row][col][0][c ^ (g * 2 & d)] = h + v * width;
            allhex[row][col][1][c ^ (g * 2 & d)] = h + v * LIBRAW_AHD_TILE;
          }
      }

  // Check allhex table initialization
  for (int i = 0; i < 3; i++)
    for (int j = 0; j < 3; j++)
      for (int k = 0; k < 2; k++)
        for (int l = 0; l < 8; l++)
          if (allhex[i][j][k][l] > maxh + maxv * width + 1 ||
              allhex[i][j][k][l] < minh + minv * width - 1)
            throw LIBRAW_EXCEPTION_IO_CORRUPT;
  int retrycount = 0;

  /* Set green1 and green3 to the minimum and maximum allowed values:	*/
  for (row = 2; row < height - 2; row++)
    for (min = ~(max = 0), col = 2; col < width - 2; col++)
    {
      if (fcol(row, col) == 1 && (min = ~(max = 0)))
        continue;
      pix = image + row * width + col;
      hex = allhex[row % 3][col % 3][0];
      if (!max)
        FORC(6)
        {
          val = pix[hex[c]][1];
          if (min > val)
            min = val;
          if (max < val)
            max = val;
        }
      pix[0][1] = min;
      pix[0][3] = max;
      switch ((row - sgrow) % 3)
      {
      case 1:
        if (row < height - 3)
        {
          row++;
          col--;
        }
        break;
      case 2:
        if ((min = ~(max = 0)) && (col += 2) < width - 3 && row > 2)
        {
          row--;
          if (retrycount++ > width * height)
            throw LIBRAW_EXCEPTION_IO_CORRUPT;
        }
      }
    }

  for (top = 3; top < height - 19; top += LIBRAW_AHD_TILE - 16)
    for (left = 3; left < width - 19; left += LIBRAW_AHD_TILE - 16)
    {
      mrow = MIN(top + LIBRAW_AHD_TILE, height - 3);
      mcol = MIN(left + LIBRAW_AHD_TILE, width - 3);
      for (row = top; row < mrow; row++)
        for (col = left; col < mcol; col++)
          memcpy(rgb[0][row - top][col - left], image[row * width + col], 6);
      FORC3 memcpy(rgb[c + 1], rgb[0], sizeof *rgb);

      /* Interpolate green horizontally, vertically, and along both diagonals:
       */
      for (row = top; row < mrow; row++)
        for (col = left; col < mcol; col++)
        {
          if ((f = fcol(row, col)) == 1)
            continue;
          pix = image + row * width + col;
          hex = allhex[row % 3][col % 3][0];
          color[1][0] = 174 * (pix[hex[1]][1] + pix[hex[0]][1]) -
                        46 * (pix[2 * hex[1]][1] + pix[2 * hex[0]][1]);
          color[1][1] = 223 * pix[hex[3]][1] + pix[hex[2]][1] * 33 +
                        92 * (pix[0][f] - pix[-hex[2]][f]);
          FORC(2)
          color[1][2 + c] = 164 * pix[hex[4 + c]][1] +
                            92 * pix[-2 * hex[4 + c]][1] +
                            33 * (2 * pix[0][f] - pix[3 * hex[4 + c]][f] -
                                  pix[-3 * hex[4 + c]][f]);
          FORC4 rgb[c ^ !((row - sgrow) % 3)][row - top][col - left][1] =
              LIM(color[1][c] >> 8, pix[0][1], pix[0][3]);
        }

      for (pass = 0; pass < passes; pass++)
      {
        if (pass == 1)
          memcpy(rgb += 4, buffer, 4 * sizeof *rgb);

        /* Recalculate green from interpolated values of closer pixels:	*/
        if (pass)
        {
          for (row = top + 2; row < mrow - 2; row++)
            for (col = left + 2; col < mcol - 2; col++)
            {
              if ((f = fcol(row, col)) == 1)
                continue;
              pix = image + row * width + col;
              hex = allhex[row % 3][col % 3][1];
              for (d = 3; d < 6; d++)
              {
                rix =
                    &rgb[(d - 2) ^ !((row - sgrow) % 3)][row - top][col - left];
                val = rix[-2 * hex[d]][1] + 2 * rix[hex[d]][1] -
                      rix[-2 * hex[d]][f] - 2 * rix[hex[d]][f] + 3 * rix[0][f];
                rix[0][1] = LIM(val / 3, pix[0][1], pix[0][3]);
              }
            }
        }

        /* Interpolate red and blue values for solitary green pixels:	*/
        for (row = (top - sgrow + 4) / 3 * 3 + sgrow; row < mrow - 2; row += 3)
          for (col = (left - sgcol + 4) / 3 * 3 + sgcol; col < mcol - 2;
               col += 3)
          {
            rix = &rgb[0][row - top][col - left];
            h = fcol(row, col + 1);
            memset(diff, 0, sizeof diff);
            for (i = 1, d = 0; d < 6; d++, i ^= LIBRAW_AHD_TILE ^ 1, h ^= 2)
            {
              for (c = 0; c < 2; c++, h ^= 2)
              {
                g = 2 * rix[0][1] - rix[i << c][1] - rix[-i << c][1];
                color[h][d] = g + rix[i << c][h] + rix[-i << c][h];
                if (d > 1)
                  diff[d] += SQR(rix[i << c][1] - rix[-i << c][1] -
                                 rix[i << c][h] + rix[-i << c][h]) +
                             SQR(g);
              }
              if (d > 1 && (d & 1))
                if (diff[d - 1] < diff[d])
                  FORC(2) color[c * 2][d] = color[c * 2][d - 1];
              if (d < 2 || (d & 1))
              {
                FORC(2) rix[0][c * 2] = CLIP(color[c * 2][d] / 2);
                rix += LIBRAW_AHD_TILE * LIBRAW_AHD_TILE;
              }
            }
          }

        /* Interpolate red for blue pixels and vice versa:		*/
        for (row = top + 3; row < mrow - 3; row++)
          for (col = left + 3; col < mcol - 3; col++)
          {
            if ((f = 2 - fcol(row, col)) == 1)
              continue;
            rix = &rgb[0][row - top][col - left];
            c = (row - sgrow) % 3 ? LIBRAW_AHD_TILE : 1;
            h = 3 * (c ^ LIBRAW_AHD_TILE ^ 1);
            for (d = 0; d < 4; d++, rix += LIBRAW_AHD_TILE * LIBRAW_AHD_TILE)
            {
              i = d > 1 || ((d ^ c) & 1) ||
                          ((ABS(rix[0][1] - rix[c][1]) +
                            ABS(rix[0][1] - rix[-c][1])) <
                           2 * (ABS(rix[0][1] - rix[h][1]) +
                                ABS(rix[0][1] - rix[-h][1])))
                      ? c
                      : h;
              rix[0][f] = CLIP((rix[i][f] + rix[-i][f] + 2 * rix[0][1] -
                                rix[i][1] - rix[-i][1]) /
                               2);
            }
          }

        /* Fill in red and blue for 2x2 blocks of green:		*/
        for (row = top + 2; row < mrow - 2; row++)
          if ((row - sgrow) % 3)
            for (col = left + 2; col < mcol - 2; col++)
              if ((col - sgcol) % 3)
              {
                rix = &rgb[0][row - top][col - left];
                hex = allhex[row % 3][col % 3][1];
                for (d = 0; d < ndir;
                     d += 2, rix += LIBRAW_AHD_TILE * LIBRAW_AHD_TILE)
                  if (hex[d] + hex[d + 1])
                  {
                    g = 3 * rix[0][1] - 2 * rix[hex[d]][1] - rix[hex[d + 1]][1];
                    for (c = 0; c < 4; c += 2)
                      rix[0][c] = CLIP(
                          (g + 2 * rix[hex[d]][c] + rix[hex[d + 1]][c]) / 3);
                  }
                  else
                  {
                    g = 2 * rix[0][1] - rix[hex[d]][1] - rix[hex[d + 1]][1];
                    for (c = 0; c < 4; c += 2)
                      rix[0][c] =
                          CLIP((g + rix[hex[d]][c] + rix[hex[d + 1]][c]) / 2);
                  }
              }
      }
      rgb = (ushort(*)[LIBRAW_AHD_TILE][LIBRAW_AHD_TILE][3])buffer;
      mrow -= top;
      mcol -= left;

      /* Convert to CIELab and differentiate in all directions:	*/
      for (d = 0; d < ndir; d++)
      {
        for (row = 2; row < mrow - 2; row++)
          for (col = 2; col < mcol - 2; col++)
            cielab(rgb[d][row][col], lab[row][col]);
        for (f = dir[d & 3], row = 3; row < mrow - 3; row++)
          for (col = 3; col < mcol - 3; col++)
          {
            lix = &lab[row][col];
            g = 2 * lix[0][0] - lix[f][0] - lix[-f][0];
            drv[d][row][col] =
                SQR(g) +
                SQR((2 * lix[0][1] - lix[f][1] - lix[-f][1] + g * 500 / 232)) +
                SQR((2 * lix[0][2] - lix[f][2] - lix[-f][2] - g * 500 / 580));
          }
      }

      /* Build homogeneity maps from the derivatives:			*/
      memset(homo, 0, ndir * LIBRAW_AHD_TILE * LIBRAW_AHD_TILE);
      for (row = 4; row < mrow - 4; row++)
        for (col = 4; col < mcol - 4; col++)
        {
          for (tr = FLT_MAX, d = 0; d < ndir; d++)
            if (tr > drv[d][row][col])
              tr = drv[d][row][col];
          tr *= 8;
          for (d = 0; d < ndir; d++)
            for (v = -1; v <= 1; v++)
              for (h = -1; h <= 1; h++)
                if (drv[d][row + v][col + h] <= tr)
                  homo[d][row][col]++;
        }

      /* Average the most homogenous pixels for the final result:	*/
      if (height - top < LIBRAW_AHD_TILE + 4)
        mrow = height - top + 2;
      if (width - left < LIBRAW_AHD_TILE + 4)
        mcol = width - left + 2;
      for (row = MIN(top, 8); row < mrow - 8; row++)
        for (col = MIN(left, 8); col < mcol - 8; col++)
        {
          for (d = 0; d < ndir; d++)
            for (hm[d] = 0, v = -2; v <= 2; v++)
              for (h = -2; h <= 2; h++)
                hm[d] += homo[d][row + v][col + h];
          for (d = 0; d < ndir - 4; d++)
            if (hm[d] < hm[d + 4])
              hm[d] = 0;
            else if (hm[d] > hm[d + 4])
              hm[d + 4] = 0;
          for (max = hm[0], d = 1; d < ndir; d++)
            if (max < hm[d])
              max = hm[d];
          max -= max >> 3;
          memset(avg, 0, sizeof avg);
          for (d = 0; d < ndir; d++)
            if (hm[d] >= max)
            {
              FORC3 avg[c] += rgb[d][row][col][c];
              avg[3]++;
            }
          FORC3 image[(row + top) * width + col + left][c] = avg[c] / avg[3];
        }
    }
  free(buffer);
  border_interpolate(8);
}

Project: LibRaw

void LibRaw::process_Hassy_Lens (int LensMount) {
// long long unsigned id =
//    mount*100000000ULL + series*10000000ULL +
//    focal1*10000ULL + focal2*10 + version;
  char *ps;
  int c = atoi(strchr(imgdata.lens.Lens, ' ') +1);
  if (!c)
    return;

  if (LensMount == LIBRAW_MOUNT_Hasselblad_H) {
    if (imgdata.lens.Lens[2] == ' ') // HC lens
      ilm.LensID = LensMount*100000000ULL + 10000000ULL;
    else                             // HCD lens
      ilm.LensID = LensMount*100000000ULL + 20000000ULL;
    ilm.LensFormat = LIBRAW_FORMAT_645;
  } else if (LensMount == LIBRAW_MOUNT_Hasselblad_XCD) {
    ilm.LensFormat = LIBRAW_FORMAT_CROP645;
    ilm.LensID = LensMount*100000000ULL;
  } else
    return;

  ilm.LensMount = LensMount;
  ilm.LensID += c*10000ULL;
  if ((ps=strchr(imgdata.lens.Lens, '-'))) {
    ilm.FocalType = LIBRAW_FT_ZOOM_LENS;
    ilm.LensID += atoi(ps+1)*10ULL;
  } else {
    ilm.FocalType = LIBRAW_FT_PRIME_LENS;
    ilm.LensID += c*10ULL;
  }
  if (strstr(imgdata.lens.Lens, "III"))
    ilm.LensID += 3ULL;
  else if (strstr(imgdata.lens.Lens, "II"))
    ilm.LensID += 2ULL;
}

Project: LibRaw

int LibRaw_bigfile_datastream::seek(INT64 o, int whence)
{
  LR_BF_CHK();
#if defined(_WIN32)
#ifdef WIN32SECURECALLS
  return _fseeki64(f, o, whence);
#else
  return fseek(f, (long)o, whence);
#endif
#else
  return fseeko(f, o, whence);
#endif
}

Project: LibRaw

void LibRaw::setPhaseOneFeatures(unsigned long long id)
{

  ushort i;
  static const struct
  {
    unsigned long long id;
    char t_model[32];
    int CamMnt;
    int CamFmt;
  } p1_unique[] = {
      // Phase One section:
      {0x001ULL, "Hasselblad V", LIBRAW_MOUNT_Hasselblad_V, LIBRAW_FORMAT_66},
      {0x00aULL, "PhaseOne/Mamiya", LIBRAW_MOUNT_Mamiya645, LIBRAW_FORMAT_645},
      {0x00cULL, "Contax 645", LIBRAW_MOUNT_Contax645, LIBRAW_FORMAT_645},
      {0x010ULL, "Hasselblad V", LIBRAW_MOUNT_Hasselblad_V, LIBRAW_FORMAT_66},
      {0x011ULL, "Hasselblad V", LIBRAW_MOUNT_Hasselblad_V, LIBRAW_FORMAT_66},
      {0x012ULL, "Contax 645", LIBRAW_MOUNT_Contax645, LIBRAW_FORMAT_645},
      {0x013ULL, "PhaseOne/Mamiya", LIBRAW_MOUNT_Mamiya645, LIBRAW_FORMAT_645},
      {0x014ULL, "Hasselblad V", LIBRAW_MOUNT_Hasselblad_V, LIBRAW_FORMAT_66},
      {0x015ULL, "Contax 645", LIBRAW_MOUNT_Contax645, LIBRAW_FORMAT_645},
      {0x016ULL, "PhaseOne/Mamiya", LIBRAW_MOUNT_Mamiya645, LIBRAW_FORMAT_645},
      {0x017ULL, "Hasselblad V", LIBRAW_MOUNT_Hasselblad_V, LIBRAW_FORMAT_66},
      {0x018ULL, "Hasselblad H", LIBRAW_MOUNT_Hasselblad_H, LIBRAW_FORMAT_645},
      {0x019ULL, "PhaseOne/Mamiya", LIBRAW_MOUNT_Mamiya645, LIBRAW_FORMAT_645},
      {0x020ULL, "Contax 645", LIBRAW_MOUNT_Contax645, LIBRAW_FORMAT_645},
      {0x022ULL, "Hasselblad V", LIBRAW_MOUNT_Hasselblad_V, LIBRAW_FORMAT_66},
      {0x023ULL, "Hasselblad V", LIBRAW_MOUNT_Hasselblad_V, LIBRAW_FORMAT_66},
      {0x024ULL, "Hasselblad H", LIBRAW_MOUNT_Hasselblad_H, LIBRAW_FORMAT_645},
      {0x025ULL, "Contax 645", LIBRAW_MOUNT_Contax645, LIBRAW_FORMAT_645},
      {0x026ULL, "PhaseOne/Mamiya", LIBRAW_MOUNT_Mamiya645, LIBRAW_FORMAT_645},
      {0x027ULL, "Hasselblad V", LIBRAW_MOUNT_Hasselblad_V, LIBRAW_FORMAT_66},
      {0x028ULL, "Hasselblad H", LIBRAW_MOUNT_Hasselblad_H, LIBRAW_FORMAT_645},
      {0x029ULL, "Contax 645", LIBRAW_MOUNT_Contax645, LIBRAW_FORMAT_645},
      {0x02aULL, "PhaseOne/Mamiya", LIBRAW_MOUNT_Mamiya645, LIBRAW_FORMAT_645},
      {0x02cULL, "Hasselblad V", LIBRAW_MOUNT_Hasselblad_V, LIBRAW_FORMAT_66},
      {0x02dULL, "Hasselblad H", LIBRAW_MOUNT_Hasselblad_H, LIBRAW_FORMAT_645},
      {0x02eULL, "Contax 645", LIBRAW_MOUNT_Contax645, LIBRAW_FORMAT_645},
      {0x02fULL, "PhaseOne/Mamiya", LIBRAW_MOUNT_Mamiya645, LIBRAW_FORMAT_645},
      {0x030ULL, "Hasselblad V", LIBRAW_MOUNT_Hasselblad_V, LIBRAW_FORMAT_66},
      {0x031ULL, "Hasselblad H", LIBRAW_MOUNT_Hasselblad_H, LIBRAW_FORMAT_645},
      {0x032ULL, "Contax 645", LIBRAW_MOUNT_Contax645, LIBRAW_FORMAT_645},
      {0x033ULL, "PhaseOne/Mamiya", LIBRAW_MOUNT_Mamiya645, LIBRAW_FORMAT_645},
      {0x034ULL, "Hasselblad V", LIBRAW_MOUNT_Hasselblad_V, LIBRAW_FORMAT_66},
      {0x035ULL, "Hasselblad H", LIBRAW_MOUNT_Hasselblad_H, LIBRAW_FORMAT_645},
      {0x036ULL, "Contax 645", LIBRAW_MOUNT_Contax645, LIBRAW_FORMAT_645},
      {0x037ULL, "PhaseOne/Mamiya", LIBRAW_MOUNT_Mamiya645, LIBRAW_FORMAT_645},
      {0x043ULL, "Hasselblad V", LIBRAW_MOUNT_Hasselblad_V, LIBRAW_FORMAT_66},
      {0x044ULL, "Hasselblad H", LIBRAW_MOUNT_Hasselblad_H, LIBRAW_FORMAT_645},
      {0x045ULL, "Contax 645", LIBRAW_MOUNT_Contax645, LIBRAW_FORMAT_645},
      {0x046ULL, "PhaseOne/Mamiya", LIBRAW_MOUNT_Mamiya645, LIBRAW_FORMAT_645},
      {0x047ULL, "Hasselblad V", LIBRAW_MOUNT_Hasselblad_V, LIBRAW_FORMAT_66},
      {0x048ULL, "Hasselblad H", LIBRAW_MOUNT_Hasselblad_H, LIBRAW_FORMAT_645},
      {0x049ULL, "Contax 645", LIBRAW_MOUNT_Contax645, LIBRAW_FORMAT_645},
      {0x04aULL, "PhaseOne/Mamiya", LIBRAW_MOUNT_Mamiya645, LIBRAW_FORMAT_645},
      {0x04cULL, "Hasselblad V", LIBRAW_MOUNT_Hasselblad_V, LIBRAW_FORMAT_66},
      {0x04dULL, "Hasselblad H", LIBRAW_MOUNT_Hasselblad_H, LIBRAW_FORMAT_645},
      {0x04eULL, "Contax 645", LIBRAW_MOUNT_Contax645, LIBRAW_FORMAT_645},
      {0x04fULL, "PhaseOne/Mamiya", LIBRAW_MOUNT_Mamiya645, LIBRAW_FORMAT_645},
      {0x050ULL, "Hasselblad V", LIBRAW_MOUNT_Hasselblad_V, LIBRAW_FORMAT_66},
      {0x051ULL, "Hasselblad H", LIBRAW_MOUNT_Hasselblad_H, LIBRAW_FORMAT_645},
      {0x052ULL, "Contax 645", LIBRAW_MOUNT_Contax645, LIBRAW_FORMAT_645},
      {0x053ULL, "PhaseOne/Mamiya", LIBRAW_MOUNT_Mamiya645, LIBRAW_FORMAT_645},
      {0x054ULL, "Hasselblad V", LIBRAW_MOUNT_Hasselblad_V, LIBRAW_FORMAT_66},
      {0x055ULL, "Hasselblad H", LIBRAW_MOUNT_Hasselblad_H, LIBRAW_FORMAT_645},
      {0x056ULL, "Contax 645", LIBRAW_MOUNT_Contax645, LIBRAW_FORMAT_645},
      {0x057ULL, "PhaseOne/Mamiya", LIBRAW_MOUNT_Mamiya645, LIBRAW_FORMAT_645},
      {0x063ULL, "Hasselblad V", LIBRAW_MOUNT_Hasselblad_V, LIBRAW_FORMAT_66},
      {0x064ULL, "Hasselblad H", LIBRAW_MOUNT_Hasselblad_H, LIBRAW_FORMAT_645},
      {0x065ULL, "Contax 645", LIBRAW_MOUNT_Contax645, LIBRAW_FORMAT_645},
      {0x066ULL, "PhaseOne/Mamiya", LIBRAW_MOUNT_Mamiya645, LIBRAW_FORMAT_645},
      {0x067ULL, "Hasselblad V", LIBRAW_MOUNT_Hasselblad_V, LIBRAW_FORMAT_66},
      {0x068ULL, "Hasselblad H", LIBRAW_MOUNT_Hasselblad_H, LIBRAW_FORMAT_645},
      {0x069ULL, "PhaseOne/Mamiya", LIBRAW_MOUNT_Mamiya645, LIBRAW_FORMAT_645},
      {0x06aULL, "Contax 645", LIBRAW_MOUNT_Contax645, LIBRAW_FORMAT_645},
      {0x070ULL, "Hasselblad V", LIBRAW_MOUNT_Hasselblad_V, LIBRAW_FORMAT_66},
      {0x071ULL, "Hasselblad H", LIBRAW_MOUNT_Hasselblad_H, LIBRAW_FORMAT_645},
      {0x072ULL, "Contax 645", LIBRAW_MOUNT_Contax645, LIBRAW_FORMAT_645},
      {0x073ULL, "PhaseOne/Mamiya", LIBRAW_MOUNT_Mamiya645, LIBRAW_FORMAT_645},
      {0x083ULL, "Hasselblad V", LIBRAW_MOUNT_Hasselblad_V, LIBRAW_FORMAT_66},
      {0x084ULL, "Hasselblad H", LIBRAW_MOUNT_Hasselblad_H, LIBRAW_FORMAT_645},
      {0x085ULL, "Contax 645", LIBRAW_MOUNT_Contax645, LIBRAW_FORMAT_645},
      {0x086ULL, "PhaseOne/Mamiya", LIBRAW_MOUNT_Mamiya645, LIBRAW_FORMAT_645},
      {0x087ULL, "Hasselblad V", LIBRAW_MOUNT_Hasselblad_V, LIBRAW_FORMAT_66},
      {0x088ULL, "Hasselblad H", LIBRAW_MOUNT_Hasselblad_H, LIBRAW_FORMAT_645},
      {0x089ULL, "Contax 645", LIBRAW_MOUNT_Contax645, LIBRAW_FORMAT_645},
      {0x08aULL, "PhaseOne/Mamiya", LIBRAW_MOUNT_Mamiya645, LIBRAW_FORMAT_645},
      {0x08cULL, "Hasselblad V", LIBRAW_MOUNT_Hasselblad_V, LIBRAW_FORMAT_66},
      {0x08dULL, "Hasselblad H", LIBRAW_MOUNT_Hasselblad_H, LIBRAW_FORMAT_645},
      {0x08eULL, "Contax 645", LIBRAW_MOUNT_Contax645, LIBRAW_FORMAT_645},
      {0x08fULL, "PhaseOne/Mamiya", LIBRAW_MOUNT_Mamiya645, LIBRAW_FORMAT_645},
      {0x094ULL, "Hasselblad V", LIBRAW_MOUNT_Hasselblad_V, LIBRAW_FORMAT_66},
      {0x095ULL, "Hasselblad H", LIBRAW_MOUNT_Hasselblad_H, LIBRAW_FORMAT_645},
      {0x096ULL, "Contax 645", LIBRAW_MOUNT_Contax645, LIBRAW_FORMAT_645},
      {0x097ULL, "PhaseOne/Mamiya", LIBRAW_MOUNT_Mamiya645, LIBRAW_FORMAT_645},
      {0x0a0ULL, "A-250", LIBRAW_MOUNT_Alpa, LIBRAW_FORMAT_69},
      {0x0a1ULL, "A-260", LIBRAW_MOUNT_Alpa, LIBRAW_FORMAT_69},
      {0x0a2ULL, "A-280", LIBRAW_MOUNT_Alpa, LIBRAW_FORMAT_69},
      {0x0a7ULL, "Hasselblad V", LIBRAW_MOUNT_Hasselblad_V, LIBRAW_FORMAT_66},
      {0x0a8ULL, "Hasselblad H", LIBRAW_MOUNT_Hasselblad_H, LIBRAW_FORMAT_645},
      {0x0a9ULL, "Contax 645", LIBRAW_MOUNT_Contax645, LIBRAW_FORMAT_645},
      {0x0aaULL, "PhaseOne/Mamiya", LIBRAW_MOUNT_Mamiya645, LIBRAW_FORMAT_645},
      {0x0acULL, "Hasselblad V", LIBRAW_MOUNT_Hasselblad_V, LIBRAW_FORMAT_66},
      {0x0adULL, "Hasselblad H", LIBRAW_MOUNT_Hasselblad_H, LIBRAW_FORMAT_645},
      {0x0aeULL, "Contax 645", LIBRAW_MOUNT_Contax645, LIBRAW_FORMAT_645},
      {0x0afULL, "PhaseOne/Mamiya", LIBRAW_MOUNT_Mamiya645, LIBRAW_FORMAT_645},
      {0x0b0ULL, "Hasselblad V", LIBRAW_MOUNT_Hasselblad_V, LIBRAW_FORMAT_66},
      {0x0b1ULL, "Hasselblad H", LIBRAW_MOUNT_Hasselblad_H, LIBRAW_FORMAT_645},
      {0x0b2ULL, "Contax 645", LIBRAW_MOUNT_Contax645, LIBRAW_FORMAT_645},
      {0x0b3ULL, "PhaseOne/Mamiya", LIBRAW_MOUNT_Mamiya645, LIBRAW_FORMAT_645},
      {0x0b4ULL, "Hasselblad V", LIBRAW_MOUNT_Hasselblad_V, LIBRAW_FORMAT_66},
      {0x0b5ULL, "Hasselblad H", LIBRAW_MOUNT_Hasselblad_H, LIBRAW_FORMAT_645},
      {0x0b6ULL, "Contax 645", LIBRAW_MOUNT_Contax645, LIBRAW_FORMAT_645},
      {0x0b7ULL, "PhaseOne/Mamiya", LIBRAW_MOUNT_Mamiya645, LIBRAW_FORMAT_645},
      {0x0d0ULL, "Hasselblad V", LIBRAW_MOUNT_Hasselblad_V, LIBRAW_FORMAT_66},
      {0x0d3ULL, "PhaseOne/Mamiya", LIBRAW_MOUNT_Mamiya645, LIBRAW_FORMAT_645},
      {0x1c0ULL, "Phase One 645AF", LIBRAW_MOUNT_Mamiya645, LIBRAW_FORMAT_645},
      {0x1c9ULL, "Phase One 645DF", LIBRAW_MOUNT_Mamiya645, LIBRAW_FORMAT_645},
      {0x1d7ULL, "Phase One 645DF+", LIBRAW_MOUNT_Mamiya645, LIBRAW_FORMAT_645},
      {0x2c0ULL, "Phase One iXA", LIBRAW_MOUNT_Unknown, LIBRAW_FORMAT_Unknown},
      {0x2c1ULL, "Phase One iXA - R", LIBRAW_MOUNT_Unknown,
       LIBRAW_FORMAT_Unknown},
      {0x2c2ULL, "Phase One iXU 150", LIBRAW_MOUNT_Unknown,
       LIBRAW_FORMAT_Unknown},
      {0x2c3ULL, "Phase One iXU 150 - NIR", LIBRAW_MOUNT_Unknown,
       LIBRAW_FORMAT_Unknown},
      {0x2c4ULL, "Phase One iXU 180", LIBRAW_MOUNT_Unknown,
       LIBRAW_FORMAT_Unknown},
      {0x2d1ULL, "Phase One iXR", LIBRAW_MOUNT_Unknown, LIBRAW_FORMAT_Unknown},
      // Leaf section:
      {0x14dULL, "Mamiya", LIBRAW_MOUNT_Unknown, LIBRAW_FORMAT_Unknown},
      {0x149ULL, "Universal", LIBRAW_MOUNT_Unknown, LIBRAW_FORMAT_Unknown},
      {0x14aULL, "Hasselblad H1/H2", LIBRAW_MOUNT_Hasselblad_H,
       LIBRAW_FORMAT_645},
      {0x14cULL, "Contax 645", LIBRAW_MOUNT_Contax645, LIBRAW_FORMAT_645},
      {0x150ULL, "AFi", LIBRAW_MOUNT_Rollei_bayonet, LIBRAW_FORMAT_66},
      {0x147ULL, "Mamiya", LIBRAW_MOUNT_Unknown, LIBRAW_FORMAT_Unknown},
      {0x144ULL, "Universal", LIBRAW_MOUNT_Unknown, LIBRAW_FORMAT_Unknown},
      {0x145ULL, "Hasselblad H1/H2", LIBRAW_MOUNT_Hasselblad_H,
       LIBRAW_FORMAT_645},
      {0x146ULL, "Contax 645", LIBRAW_MOUNT_Contax645, LIBRAW_FORMAT_645},
      {0x14fULL, "AFi", LIBRAW_MOUNT_Rollei_bayonet, LIBRAW_FORMAT_66},
      {0x154ULL, "Mamiya", LIBRAW_MOUNT_Unknown, LIBRAW_FORMAT_Unknown},
      {0x151ULL, "Universal", LIBRAW_MOUNT_Unknown, LIBRAW_FORMAT_Unknown},
      {0x152ULL, "Hasselblad H1/H2", LIBRAW_MOUNT_Hasselblad_H,
       LIBRAW_FORMAT_645},
      {0x153ULL, "Contax 645", LIBRAW_MOUNT_Contax645, LIBRAW_FORMAT_645},
      {0x143ULL, "Mamiya", LIBRAW_MOUNT_Unknown, LIBRAW_FORMAT_Unknown},
      {0x140ULL, "Universal", LIBRAW_MOUNT_Unknown, LIBRAW_FORMAT_Unknown},
      {0x142ULL, "Hasselblad H1/H2", LIBRAW_MOUNT_Hasselblad_H,
       LIBRAW_FORMAT_645},
      {0x141ULL, "Contax 645", LIBRAW_MOUNT_Contax645, LIBRAW_FORMAT_645},
      {0x14eULL, "AFi", LIBRAW_MOUNT_Rollei_bayonet, LIBRAW_FORMAT_66},
      {0x171ULL, "Universal", LIBRAW_MOUNT_Unknown, LIBRAW_FORMAT_Unknown},
      {0x172ULL, "Mamiya", LIBRAW_MOUNT_Unknown, LIBRAW_FORMAT_Unknown},
      {0x173ULL, "Hasselblad H1/H2", LIBRAW_MOUNT_Hasselblad_H,
       LIBRAW_FORMAT_645},
      {0x174ULL, "Contax 645", LIBRAW_MOUNT_Contax645, LIBRAW_FORMAT_645},
      {0x175ULL, "AFi", LIBRAW_MOUNT_Rollei_bayonet, LIBRAW_FORMAT_66},
  };
  ilm.CamID = id;
  if (id && !ilm.body[0])
  {
    for (i = 0; i < sizeof p1_unique / sizeof *p1_unique; i++)
      if (id == p1_unique[i].id)
      {
        strcpy(ilm.body, p1_unique[i].t_model);
        ilm.CameraFormat = p1_unique[i].CamFmt;
        ilm.CameraMount = p1_unique[i].CamMnt;
      }
  }
  return;
}

Project: LibRaw

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

  switch (type)
  {
  case 3: // ushort "SHORT" (int16u)
    return (unsigned short)get2();
  case 4: // unsigned "LONG" (int32u)
    return (unsigned int)get4();
  case 5: // (unsigned, unsigned) "RATIONAL" (rational64u)
    u.d = (unsigned int)get4();
    v.d = (unsigned int)get4();
    return u.d / (v.d ? v.d : 1);
  case 8: // short "SSHORT" (int16s)
    return (signed short)get2();
  case 9: // int "SLONG" (int32s)
    return (signed int)get4();
  case 10: // (int, int) "SRATIONAL" (rational64s)
    u.d = (signed int)get4();
    v.d = (signed int)get4();
    return u.d / (v.d ? v.d : 1);
  case 11: // float "FLOAT" (float)
    return int_to_float(get4());
  case 12: // double "DOUBLE" (double)
    rev = 7 * ((order == 0x4949) == (ntohs(0x1234) == 0x1234));
    for (i = 0; i < 8; i++)
      u.c[i ^ rev] = fgetc(ifp);
    return u.d;
  default:
    return fgetc(ifp);
  }
}

Project: LibRaw

int LibRaw::flip_index(int row, int col)
{
  if (flip & 4)
    SWAP(row, col);
  if (flip & 2)
    row = iheight - 1 - row;
  if (flip & 1)
    col = iwidth - 1 - col;
  return row * iwidth + col;
}

Project: LibRaw

void LibRaw::parseLeicaLensID()
{
  ilm.LensID = get4();
  if (ilm.LensID)
  {
    ilm.LensID = ((ilm.LensID >> 2) << 8) | (ilm.LensID & 0x3);
    if ((ilm.LensID > 0x00ff) && (ilm.LensID < 0x3b00))
    {
      ilm.LensMount = ilm.CameraMount;
      ilm.LensFormat = LIBRAW_FORMAT_FF;
    }
  }
}

Project: LibRaw

void LibRaw::sony_arq_load_raw()
{
  int row, col;
  read_shorts(imgdata.rawdata.raw_image,
              imgdata.sizes.raw_width * imgdata.sizes.raw_height * 4);
  libraw_internal_data.internal_data.input->seek(
      -2, SEEK_CUR); // avoid wrong eof error
  for (row = 0; row < imgdata.sizes.raw_height; row++)
  {
    unsigned short(*rowp)[4] =
        (unsigned short(*)[4]) &
        imgdata.rawdata.raw_image[row * imgdata.sizes.raw_width * 4];
    for (col = 0; col < imgdata.sizes.raw_width; col++)
    {
      unsigned short g2 = rowp[col][2];
      rowp[col][2] = rowp[col][3];
      rowp[col][3] = g2;
      if (((unsigned)(row - imgdata.sizes.top_margin) < imgdata.sizes.height) &&
          ((unsigned)(col - imgdata.sizes.left_margin) < imgdata.sizes.width) &&
          (MAX(MAX(rowp[col][0], rowp[col][1]),
               MAX(rowp[col][2], rowp[col][3])) > imgdata.color.maximum))
        derror();
    }
  }
}

Project: LibRaw

void LibRaw::apply_profile(const char *input, const char *output)
{
  char *prof;
  cmsHPROFILE hInProfile = 0, hOutProfile = 0;
  cmsHTRANSFORM hTransform;
  FILE *fp;
  unsigned size;

  if (strcmp(input, "embed"))
    hInProfile = cmsOpenProfileFromFile(input, "r");
  else if (profile_length)
  {
    hInProfile = cmsOpenProfileFromMem(imgdata.color.profile, profile_length);
  }
  else
  {
    imgdata.process_warnings |= LIBRAW_WARN_NO_EMBEDDED_PROFILE;
  }
  if (!hInProfile)
  {
    imgdata.process_warnings |= LIBRAW_WARN_NO_INPUT_PROFILE;
    return;
  }
  if (!output)
    hOutProfile = cmsCreate_sRGBProfile();
  else if ((fp = fopen(output, "rb")))
  {
    fread(&size, 4, 1, fp);
    fseek(fp, 0, SEEK_SET);
    oprof = (unsigned *)malloc(size = ntohl(size));
    merror(oprof, "apply_profile()");
    fread(oprof, 1, size, fp);
    fclose(fp);
    if (!(hOutProfile = cmsOpenProfileFromMem(oprof, size)))
    {
      free(oprof);
      oprof = 0;
    }
  }
  if (!hOutProfile)
  {
    imgdata.process_warnings |= LIBRAW_WARN_BAD_OUTPUT_PROFILE;
    goto quit;
  }
  RUN_CALLBACK(LIBRAW_PROGRESS_APPLY_PROFILE, 0, 2);
  hTransform = cmsCreateTransform(hInProfile, TYPE_RGBA_16, hOutProfile,
                                  TYPE_RGBA_16, INTENT_PERCEPTUAL, 0);
  cmsDoTransform(hTransform, image, image, width * height);
  raw_color = 1; /* Don't use rgb_cam with a profile */
  cmsDeleteTransform(hTransform);
  cmsCloseProfile(hOutProfile);
quit:
  cmsCloseProfile(hInProfile);
  RUN_CALLBACK(LIBRAW_PROGRESS_APPLY_PROFILE, 1, 2);
}

Project: LibRaw

void LibRaw::crop_masked_pixels()
{
  int row, col;
  unsigned c, m, zero, val;
#define mblack imgdata.color.black_stat

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

Project: LibRaw

void LibRaw::processNikonLensData(uchar *LensData, unsigned len)
{

  ushort i;

  if (!(imgdata.lens.nikon.LensType & 0x01))
  {
    ilm.LensFeatures_pre[0] = 'A';
    ilm.LensFeatures_pre[1] = 'F';
  }
  else
  {
    ilm.LensFeatures_pre[0] = 'M';
    ilm.LensFeatures_pre[1] = 'F';
  }

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

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

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

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

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

  if ((len < 20) || (len == 58))
  {
    switch (len)
    {
    case 9:
      i = 2;
      break;
    case 15:
      i = 7;
      break;
    case 16:
      i = 8;
      break;
    case 58: // "Z 6", "Z 7"
      ilm.CameraMount = LIBRAW_MOUNT_Nikon_Z;
      ilm.CameraFormat = LIBRAW_FORMAT_FF;
      i = 1;
      while ((LensData[i] == LensData[0]) && (i < 17))
        i++;
      if (i == 17)
      {
        ilm.LensMount = LIBRAW_MOUNT_Nikon_Z;
        ilm.LensFormat = LIBRAW_FORMAT_FF;
        ilm.LensID = sget2(LensData + 0x2c);
        if (ilm.MaxAp4CurFocal < 0.7f)
          ilm.MaxAp4CurFocal = libraw_powf64l(
              2.0f, (float)sget2(LensData + 0x32) / 384.0f - 1.0f);
        if (ilm.CurAp < 0.7f)
          ilm.CurAp = libraw_powf64l(
              2.0f, (float)sget2(LensData + 0x34) / 384.0f - 1.0f);
        if (fabsf(ilm.CurFocal) < 1.1f)
          ilm.CurFocal = sget2(LensData + 0x38);
        return;
      }
      i = 9;
      ilm.LensMount = LIBRAW_MOUNT_Nikon_F;
      strcpy(ilm.Adapter, "FTZ");
      break;
    }
    imgdata.lens.nikon.LensIDNumber = LensData[i];
    imgdata.lens.nikon.LensFStops = LensData[i + 1];
    ilm.LensFStops = (float)imgdata.lens.nikon.LensFStops / 12.0f;
    if (fabsf(ilm.MinFocal) < 1.1f)
    {
      if ((imgdata.lens.nikon.LensType ^ (uchar)0x01) || LensData[i + 2])
        ilm.MinFocal =
            5.0f * libraw_powf64l(2.0f, (float)LensData[i + 2] / 24.0f);
      if ((imgdata.lens.nikon.LensType ^ (uchar)0x01) || LensData[i + 3])
        ilm.MaxFocal =
            5.0f * libraw_powf64l(2.0f, (float)LensData[i + 3] / 24.0f);
      if ((imgdata.lens.nikon.LensType ^ (uchar)0x01) || LensData[i + 4])
        ilm.MaxAp4MinFocal =
            libraw_powf64l(2.0f, (float)LensData[i + 4] / 24.0f);
      if ((imgdata.lens.nikon.LensType ^ (uchar)0x01) || LensData[i + 5])
        ilm.MaxAp4MaxFocal =
            libraw_powf64l(2.0f, (float)LensData[i + 5] / 24.0f);
    }
    imgdata.lens.nikon.MCUVersion = LensData[i + 6];
    if (i != 2)
    {
      if ((LensData[i - 1]) && (fabsf(ilm.CurFocal) < 1.1f))
        ilm.CurFocal =
            5.0f * libraw_powf64l(2.0f, (float)LensData[i - 1] / 24.0f);
      if (LensData[i + 7])
        imgdata.lens.nikon.EffectiveMaxAp =
            libraw_powf64l(2.0f, (float)LensData[i + 7] / 24.0f);
    }
    ilm.LensID = (unsigned long long)LensData[i] << 56 |
                 (unsigned long long)LensData[i + 1] << 48 |
                 (unsigned long long)LensData[i + 2] << 40 |
                 (unsigned long long)LensData[i + 3] << 32 |
                 (unsigned long long)LensData[i + 4] << 24 |
                 (unsigned long long)LensData[i + 5] << 16 |
                 (unsigned long long)LensData[i + 6] << 8 |
                 (unsigned long long)imgdata.lens.nikon.LensType;
  }
  else if ((len == 459) || (len == 590))
  {
    memcpy(ilm.Lens, LensData + 390, 64);
  }
  else if (len == 509)
  {
    memcpy(ilm.Lens, LensData + 391, 64);
  }
  else if (len == 879)
  {
    memcpy(ilm.Lens, LensData + 680, 64);
  }

  return;
}

Project: LibRaw

void LibRaw::simple_coeff(int index)
{
  static const float table[][12] = {
      /* index 0 -- all Foveon cameras */
      {1.4032, -0.2231, -0.1016, -0.5263, 1.4816, 0.017, -0.0112, 0.0183,
       0.9113},
      /* index 1 -- Kodak DC20 and DC25 */
      {2.25, 0.75, -1.75, -0.25, -0.25, 0.75, 0.75, -0.25, -0.25, -1.75, 0.75,
       2.25},
      /* index 2 -- Logitech Fotoman Pixtura */
      {1.893, -0.418, -0.476, -0.495, 1.773, -0.278, -1.017, -0.655, 2.672},
      /* index 3 -- Nikon E880, E900, and E990 */
      {-1.936280, 1.800443, -1.448486, 2.584324, 1.405365, -0.524955, -0.289090,
       0.408680, -1.204965, 1.082304, 2.941367, -1.818705}};
  int i, c;

  for (raw_color = i = 0; i < 3; i++)
    FORCC rgb_cam[i][c] = table[index][i * colors + c];
}

Project: LibRaw

char *get_next_file()
{
  char *ret;
  DWORD dwWaitResult;
  if (!queue)
    return NULL;
  if (qptr >= qsize)
    return NULL;

  dwWaitResult = WaitForSingleObject(qmutex,    // handle to mutex
                                     INFINITE); // no time-out interval
  switch (dwWaitResult)
  {
  // The thread got ownership of the mutex
  case WAIT_OBJECT_0:
    ret = queue[qptr++];
    ReleaseMutex(qmutex);
    break;
  case WAIT_ABANDONED:
    return NULL; // cannot obtain the lock
  };
  return ret;
}

Project: LibRaw

void LibRaw::Canon_WBpresets(int skip1, int skip2)
{
  int c;
  FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_Daylight][c ^ (c >> 1)] = get2();

  if (skip1)
    fseek(ifp, skip1, SEEK_CUR);
  FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_Shade][c ^ (c >> 1)] = get2();

  if (skip1)
    fseek(ifp, skip1, SEEK_CUR);
  FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_Cloudy][c ^ (c >> 1)] = get2();

  if (skip1)
    fseek(ifp, skip1, SEEK_CUR);
  FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_Tungsten][c ^ (c >> 1)] = get2();

  if (skip1)
    fseek(ifp, skip1, SEEK_CUR);
  FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_FL_W][c ^ (c >> 1)] = get2();

  if (skip2)
    fseek(ifp, skip2, SEEK_CUR);
  FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_Flash][c ^ (c >> 1)] = get2();

  return;
}

Project: LibRaw

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

Project: LibRaw

void trimSpaces(char *s)
{
  char *p = s;
  if (!strncasecmp(p, "NO=", 3))
    p = p + 3; /* fix for Nikon D70, D70s */
  int l = strlen(p);
  if (!l)
    return;
  while (isspace(p[l - 1]))
    p[--l] = 0; /* trim trailing spaces */
  while (*p && isspace(*p))
    ++p, --l; /* trim leading spaces */
  memmove(s, p, l + 1);
}

Project: LibRaw

INT64 LibRaw_bigfile_datastream::tell()
{
  LR_BF_CHK();
#if defined(_WIN32)
#ifdef WIN32SECURECALLS
  return _ftelli64(f);
#else
  return ftell(f);
#endif
#else
  return ftello(f);
#endif
}

Project: LibRaw

void LibRaw::PentaxISO(ushort c)
{
  int code[] = {3,    4,    5,   6,   7,   8,   9,   10,  11,  12,  13,  14,
                15,   16,   17,  18,  19,  20,  21,  22,  23,  24,  25,  26,
                27,   28,   29,  30,  31,  32,  33,  34,  35,  36,  37,  38,
                39,   40,   41,  42,  43,  44,  45,  50,  100, 200, 400, 800,
                1600, 3200, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267,
                268,  269,  270, 271, 272, 273, 274, 275, 276, 277, 278};
  double value[] = {
      50,     64,     80,     100,    125,    160,    200,    250,    320,
      400,    500,    640,    800,    1000,   1250,   1600,   2000,   2500,
      3200,   4000,   5000,   6400,   8000,   10000,  12800,  16000,  20000,
      25600,  32000,  40000,  51200,  64000,  80000,  102400, 128000, 160000,
      204800, 258000, 325000, 409600, 516000, 650000, 819200, 50,     100,
      200,    400,    800,    1600,   3200,   50,     70,     100,    140,
      200,    280,    400,    560,    800,    1100,   1600,   2200,   3200,
      4500,   6400,   9000,   12800,  18000,  25600,  36000,  51200};
#define numel (sizeof(code) / sizeof(code[0]))
  int i;
  for (i = 0; i < numel; i++)
  {
    if (code[i] == c)
    {
      iso_speed = value[i];
      return;
    }
  }
  if (i == numel)
    iso_speed = 65535.0f;
}

Project: LibRaw

  static inline float Thot(void) throw() { return 64.0f; }

Project: LibRaw

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

Project: LibRaw

void DHT::make_rbdiag(int i)
{
  int iwidth = libraw.imgdata.sizes.iwidth;
  int js = libraw.COLOR(i, 0) & 1;
  int uc = libraw.COLOR(i, js);
  int cl = uc ^ 2;
  /*
   * js -- начальная х-координата, которая попадает на уже интерполированный
   * зелёный al -- известный цвет (кроме зелёного) в точке интерполирования cl
   * -- неизвестный цвет
   */
  for (int j = js; j < iwidth; j += 2)
  {
    int x = j + nr_leftmargin;
    int y = i + nr_topmargin;
    int dx, dy, dx2, dy2;
    if (ndir[nr_offset(y, x)] & LURD)
    {
      dx = -1;
      dx2 = 1;
      dy = -1;
      dy2 = 1;
    }
    else
    {
      dx = -1;
      dx2 = 1;
      dy = 1;
      dy2 = -1;
    }
    float g1 = 1 / calc_dist(nraw[nr_offset(y, x)][1],
                             nraw[nr_offset(y + dy, x + dx)][1]);
    float g2 = 1 / calc_dist(nraw[nr_offset(y, x)][1],
                             nraw[nr_offset(y + dy2, x + dx2)][1]);
    g1 *= g1 * g1;
    g2 *= g2 * g2;

    float eg;
    eg = nraw[nr_offset(y, x)][1] *
         (g1 * nraw[nr_offset(y + dy, x + dx)][cl] /
              nraw[nr_offset(y + dy, x + dx)][1] +
          g2 * nraw[nr_offset(y + dy2, x + dx2)][cl] /
              nraw[nr_offset(y + dy2, x + dx2)][1]) /
         (g1 + g2);
    float min, max;
    min = MIN(nraw[nr_offset(y + dy, x + dx)][cl],
              nraw[nr_offset(y + dy2, x + dx2)][cl]);
    max = MAX(nraw[nr_offset(y + dy, x + dx)][cl],
              nraw[nr_offset(y + dy2, x + dx2)][cl]);
    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[cl])
      eg = channel_maximum[cl];
    else if (eg < channel_minimum[cl])
      eg = channel_minimum[cl];
    nraw[nr_offset(y, x)][cl] = eg;
  }
}

Project: LibRaw

const char *LibRaw_bigfile_datastream::fname()
{
  return filename.size() > 0 ? filename.c_str() : NULL;
}

Project: LibRaw

void LibRaw::process_Sony_0x9403(uchar *buf, ushort len)
{
  if (len < 6)
    return;
  uchar bufx = SonySubstitution[buf[4]];
  if ((bufx == 0x00) || (bufx == 0x94))
    return;

  imgdata.makernotes.common.SensorTemperature = (float)((short)SonySubstitution[buf[5]]);

  return;
}

Project: LibRaw

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

  if (meta_offset)
  {
    fseek(ifp, meta_offset, SEEK_SET);
    order = 0x4d4d;
    ntags = get4();
    while (ntags--)
    {
      opcode = get4();
      get4();
      get4();
      if (opcode != 8)
      {
        fseek(ifp, get4(), SEEK_CUR);
        continue;
      }
      fseek(ifp, 20, SEEK_CUR);
      if ((c = get4()) > 2)
        break;
      fseek(ifp, 12, SEEK_CUR);
      if ((deg = get4()) > 8)
        break;
      for (i = 0; i <= deg && i < 9; i++)
        coeff[i] = getreal(12);
      for (i = 0; i < 256; i++)
      {
        for (tot = j = 0; j <= deg; j++)
          tot += coeff[j] * pow(i / 255.0, (int)j);
        cur[c][i] = tot * 0xffff;
      }
    }
    order = sorder;
  }
  else
  {
    gamma_curve(1 / 2.4, 12.92, 1, 255);
    FORC3 memcpy(cur[c], curve, sizeof cur[0]);
  }

  struct jpeg_error_mgr pub;
  cinfo.err = jpeg_std_error(&pub);
  pub.error_exit = jpegErrorExit_d;

  jpeg_create_decompress(&cinfo);

  while (trow < raw_height)
  {
    fseek(ifp, save += 4, SEEK_SET);
    if (tile_length < INT_MAX)
      fseek(ifp, get4(), SEEK_SET);
    if (libraw_internal_data.internal_data.input->jpeg_src(&cinfo) == -1)
    {
      jpeg_destroy_decompress(&cinfo);
      throw LIBRAW_EXCEPTION_DECODE_JPEG;
    }
    jpeg_read_header(&cinfo, TRUE);
    jpeg_start_decompress(&cinfo);
    buf = (*cinfo.mem->alloc_sarray)((j_common_ptr)&cinfo, JPOOL_IMAGE,
                                     cinfo.output_width * 3, 1);
    try
    {
      while (cinfo.output_scanline < cinfo.output_height &&
             (row = trow + cinfo.output_scanline) < height)
      {
        checkCancel();
        jpeg_read_scanlines(&cinfo, buf, 1);
        pixel = (JSAMPLE(*)[3])buf[0];
        for (col = 0; col < cinfo.output_width && tcol + col < width; col++)
        {
          FORC3 image[row * width + tcol + col][c] = cur[c][pixel[col][c]];
        }
      }
    }
    catch (...)
    {
      jpeg_destroy_decompress(&cinfo);
      throw;
    }
    jpeg_abort_decompress(&cinfo);
    if ((tcol += tile_width) >= raw_width)
      trow += tile_length + (tcol = 0);
  }
  jpeg_destroy_decompress(&cinfo);
  maximum = 0xffff;
}

Project: LibRaw

void LibRaw::fbdd_correction2(double (*image2)[3])
{
  int indx, u = width, v = 2 * width;
  int col, row;
  double Co, Ho, ratio;

  for (row = 6; row < height - 6; row++)
  {
    for (col = 6; col < width - 6; col++)
    {
      indx = row * width + col;

      if (image2[indx][1] * image2[indx][2] != 0)
      {
        Co = (image2[indx + v][1] + image2[indx - v][1] + image2[indx - 2][1] +
              image2[indx + 2][1] -
              MAX(image2[indx - 2][1],
                  MAX(image2[indx + 2][1],
                      MAX(image2[indx - v][1], image2[indx + v][1]))) -
              MIN(image2[indx - 2][1],
                  MIN(image2[indx + 2][1],
                      MIN(image2[indx - v][1], image2[indx + v][1])))) /
             2.0;
        Ho = (image2[indx + v][2] + image2[indx - v][2] + image2[indx - 2][2] +
              image2[indx + 2][2] -
              MAX(image2[indx - 2][2],
                  MAX(image2[indx + 2][2],
                      MAX(image2[indx - v][2], image2[indx + v][2]))) -
              MIN(image2[indx - 2][2],
                  MIN(image2[indx + 2][2],
                      MIN(image2[indx - v][2], image2[indx + v][2])))) /
             2.0;
        ratio = sqrt((Co * Co + Ho * Ho) / (image2[indx][1] * image2[indx][1] +
                                            image2[indx][2] * image2[indx][2]));

        if (ratio < 0.85)
        {
          image2[indx][0] =
              -(image2[indx][1] + image2[indx][2] - Co - Ho) + image2[indx][0];
          image2[indx][1] = Co;
          image2[indx][2] = Ho;
        }
      }
    }
  }
}

Project: LibRaw

LibRaw::LibRaw(unsigned int flags) : memmgr(1024)
{
  double aber[4] = {1, 1, 1, 1};
  double gamm[6] = {0.45, 4.5, 0, 0, 0, 0};
  unsigned greybox[4] = {0, 0, UINT_MAX, UINT_MAX};
  unsigned cropbox[4] = {0, 0, UINT_MAX, UINT_MAX};
  ZERO(imgdata);

  cleargps(&imgdata.other.parsed_gps);
  ZERO(libraw_internal_data);
  ZERO(callbacks);

  _rawspeed_camerameta = _rawspeed_decoder = NULL;
  dnghost = NULL;
  dngnegative = NULL;
  dngimage = NULL;
  _x3f_data = NULL;

#ifdef USE_RAWSPEED
  CameraMetaDataLR *camerameta =
      make_camera_metadata(); // May be NULL in case of exception in
                              // make_camera_metadata()
  _rawspeed_camerameta = static_cast<void *>(camerameta);
#endif
  callbacks.mem_cb = (flags & LIBRAW_OPIONS_NO_MEMERR_CALLBACK)
                         ? NULL
                         : &default_memory_callback;
  callbacks.data_cb = (flags & LIBRAW_OPIONS_NO_DATAERR_CALLBACK)
                          ? NULL
                          : &default_data_callback;
  callbacks.exif_cb = NULL; // no default callback
  callbacks.pre_identify_cb = NULL;
  callbacks.post_identify_cb = NULL;
  callbacks.pre_subtractblack_cb = callbacks.pre_scalecolors_cb =
      callbacks.pre_preinterpolate_cb = callbacks.pre_interpolate_cb =
          callbacks.interpolate_bayer_cb = callbacks.interpolate_xtrans_cb =
              callbacks.post_interpolate_cb = callbacks.pre_converttorgb_cb =
                  callbacks.post_converttorgb_cb = NULL;

  memmove(&imgdata.params.aber, &aber, sizeof(aber));
  memmove(&imgdata.params.gamm, &gamm, sizeof(gamm));
  memmove(&imgdata.params.greybox, &greybox, sizeof(greybox));
  memmove(&imgdata.params.cropbox, &cropbox, sizeof(cropbox));

  imgdata.params.bright = 1;
  imgdata.params.use_camera_matrix = 1;
  imgdata.params.user_flip = -1;
  imgdata.params.user_black = -1;
  imgdata.params.user_cblack[0] = imgdata.params.user_cblack[1] =
      imgdata.params.user_cblack[2] = imgdata.params.user_cblack[3] = -1000001;
  imgdata.params.user_sat = -1;
  imgdata.params.user_qual = -1;
  imgdata.params.output_color = 1;
  imgdata.params.output_bps = 8;
  imgdata.params.use_fuji_rotate = 1;
  imgdata.params.exp_shift = 1.0;
  imgdata.params.auto_bright_thr = LIBRAW_DEFAULT_AUTO_BRIGHTNESS_THRESHOLD;
  imgdata.params.adjust_maximum_thr = LIBRAW_DEFAULT_ADJUST_MAXIMUM_THRESHOLD;
  imgdata.params.use_rawspeed = 1;
  imgdata.params.use_dngsdk = LIBRAW_DNG_DEFAULT;
  imgdata.params.no_auto_scale = 0;
  imgdata.params.no_interpolation = 0;
  imgdata.params.raw_processing_options = LIBRAW_PROCESSING_DP2Q_INTERPOLATERG |
                                          LIBRAW_PROCESSING_DP2Q_INTERPOLATEAF |
                                          LIBRAW_PROCESSING_CONVERTFLOAT_TO_INT;
  imgdata.params.sony_arw2_posterization_thr = 0;
  imgdata.params.max_raw_memory_mb = LIBRAW_MAX_ALLOC_MB_DEFAULT;
  imgdata.params.green_matching = 0;
  imgdata.params.custom_camera_strings = 0;
  imgdata.params.coolscan_nef_gamma = 1.0f;
  imgdata.parent_class = this;
  imgdata.progress_flags = 0;
  imgdata.color.dng_levels.baseline_exposure = -999.f;
  imgdata.color.dng_levels.LinearResponseLimit = 1.0f;
  imgdata.makernotes.hasselblad.nIFD_CM[0] =
    imgdata.makernotes.hasselblad.nIFD_CM[1] = -1;
  imgdata.makernotes.kodak.ISOCalibrationGain = 1.0f;
  _exitflag = 0;
  tls = new LibRaw_TLS;
  tls->init();
}

Project: LibRaw

void LibRaw::kodak_radc_load_raw()
{
  // All kodak radc images are 768x512
  if (width > 768 || raw_width > 768 || height > 512 || raw_height > 512)
    throw LIBRAW_EXCEPTION_IO_CORRUPT;
  static const signed char src[] = {
      1, 1,   2, 3,   3, 4,   4, 2,   5, 7,   6, 5,   7, 6,   7, 8,   1, 0,
      2, 1,   3, 3,   4, 4,   5, 2,   6, 7,   7, 6,   8, 5,   8, 8,   2, 1,
      2, 3,   3, 0,   3, 2,   3, 4,   4, 6,   5, 5,   6, 7,   6, 8,   2, 0,
      2, 1,   2, 3,   3, 2,   4, 4,   5, 6,   6, 7,   7, 5,   7, 8,   2, 1,
      2, 4,   3, 0,   3, 2,   3, 3,   4, 7,   5, 5,   6, 6,   6, 8,   2, 3,
      3, 1,   3, 2,   3, 4,   3, 5,   3, 6,   4, 7,   5, 0,   5, 8,   2, 3,
      2, 6,   3, 0,   3, 1,   4, 4,   4, 5,   4, 7,   5, 2,   5, 8,   2, 4,
      2, 7,   3, 3,   3, 6,   4, 1,   4, 2,   4, 5,   5, 0,   5, 8,   2, 6,
      3, 1,   3, 3,   3, 5,   3, 7,   3, 8,   4, 0,   5, 2,   5, 4,   2, 0,
      2, 1,   3, 2,   3, 3,   4, 4,   4, 5,   5, 6,   5, 7,   4, 8,   1, 0,
      2, 2,   2, -2,  1, -3,  1, 3,   2, -17, 2, -5,  2, 5,   2, 17,  2, -7,
      2, 2,   2, 9,   2, 18,  2, -18, 2, -9,  2, -2,  2, 7,   2, -28, 2, 28,
      3, -49, 3, -9,  3, 9,   4, 49,  5, -79, 5, 79,  2, -1,  2, 13,  2, 26,
      3, 39,  4, -16, 5, 55,  6, -37, 6, 76,  2, -26, 2, -13, 2, 1,   3, -39,
      4, 16,  5, -55, 6, -76, 6, 37};
  ushort huff[19][256];
  int row, col, tree, nreps, rep, step, i, c, s, r, x, y, val;
  short last[3] = {16, 16, 16}, mul[3], buf[3][3][386];
  static const ushort pt[] = {0,    0,    1280, 1344,  2320,  3616,
                              3328, 8000, 4095, 16383, 65535, 16383};

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

Project: LibRaw

int LibRaw::dcraw_process(void)
{
  return LIBRAW_NOT_IMPLEMENTED;
}

Project: LibRaw

  const char *libraw_unpack_function_name(libraw_data_t *lr)
  {
    if (!lr)
      return "NULL parameter passed";
    LibRaw *ip = (LibRaw *)lr->parent_class;
    return ip->unpack_function_name();
  }

Project: LibRaw

void LibRaw::process_Sony_0x9402(uchar *buf, ushort len)
{

  if (len < 23)
    return;

  imgdata.shootinginfo.FocusMode = SonySubstitution[buf[0x16]];

  if ((imSony.CameraType == LIBRAW_SONY_SLT) ||
      (imSony.CameraType == LIBRAW_SONY_ILCA))
    return;

  uchar bufx = buf[0x00];
  if ((bufx == 0x05) || (bufx == 0xff) || (buf[0x02] != 0xff))
    return;

  imgdata.makernotes.common.AmbientTemperature =
      (float)((short)SonySubstitution[buf[0x04]]);

  return;
}

Project: LibRaw

void LibRaw::median_filter()
{
  ushort(*pix)[4];
  int pass, c, i, j, k, med[9];
  static const uchar opt[] = /* Optimal 9-element median search */
      {1, 2, 4, 5, 7, 8, 0, 1, 3, 4, 6, 7, 1, 2, 4, 5, 7, 8, 0,
       3, 5, 8, 4, 7, 3, 6, 1, 4, 2, 5, 4, 7, 4, 2, 6, 4, 4, 2};

  for (pass = 1; pass <= med_passes; pass++)
  {
    RUN_CALLBACK(LIBRAW_PROGRESS_MEDIAN_FILTER, pass - 1, med_passes);
    for (c = 0; c < 3; c += 2)
    {
      for (pix = image; pix < image + width * height; pix++)
        pix[0][3] = pix[0][c];
      for (pix = image + width; pix < image + width * (height - 1); pix++)
      {
        if ((pix - image + 1) % width < 2)
          continue;
        for (k = 0, i = -width; i <= width; i += width)
          for (j = i - 1; j <= i + 1; j++)
            med[k++] = pix[j][3] - pix[j][1];
        for (i = 0; i < sizeof opt; i += 2)
          if (med[opt[i]] > med[opt[i + 1]])
            SWAP(med[opt[i]], med[opt[i + 1]]);
        pix[0][c] = CLIP(med[4] + pix[0][1]);
      }
    }
  }
}

Project: LibRaw

void write_thumb(libraw_processed_image_t *img, const char *basename)
{
  if (!img)
    return;

  if (img->type == LIBRAW_IMAGE_BITMAP)
  {
    char fnt[1024];
    snprintf(fnt, 1024, "%s.thumb", basename);
    write_ppm(img, fnt);
  }
  else if (img->type == LIBRAW_IMAGE_JPEG)
  {
    char fn[1024];
    snprintf(fn, 1024, "%s.thumb.jpg", basename);
    FILE *f = fopen(fn, "wb");
    if (!f)
      return;
    fwrite(img->data, img->data_size, 1, f);
    fclose(f);
  }
}

Project: LibRaw

void LibRaw::canon_600_auto_wb()
{
  int mar, row, col, i, j, st, count[] = {0, 0};
  int test[8], total[2][8], ratio[2][2], stat[2];

  memset(&total, 0, sizeof total);
  i = canon_ev + 0.5;
  if (i < 10)
    mar = 150;
  else if (i > 12)
    mar = 20;
  else
    mar = 280 - 20 * i;
  if (flash_used)
    mar = 80;
  for (row = 14; row < height - 14; row += 4)
    for (col = 10; col < width; col += 2)
    {
      for (i = 0; i < 8; i++)
        test[(i & 4) + FC(row + (i >> 1), col + (i & 1))] =
            BAYER(row + (i >> 1), col + (i & 1));
      for (i = 0; i < 8; i++)
        if (test[i] < 150 || test[i] > 1500)
          goto next;
      for (i = 0; i < 4; i++)
        if (abs(test[i] - test[i + 4]) > 50)
          goto next;
      for (i = 0; i < 2; i++)
      {
        for (j = 0; j < 4; j += 2)
          ratio[i][j >> 1] =
              ((test[i * 4 + j + 1] - test[i * 4 + j]) << 10) / test[i * 4 + j];
        stat[i] = canon_600_color(ratio[i], mar);
      }
      if ((st = stat[0] | stat[1]) > 1)
        goto next;
      for (i = 0; i < 2; i++)
        if (stat[i])
          for (j = 0; j < 2; j++)
            test[i * 4 + j * 2 + 1] =
                test[i * 4 + j * 2] * (0x400 + ratio[i][j]) >> 10;
      for (i = 0; i < 8; i++)
        total[st][i] += test[i];
      count[st]++;
    next:;
    }
  if (count[0] | count[1])
  {
    st = count[0] * 200 < count[1];
    for (i = 0; i < 4; i++)
      pre_mul[i] = 1.0 / (total[st][i] + total[st][i + 4]);
  }
}

Project: LibRaw

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

  x3f_header_t *H = NULL;

  H = &x3f->header;
  // Parse RAW size from RAW section
  x3f_directory_entry_t *DE = x3f_get_raw(x3f);
  if (!DE)
    return;
  imgdata.sizes.flip = H->rotation;
  x3f_directory_entry_header_t *DEH = &DE->header;
  x3f_image_data_t *ID = &DEH->data_subsection.image_data;
  imgdata.sizes.raw_width = ID->columns;
  imgdata.sizes.raw_height = ID->rows;
  // Parse other params from property section

  DE = x3f_get_prop(x3f);
  if ((x3f_load_data(x3f, DE) == X3F_OK))
  {
    // Parse property list
    DEH = &DE->header;
    x3f_property_list_t *PL = &DEH->data_subsection.property_list;
    utf16_t *datap = (utf16_t *)PL->data;
    uint32_t maxitems = PL->data_size / sizeof(utf16_t);
    if (PL->property_table.size != 0)
    {
      int i;
      x3f_property_t *P = PL->property_table.element;
      for (i = 0; i < PL->num_properties; i++)
      {
        char name[100], value[100];
        int noffset = (P[i].name - datap);
        int voffset = (P[i].value - datap);
        if (noffset < 0 || noffset > maxitems || voffset < 0 ||
            voffset > maxitems)
          throw LIBRAW_EXCEPTION_IO_CORRUPT;
        int maxnsize = maxitems - (P[i].name - datap);
        int maxvsize = maxitems - (P[i].value - datap);
        utf2char(P[i].name, name, MIN(maxnsize, sizeof(name)));
        utf2char(P[i].value, value, MIN(maxvsize, sizeof(value)));
        if (!strcmp(name, "ISO"))
          imgdata.other.iso_speed = atoi(value);
        if (!strcmp(name, "CAMMANUF"))
          strcpy(imgdata.idata.make, value);
        if (!strcmp(name, "CAMMODEL"))
          strcpy(imgdata.idata.model, value);
        if (!strcmp(name, "CAMSERIAL"))
          strcpy(imgdata.shootinginfo.BodySerial, value);
        if (!strcmp(name, "WB_DESC"))
          strcpy(imgdata.color.model2, value);
        if (!strcmp(name, "TIME"))
          imgdata.other.timestamp = atoi(value);
        if (!strcmp(name, "SHUTTER"))
          imgdata.other.shutter = atof(value);
        if (!strcmp(name, "APERTURE"))
          imgdata.other.aperture = atof(value);
        if (!strcmp(name, "FLENGTH"))
          imgdata.other.focal_len = atof(value);
        if (!strcmp(name, "FLEQ35MM"))
          imgdata.lens.makernotes.FocalLengthIn35mmFormat = atof(value);
        if (!strcmp(name, "IMAGERTEMP"))
          imgdata.makernotes.common.SensorTemperature = atof(value);
        if (!strcmp(name, "LENSARANGE"))
        {
          char *sp;
          imgdata.lens.makernotes.MaxAp4CurFocal =
              imgdata.lens.makernotes.MinAp4CurFocal = atof(value);
          sp = strrchr(value, ' ');
          if (sp)
          {
            imgdata.lens.makernotes.MinAp4CurFocal = atof(sp);
            if (imgdata.lens.makernotes.MaxAp4CurFocal >
                imgdata.lens.makernotes.MinAp4CurFocal)
              my_swap(float, imgdata.lens.makernotes.MaxAp4CurFocal,
                      imgdata.lens.makernotes.MinAp4CurFocal);
          }
        }
        if (!strcmp(name, "LENSFRANGE"))
        {
          char *sp;
          imgdata.lens.makernotes.MinFocal = imgdata.lens.makernotes.MaxFocal =
              atof(value);
          sp = strrchr(value, ' ');
          if (sp)
          {
            imgdata.lens.makernotes.MaxFocal = atof(sp);
            if ((imgdata.lens.makernotes.MaxFocal + 0.17f) <
                imgdata.lens.makernotes.MinFocal)
              my_swap(float, imgdata.lens.makernotes.MaxFocal,
                      imgdata.lens.makernotes.MinFocal);
          }
        }
        if (!strcmp(name, "LENSMODEL"))
        {
          char *sp;
          imgdata.lens.makernotes.LensID =
              strtol(value, &sp, 16); // atoi(value);
          if (imgdata.lens.makernotes.LensID)
            imgdata.lens.makernotes.LensMount = Sigma_X3F;
        }
      }
      imgdata.idata.raw_count = 1;
      load_raw = &LibRaw::x3f_load_raw;
      imgdata.sizes.raw_pitch = imgdata.sizes.raw_width * 6;
      imgdata.idata.is_foveon = 1;
      libraw_internal_data.internal_output_params.raw_color =
          1;                          // Force adobe coeff
      imgdata.color.maximum = 0x3fff; // To be reset by color table
      libraw_internal_data.unpacker_data.order = 0x4949;
    }
  }
  else
  {
    // No property list
    if (imgdata.sizes.raw_width == 5888 || imgdata.sizes.raw_width == 2944 ||
        imgdata.sizes.raw_width == 6656 || imgdata.sizes.raw_width == 3328 ||
        imgdata.sizes.raw_width == 5504 ||
        imgdata.sizes.raw_width == 2752) // Quattro
    {
      imgdata.idata.raw_count = 1;
      load_raw = &LibRaw::x3f_load_raw;
      imgdata.sizes.raw_pitch = imgdata.sizes.raw_width * 6;
      imgdata.idata.is_foveon = 1;
      libraw_internal_data.internal_output_params.raw_color =
          1; // Force adobe coeff
      libraw_internal_data.unpacker_data.order = 0x4949;
      strcpy(imgdata.idata.make, "SIGMA");
#if 1
      // Try to find model number in first 2048 bytes;
      int pos = libraw_internal_data.internal_data.input->tell();
      libraw_internal_data.internal_data.input->seek(0, SEEK_SET);
      unsigned char buf[2048];
      libraw_internal_data.internal_data.input->read(buf, 2048, 1);
      libraw_internal_data.internal_data.input->seek(pos, SEEK_SET);
      unsigned char *fnd = (unsigned char *)lr_memmem(buf, 2048, "SIGMA dp", 8);
      unsigned char *fndsd =
          (unsigned char *)lr_memmem(buf, 2048, "sd Quatt", 8);
      if (fnd)
      {
        unsigned char *nm = fnd + 8;
        snprintf(imgdata.idata.model, 64, "dp%c Quattro",
                 *nm <= '9' && *nm >= '0' ? *nm : '2');
      }
      else if (fndsd)
      {
        snprintf(imgdata.idata.model, 64, "%s", fndsd);
      }
      else
#endif
          if (imgdata.sizes.raw_width == 6656 ||
              imgdata.sizes.raw_width == 3328)
        strcpy(imgdata.idata.model, "sd Quattro H");
      else
        strcpy(imgdata.idata.model, "dp2 Quattro");
    }
    // else
  }
  // Try to get thumbnail data
  LibRaw_thumbnail_formats format = LIBRAW_THUMBNAIL_UNKNOWN;
  if ((DE = x3f_get_thumb_jpeg(x3f)))
  {
    format = LIBRAW_THUMBNAIL_JPEG;
  }
  else if ((DE = x3f_get_thumb_plain(x3f)))
  {
    format = LIBRAW_THUMBNAIL_BITMAP;
  }
  if (DE)
  {
    x3f_directory_entry_header_t *DEH = &DE->header;
    x3f_image_data_t *ID = &DEH->data_subsection.image_data;
    imgdata.thumbnail.twidth = ID->columns;
    imgdata.thumbnail.theight = ID->rows;
    imgdata.thumbnail.tcolors = 3;
    imgdata.thumbnail.tformat = format;
    libraw_internal_data.internal_data.toffset = DE->input.offset;
    write_thumb = &LibRaw::x3f_thumb_loader;
  }
  DE = x3f_get_camf(x3f);
  if (DE && DE->input.size > 28)
  {
    libraw_internal_data.unpacker_data.meta_offset = DE->input.offset + 8;
    libraw_internal_data.unpacker_data.meta_length = DE->input.size - 28;
  }
}

Project: LibRaw

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

Project: LibRaw

void LibRaw::parse_broadcom()
{

  /* This structure is at offset 0xb0 from the 'BRCM' ident. */
  struct
  {
    uint8_t umode[32];
    uint16_t uwidth;
    uint16_t uheight;
    uint16_t padding_right;
    uint16_t padding_down;
    uint32_t unknown_block[6];
    uint16_t transform;
    uint16_t format;
    uint8_t bayer_order;
    uint8_t bayer_format;
  } header;

  header.bayer_order = 0;
  fseek(ifp, 0xb0 - 0x20, SEEK_CUR);
  fread(&header, 1, sizeof(header), ifp);
  /* load_flags is not used in broadcom loader, so reuse it for raw_stride */
  load_flags =
      ((((((header.uwidth + header.padding_right) * 5) + 3) >> 2) + 0x1f) &
       (~0x1f));
  raw_width = width = header.uwidth;
  raw_height = height = header.uheight;
  filters = 0x16161616; /* default Bayer order is 2, BGGR */

  switch (header.bayer_order)
  {
  case 0: /* RGGB */
    filters = 0x94949494;
    break;
  case 1: /* GBRG */
    filters = 0x49494949;
    break;
  case 3: /* GRBG */
    filters = 0x61616161;
    break;
  }
}

Project: LibRaw

int LibRaw::thumbOK(INT64 maxsz)
{
  if (!ID.input)
    return 0;
  if (!ID.toffset && !(imgdata.thumbnail.tlength > 0 &&
                       load_raw == &LibRaw::broadcom_load_raw) // RPi
  )
    return 0;
  INT64 fsize = ID.input->size();
  if (fsize > 0x7fffffffU)
    return 0; // No thumb for raw > 2Gb
  int tsize = 0;
  int tcol = (T.tcolors > 0 && T.tcolors < 4) ? T.tcolors : 3;
  if (write_thumb == &LibRaw::jpeg_thumb)
    tsize = T.tlength;
  else if (write_thumb == &LibRaw::ppm_thumb)
    tsize = tcol * T.twidth * T.theight;
  else if (write_thumb == &LibRaw::ppm16_thumb)
    tsize = tcol * T.twidth * T.theight *
            ((imgdata.params.raw_processing_options &
              LIBRAW_PROCESSING_USE_PPM16_THUMBS)
                 ? 2
                 : 1);
  else if (write_thumb == &LibRaw::x3f_thumb_loader)
  {
    tsize = x3f_thumb_size();
  }
  else // Kodak => no check
    tsize = 1;
  if (tsize < 0)
    return 0;
  if (maxsz > 0 && tsize > maxsz)
    return 0;
  return (tsize + ID.toffset <= fsize) ? 1 : 0;
}

Project: LibRaw

int main(int ac, char *av[])
{
  int i, max_threads = 2;
  HANDLE *threads;
  DWORD ThreadID;

  if (ac < 2)
    usage(av[0]);

  queue = calloc(ac - 1, sizeof(queue[0]));

  for (i = 1; i < ac; i++)
  {
    if (av[i][0] == '-')
    {
      if (av[i][1] == 'w')
        use_camera_wb = 1;
      if (av[i][1] == 'a')
        use_auto_wb = 1;
      if (av[i][1] == 'v')
        verbose = 1;
      if (av[i][1] == 'T')
        tiff_mode = 1;
      if (av[i][1] == 'J')
      {
        max_threads = atoi(av[++i]);
        if (max_threads < 1)
        {
          fprintf(stderr, "Job count should be at least 1\n");
          exit(1);
        }
      }
    }
    else
      queue[qsize++] = av[i];
  }
  qmutex = CreateMutex(NULL, FALSE, NULL);
  threads = calloc(max_threads, sizeof(threads[0]));
  for (i = 0; i < max_threads; i++)
  {

    if (NULL ==
        (threads[i] = CreateThread(NULL, // default security attributes
                                   0,    // default stack size
                                   (LPTHREAD_START_ROUTINE)process_files,
                                   NULL,      // no thread function arguments
                                   0,         // default creation flags
                                   &ThreadID) // receive thread identifier
         ))
    {
      printf("CreateThread error: %d\n", GetLastError());
      return 1;
    }
  }

  WaitForMultipleObjects(max_threads, threads, TRUE, INFINITE);

  // Close thread and mutex handles

  for (i = 0; i < max_threads; i++)
    CloseHandle(threads[i]);

  CloseHandle(qmutex);

  return 0;
}

Project: LibRaw

void pana_cs6_page_decoder::read_page()
{
  if (!buffer || (maxoffset - lastoffset < 16))
    throw LIBRAW_EXCEPTION_IO_EOF;
#define wbuffer(i) ((unsigned short)buffer[lastoffset + 15 - i])
  pixelbuffer[0] = (wbuffer(0) << 6) | (wbuffer(1) >> 2); // 14 bit
  pixelbuffer[1] =
      (((wbuffer(1) & 0x3) << 12) | (wbuffer(2) << 4) | (wbuffer(3) >> 4)) &
      0x3fff;
  pixelbuffer[2] = (wbuffer(3) >> 2) & 0x3;
  pixelbuffer[3] = ((wbuffer(3) & 0x3) << 8) | wbuffer(4);
  pixelbuffer[4] = (wbuffer(5) << 2) | (wbuffer(6) >> 6);
  pixelbuffer[5] = ((wbuffer(6) & 0x3f) << 4) | (wbuffer(7) >> 4);
  pixelbuffer[6] = (wbuffer(7) >> 2) & 0x3;
  pixelbuffer[7] = ((wbuffer(7) & 0x3) << 8) | wbuffer(8);
  pixelbuffer[8] = ((wbuffer(9) << 2) & 0x3fc) | (wbuffer(10) >> 6);
  pixelbuffer[9] = ((wbuffer(10) << 4) | (wbuffer(11) >> 4)) & 0x3ff;
  pixelbuffer[10] = (wbuffer(11) >> 2) & 0x3;
  pixelbuffer[11] = ((wbuffer(11) & 0x3) << 8) | wbuffer(12);
  pixelbuffer[12] = (((wbuffer(13) << 2) & 0x3fc) | wbuffer(14) >> 6) & 0x3ff;
  pixelbuffer[13] = ((wbuffer(14) << 4) | (wbuffer(15) >> 4)) & 0x3ff;
#undef wbuffer
  current = 0;
  lastoffset += 16;
}

Project: LibRaw

int main(int ac, char *av[])
{
  int i, ret;
  int autoscale = 0, black_subtraction = 1, use_gamma = 0;
  char outfn[1024];

  LibRaw RawProcessor;
  if (ac < 2)
  {
  usage:
    printf("4channels - LibRaw %s sample. %d cameras supported\n"
           "Usage: %s [-s N] [-g] [-A] [-B] [-N] raw-files....\n"
           "\t-s N - select Nth image in file (default=0)\n"
           "\t-g - use gamma correction with gamma 2.2 (not precise,use for "
           "visual inspection only)\n"
           "\t-A - autoscaling (by integer factor)\n"
           "\t-B - no black subtraction\n",
           LibRaw::version(), LibRaw::cameraCount(), av[0]);
    return 0;
  }

#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

  OUT.output_bps = 16;
  OUT.output_tiff = 1;
  OUT.user_flip = 0;
  OUT.no_auto_bright = 1;
  OUT.half_size = 1;

  for (i = 1; i < ac; i++)
  {
    if (av[i][0] == '-')
    {
      if (av[i][1] == 's' && av[i][2] == 0)
      {
        i++;
        OUT.shot_select = av[i] ? atoi(av[i]) : 0;
      }
      else if (av[i][1] == 'g' && av[i][2] == 0)
        use_gamma = 1;
      else if (av[i][1] == 'A' && av[i][2] == 0)
        autoscale = 1;
      else if (av[i][1] == 'B' && av[i][2] == 0)
      {
        black_subtraction = 0;
      }
      else
        goto usage;
      continue;
    }
    if (!use_gamma)
      OUT.gamm[0] = OUT.gamm[1] = 1;

    int c;
    printf("Processing file %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 (P1.is_foveon)
    {
      printf("Cannot process Foveon image %s\n", av[i]);
      continue;
    }
    if ((ret = RawProcessor.unpack()) != LIBRAW_SUCCESS)
    {
      fprintf(stderr, "Cannot unpack %s: %s\n", av[i], libraw_strerror(ret));
      continue;
    }
    RawProcessor.raw2image();
    if (black_subtraction)
    {
      RawProcessor.subtract_black();
    }

    if (autoscale)
    {
      unsigned max = 0, scale = 1;
      for (int j = 0; j < S.iheight * S.iwidth; j++)
        for (int c = 0; c < 4; c++)
          if (max < RawProcessor.imgdata.image[j][c])
            max = RawProcessor.imgdata.image[j][c];
      if (max > 0 && max < 1 << 15)
      {
        scale = (1 << 16) / max;
        printf("Scaling with multiplier=%d (max=%d)\n", scale, max);
        for (int j = 0; j < S.iheight * S.iwidth; j++)
          for (c = 0; c < 4; c++)
            RawProcessor.imgdata.image[j][c] *= scale;
      }
      printf("Black level (scaled)=%d\n", C.black * scale);
    }
    else
      printf("Black level (unscaled)=%d\n", C.black);

    // hack to make dcraw tiff writer happy
    int isrgb = (P1.colors == 4 ? 0 : 1);
    P1.colors = 1;
    S.width = S.iwidth;
    S.height = S.iheight;

    for (int layer = 0; layer < 4; layer++)
    {
      if (layer > 0)
      {
        for (int rc = 0; rc < S.iheight * S.iwidth; rc++)
          RawProcessor.imgdata.image[rc][0] =
              RawProcessor.imgdata.image[rc][layer];
      }
      char lname[8];
      if (isrgb)
      {
        snprintf(lname, 7, "%c", ((char *)("RGBG"))[layer]);
        if (layer == 3)
          strcat(lname, "2");
      }
      else
        snprintf(lname, 7, "%c", ((char *)("GCMY"))[layer]);

      if (OUT.shot_select)
        snprintf(outfn, sizeof(outfn), "%s-%d.%s.tiff", av[i], OUT.shot_select,
                 lname);
      else
        snprintf(outfn, sizeof(outfn), "%s.%s.tiff", av[i], lname);

      printf("Writing file %s\n", outfn);
      if (LIBRAW_SUCCESS != (ret = RawProcessor.dcraw_ppm_tiff_writer(outfn)))
        fprintf(stderr, "Cannot write %s: %s\n", outfn, libraw_strerror(ret));
    }
  }
  return 0;
}

Project: LibRaw

int LibRaw::dcraw_ppm_tiff_writer(const char *filename)
{
  CHECK_ORDER_LOW(LIBRAW_PROGRESS_LOAD_RAW);

  if (!imgdata.image)
    return LIBRAW_OUT_OF_ORDER_CALL;

  if (!filename)
    return ENOENT;
  FILE *f = NULL;
  if (!strcmp(filename, "-"))
  {
#ifdef LIBRAW_WIN32_CALLS
    _setmode(_fileno(stdout), _O_BINARY);
#endif
    f = stdout;
  }
  else
    f = fopen(filename, "wb");

  if (!f)
    return errno;

  try
  {
    if (!libraw_internal_data.output_data.histogram)
    {
      libraw_internal_data.output_data.histogram =
          (int(*)[LIBRAW_HISTOGRAM_SIZE])malloc(
              sizeof(*libraw_internal_data.output_data.histogram) * 4);
      merror(libraw_internal_data.output_data.histogram,
             "LibRaw::dcraw_ppm_tiff_writer()");
    }
    libraw_internal_data.internal_data.output = f;
    write_ppm_tiff();
    SET_PROC_FLAG(LIBRAW_PROGRESS_FLIP);
    libraw_internal_data.internal_data.output = NULL;
    if (strcmp(filename, "-"))
      fclose(f);
    return 0;
  }
  catch (LibRaw_exceptions err)
  {
    if (strcmp(filename, "-"))
      fclose(f);
    EXCEPTION_HANDLER(err);
  }
}

Project: LibRaw

CameraMetaDataLR *make_camera_metadata()
{
  int len = 0, i;
  for (i = 0; i < RAWSPEED_DATA_COUNT; i++)
    if (_rawspeed_data_xml[i])
    {
      len += strlen(_rawspeed_data_xml[i]);
    }
  char *rawspeed_xml =
      (char *)calloc(len + 1, sizeof(_rawspeed_data_xml[0][0]));
  if (!rawspeed_xml)
    return NULL;
  int offt = 0;
  for (i = 0; i < RAWSPEED_DATA_COUNT; i++)
    if (_rawspeed_data_xml[i])
    {
      int ll = strlen(_rawspeed_data_xml[i]);
      if (offt + ll > len)
        break;
      memmove(rawspeed_xml + offt, _rawspeed_data_xml[i], ll);
      offt += ll;
    }
  rawspeed_xml[offt] = 0;
  CameraMetaDataLR *ret = NULL;
  try
  {
    ret = new CameraMetaDataLR(rawspeed_xml, offt);
  }
  catch (...)
  {
    // Mask all exceptions
  }
  free(rawspeed_xml);
  return ret;
}

Project: LibRaw

void LibRaw::fuji_14bit_load_raw()
{
  const unsigned linelen = S.raw_width * 7 / 4;
  const unsigned pitch = S.raw_pitch ? S.raw_pitch / 2 : S.raw_width;
  unsigned char *buf = (unsigned char *)malloc(linelen);
  merror(buf, "fuji_14bit_load_raw()");

  for (int row = 0; row < S.raw_height; row++)
  {
    unsigned bytesread =
        libraw_internal_data.internal_data.input->read(buf, 1, linelen);
    unsigned short *dest = &imgdata.rawdata.raw_image[pitch * row];
    if (bytesread % 28)
    {
      swab32arr((unsigned *)buf, bytesread / 4);
      for (int sp = 0, dp = 0;
           dp < pitch - 3 && sp < linelen - 6 && sp < bytesread - 6;
           sp += 7, dp += 4)
        unpack7bytesto4x16(buf + sp, dest + dp);
    }
    else
      for (int sp = 0, dp = 0;
           dp < pitch - 15 && sp < linelen - 27 && sp < bytesread - 27;
           sp += 28, dp += 16)
        unpack28bytesto16x16ns(buf + sp, dest + dp);
  }
  free(buf);
}

Project: LibRaw

void LibRaw::deflate_dng_load_raw()
{
  int iifd = find_ifd_by_offset(libraw_internal_data.unpacker_data.data_offset);
  if(iifd < 0 || iifd > libraw_internal_data.identify_data.tiff_nifds)
      throw LIBRAW_EXCEPTION_DECODE_RAW;
  struct tiff_ifd_t *ifd = &tiff_ifd[iifd];

  float *float_raw_image = 0;
  float max = 0.f;

  if (ifd->samples != 1 && ifd->samples != 3 && ifd->samples != 4)
    throw LIBRAW_EXCEPTION_DECODE_RAW; // Only float deflated supported

  if (libraw_internal_data.unpacker_data.tiff_samples != ifd->samples)
    throw LIBRAW_EXCEPTION_DECODE_RAW; // Wrong IFD

  size_t tilesH = (imgdata.sizes.raw_width +
                   libraw_internal_data.unpacker_data.tile_width - 1) /
                  libraw_internal_data.unpacker_data.tile_width;
  size_t tilesV = (imgdata.sizes.raw_height +
                   libraw_internal_data.unpacker_data.tile_length - 1) /
                  libraw_internal_data.unpacker_data.tile_length;
  size_t tileCnt = tilesH * tilesV;

  if (ifd->sample_format == 3)
  { // Floating point data
    float_raw_image = (float *)calloc(
        tileCnt * libraw_internal_data.unpacker_data.tile_length *
            libraw_internal_data.unpacker_data.tile_width * ifd->samples,
        sizeof(float));
    // imgdata.color.maximum = 65535;
    // imgdata.color.black = 0;
    // memset(imgdata.color.cblack,0,sizeof(imgdata.color.cblack));
  }
  else
    throw LIBRAW_EXCEPTION_DECODE_RAW; // Only float deflated supported

  int xFactor;
  switch (ifd->predictor)
  {
  case 3:
  default:
    xFactor = 1;
    break;
  case 34894:
    xFactor = 2;
    break;
  case 34895:
    xFactor = 4;
    break;
  }

  if (libraw_internal_data.unpacker_data.tile_length < INT_MAX)
  {
    if (tileCnt < 1 || tileCnt > 1000000)
      throw LIBRAW_EXCEPTION_DECODE_RAW;

    size_t *tOffsets = (size_t *)malloc(tileCnt * sizeof(size_t));
    for (int t = 0; t < tileCnt; ++t)
      tOffsets[t] = get4();

    size_t *tBytes = (size_t *)malloc(tileCnt * sizeof(size_t));
    unsigned long maxBytesInTile = 0;
    if (tileCnt == 1)
      tBytes[0] = maxBytesInTile = ifd->bytes;
    else
    {
      libraw_internal_data.internal_data.input->seek(ifd->bytes, SEEK_SET);
      for (size_t t = 0; t < tileCnt; ++t)
      {
        tBytes[t] = get4();
        maxBytesInTile = MAX(maxBytesInTile, tBytes[t]);
      }
    }
    unsigned tilePixels = libraw_internal_data.unpacker_data.tile_width *
                          libraw_internal_data.unpacker_data.tile_length;
    unsigned pixelSize = sizeof(float) * ifd->samples;
    unsigned tileBytes = tilePixels * pixelSize;
    unsigned tileRowBytes =
        libraw_internal_data.unpacker_data.tile_width * pixelSize;

    unsigned char *cBuffer = (unsigned char *)malloc(maxBytesInTile);
    unsigned char *uBuffer = (unsigned char *)malloc(
        tileBytes + tileRowBytes); // extra row for decoding

    for (size_t y = 0, t = 0; y < imgdata.sizes.raw_height;
         y += libraw_internal_data.unpacker_data.tile_length)
    {
      for (size_t x = 0; x < imgdata.sizes.raw_width;
           x += libraw_internal_data.unpacker_data.tile_width, ++t)
      {
        libraw_internal_data.internal_data.input->seek(tOffsets[t], SEEK_SET);
        libraw_internal_data.internal_data.input->read(cBuffer, 1, tBytes[t]);
        unsigned long dstLen = tileBytes;
        int err =
            uncompress(uBuffer + tileRowBytes, &dstLen, cBuffer, tBytes[t]);
        if (err != Z_OK)
        {
          free(tOffsets);
          free(tBytes);
          free(cBuffer);
          free(uBuffer);
          throw LIBRAW_EXCEPTION_DECODE_RAW;
          return;
        }
        else
        {
          int bytesps = ifd->bps >> 3;
          size_t rowsInTile =
              y + libraw_internal_data.unpacker_data.tile_length >
                      imgdata.sizes.raw_height
                  ? imgdata.sizes.raw_height - y
                  : libraw_internal_data.unpacker_data.tile_length;
          size_t colsInTile =
              x + libraw_internal_data.unpacker_data.tile_width >
                      imgdata.sizes.raw_width
                  ? imgdata.sizes.raw_width - x
                  : libraw_internal_data.unpacker_data.tile_width;

          for (size_t row = 0; row < rowsInTile;
               ++row) // do not process full tile if not needed
          {
            unsigned char *dst =
                uBuffer + row * libraw_internal_data.unpacker_data.tile_width *
                              bytesps * ifd->samples;
            unsigned char *src = dst + tileRowBytes;
            DecodeFPDelta(src, dst,
                          libraw_internal_data.unpacker_data.tile_width /
                              xFactor,
                          ifd->samples * xFactor, bytesps);
            float lmax = expandFloats(
                dst,
                libraw_internal_data.unpacker_data.tile_width * ifd->samples,
                bytesps);
            max = MAX(max, lmax);
            unsigned char *dst2 = (unsigned char *)&float_raw_image
                [((y + row) * imgdata.sizes.raw_width + x) * ifd->samples];
            memmove(dst2, dst, colsInTile * ifd->samples * sizeof(float));
          }
        }
      }
    }
    free(tOffsets);
    free(tBytes);
    free(cBuffer);
    free(uBuffer);
  }
  imgdata.color.fmaximum = max;

  // Set fields according to data format

  imgdata.rawdata.raw_alloc = float_raw_image;
  if (ifd->samples == 1)
  {
    imgdata.rawdata.float_image = float_raw_image;
    imgdata.rawdata.sizes.raw_pitch = imgdata.sizes.raw_pitch =
        imgdata.sizes.raw_width * 4;
  }
  else if (ifd->samples == 3)
  {
    imgdata.rawdata.float3_image = (float(*)[3])float_raw_image;
    imgdata.rawdata.sizes.raw_pitch = imgdata.sizes.raw_pitch =
        imgdata.sizes.raw_width * 12;
  }
  else if (ifd->samples == 4)
  {
    imgdata.rawdata.float4_image = (float(*)[4])float_raw_image;
    imgdata.rawdata.sizes.raw_pitch = imgdata.sizes.raw_pitch =
        imgdata.sizes.raw_width * 16;
  }

  if (imgdata.params.raw_processing_options &
      LIBRAW_PROCESSING_CONVERTFLOAT_TO_INT)
    convertFloatToInt(); // with default settings
}

Project: LibRaw

void LibRaw::trimSpaces(char *s)
{
  char *p = s;
  int l = strlen(p);
  if (!l)
    return;
  while (isspace(p[l - 1]))
    p[--l] = 0; /* trim trailing spaces */
  while (*p && isspace(*p))
    ++p, --l;   /* trim leading spaces */
  memmove(s, p, l + 1);
}

Project: LibRaw

void *LibRaw_file_datastream::make_jas_stream()
{
#ifdef NO_JASPER
  return NULL;
#else
#ifdef LIBRAW_WIN32_UNICODEPATHS
  if (wfname())
  {
    jas_file = _wfopen(wfname(), L"rb");
    return jas_stream_fdopen(fileno(jas_file), "rb");
  }
  else
#endif
  {
    return jas_stream_fopen(fname(), "rb");
  }
#endif
}

Project: LibRaw

void LibRaw::process_Sony_0x9406(uchar *buf, ushort len)
{
  if (len < 6)
    return;
  uchar bufx = buf[0];
  if ((bufx != 0x01) && (bufx != 0x08) && (bufx != 0x1b))
    return;
  bufx = buf[2];
  if ((bufx != 0x08) && (bufx != 0x1b))
    return;

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

  return;
}

Project: LibRaw

static inline void unpack28bytesto16x16ns(unsigned char *src,
                                          unsigned short *dest)
{
  dest[0] = (src[3] << 6) | (src[2] >> 2);
  dest[1] = ((src[2] & 0x3) << 12) | (src[1] << 4) | (src[0] >> 4);
  dest[2] = (src[0] & 0xf) << 10 | (src[7] << 2) | (src[6] >> 6);
  dest[3] = ((src[6] & 0x3f) << 8) | src[5];
  dest[4] = (src[4] << 6) | (src[11] >> 2);
  dest[5] = ((src[11] & 0x3) << 12) | (src[10] << 4) | (src[9] >> 4);
  dest[6] = (src[9] & 0xf) << 10 | (src[8] << 2) | (src[15] >> 6);
  dest[7] = ((src[15] & 0x3f) << 8) | src[14];
  dest[8] = (src[13] << 6) | (src[12] >> 2);
  dest[9] = ((src[12] & 0x3) << 12) | (src[19] << 4) | (src[18] >> 4);
  dest[10] = (src[18] & 0xf) << 10 | (src[17] << 2) | (src[16] >> 6);
  dest[11] = ((src[16] & 0x3f) << 8) | src[23];
  dest[12] = (src[22] << 6) | (src[21] >> 2);
  dest[13] = ((src[21] & 0x3) << 12) | (src[20] << 4) | (src[27] >> 4);
  dest[14] = (src[27] & 0xf) << 10 | (src[26] << 2) | (src[25] >> 6);
  dest[15] = ((src[25] & 0x3f) << 8) | src[24];
}

Project: LibRaw

int LibRaw::unpack_thumb(void)
{
  CHECK_ORDER_LOW(LIBRAW_PROGRESS_IDENTIFY);
  CHECK_ORDER_BIT(LIBRAW_PROGRESS_THUMB_LOAD);

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

    int t_colors = libraw_internal_data.unpacker_data.thumb_misc >> 5 & 7;
    int t_bytesps = (libraw_internal_data.unpacker_data.thumb_misc & 31) / 8;

    if (!ID.toffset && !(imgdata.thumbnail.tlength > 0 &&
                         load_raw == &LibRaw::broadcom_load_raw) // RPi
    )
    {
      return LIBRAW_NO_THUMBNAIL;
    }
    else if (thumb_load_raw)
    {
      kodak_thumb_loader();
      T.tformat = LIBRAW_THUMBNAIL_BITMAP;
      SET_PROC_FLAG(LIBRAW_PROGRESS_THUMB_LOAD);
      return 0;
    }
    else
    {
      if (write_thumb == &LibRaw::x3f_thumb_loader)
      {
        INT64 tsize = x3f_thumb_size();
        if (tsize < 2048 || INT64(ID.toffset) + tsize < 1)
          throw LIBRAW_EXCEPTION_IO_CORRUPT;

        if (INT64(ID.toffset) + tsize > ID.input->size() + THUMB_READ_BEYOND)
          throw LIBRAW_EXCEPTION_IO_EOF;
      }
      else
      {
        if (INT64(ID.toffset) + INT64(T.tlength) < 1)
          throw LIBRAW_EXCEPTION_IO_CORRUPT;

        if (INT64(ID.toffset) + INT64(T.tlength) >
            ID.input->size() + THUMB_READ_BEYOND)
          throw LIBRAW_EXCEPTION_IO_EOF;
      }

      ID.input->seek(ID.toffset, SEEK_SET);
      if (write_thumb == &LibRaw::jpeg_thumb)
      {
        if (T.thumb)
          free(T.thumb);
        T.thumb = (char *)malloc(T.tlength);
        merror(T.thumb, "jpeg_thumb()");
        ID.input->read(T.thumb, 1, T.tlength);
        unsigned char *tthumb = (unsigned char *)T.thumb;
        tthumb[0] = 0xff;
        tthumb[1] = 0xd8;
#ifdef NO_JPEG
        T.tcolors = 3;
#else
        {
          jpegErrorManager jerr;
          struct jpeg_decompress_struct cinfo;
          cinfo.err = jpeg_std_error(&jerr.pub);
          jerr.pub.error_exit = jpegErrorExit;
          if (setjmp(jerr.setjmp_buffer))
          {
          err2:
            // Error in original JPEG thumb, read it again because
            // original bytes 0-1 was damaged above
            jpeg_destroy_decompress(&cinfo);
            T.tcolors = 3;
            T.tformat = LIBRAW_THUMBNAIL_UNKNOWN;
            ID.input->seek(ID.toffset, SEEK_SET);
            ID.input->read(T.thumb, 1, T.tlength);
            SET_PROC_FLAG(LIBRAW_PROGRESS_THUMB_LOAD);
            return 0;
          }
          jpeg_create_decompress(&cinfo);
          jpeg_mem_src(&cinfo, (unsigned char *)T.thumb, T.tlength);
          int rc = jpeg_read_header(&cinfo, TRUE);
          if (rc != 1)
            goto err2;
          T.tcolors = (cinfo.num_components > 0 && cinfo.num_components <= 3)
                          ? cinfo.num_components
                          : 3;
          jpeg_destroy_decompress(&cinfo);
        }
#endif
        T.tformat = LIBRAW_THUMBNAIL_JPEG;
        SET_PROC_FLAG(LIBRAW_PROGRESS_THUMB_LOAD);
        return 0;
      }
      else if (write_thumb == &LibRaw::layer_thumb)
      {
        int colors = libraw_internal_data.unpacker_data.thumb_misc >> 5 & 7;
        if (colors != 1 && colors != 3)
          return LIBRAW_UNSUPPORTED_THUMBNAIL;

        int tlength = T.twidth * T.theight;
        if (T.thumb)
          free(T.thumb);
        T.thumb = (char *)calloc(colors, tlength);
        merror(T.thumb, "layer_thumb()");
        unsigned char *tbuf = (unsigned char *)calloc(colors, tlength);
        merror(tbuf, "layer_thumb()");
        ID.input->read(tbuf, colors, T.tlength);
        if (libraw_internal_data.unpacker_data.thumb_misc >> 8 &&
            colors == 3) // GRB order
          for (int i = 0; i < tlength; i++)
          {
            T.thumb[i * 3] = tbuf[i + tlength];
            T.thumb[i * 3 + 1] = tbuf[i];
            T.thumb[i * 3 + 2] = tbuf[i + 2 * tlength];
          }
        else if (colors == 3) // RGB or 1-channel
          for (int i = 0; i < tlength; i++)
          {
            T.thumb[i * 3] = tbuf[i];
            T.thumb[i * 3 + 1] = tbuf[i + tlength];
            T.thumb[i * 3 + 2] = tbuf[i + 2 * tlength];
          }
        else if (colors == 1)
        {
          free(T.thumb);
          T.thumb = (char *)tbuf;
          tbuf = 0;
        }
        if (tbuf)
          free(tbuf);
        T.tcolors = colors;
        T.tlength = colors * tlength;
        T.tformat = LIBRAW_THUMBNAIL_BITMAP;
        SET_PROC_FLAG(LIBRAW_PROGRESS_THUMB_LOAD);
        return 0;
      }
      else if (write_thumb == &LibRaw::rollei_thumb)
      {
        unsigned i;
        int tlength = T.twidth * T.theight;
        if (T.thumb)
          free(T.thumb);
        T.tcolors = 3;
        T.thumb = (char *)calloc(T.tcolors, tlength);
        merror(T.thumb, "layer_thumb()");
        unsigned short *tbuf = (unsigned short *)calloc(2, tlength);
        merror(tbuf, "layer_thumb()");
        read_shorts(tbuf, tlength);
        for (i = 0; i < tlength; i++)
        {
          T.thumb[i * 3] = (tbuf[i] << 3) & 0xff;
          T.thumb[i * 3 + 1] = (tbuf[i] >> 5 << 2) & 0xff;
          T.thumb[i * 3 + 2] = (tbuf[i] >> 11 << 3) & 0xff;
        }
        free(tbuf);
        T.tlength = T.tcolors * tlength;
        T.tformat = LIBRAW_THUMBNAIL_BITMAP;
        SET_PROC_FLAG(LIBRAW_PROGRESS_THUMB_LOAD);
        return 0;
      }
      else if (write_thumb == &LibRaw::ppm_thumb)
      {
        if (t_bytesps > 1)
          throw LIBRAW_EXCEPTION_IO_CORRUPT; // 8-bit thumb, but parsed for more
                                             // bits
        int t_length = T.twidth * T.theight * t_colors;

        if (T.tlength &&
            T.tlength < t_length) // try to find tiff ifd with needed offset
        {
          int pifd = find_ifd_by_offset(libraw_internal_data.internal_data.toffset);
          if (pifd >= 0 && tiff_ifd[pifd].strip_offsets_count &&
              tiff_ifd[pifd].strip_byte_counts_count)
          {
            // We found it, calculate final size
            unsigned total_size = 0;
            for (int i = 0; i < tiff_ifd[pifd].strip_byte_counts_count; i++)
              total_size += tiff_ifd[pifd].strip_byte_counts[i];
            if (total_size != t_length) // recalculate colors
            {
              if (total_size == T.twidth * T.tlength * 3)
                T.tcolors = 3;
              else if (total_size == T.twidth * T.tlength)
                T.tcolors = 1;
            }
            T.tlength = total_size;
            if (T.thumb)
              free(T.thumb);
            T.thumb = (char *)malloc(T.tlength);
            merror(T.thumb, "ppm_thumb()");

            char *dest = T.thumb;
            INT64 pos = ID.input->tell();

            for (int i = 0; i < tiff_ifd[pifd].strip_byte_counts_count &&
                            i < tiff_ifd[pifd].strip_offsets_count;
                 i++)
            {
              int remain = T.tlength;
              int sz = tiff_ifd[pifd].strip_byte_counts[i];
              int off = tiff_ifd[pifd].strip_offsets[i];
              if (off >= 0 && off + sz <= ID.input->size() && sz <= remain)
              {
                ID.input->seek(off, SEEK_SET);
                ID.input->read(dest, sz, 1);
                remain -= sz;
                dest += sz;
              }
            }
            ID.input->seek(pos, SEEK_SET);
            T.tformat = LIBRAW_THUMBNAIL_BITMAP;
            SET_PROC_FLAG(LIBRAW_PROGRESS_THUMB_LOAD);
            return 0;
          }
        }

        if (!T.tlength)
          T.tlength = t_length;
        if (T.thumb)
          free(T.thumb);

        T.thumb = (char *)malloc(T.tlength);
        if (!T.tcolors)
          T.tcolors = t_colors;
        merror(T.thumb, "ppm_thumb()");

        ID.input->read(T.thumb, 1, T.tlength);

        T.tformat = LIBRAW_THUMBNAIL_BITMAP;
        SET_PROC_FLAG(LIBRAW_PROGRESS_THUMB_LOAD);
        return 0;
      }
      else if (write_thumb == &LibRaw::ppm16_thumb)
      {
        if (t_bytesps > 2)
          throw LIBRAW_EXCEPTION_IO_CORRUPT; // 16-bit thumb, but parsed for
                                             // more bits
        int o_bps = (imgdata.params.raw_processing_options &
                     LIBRAW_PROCESSING_USE_PPM16_THUMBS)
                        ? 2
                        : 1;
        int o_length = T.twidth * T.theight * t_colors * o_bps;
        int i_length = T.twidth * T.theight * t_colors * 2;
        if (!T.tlength)
          T.tlength = o_length;
        ushort *t_thumb = (ushort *)calloc(i_length, 1);
        ID.input->read(t_thumb, 1, i_length);
        if ((libraw_internal_data.unpacker_data.order == 0x4949) ==
            (ntohs(0x1234) == 0x1234))
          swab((char *)t_thumb, (char *)t_thumb, i_length);

        if (T.thumb)
          free(T.thumb);
        if ((imgdata.params.raw_processing_options &
             LIBRAW_PROCESSING_USE_PPM16_THUMBS))
        {
          T.thumb = (char *)t_thumb;
          T.tformat = LIBRAW_THUMBNAIL_BITMAP16;
        }
        else
        {
          T.thumb = (char *)malloc(o_length);
          merror(T.thumb, "ppm_thumb()");
          for (int i = 0; i < o_length; i++)
            T.thumb[i] = t_thumb[i] >> 8;
          free(t_thumb);
          T.tformat = LIBRAW_THUMBNAIL_BITMAP;
        }
        SET_PROC_FLAG(LIBRAW_PROGRESS_THUMB_LOAD);
        return 0;
      }
      else if (write_thumb == &LibRaw::x3f_thumb_loader)
      {
        x3f_thumb_loader();
        SET_PROC_FLAG(LIBRAW_PROGRESS_THUMB_LOAD);
        return 0;
      }
      else
      {
        return LIBRAW_UNSUPPORTED_THUMBNAIL;
      }
    }
    // last resort
    return LIBRAW_UNSUPPORTED_THUMBNAIL;
  }
  catch (LibRaw_exceptions err)
  {
    EXCEPTION_HANDLER(err);
  }
}

Project: LibRaw

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

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

Project: LibRaw

void DHT::make_hv_dirs()
{
#if defined(LIBRAW_USE_OPENMP)
#pragma omp parallel for schedule(guided)
#endif
  for (int i = 0; i < libraw.imgdata.sizes.iheight; ++i)
  {
    make_hv_dline(i);
  }
#if defined(LIBRAW_USE_OPENMP)
#pragma omp parallel for schedule(guided)
#endif
  for (int i = 0; i < libraw.imgdata.sizes.iheight; ++i)
  {
    refine_hv_dirs(i, i & 1);
  }
#if defined(LIBRAW_USE_OPENMP)
#pragma omp parallel for schedule(guided)
#endif
  for (int i = 0; i < libraw.imgdata.sizes.iheight; ++i)
  {
    refine_hv_dirs(i, (i & 1) ^ 1);
  }
#if defined(LIBRAW_USE_OPENMP)
#pragma omp parallel for schedule(guided)
#endif
  for (int i = 0; i < libraw.imgdata.sizes.iheight; ++i)
  {
    refine_ihv_dirs(i);
  }
}

Project: LibRaw

void LibRaw::kodak_jpeg_load_raw() {}

Project: LibRaw

void LibRaw::romm_coeff(float romm_cam[3][3])
{
  static const float rgb_romm[3][3] = /* ROMM == Kodak ProPhoto */
      {{2.034193, -0.727420, -0.306766},
       {-0.228811, 1.231729, -0.002922},
       {-0.008565, -0.153273, 1.161839}};
  int i, j, k;

  for (i = 0; i < 3; i++)
    for (j = 0; j < 3; j++)
      for (cmatrix[i][j] = k = 0; k < 3; k++)
        cmatrix[i][j] += rgb_romm[i][k] * romm_cam[k][j];
}

Project: LibRaw

void print_2fun(FILE* outfile, LibRaw& MyCoolRawProcessor, std::string& fn)
{
	fprintf(outfile, "// %s %s", P1.make, P1.model);
	if (C.cam_mul[0] > 0)
	{
		fprintf(outfile, "\n'As shot' WB:");
		for (int c = 0; c < 4; c++)
			fprintf(outfile, " %.3f", C.cam_mul[c]);
	}
	if (C.WB_Coeffs[LIBRAW_WBI_Auto][0] > 0)
	{
		fprintf(outfile, "\n'Camera Auto' WB:");
		for (int c = 0; c < 4; c++)
			fprintf(outfile, " %d", C.WB_Coeffs[LIBRAW_WBI_Auto][c]);
	}
	if (C.WB_Coeffs[LIBRAW_WBI_Measured][0] > 0)
	{
		fprintf(outfile, "\n'Camera Measured' WB:");
		for (int c = 0; c < 4; c++)
			fprintf(outfile, " %d", C.WB_Coeffs[LIBRAW_WBI_Measured][c]);
	}
	fprintf(outfile, "\n\n");
}

Project: LibRaw

  DllDef int libraw_get_color_maximum(libraw_data_t *lr)
  {
    if (!lr)
      return EINVAL;
    return lr->color.maximum;
  }

Project: LibRaw

void LibRaw::nikon_load_striped_packed_raw()
{
  int vbits = 0, bwide, rbits, bite, row, col, val, i;

  UINT64 bitbuf = 0;
  unsigned load_flags = 24; // libraw_internal_data.unpacker_data.load_flags;
  unsigned tiff_bps = libraw_internal_data.unpacker_data.tiff_bps;
  int tiff_compress = libraw_internal_data.unpacker_data.tiff_compress;

  struct tiff_ifd_t *ifd = &tiff_ifd[0];
  while (ifd < &tiff_ifd[libraw_internal_data.identify_data.tiff_nifds] &&
         ifd->offset != libraw_internal_data.unpacker_data.data_offset)
    ++ifd;
  if (ifd == &tiff_ifd[libraw_internal_data.identify_data.tiff_nifds])
    throw LIBRAW_EXCEPTION_DECODE_RAW;

  if (!ifd->rows_per_strip || !ifd->strip_offsets_count)
    return; // not unpacked
  int stripcnt = 0;

  bwide = S.raw_width * tiff_bps / 8;
  bwide += bwide & load_flags >> 7;
  rbits = bwide * 8 - S.raw_width * tiff_bps;
  if (load_flags & 1)
    bwide = bwide * 16 / 15;
  bite = 8 + (load_flags & 24);
  for (row = 0; row < S.raw_height; row++)
  {
    checkCancel();
    if (!(row % ifd->rows_per_strip))
    {
      if (stripcnt >= ifd->strip_offsets_count)
        return; // run out of data
      libraw_internal_data.internal_data.input->seek(
          ifd->strip_offsets[stripcnt], SEEK_SET);
      stripcnt++;
    }
    for (col = 0; col < S.raw_width; col++)
    {
      for (vbits -= tiff_bps; vbits < 0; vbits += bite)
      {
        bitbuf <<= bite;
        for (i = 0; i < bite; i += 8)
          bitbuf |=
              (unsigned)(libraw_internal_data.internal_data.input->get_char()
                         << i);
      }
      imgdata.rawdata.raw_image[(row)*S.raw_width + (col)] =
          bitbuf << (64 - tiff_bps - vbits) >> (64 - tiff_bps);
    }
    vbits -= rbits;
  }
}

Project: LibRaw

float LibRaw::find_green(int bps, int bite, int off0, int off1)
{
  UINT64 bitbuf = 0;
  int vbits, col, i, c;
  ushort img[2][2064];
  double sum[] = {0, 0};
  if (width > 2064)
    return 0.f; // too wide

  FORC(2)
  {
    fseek(ifp, c ? off1 : off0, SEEK_SET);
    for (vbits = col = 0; col < width; col++)
    {
      for (vbits -= bps; vbits < 0; vbits += bite)
      {
        bitbuf <<= bite;
        for (i = 0; i < bite; i += 8)
          bitbuf |= (unsigned)(fgetc(ifp) << i);
      }
      img[c][col] = bitbuf << (64 - bps - vbits) >> (64 - bps);
    }
  }
  FORC(width - 1)
  {
    sum[c & 1] += ABS(img[0][c] - img[1][c + 1]);
    sum[~c & 1] += ABS(img[1][c] - img[0][c + 1]);
  }
  if (sum[0] >= 1.0 && sum[1] >= 1.0)
    return 100 * log(sum[0] / sum[1]);
  else
    return 0.f;
}

Project: LibRaw

  pana_cs6_page_decoder(unsigned char *_buffer, unsigned int bsize)
      : lastoffset(0), maxoffset(bsize), current(0), buffer(_buffer)
  {
  }

Project: LibRaw

void LibRaw::recover_highlights()
{
  float *map, sum, wgt, grow;
  int hsat[4], count, spread, change, val, i;
  unsigned high, wide, mrow, mcol, row, col, kc, c, d, y, x;
  ushort *pixel;
  static const signed char dir[8][2] = {{-1, -1}, {-1, 0}, {-1, 1}, {0, 1},
                                        {1, 1},   {1, 0},  {1, -1}, {0, -1}};

  grow = pow(2.0, 4 - highlight);
  FORCC hsat[c] = 32000 * pre_mul[c];
  for (kc = 0, c = 1; c < colors; c++)
    if (pre_mul[kc] < pre_mul[c])
      kc = c;
  high = height / SCALE;
  wide = width / SCALE;
  map = (float *)calloc(high, wide * sizeof *map);
  merror(map, "recover_highlights()");
  FORCC if (c != kc)
  {
    RUN_CALLBACK(LIBRAW_PROGRESS_HIGHLIGHTS, c - 1, colors - 1);
    memset(map, 0, high * wide * sizeof *map);
    for (mrow = 0; mrow < high; mrow++)
      for (mcol = 0; mcol < wide; mcol++)
      {
        sum = wgt = count = 0;
        for (row = mrow * SCALE; row < (mrow + 1) * SCALE; row++)
          for (col = mcol * SCALE; col < (mcol + 1) * SCALE; col++)
          {
            pixel = image[row * width + col];
            if (pixel[c] / hsat[c] == 1 && pixel[kc] > 24000)
            {
              sum += pixel[c];
              wgt += pixel[kc];
              count++;
            }
          }
        if (count == SCALE * SCALE)
          map[mrow * wide + mcol] = sum / wgt;
      }
    for (spread = 32 / grow; spread--;)
    {
      for (mrow = 0; mrow < high; mrow++)
        for (mcol = 0; mcol < wide; mcol++)
        {
          if (map[mrow * wide + mcol])
            continue;
          sum = count = 0;
          for (d = 0; d < 8; d++)
          {
            y = mrow + dir[d][0];
            x = mcol + dir[d][1];
            if (y < high && x < wide && map[y * wide + x] > 0)
            {
              sum += (1 + (d & 1)) * map[y * wide + x];
              count += 1 + (d & 1);
            }
          }
          if (count > 3)
            map[mrow * wide + mcol] = -(sum + grow) / (count + grow);
        }
      for (change = i = 0; i < high * wide; i++)
        if (map[i] < 0)
        {
          map[i] = -map[i];
          change = 1;
        }
      if (!change)
        break;
    }
    for (i = 0; i < high * wide; i++)
      if (map[i] == 0)
        map[i] = 1;
    for (mrow = 0; mrow < high; mrow++)
      for (mcol = 0; mcol < wide; mcol++)
      {
        for (row = mrow * SCALE; row < (mrow + 1) * SCALE; row++)
          for (col = mcol * SCALE; col < (mcol + 1) * SCALE; col++)
          {
            pixel = image[row * width + col];
            if (pixel[c] / hsat[c] > 1)
            {
              val = pixel[kc] * map[mrow * wide + mcol];
              if (pixel[c] < val)
                pixel[c] = CLIP(val);
            }
          }
      }
  }
  free(map);
}

Project: LibRaw

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

Project: LibRaw

LibRaw_bigfile_datastream::~LibRaw_bigfile_datastream()
{
  if (f)
    fclose(f);
}

Project: LibRaw

libraw_processed_image_t *LibRaw::dcraw_make_mem_thumb(int *){ return NULL;}

Project: LibRaw

		void adjust_blacklevel() { LibRaw::adjust_bl(); }

Project: LibRaw

void LibRaw::process_Sony_0x2010(uchar *buf, ushort len)
{
  if (!imSony.group2010)
    return;

  if ((imSony.real_iso_offset != 0xffff) &&
      (len >= (imSony.real_iso_offset + 2)) && (imgdata.makernotes.common.real_ISO < 0.1f))
  {
    uchar s[2];
    s[0] = SonySubstitution[buf[imSony.real_iso_offset]];
    s[1] = SonySubstitution[buf[imSony.real_iso_offset + 1]];
    imgdata.makernotes.common.real_ISO =
        100.0f * libraw_powf64l(2.0f, (16 - ((float)sget2(s)) / 256.0f));
  }

  if (len >= (imSony.MeteringMode_offset + 2))
  {
    imgdata.shootinginfo.MeteringMode =
        SonySubstitution[buf[imSony.MeteringMode_offset]];
    imgdata.shootinginfo.ExposureProgram =
        SonySubstitution[buf[imSony.ExposureProgram_offset]];
  }

  if (len >= (imSony.ReleaseMode2_offset + 2))
  {
    imgdata.shootinginfo.DriveMode =
        SonySubstitution[buf[imSony.ReleaseMode2_offset]];
  }
}

Project: LibRaw

  int libraw_COLOR(libraw_data_t *lr, int row, int col)
  {
    if (!lr)
      return EINVAL;
    LibRaw *ip = (LibRaw *)lr->parent_class;
    return ip->COLOR(row, col);
  }

Project: LibRaw

int main(int ac, char *av[])
{
  if (ac != 2)
    return 1;
  FILE *in = fopen(av[1], "rb");
  fseek(in, 0, SEEK_END);
  unsigned fsz = ftell(in);
  unsigned char *buffer = (unsigned char *)malloc(fsz);
  if (!buffer)
    return 2;
  fseek(in, 0, SEEK_SET);
  unsigned readb = fread(buffer, 1, fsz, in);
  if (readb != fsz)
    return 3;
  LibRaw rp;
  rp.imgdata.params.output_tiff = 1;
  int ret = rp.open_bayer(buffer, fsz, 640, 480, 0, 0, 0, 0, 0,
                          LIBRAW_OPENBAYER_RGGB, 0, 0, 1400);
  if (ret != LIBRAW_SUCCESS)
    return 4;
  if ((ret = rp.unpack()) != LIBRAW_SUCCESS)
    printf("Unpack error: %d\n", ret);

  if ((ret = rp.dcraw_process()) != LIBRAW_SUCCESS)
    printf("Processing error: %d\n", ret);

  char outfn[256];
  sprintf(outfn, "%s.tif", av[1]);
  if (LIBRAW_SUCCESS != (ret = rp.dcraw_ppm_tiff_writer(outfn)))
    printf("Cannot write %s: %s\n", outfn, libraw_strerror(ret));
  else
    printf("Created %s\n", outfn);
}

Project: LibRaw
File: libraw_cxx.cpp

int LibRaw::set_rawspeed_camerafile(char *filename)
{
#ifdef USE_RAWSPEED
  try
  {
    CameraMetaDataLR *camerameta = new CameraMetaDataLR(filename);
    if (_rawspeed_camerameta)
    {
      CameraMetaDataLR *d =
          static_cast<CameraMetaDataLR *>(_rawspeed_camerameta);
      delete d;
    }
    _rawspeed_camerameta = static_cast<void *>(camerameta);
  }
  catch (...)
  {
    // just return error code
    return -1;
  }
#endif
  return 0;
}

Project: LibRaw

void LibRaw::parseOlympus_CameraSettings(int base, unsigned tag, unsigned type,
                                         unsigned len, unsigned dng_writer)
{
  // uptag 0x2020

  int c;
  uchar uc;
  switch (tag)
  {
  case 0x0101:
    if (dng_writer == nonDNG)
    {
      thumb_offset = get4() + base;
    }
    break;
  case 0x0102:
    if (dng_writer == nonDNG)
    {
      thumb_length = get4();
    }
    break;
  case 0x0200:
    imgdata.shootinginfo.ExposureMode = get2();
    break;
  case 0x0202:
    imgdata.shootinginfo.MeteringMode = get2();
    break;
  case 0x0301:
    imgdata.shootinginfo.FocusMode = imOly.FocusMode[0] = get2();
    if (len == 2)
    {
      imOly.FocusMode[1] = get2();
    }
    break;
  case 0x0304:
    for (c = 0; c < 64; c++)
    {
      imOly.AFAreas[c] = get4();
    }
    break;
  case 0x0305:
    for (c = 0; c < 5; c++)
    {
      imOly.AFPointSelected[c] = getreal(type);
    }
    break;
  case 0x0306:
    fread(&uc, 1, 1, ifp);
    imOly.AFFineTune = uc;
    break;
  case 0x0307:
    FORC3 imOly.AFFineTuneAdj[c] = get2();
    break;
  case 0x0401:
    imgdata.makernotes.common.FlashEC = getreal(type);
    break;
  case 0x0507:
    imOly.ColorSpace = get2();
    break;
  case 0x0600:
    imgdata.shootinginfo.DriveMode = imOly.DriveMode[0] = get2();
    for (c = 1; c < len && c < 5; c++)
    {
      imOly.DriveMode[c] = get2();
    }
    break;
  case 0x0604:
    imgdata.shootinginfo.ImageStabilization = get4();
    break;
  }

  return;
}

Project: LibRaw

void LibRaw::rollei_thumb()
{
  unsigned i;
  ushort *thumb;

  thumb_length = thumb_width * thumb_height;
  thumb = (ushort *)calloc(thumb_length, 2);
  merror(thumb, "rollei_thumb()");
  fprintf(ofp, "P6\n%d %d\n255\n", thumb_width, thumb_height);
  read_shorts(thumb, thumb_length);
  for (i = 0; i < thumb_length; i++)
  {
    putc(thumb[i] << 3, ofp);
    putc(thumb[i] >> 5 << 2, ofp);
    putc(thumb[i] >> 11 << 3, ofp);
  }
  free(thumb);
}

Project: LibRaw

LibRaw_windows_datastream::LibRaw_windows_datastream(const TCHAR *sFile)
    : LibRaw_buffer_datastream(NULL, 0), hMap_(0), pView_(NULL)
{
  HANDLE hFile = CreateFile(sFile, GENERIC_READ, 0, 0, OPEN_EXISTING,
                            FILE_ATTRIBUTE_NORMAL, 0);
  if (hFile == INVALID_HANDLE_VALUE)
    throw std::runtime_error("failed to open the file");

  try
  {
    Open(hFile);
  }
  catch (...)
  {
    CloseHandle(hFile);
    throw;
  }

  CloseHandle(hFile); // windows will defer the actual closing of this handle
                      // until the hMap_ is closed
  reconstruct_base();
}

Project: LibRaw

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

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

Project: LibRaw

void LibRaw::fbdd_correction()
{
  int row, col, c, u = width, indx;
  ushort(*pix)[4];

  for (row = 2; row < height - 2; row++)
  {
    for (col = 2, indx = row * width + col; col < width - 2; col++, indx++)
    {

      c = fcol(row, col);

      image[indx][c] =
          ULIM(image[indx][c],
               MAX(image[indx - 1][c],
                   MAX(image[indx + 1][c],
                       MAX(image[indx - u][c], image[indx + u][c]))),
               MIN(image[indx - 1][c],
                   MIN(image[indx + 1][c],
                       MIN(image[indx - u][c], image[indx + u][c]))));
    }
  }
}

Project: LibRaw
File: exif_gps.cpp

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

  entries = get2();
  if (entries > 40)
    return;
  if (entries > 0)
    imgdata.other.parsed_gps.gpsparsed = 1;
  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:
      imgdata.other.parsed_gps.latref = getc(ifp);
      break;
    case 0x0003:
      imgdata.other.parsed_gps.longref = getc(ifp);
      break;
    case 0x0005:
      imgdata.other.parsed_gps.altref = getc(ifp);
      break;
    case 0x0002:
      if (len == 3)
        FORC(3) imgdata.other.parsed_gps.latitude[c] = getreal(type);
      break;
    case 0x0004:
      if (len == 3)
        FORC(3) imgdata.other.parsed_gps.longtitude[c] = getreal(type);
      break;
    case 0x0007:
      if (len == 3)
        FORC(3) imgdata.other.parsed_gps.gpstimestamp[c] = getreal(type);
      break;
    case 0x0006:
      imgdata.other.parsed_gps.altitude = getreal(type);
      break;
    case 0x0009:
      imgdata.other.parsed_gps.gpsstatus = getc(ifp);
      break;
    }
    fseek(ifp, save, SEEK_SET);
  }
}

Project: LibRaw

void LibRaw::fixupArri()
{
    struct alist_t
    {
        const char *a_model;
        const char *a_software;
        ushort a_width,a_height;
        int a_black;
        unsigned a_filters;
        float a_aspect;
    }
    alist[] =
    {
        {"ALEXA65", "Alexa65  XT", 6560 ,3100, 256,0x49494949,1.f},

        {"ALEXALF", "Alexa LF Plus W", 3840 ,2160, 256,0x49494949,1.0f },
        {"ALEXALF", "Alexa LF Plus W", 4448 ,1856, 256,0x49494949,0.75f },
        {"ALEXALF", "Alexa LF Plus W", 4448 ,3096, 256,0x49494949,1.f },

        {"ALEXA", "Alexa Plus 4:3 SXT", 2880 ,1620, 256,0x61616161,.75f},
        {"ALEXA", "Alexa Plus 4:3 SXT", 3168 ,1782, 256,0x61616161,0.75f},
        {"ALEXA", "Alexa Plus 4:3 SXT", 3424 ,2202, 256,0x61616161,1.f},
        {"ALEXA", "Alexa Plus 4:3 SXT", 2592 ,2160, 256,0x61616161,1.12f},

        {"ALEXA", "Alexa Plus 4:3 XT", 2592 ,2160, 256,0x61616161,1.12f},
        {"ALEXA", "Alexa Plus 4:3 XT", 2880 ,2160, 256,0x61616161,1.f},
        {"ALEXA", "Alexa Plus 4:3 XT", 2880 ,1620, 256,0x61616161,0.75f},
        {"ALEXA", "Alexa Plus 4:3 XT", 3424 ,2202, 256,0x61616161,1.f},
    };
    for(int i = 0; i < sizeof(alist)/sizeof(alist[0]); i++)
        if(!strncasecmp(model,alist[i].a_model,strlen(alist[i].a_model)) && software
            && !strncasecmp(software,alist[i].a_software,strlen(alist[i].a_software))
            && width == alist[i].a_width && height == alist[i].a_height)
        {
            filters = alist[i].a_filters;
            black = alist[i].a_black;
            pixel_aspect = alist[i].a_aspect;
            strcpy(model,software);
            software[0]=0;
            return;
        }
}

Project: LibRaw

int LibRaw::get_decoder_info(libraw_decoder_info_t *d_info)
{
  if (!d_info)
    return LIBRAW_UNSPECIFIED_ERROR;
  d_info->decoder_name = 0;
  d_info->decoder_flags = 0;
  if (!load_raw)
    return LIBRAW_OUT_OF_ORDER_CALL;

  int rawdata = (imgdata.idata.filters || P1.colors == 1);
  // dcraw.c names order
  if (load_raw == &LibRaw::android_tight_load_raw)
  {
    d_info->decoder_name = "android_tight_load_raw()";
    d_info->decoder_flags = LIBRAW_DECODER_FIXEDMAXC;
  }
  else if (load_raw == &LibRaw::android_loose_load_raw)
  {
    d_info->decoder_name = "android_loose_load_raw()";
    d_info->decoder_flags = LIBRAW_DECODER_FIXEDMAXC;
  }
  else if (load_raw == &LibRaw::float_dng_load_raw_placeholder)
  {
    d_info->decoder_name = "float_dng_load_raw_placeholder()";
  }
  else if (load_raw == &LibRaw::vc5_dng_load_raw_placeholder)
  {
      d_info->decoder_name = "vc5_dng_load_raw_placeholder()";
  }
  else if (load_raw == &LibRaw::canon_600_load_raw)
  {
    d_info->decoder_name = "canon_600_load_raw()";
    d_info->decoder_flags = LIBRAW_DECODER_FIXEDMAXC;
  }
  else if (load_raw == &LibRaw::fuji_compressed_load_raw)
  {
    d_info->decoder_name = "fuji_compressed_load_raw()";
  }
  else if (load_raw == &LibRaw::fuji_14bit_load_raw)
  {
    d_info->decoder_name = "fuji_14bit_load_raw()";
  }
  else if (load_raw == &LibRaw::canon_load_raw)
  {
    d_info->decoder_name = "canon_load_raw()";
  }
  else if (load_raw == &LibRaw::lossless_jpeg_load_raw)
  {
    d_info->decoder_name = "lossless_jpeg_load_raw()";
    d_info->decoder_flags =
        LIBRAW_DECODER_HASCURVE | LIBRAW_DECODER_TRYRAWSPEED;
  }
  else if (load_raw == &LibRaw::canon_sraw_load_raw)
  {
    d_info->decoder_name = "canon_sraw_load_raw()";
    // d_info->decoder_flags = LIBRAW_DECODER_TRYRAWSPEED;
  }
  else if (load_raw == &LibRaw::crxLoadRaw)
  {
    d_info->decoder_name = "crxLoadRaw()";
  }
  else if (load_raw == &LibRaw::lossless_dng_load_raw)
  {
    d_info->decoder_name = "lossless_dng_load_raw()";
    d_info->decoder_flags = LIBRAW_DECODER_HASCURVE |
                            LIBRAW_DECODER_TRYRAWSPEED |
                            LIBRAW_DECODER_ADOBECOPYPIXEL;
  }
  else if (load_raw == &LibRaw::packed_dng_load_raw)
  {
    d_info->decoder_name = "packed_dng_load_raw()";
    d_info->decoder_flags = LIBRAW_DECODER_HASCURVE |
                            LIBRAW_DECODER_TRYRAWSPEED |
                            LIBRAW_DECODER_ADOBECOPYPIXEL;
  }
  else if (load_raw == &LibRaw::pentax_load_raw)
  {
    d_info->decoder_name = "pentax_load_raw()";
    d_info->decoder_flags = LIBRAW_DECODER_TRYRAWSPEED;
  }
  else if (load_raw == &LibRaw::nikon_load_raw)
  {
    d_info->decoder_name = "nikon_load_raw()";
    d_info->decoder_flags =
        LIBRAW_DECODER_TRYRAWSPEED | LIBRAW_DECODER_HASCURVE;
  }
  else if (load_raw == &LibRaw::nikon_coolscan_load_raw)
  {
    d_info->decoder_name = "nikon_coolscan_load_raw()";
    d_info->decoder_flags = LIBRAW_DECODER_FIXEDMAXC;
  }
  else if (load_raw == &LibRaw::nikon_load_sraw)
  {
    d_info->decoder_name = "nikon_load_sraw()";
    d_info->decoder_flags = LIBRAW_DECODER_HASCURVE | LIBRAW_DECODER_FIXEDMAXC;
  }
  else if (load_raw == &LibRaw::nikon_yuv_load_raw)
  {
    d_info->decoder_name = "nikon_load_yuv_load_raw()";
    d_info->decoder_flags = LIBRAW_DECODER_HASCURVE | LIBRAW_DECODER_FIXEDMAXC;
  }
  else if (load_raw == &LibRaw::rollei_load_raw)
  {
    // UNTESTED
    d_info->decoder_name = "rollei_load_raw()";
    d_info->decoder_flags = LIBRAW_DECODER_FIXEDMAXC;
  }
  else if (load_raw == &LibRaw::phase_one_load_raw)
  {
    d_info->decoder_name = "phase_one_load_raw()";
  }
  else if (load_raw == &LibRaw::phase_one_load_raw_c)
  {
    d_info->decoder_name = "phase_one_load_raw_c()";
  }
  else if (load_raw == &LibRaw::hasselblad_load_raw)
  {
    d_info->decoder_name = "hasselblad_load_raw()";
  }
  else if (load_raw == &LibRaw::leaf_hdr_load_raw)
  {
    d_info->decoder_name = "leaf_hdr_load_raw()";
  }
  else if (load_raw == &LibRaw::unpacked_load_raw)
  {
    d_info->decoder_name = "unpacked_load_raw()";
	d_info->decoder_flags = LIBRAW_DECODER_FLATDATA;
  }
  else if (load_raw == &LibRaw::unpacked_load_raw_reversed)
  {
    d_info->decoder_name = "unpacked_load_raw_reversed()";
    d_info->decoder_flags = LIBRAW_DECODER_FIXEDMAXC;
  }
  else if (load_raw == &LibRaw::sinar_4shot_load_raw)
  {
    // UNTESTED
    d_info->decoder_name = "sinar_4shot_load_raw()";
    d_info->decoder_flags = LIBRAW_DECODER_SINAR4SHOT;
  }
  else if (load_raw == &LibRaw::imacon_full_load_raw)
  {
    d_info->decoder_name = "imacon_full_load_raw()";
  }
  else if (load_raw == &LibRaw::hasselblad_full_load_raw)
  {
    d_info->decoder_name = "hasselblad_full_load_raw()";
  }
  else if (load_raw == &LibRaw::packed_load_raw)
  {
    d_info->decoder_name = "packed_load_raw()";
    d_info->decoder_flags = LIBRAW_DECODER_TRYRAWSPEED;
  }
  else if (load_raw == &LibRaw::broadcom_load_raw)
  {
    // UNTESTED
    d_info->decoder_name = "broadcom_load_raw()";
    d_info->decoder_flags = LIBRAW_DECODER_FIXEDMAXC;
  }
  else if (load_raw == &LibRaw::nokia_load_raw)
  {
    // UNTESTED
    d_info->decoder_name = "nokia_load_raw()";
    d_info->decoder_flags = LIBRAW_DECODER_FIXEDMAXC;
  }
  else if (load_raw == &LibRaw::canon_rmf_load_raw)
  {
    // UNTESTED
    d_info->decoder_name = "canon_rmf_load_raw()";
  }
  else if (load_raw == &LibRaw::panasonic_load_raw)
  {
    d_info->decoder_name = "panasonic_load_raw()";
    d_info->decoder_flags = LIBRAW_DECODER_TRYRAWSPEED;
  }
  else if (load_raw == &LibRaw::panasonicC6_load_raw)
  {
    d_info->decoder_name = "panasonicC6_load_raw()";
  }
  else if (load_raw == &LibRaw::panasonicC7_load_raw)
  {
    d_info->decoder_name = "panasonicC7_load_raw()";
  }
  else if (load_raw == &LibRaw::olympus_load_raw)
  {
    d_info->decoder_name = "olympus_load_raw()";
    d_info->decoder_flags = LIBRAW_DECODER_TRYRAWSPEED;
  }
  else if (load_raw == &LibRaw::minolta_rd175_load_raw)
  {
    // UNTESTED
    d_info->decoder_name = "minolta_rd175_load_raw()";
  }
  else if (load_raw == &LibRaw::quicktake_100_load_raw)
  {
    // UNTESTED
    d_info->decoder_name = "quicktake_100_load_raw()";
  }
  else if (load_raw == &LibRaw::kodak_radc_load_raw)
  {
    d_info->decoder_name = "kodak_radc_load_raw()";
  }
  else if (load_raw == &LibRaw::kodak_jpeg_load_raw)
  {
    // UNTESTED + RBAYER
    d_info->decoder_name = "kodak_jpeg_load_raw()";
  }
  else if (load_raw == &LibRaw::lossy_dng_load_raw)
  {
    // Check rbayer
    d_info->decoder_name = "lossy_dng_load_raw()";
    d_info->decoder_flags =
        LIBRAW_DECODER_TRYRAWSPEED | LIBRAW_DECODER_HASCURVE;
  }
  else if (load_raw == &LibRaw::kodak_dc120_load_raw)
  {
    d_info->decoder_name = "kodak_dc120_load_raw()";
  }
  else if (load_raw == &LibRaw::eight_bit_load_raw)
  {
    d_info->decoder_name = "eight_bit_load_raw()";
    d_info->decoder_flags = LIBRAW_DECODER_HASCURVE | LIBRAW_DECODER_FIXEDMAXC;
  }
  else if (load_raw == &LibRaw::kodak_c330_load_raw)
  {
    d_info->decoder_name = "kodak_yrgb_load_raw()";
    d_info->decoder_flags = LIBRAW_DECODER_HASCURVE | LIBRAW_DECODER_FIXEDMAXC;
  }
  else if (load_raw == &LibRaw::kodak_c603_load_raw)
  {
    d_info->decoder_name = "kodak_yrgb_load_raw()";
    d_info->decoder_flags = LIBRAW_DECODER_HASCURVE | LIBRAW_DECODER_FIXEDMAXC;
  }
  else if (load_raw == &LibRaw::kodak_262_load_raw)
  {
    d_info->decoder_name = "kodak_262_load_raw()"; // UNTESTED!
    d_info->decoder_flags = LIBRAW_DECODER_HASCURVE | LIBRAW_DECODER_FIXEDMAXC;
  }
  else if (load_raw == &LibRaw::kodak_65000_load_raw)
  {
    d_info->decoder_name = "kodak_65000_load_raw()";
    d_info->decoder_flags = LIBRAW_DECODER_HASCURVE;
  }
  else if (load_raw == &LibRaw::kodak_ycbcr_load_raw)
  {
    // UNTESTED
    d_info->decoder_name = "kodak_ycbcr_load_raw()";
    d_info->decoder_flags = LIBRAW_DECODER_HASCURVE | LIBRAW_DECODER_FIXEDMAXC;
  }
  else if (load_raw == &LibRaw::kodak_rgb_load_raw)
  {
    // UNTESTED
    d_info->decoder_name = "kodak_rgb_load_raw()";
    d_info->decoder_flags = LIBRAW_DECODER_FIXEDMAXC;
  }
  else if (load_raw == &LibRaw::sony_load_raw)
  {
    d_info->decoder_name = "sony_load_raw()";
  }
  else if (load_raw == &LibRaw::sony_arw_load_raw)
  {
    d_info->decoder_name = "sony_arw_load_raw()";
    d_info->decoder_flags = LIBRAW_DECODER_TRYRAWSPEED;
  }
  else if (load_raw == &LibRaw::sony_arw2_load_raw)
  {
    d_info->decoder_name = "sony_arw2_load_raw()";
    d_info->decoder_flags = LIBRAW_DECODER_HASCURVE |
                            LIBRAW_DECODER_TRYRAWSPEED |
                            LIBRAW_DECODER_SONYARW2;
  }
  else if (load_raw == &LibRaw::sony_arq_load_raw)
  {
    d_info->decoder_name = "sony_arq_load_raw()";
    d_info->decoder_flags = LIBRAW_DECODER_LEGACY_WITH_MARGINS | LIBRAW_DECODER_FLATDATA | LIBRAW_DECODER_FLAT_BG2_SWAPPED;
  }
  else if (load_raw == &LibRaw::samsung_load_raw)
  {
    d_info->decoder_name = "samsung_load_raw()";
    d_info->decoder_flags = LIBRAW_DECODER_TRYRAWSPEED;
  }
  else if (load_raw == &LibRaw::samsung2_load_raw)
  {
    d_info->decoder_name = "samsung2_load_raw()";
  }
  else if (load_raw == &LibRaw::samsung3_load_raw)
  {
    d_info->decoder_name = "samsung3_load_raw()";
  }
  else if (load_raw == &LibRaw::smal_v6_load_raw)
  {
    // UNTESTED
    d_info->decoder_name = "smal_v6_load_raw()";
    d_info->decoder_flags = LIBRAW_DECODER_FIXEDMAXC;
  }
  else if (load_raw == &LibRaw::smal_v9_load_raw)
  {
    // UNTESTED
    d_info->decoder_name = "smal_v9_load_raw()";
    d_info->decoder_flags = LIBRAW_DECODER_FIXEDMAXC;
  }
  else if (load_raw == &LibRaw::redcine_load_raw)
  {
    d_info->decoder_name = "redcine_load_raw()";
    d_info->decoder_flags = LIBRAW_DECODER_HASCURVE;
  }
  else if (load_raw == &LibRaw::x3f_load_raw)
  {
    d_info->decoder_name = "x3f_load_raw()";
    d_info->decoder_flags = LIBRAW_DECODER_OWNALLOC | LIBRAW_DECODER_FIXEDMAXC |
                            LIBRAW_DECODER_LEGACY_WITH_MARGINS;
  }
  else if (load_raw == &LibRaw::pentax_4shot_load_raw)
  {
    d_info->decoder_name = "pentax_4shot_load_raw()";
    d_info->decoder_flags = LIBRAW_DECODER_OWNALLOC;
  }
  else if (load_raw == &LibRaw::deflate_dng_load_raw)
  {
    d_info->decoder_name = "deflate_dng_load_raw()";
    d_info->decoder_flags = LIBRAW_DECODER_OWNALLOC;
  }
  else if (load_raw == &LibRaw::nikon_load_striped_packed_raw)
  {
    d_info->decoder_name = "nikon_load_striped_packed_raw()";
  }
  else if (load_raw == &LibRaw::nikon_load_padded_packed_raw)
  {
    d_info->decoder_name = "nikon_load_padded_packed_raw()";
  }
  else if (load_raw == &LibRaw::nikon_14bit_load_raw)
  {
    d_info->decoder_name = "nikon_14bit_load_raw()";
  }
  /* -- added 07/02/18 -- */
  else if (load_raw == &LibRaw::unpacked_load_raw_fuji_f700s20)
  {
    d_info->decoder_name = "unpacked_load_raw_fuji_f700s20()";
  }
  else if (load_raw == &LibRaw::unpacked_load_raw_FujiDBP)
  {
    d_info->decoder_name = "unpacked_load_raw_FujiDBP()";
  }
  else
  {
    d_info->decoder_name = "Unknown unpack function";
    d_info->decoder_flags = LIBRAW_DECODER_NOTSET;
  }
  return LIBRAW_SUCCESS;
}

Project: LibRaw

  void libraw_set_memerror_handler(libraw_data_t *lr, memory_callback cb,
                                   void *data)
  {
    if (!lr)
      return;
    LibRaw *ip = (LibRaw *)lr->parent_class;
    ip->set_memerror_handler(cb, data);
  }

Project: LibRaw

void DHT::refine_hv_dirs(int i, int js)
{
  int iwidth = libraw.imgdata.sizes.iwidth;
  for (int j = js; j < iwidth; j += 2)
  {
    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);
    bool codir = (ndir[nr_offset(y, x)] & VER)
                     ? ((ndir[nr_offset(y - 1, x)] & VER) ||
                        (ndir[nr_offset(y + 1, x)] & VER))
                     : ((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 > 2 && !codir))
    {
      ndir[nr_offset(y, x)] &= ~VER;
      ndir[nr_offset(y, x)] |= HOR;
    }
    if ((ndir[nr_offset(y, x)] & HOR) && (nv > 2 && !codir))
    {
      ndir[nr_offset(y, x)] &= ~HOR;
      ndir[nr_offset(y, x)] |= VER;
    }
  }
}

Project: LibRaw

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

Project: LibRaw

void LibRaw::Kodak_KDC_WBtags(int wb, int wbi)
{
  int c;
  FORC3 imgdata.color.WB_Coeffs[wb][c] = get4();
  imgdata.color.WB_Coeffs[wb][3] = imgdata.color.WB_Coeffs[wb][1];
  if (wbi == wb)
    FORC4 cam_mul[c] = imgdata.color.WB_Coeffs[wb][c];
  return;
}

Project: LibRaw

int LibRaw_bigfile_datastream::eof()
{
  LR_BF_CHK();
  return feof(f);
}

Project: LibRaw

void LibRaw::clearCancelFlag()
{
#ifdef _MSC_VER
  InterlockedExchange(&_exitflag, 0);
#else
  __sync_fetch_and_and(&_exitflag, 0);
#endif
#ifdef RAWSPEED_FASTEXIT
  if (_rawspeed_decoder)
  {
    RawSpeed::RawDecoder *d =
        static_cast<RawSpeed::RawDecoder *>(_rawspeed_decoder);
    d->resumeProcessing();
  }
#endif
}

Project: LibRaw

short LibRaw::guess_byte_order(int words)
{
  uchar test[4][2];
  int t = 2, msb;
  double diff, sum[2] = {0, 0};

  fread(test[0], 2, 2, ifp);
  for (words -= 2; words--;)
  {
    fread(test[t], 2, 1, ifp);
    for (msb = 0; msb < 2; msb++)
    {
      diff = (test[t ^ 2][msb] << 8 | test[t ^ 2][!msb]) -
             (test[t][msb] << 8 | test[t][!msb]);
      sum[msb] += diff * diff;
    }
    t = (t + 1) & 3;
  }
  return sum[0] < sum[1] ? 0x4d4d : 0x4949;
}

Project: LibRaw

libraw_processed_image_t *LibRaw::dcraw_make_mem_image(int *) {
  return NULL;
}

Project: LibRaw

void LibRaw::lossy_dng_load_raw() {}

Project: LibRaw

void LibRaw::layer_thumb(){}

Project: LibRaw

int LibRaw::p1raw(unsigned row, unsigned col)
{
  return (row < raw_height && col < raw_width) ? RAW(row, col) : 0;
}

Project: LibRaw

void LibRaw::subtract(const char *fname)
{
  FILE *fp;
  int dim[3] = {0, 0, 0}, comment = 0, number = 0, error = 0, nd = 0, c, row,
      col;
  ushort *pixel;
  RUN_CALLBACK(LIBRAW_PROGRESS_DARK_FRAME, 0, 2);

  if (!(fp = fopen(fname, "rb")))
  {
    imgdata.process_warnings |= LIBRAW_WARN_BAD_DARKFRAME_FILE;
    return;
  }
  if (fgetc(fp) != 'P' || fgetc(fp) != '5')
    error = 1;
  while (!error && nd < 3 && (c = fgetc(fp)) != EOF)
  {
    if (c == '#')
      comment = 1;
    if (c == '\n')
      comment = 0;
    if (comment)
      continue;
    if (isdigit(c))
      number = 1;
    if (number)
    {
      if (isdigit(c))
        dim[nd] = dim[nd] * 10 + c - '0';
      else if (isspace(c))
      {
        number = 0;
        nd++;
      }
      else
        error = 1;
    }
  }
  if (error || nd < 3)
  {
    fclose(fp);
    return;
  }
  else if (dim[0] != width || dim[1] != height || dim[2] != 65535)
  {
    imgdata.process_warnings |= LIBRAW_WARN_BAD_DARKFRAME_DIM;
    fclose(fp);
    return;
  }
  pixel = (ushort *)calloc(width, sizeof *pixel);
  merror(pixel, "subtract()");
  for (row = 0; row < height; row++)
  {
    fread(pixel, 2, width, fp);
    for (col = 0; col < width; col++)
      BAYER(row, col) = MAX(BAYER(row, col) - ntohs(pixel[col]), 0);
  }
  free(pixel);
  fclose(fp);
  memset(cblack, 0, sizeof cblack);
  black = 0;
  RUN_CALLBACK(LIBRAW_PROGRESS_DARK_FRAME, 1, 2);
}

Project: LibRaw

void print_wbfun(FILE* outfile, LibRaw& MyCoolRawProcessor, std::string& fn)
{
	const char *CamMakerName = LibRaw::cameramakeridx2maker(P1.maker_index);
	fprintf(outfile, "// %s %s\n", P1.make, P1.model);
	for (int cnt = 0; cnt < nEXIF_LightSources; cnt++)
		if (C.WB_Coeffs[cnt][0])
		{
			fprintf(outfile, "{LIBRAW_CAMERAMAKER_%s, \"%s\", %d, {%6.5ff, 1.0f, %6.5ff, ", CamMakerName,
				P1.normalized_model, cnt,
				C.WB_Coeffs[cnt][0] / (float)C.WB_Coeffs[cnt][1],
				C.WB_Coeffs[cnt][2] / (float)C.WB_Coeffs[cnt][1]);
			if (C.WB_Coeffs[cnt][1] == C.WB_Coeffs[cnt][3])
				fprintf(outfile, "1.0f}},\n");
			else
				fprintf(outfile, "%6.5ff}},\n",
				C.WB_Coeffs[cnt][3] / (float)C.WB_Coeffs[cnt][1]);
		}
	if (C.WB_Coeffs[LIBRAW_WBI_Sunset][0])
	{
		fprintf(outfile, "{LIBRAW_CAMERAMAKER_%s, \"%s\", %d, {%6.5ff, 1.0f, %6.5ff, ", CamMakerName,
			P1.normalized_model, LIBRAW_WBI_Sunset,
			C.WB_Coeffs[LIBRAW_WBI_Sunset][0] /
			(float)C.WB_Coeffs[LIBRAW_WBI_Sunset][1],
			C.WB_Coeffs[LIBRAW_WBI_Sunset][2] /
			(float)C.WB_Coeffs[LIBRAW_WBI_Sunset][1]);
		if (C.WB_Coeffs[LIBRAW_WBI_Sunset][1] ==
			C.WB_Coeffs[LIBRAW_WBI_Sunset][3])
			fprintf(outfile, "1.0f}},\n");
		else
			fprintf(outfile, "%6.5ff}},\n", C.WB_Coeffs[LIBRAW_WBI_Sunset][3] /
			(float)C.WB_Coeffs[LIBRAW_WBI_Sunset][1]);
	}

	for (int cnt = 0; cnt < 64; cnt++)
		if (C.WBCT_Coeffs[cnt][0])
		{
			fprintf(outfile, "{LIBRAW_CAMERAMAKER_%s, \"%s\", %d, {%6.5ff, 1.0f, %6.5ff, ", CamMakerName,
				P1.normalized_model, (int)C.WBCT_Coeffs[cnt][0],
				C.WBCT_Coeffs[cnt][1] / C.WBCT_Coeffs[cnt][2],
				C.WBCT_Coeffs[cnt][3] / C.WBCT_Coeffs[cnt][2]);
			if (C.WBCT_Coeffs[cnt][2] == C.WBCT_Coeffs[cnt][4])
				fprintf(outfile, "1.0f}},\n");
			else
				fprintf(outfile, "%6.5ff}},\n",
				C.WBCT_Coeffs[cnt][4] / C.WBCT_Coeffs[cnt][2]);
		}
		else
			break;
	fprintf(outfile, "\n");
}

Project: LibRaw

int main(int argc, char *argv[])
{
  int i, ret, rep = 1;
  LibRaw RawProcessor;
#ifdef OUT
#undef OUT
#endif
#define OUT RawProcessor.imgdata.params
#define S RawProcessor.imgdata.sizes

  if (argc < 2)
  {
    printf(
        "postprocessing benchmark: LibRaw %s sample, %d cameras supported\n"
        "Measures postprocessing speed with different options\n"
        "Usage: %s [-a] [-H N] [-q N] [-h] [-m N] [-n N] [-s N] [-B x y w h] "
        "[-R N]\n"
        "-a             average image for white balance\n"
        "-H <num>       Highlight mode (0=clip, 1=unclip, 2=blend, "
        "3+=rebuild)\n"
        "-q <num>       Set the interpolation quality\n"
        "-h             Half-size color image\n"
        "-m <num>       Apply a num-passes 3x3 median filter to R-G and B-G\n"
        "-n <num>       Set threshold for wavelet denoising\n"
        "-s <num>       Select one raw image from input file\n"
        "-B <x y w h>   Crop output image\n"
        "-R <num>       Number of repetitions\n"
        "-c             Do not use rawspeed\n",
        LibRaw::version(), LibRaw::cameraCount(), argv[0]);
    return 0;
  }
  char opm, opt, *cp, *sp;
  int arg, c;
  int shrink = 0;

  argv[argc] = (char *)"";
  for (arg = 1; (((opm = argv[arg][0]) - 2) | 2) == '+';)
  {
    char *optstr = argv[arg];
    opt = argv[arg++][1];
    if ((cp = strchr(sp = (char *)"HqmnsBR", opt)) != 0)
      for (i = 0; i < "1111141"[cp - sp] - '0'; i++)
        if (!isdigit(argv[arg + i][0]) && !optstr[2])
        {
          fprintf(stderr, "Non-numeric argument to \"-%c\"\n", opt);
          return 1;
        }
    switch (opt)
    {
    case 'a':
      OUT.use_auto_wb = 1;
      break;
    case 'H':
      OUT.highlight = atoi(argv[arg++]);
      break;
    case 'q':
      OUT.user_qual = atoi(argv[arg++]);
      break;
    case 'h':
      OUT.half_size = 1;
      OUT.four_color_rgb = 1;
      shrink = 1;
      break;
    case 'm':
      OUT.med_passes = atoi(argv[arg++]);
      break;
    case 'n':
      OUT.threshold = (float)atof(argv[arg++]);
      break;
    case 's':
      OUT.shot_select = abs(atoi(argv[arg++]));
      break;
    case 'B':
      for (c = 0; c < 4; c++)
        OUT.cropbox[c] = atoi(argv[arg++]);
      break;
    case 'R':
      rep = abs(atoi(argv[arg++]));
      if (rep < 1)
        rep = 1;
      break;
    case 'c':
      OUT.use_rawspeed = 0;
      break;
    default:
      fprintf(stderr, "Unknown option \"-%c\".\n", opt);
      return 1;
    }
  }
  for (; arg < argc; arg++)
  {
    printf("Processing file %s\n", argv[arg]);
    timerstart();
    if ((ret = RawProcessor.open_file(argv[arg])) != LIBRAW_SUCCESS)
    {
      fprintf(stderr, "Cannot open_file %s: %s\n", argv[arg],
              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", argv[arg],
              libraw_strerror(ret));
      continue;
    }
    float qsec = timerend();
    printf("\n%.1f msec for unpack\n", qsec);
    float mpix, rmpix;
    timerstart();
    for (c = 0; c < rep; c++)
    {
      if ((ret = RawProcessor.dcraw_process()) != LIBRAW_SUCCESS)
      {
        fprintf(stderr, "Cannot postprocess %s: %s\n", argv[arg],
                libraw_strerror(ret));
        break;
      }
      libraw_processed_image_t *p = RawProcessor.dcraw_make_mem_image();
      if (p)
        RawProcessor.dcraw_clear_mem(p);
      RawProcessor.free_image();
    }
    float msec = timerend() / (float)rep;

    if ((ret = RawProcessor.adjust_sizes_info_only()) != LIBRAW_SUCCESS)
    {
      fprintf(stderr, "Cannot adjust sizes for %s: %s\n", argv[arg],
              libraw_strerror(ret));
      break;
    }
    rmpix = (S.iwidth * S.iheight) / 1000000.0f;

    if (c == rep) // no failure
    {
      unsigned int crop[4];
      for (int i = 0; i < 4; i++)
        crop[i] = (OUT.cropbox[i]) >> shrink;
      if (crop[0] + crop[2] > S.iwidth)
        crop[2] = S.iwidth - crop[0];
      if (crop[1] + crop[3] > S.iheight)
        crop[3] = S.iheight - crop[1];

      mpix = float(crop[2] * crop[3]) / 1000000.0f;
      float mpixsec = mpix * 1000.0f / msec;

      printf("Performance: %.2f Mpix/sec\n"
             "File: %s, Frame: %d %.1f total Mpix, %.1f msec\n"
             "Params:      WB=%s Highlight=%d Qual=%d HalfSize=%s Median=%d "
             "Wavelet=%.0f\n"
             "Crop:        %u-%u:%ux%u, active Mpix: %.2f, %.1f frames/sec\n",
             mpixsec, argv[arg], OUT.shot_select, rmpix, msec,
             OUT.use_auto_wb ? "auto" : "default", OUT.highlight, OUT.user_qual,
             OUT.half_size ? "YES" : "No", OUT.med_passes, OUT.threshold,
             crop[0], crop[1], crop[2], crop[3], mpix, 1000.0f / msec);
    }
  }

  return 0;
}

Project: LibRaw

const wchar_t *LibRaw_file_datastream::wfname()
{
  return wfilename.size() > 0 ? wfilename.c_str() : NULL;
}

Project: LibRaw

  libraw_memmgr(unsigned ee) : extra_bytes(ee)
  {
    size_t alloc_sz = LIBRAW_MSIZE * sizeof(void *);
    mems = (void **)::malloc(alloc_sz);
    memset(mems, 0, alloc_sz);
  }

Project: LibRaw

void LibRaw::nikon_load_sraw()
{
  // We're already seeked to data!
  unsigned char *rd =
      (unsigned char *)malloc(3 * (imgdata.sizes.raw_width + 2));
  if (!rd)
    throw LIBRAW_EXCEPTION_ALLOC;
  try
  {
    int row, col;
    for (row = 0; row < imgdata.sizes.raw_height; row++)
    {
      checkCancel();
      libraw_internal_data.internal_data.input->read(rd, 3,
                                                     imgdata.sizes.raw_width);
      for (col = 0; col < imgdata.sizes.raw_width - 1; col += 2)
      {
        int bi = col * 3;
        ushort bits1 = (rd[bi + 1] & 0xf) << 8 | rd[bi];            // 3,0,1
        ushort bits2 = rd[bi + 2] << 4 | ((rd[bi + 1] >> 4) & 0xf); // 452
        ushort bits3 = ((rd[bi + 4] & 0xf) << 8) | rd[bi + 3];      // 967
        ushort bits4 = rd[bi + 5] << 4 | ((rd[bi + 4] >> 4) & 0xf); // ab8
        imgdata.image[row * imgdata.sizes.raw_width + col][0] = bits1;
        imgdata.image[row * imgdata.sizes.raw_width + col][1] = bits3;
        imgdata.image[row * imgdata.sizes.raw_width + col][2] = bits4;
        imgdata.image[row * imgdata.sizes.raw_width + col + 1][0] = bits2;
        imgdata.image[row * imgdata.sizes.raw_width + col + 1][1] = 2048;
        imgdata.image[row * imgdata.sizes.raw_width + col + 1][2] = 2048;
      }
    }
  }
  catch (...)
  {
    free(rd);
    throw;
  }
  free(rd);
  C.maximum = 0xfff; // 12 bit?
  if (imgdata.params.raw_processing_options &
      LIBRAW_PROCESSING_SRAW_NO_INTERPOLATE)
  {
    return; // no CbCr interpolation
  }
  // Interpolate CC channels
  int row, col;
  for (row = 0; row < imgdata.sizes.raw_height; row++)
  {
    checkCancel(); // will throw out
    for (col = 0; col < imgdata.sizes.raw_width; col += 2)
    {
      int col2 = col < imgdata.sizes.raw_width - 2 ? col + 2 : col;
      imgdata.image[row * imgdata.sizes.raw_width + col + 1][1] =
          (unsigned short)(int(imgdata.image[row * imgdata.sizes.raw_width +
                                             col][1] +
                               imgdata.image[row * imgdata.sizes.raw_width +
                                             col2][1]) /
                           2);
      imgdata.image[row * imgdata.sizes.raw_width + col + 1][2] =
          (unsigned short)(int(imgdata.image[row * imgdata.sizes.raw_width +
                                             col][2] +
                               imgdata.image[row * imgdata.sizes.raw_width +
                                             col2][2]) /
                           2);
    }
  }
  if (imgdata.params.raw_processing_options & LIBRAW_PROCESSING_SRAW_NO_RGB)
    return;

  for (row = 0; row < imgdata.sizes.raw_height; row++)
  {
    checkCancel(); // will throw out
    for (col = 0; col < imgdata.sizes.raw_width; col++)
    {
      float Y =
          float(imgdata.image[row * imgdata.sizes.raw_width + col][0]) / 2549.f;
      float Ch2 =
          float(imgdata.image[row * imgdata.sizes.raw_width + col][1] - 1280) /
          1536.f;
      float Ch3 =
          float(imgdata.image[row * imgdata.sizes.raw_width + col][2] - 1280) /
          1536.f;
      if (Y > 1.f)
        Y = 1.f;
      if (Y > 0.803f)
        Ch2 = Ch3 = 0.5f;
      float r = Y + 1.40200f * (Ch3 - 0.5f);
      if (r < 0.f)
        r = 0.f;
      if (r > 1.f)
        r = 1.f;
      float g = Y - 0.34414f * (Ch2 - 0.5f) - 0.71414 * (Ch3 - 0.5f);
      if (g > 1.f)
        g = 1.f;
      if (g < 0.f)
        g = 0.f;
      float b = Y + 1.77200 * (Ch2 - 0.5f);
      if (b > 1.f)
        b = 1.f;
      if (b < 0.f)
        b = 0.f;
      imgdata.image[row * imgdata.sizes.raw_width + col][0] =
          imgdata.color.curve[int(r * 3072.f)];
      imgdata.image[row * imgdata.sizes.raw_width + col][1] =
          imgdata.color.curve[int(g * 3072.f)];
      imgdata.image[row * imgdata.sizes.raw_width + col][2] =
          imgdata.color.curve[int(b * 3072.f)];
    }
  }
  C.maximum = 16383;
}

Project: LibRaw

  static inline float Tg(void) throw() { return 256.0f; }

Project: LibRaw

int LibRaw_bigfile_datastream::jpeg_src(void *jpegdata)
{
#ifdef NO_JPEG
  return -1;
#else
  if (!f)
    return -1;
  j_decompress_ptr cinfo = (j_decompress_ptr)jpegdata;
  jpeg_stdio_src(cinfo, f);
  return 0; // OK
#endif
}

Project: LibRaw

static inline void unpack7bytesto4x16_nikon(unsigned char *src,
                                            unsigned short *dest)
{
  dest[3] = (src[6] << 6) | (src[5] >> 2);
  dest[2] = ((src[5] & 0x3) << 12) | (src[4] << 4) | (src[3] >> 4);
  dest[1] = (src[3] & 0xf) << 10 | (src[2] << 2) | (src[1] >> 6);
  dest[0] = ((src[1] & 0x3f) << 8) | src[0];
}

Project: LibRaw

LibRaw_windows_datastream::LibRaw_windows_datastream(HANDLE hFile)
    : LibRaw_buffer_datastream(NULL, 0), hMap_(0), pView_(NULL)
{
  Open(hFile);
  reconstruct_base();
}

Project: LibRaw

  int libraw_dcraw_thumb_writer(libraw_data_t *lr, const char *fname)
  {
    if (!lr)
      return EINVAL;
    LibRaw *ip = (LibRaw *)lr->parent_class;
    return ip->dcraw_thumb_writer(fname);
  }

Project: LibRaw

int LibRaw::open_file(const wchar_t *, INT64)
{
  return LIBRAW_NOT_IMPLEMENTED;
}

Project: LibRaw

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

  int iterations = -1, dcb_enhance = 1, noiserd = 0;
  float preser = 0;
  float expos = 1.0;

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

  try
  {

    int no_crop = 1;

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

    libraw_decoder_info_t di;
    get_decoder_info(&di);

    bool is_bayer = (imgdata.idata.filters || P1.colors == 1);
    int subtract_inline =
        !O.bad_pixels && !O.dark_frame && is_bayer && !IO.zero_is_bad;

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

    // Adjust sizes

    int save_4color = O.four_color_rgb;

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

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

    if (O.dark_frame && no_crop)
    {
      subtract(O.dark_frame);
      SET_PROC_FLAG(LIBRAW_PROGRESS_DARK_FRAME);
    }
    /* pre subtract black callback: check for it above to disable subtract
     * inline */

    if (callbacks.pre_subtractblack_cb)
      (callbacks.pre_subtractblack_cb)(this);

    quality = 2 + !IO.fuji_width;

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

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

    if (!(di.decoder_flags & LIBRAW_DECODER_FIXEDMAXC))
      adjust_maximum();

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

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

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

    if (callbacks.pre_scalecolors_cb)
      (callbacks.pre_scalecolors_cb)(this);

    if (!O.no_auto_scale)
    {
      scale_colors();
      SET_PROC_FLAG(LIBRAW_PROGRESS_SCALE_COLORS);
    }

    if (callbacks.pre_preinterpolate_cb)
      (callbacks.pre_preinterpolate_cb)(this);

    pre_interpolate();

    SET_PROC_FLAG(LIBRAW_PROGRESS_PRE_INTERPOLATE);

    if (O.dcb_iterations >= 0)
      iterations = O.dcb_iterations;
    if (O.dcb_enhance_fl >= 0)
      dcb_enhance = O.dcb_enhance_fl;
    if (O.fbdd_noiserd >= 0)
      noiserd = O.fbdd_noiserd;

    /* pre-exposure correction callback */

    if (O.exp_correc > 0)
    {
      expos = O.exp_shift;
      preser = O.exp_preser;
      exp_bef(expos, preser);
    }

    if (callbacks.pre_interpolate_cb)
      (callbacks.pre_interpolate_cb)(this);

    /* post-exposure correction fallback */
    if (P1.filters && !O.no_interpolation)
    {
      if (noiserd > 0 && P1.colors == 3 && P1.filters)
        fbdd(noiserd);

      if (P1.filters > 1000 && callbacks.interpolate_bayer_cb)
        (callbacks.interpolate_bayer_cb)(this);
      else if (P1.filters == 9 && callbacks.interpolate_xtrans_cb)
        (callbacks.interpolate_xtrans_cb)(this);
      else if (quality == 0)
        lin_interpolate();
      else if (quality == 1 || P1.colors > 3)
        vng_interpolate();
      else if (quality == 2 && P1.filters > 1000)
        ppg_interpolate();
      else if (P1.filters == LIBRAW_XTRANS)
      {
        // Fuji X-Trans
        xtrans_interpolate(quality > 2 ? 3 : 1);
      }
      else if (quality == 3)
        ahd_interpolate(); // really don't need it here due to fallback op
      else if (quality == 4)
        dcb(iterations, dcb_enhance);

      else if (quality == 11)
        dht_interpolate();
      else if (quality == 12)
        aahd_interpolate();
      // fallback to AHD
      else
      {
        ahd_interpolate();
        imgdata.process_warnings |= LIBRAW_WARN_FALLBACK_TO_AHD;
      }

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

    if (callbacks.post_interpolate_cb)
      (callbacks.post_interpolate_cb)(this);
    else if (!P1.is_foveon && P1.colors == 3 && O.med_passes > 0)
    {
      median_filter();
      SET_PROC_FLAG(LIBRAW_PROGRESS_MEDIAN_FILTER);
    }

    if (O.highlight == 2)
    {
      blend_highlights();
      SET_PROC_FLAG(LIBRAW_PROGRESS_HIGHLIGHTS);
    }

    if (O.highlight > 2)
    {
      recover_highlights();
      SET_PROC_FLAG(LIBRAW_PROGRESS_HIGHLIGHTS);
    }

    if (O.use_fuji_rotate)
    {
      fuji_rotate();
      SET_PROC_FLAG(LIBRAW_PROGRESS_FUJI_ROTATE);
    }

    if (!libraw_internal_data.output_data.histogram)
    {
      libraw_internal_data.output_data.histogram =
          (int(*)[LIBRAW_HISTOGRAM_SIZE])malloc(
              sizeof(*libraw_internal_data.output_data.histogram) * 4);
      merror(libraw_internal_data.output_data.histogram,
             "LibRaw::dcraw_process()");
    }
#ifndef NO_LCMS
    if (O.camera_profile)
    {
      apply_profile(O.camera_profile, O.output_profile);
      SET_PROC_FLAG(LIBRAW_PROGRESS_APPLY_PROFILE);
    }
#endif

    if (callbacks.pre_converttorgb_cb)
      (callbacks.pre_converttorgb_cb)(this);

    convert_to_rgb();
    SET_PROC_FLAG(LIBRAW_PROGRESS_CONVERT_RGB);

    if (callbacks.post_converttorgb_cb)
      (callbacks.post_converttorgb_cb)(this);

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

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

Project: LibRaw

void LibRaw::vc5_dng_load_raw_placeholder()
{
    // placeholder only, real decoding implemented in GPR SDK
    throw LIBRAW_EXCEPTION_DECODE_RAW;
}

Project: LibRaw

void LibRaw::eight_bit_load_raw()
{
  uchar *pixel;
  unsigned row, col;

  pixel = (uchar *)calloc(raw_width, sizeof *pixel);
  merror(pixel, "eight_bit_load_raw()");
  try
  {
    for (row = 0; row < raw_height; row++)
    {
      checkCancel();
      if (fread(pixel, 1, raw_width, ifp) < raw_width)
        derror();
      for (col = 0; col < raw_width; col++)
        RAW(row, col) = curve[pixel[col]];
    }
  }
  catch (...)
  {
    free(pixel);
    throw;
  }
  free(pixel);
  maximum = curve[0xff];
}

Project: LibRaw

void LibRaw::kodak_c330_load_raw()
{
  if (!image)
    throw LIBRAW_EXCEPTION_IO_CORRUPT;
  uchar *pixel;
  int row, col, y, cb, cr, rgb[3], c;

  pixel = (uchar *)calloc(raw_width, 2 * sizeof *pixel);
  merror(pixel, "kodak_c330_load_raw()");
  try
  {
    for (row = 0; row < height; row++)
    {
      checkCancel();
      if (fread(pixel, raw_width, 2, ifp) < 2)
        derror();
      if (load_flags && (row & 31) == 31)
        fseek(ifp, raw_width * 32, SEEK_CUR);
      for (col = 0; col < width; col++)
      {
        y = pixel[col * 2];
        cb = pixel[(col * 2 & -4) | 1] - 128;
        cr = pixel[(col * 2 & -4) | 3] - 128;
        rgb[1] = y - ((cb + cr + 2) >> 2);
        rgb[2] = rgb[1] + cb;
        rgb[0] = rgb[1] + cr;
        FORC3 image[row * width + col][c] = curve[LIM(rgb[c], 0, 255)];
      }
    }
  }
  catch (...)
  {
    free(pixel);
    throw;
  }
  free(pixel);
  maximum = curve[0xff];
}

Project: LibRaw

  DllDef int libraw_get_raw_width(libraw_data_t *lr)
  {
    if (!lr)
      return EINVAL;
    return lr->sizes.raw_width;
  }

Project: LibRaw

int LibRaw::nikon_e2100()
{
  uchar t[12];
  int i;

  fseek(ifp, 0, SEEK_SET);
  for (i = 0; i < 1024; i++)
  {
    fread(t, 1, 12, ifp);
    if (((t[2] & t[4] & t[7] & t[9]) >> 4 & t[1] & t[6] & t[8] & t[11] & 3) !=
        3)
      return 0;
  }
  return 1;
}

Project: LibRaw

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

Project: LibRaw

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

Project: LibRaw

int LibRaw::nikon_e995()
{
  int i, histo[256];
  const uchar often[] = {0x00, 0x55, 0xaa, 0xff};

  memset(histo, 0, sizeof histo);
  fseek(ifp, -2000, SEEK_END);
  for (i = 0; i < 2000; i++)
    histo[fgetc(ifp)]++;
  for (i = 0; i < 4; i++)
    if (histo[often[i]] < 200)
      return 0;
  return 1;
}

Project: LibRaw

  static inline float T(void) throw() { return 1.4f; }

Project: LibRaw

void LibRaw::x3f_load_raw()
{
  // already in try/catch
  int raise_error = 0;
  x3f_t *x3f = (x3f_t *)_x3f_data;
  if (!x3f)
    return; // No data pointer set
  if (X3F_OK == x3f_load_data(x3f, x3f_get_raw(x3f)))
  {
    x3f_directory_entry_t *DE = x3f_get_raw(x3f);
    x3f_directory_entry_header_t *DEH = &DE->header;
    x3f_image_data_t *ID = &DEH->data_subsection.image_data;
    if (!ID)
      throw LIBRAW_EXCEPTION_IO_CORRUPT;
    x3f_quattro_t *Q = ID->quattro;
    x3f_huffman_t *HUF = ID->huffman;
    x3f_true_t *TRU = ID->tru;
    uint16_t *data = NULL;
    if (ID->rows != S.raw_height || ID->columns != S.raw_width)
    {
      raise_error = 1;
      goto end;
    }
    if (HUF != NULL)
      data = HUF->x3rgb16.data;
    if (TRU != NULL)
      data = TRU->x3rgb16.data;
    if (data == NULL)
    {
      raise_error = 1;
      goto end;
    }

    size_t datasize = S.raw_height * S.raw_width * 3 * sizeof(unsigned short);
    S.raw_pitch = S.raw_width * 3 * sizeof(unsigned short);
    if (!(imgdata.rawdata.raw_alloc = malloc(datasize)))
      throw LIBRAW_EXCEPTION_ALLOC;

    imgdata.rawdata.color3_image = (ushort(*)[3])imgdata.rawdata.raw_alloc;
    // swap R/B channels for known old cameras
    if (!strcasecmp(P1.make, "Polaroid") && !strcasecmp(P1.model, "x530"))
    {
      ushort(*src)[3] = (ushort(*)[3])data;
      for (int p = 0; p < S.raw_height * S.raw_width; p++)
      {
        imgdata.rawdata.color3_image[p][0] = src[p][2];
        imgdata.rawdata.color3_image[p][1] = src[p][1];
        imgdata.rawdata.color3_image[p][2] = src[p][0];
      }
    }
    else if (HUF)
      memmove(imgdata.rawdata.raw_alloc, data, datasize);
    else if (TRU && (!Q || !Q->quattro_layout))
      memmove(imgdata.rawdata.raw_alloc, data, datasize);
    else if (TRU && Q)
    {
      // Move quattro data in place
      // R/B plane
      for (int prow = 0; prow < TRU->x3rgb16.rows && prow < S.raw_height / 2;
           prow++)
      {
        ushort(*destrow)[3] =
            (unsigned short(*)[3]) &
            imgdata.rawdata
                .color3_image[prow * 2 * S.raw_pitch / 3 / sizeof(ushort)][0];
        ushort(*srcrow)[3] =
            (unsigned short(*)[3]) & data[prow * TRU->x3rgb16.row_stride];
        for (int pcol = 0;
             pcol < TRU->x3rgb16.columns && pcol < S.raw_width / 2; pcol++)
        {
          destrow[pcol * 2][0] = srcrow[pcol][0];
          destrow[pcol * 2][1] = srcrow[pcol][1];
        }
      }
      for (int row = 0; row < Q->top16.rows && row < S.raw_height; row++)
      {
        ushort(*destrow)[3] =
            (unsigned short(*)[3]) &
            imgdata.rawdata
                .color3_image[row * S.raw_pitch / 3 / sizeof(ushort)][0];
        ushort(*srcrow) =
            (unsigned short *)&Q->top16.data[row * Q->top16.columns];
        for (int col = 0; col < Q->top16.columns && col < S.raw_width; col++)
          destrow[col][2] = srcrow[col];
      }
    }

#if 1
    if (TRU && Q &&
        (imgdata.params.raw_processing_options &
         LIBRAW_PROCESSING_DP2Q_INTERPOLATEAF))
    {
      if (imgdata.sizes.raw_width == 5888 &&
          imgdata.sizes.raw_height == 3672) // dpN Quattro normal
      {
        x3f_dpq_interpolate_af(32, 8, 2);
      }
      else if (imgdata.sizes.raw_width == 5888 &&
               imgdata.sizes.raw_height == 3776) // sd Quattro normal raw
      {
        x3f_dpq_interpolate_af_sd(216, 464, imgdata.sizes.raw_width - 1, 3312,
                                  16, 32, 2);
      }
      else if (imgdata.sizes.raw_width == 6656 &&
               imgdata.sizes.raw_height == 4480) // sd Quattro H normal raw
      {
        x3f_dpq_interpolate_af_sd(232, 592, imgdata.sizes.raw_width - 1, 3920,
                                  16, 32, 2);
      }
      else if (imgdata.sizes.raw_width == 3328 &&
               imgdata.sizes.raw_height == 2240) // sd Quattro H half size
      {
        x3f_dpq_interpolate_af_sd(116, 296, imgdata.sizes.raw_width - 1, 2200,
                                  8, 16, 1);
      }
      else if (imgdata.sizes.raw_width == 5504 &&
               imgdata.sizes.raw_height == 3680) // sd Quattro H APS-C raw
      {
        x3f_dpq_interpolate_af_sd(8, 192, imgdata.sizes.raw_width - 1, 3185, 16,
                                  32, 2);
      }
      else if (imgdata.sizes.raw_width == 2752 &&
               imgdata.sizes.raw_height == 1840) // sd Quattro H APS-C half size
      {
        x3f_dpq_interpolate_af_sd(4, 96, imgdata.sizes.raw_width - 1, 1800, 8,
                                  16, 1);
      }
      else if (imgdata.sizes.raw_width == 2944 &&
               imgdata.sizes.raw_height == 1836) // dpN Quattro small raw
      {
        x3f_dpq_interpolate_af(16, 4, 1);
      }
      else if (imgdata.sizes.raw_width == 2944 &&
               imgdata.sizes.raw_height == 1888) // sd Quattro small
      {
        x3f_dpq_interpolate_af_sd(108, 232, imgdata.sizes.raw_width - 1, 1656,
                                  8, 16, 1);
      }
    }
#endif
    if (TRU && Q && Q->quattro_layout &&
        (imgdata.params.raw_processing_options &
         LIBRAW_PROCESSING_DP2Q_INTERPOLATERG))
      x3f_dpq_interpolate_rg();
  }
  else
    raise_error = 1;
end:
  if (raise_error)
    throw LIBRAW_EXCEPTION_IO_CORRUPT;
}

Project: LibRaw

void LibRaw::kodak_c603_load_raw()
{
  if (!image)
    throw LIBRAW_EXCEPTION_IO_CORRUPT;
  uchar *pixel;
  int row, col, y, cb, cr, rgb[3], c;

  pixel = (uchar *)calloc(raw_width, 3 * sizeof *pixel);
  merror(pixel, "kodak_c603_load_raw()");
  try
  {
    for (row = 0; row < height; row++)
    {
      checkCancel();
      if (~row & 1)
        if (fread(pixel, raw_width, 3, ifp) < 3)
          derror();
      for (col = 0; col < width; col++)
      {
        y = pixel[width * 2 * (row & 1) + col];
        cb = pixel[width + (col & -2)] - 128;
        cr = pixel[width + (col & -2) + 1] - 128;
        rgb[1] = y - ((cb + cr + 2) >> 2);
        rgb[2] = rgb[1] + cb;
        rgb[0] = rgb[1] + cr;
        FORC3 image[row * width + col][c] = curve[LIM(rgb[c], 0, 255)];
      }
    }
  }
  catch (...)
  {
    free(pixel);
    throw;
  }
  free(pixel);
  maximum = curve[0xff];
}

Project: LibRaw

void LibRaw::dcb_map()
{
  int current, row, col, c, u = width, v = 2 * u, indx;

  for (row = 1; row < height - 1; row++)
  {
    for (col = 1, indx = row * width + col; col < width - 1; col++, indx++)
    {

      if (image[indx][1] > (image[indx - 1][1] + image[indx + 1][1] +
                            image[indx - u][1] + image[indx + u][1]) /
                               4.0)
        image[indx][3] = ((MIN(image[indx - 1][1], image[indx + 1][1]) +
                           image[indx - 1][1] + image[indx + 1][1]) <
                          (MIN(image[indx - u][1], image[indx + u][1]) +
                           image[indx - u][1] + image[indx + u][1]));
      else
        image[indx][3] = ((MAX(image[indx - 1][1], image[indx + 1][1]) +
                           image[indx - 1][1] + image[indx + 1][1]) >
                          (MAX(image[indx - u][1], image[indx + u][1]) +
                           image[indx - u][1] + image[indx + u][1]));
    }
  }
}

Project: LibRaw

unsigned subtract_bl(unsigned int val, int bl)
{
	return val > bl ? val - bl : 0;
}

Project: LibRaw

static inline int bitDiff(int value1, int value2)
{
  int decBits = 0;
  if (value2 < value1)
    while (decBits <= 14 && (value2 << ++decBits) < value1)
      ;
  return decBits;
}

Project: LibRaw

void print_szfun(FILE* outfile, LibRaw& MyCoolRawProcessor, std::string& fn)
{
	id2hr_t *Aspect;
	fprintf(outfile, "%s\t%s\t%s\t%d\t%d\n", fn.c_str(), P1.make, P1.model, S.width,
		S.height);
	/*
	fprintf(outfile, "\n%s\t%s\t%s\n", filelist[i].c_str(), P1.make, P1.model);
	fprintf(outfile, "\tCoffin:\traw %dx%d mrg %d %d img %dx%d\n", S.raw_width,
	S.raw_height, S.left_margin, S.top_margin, S.width, S.height); printf
	("\tmnote: \t"); if (Canon.SensorWidth) printf ("sensor %dx%d ",
	Canon.SensorWidth, Canon.SensorHeight); if (Nikon.SensorWidth) printf
	("sensor %dx%d ", Nikon.SensorWidth, Nikon.SensorHeight);
	fprintf(outfile, "inset: start %d %d img %dx%d aspect calc: %f Aspect in file:
	", S.raw_inset_crop.cleft, S.raw_inset_crop.ctop,
	S.raw_inset_crop.cwidth, S.raw_inset_crop.cheight,
	((float)S.raw_inset_crop.cwidth /
	(float)S.raw_inset_crop.cheight)); Aspect =
	lookup_id2hr(S.raw_inset_crop.aspect, AspectRatios, nAspectRatios); if
	(Aspect) printf ("%s\n", Aspect->name); else printf ("Other %d\n",
	S.raw_inset_crop.aspect);

	if (Nikon.SensorHighSpeedCrop.cwidth) {
	fprintf(outfile, "\tHighSpeed crop from: %d x %d at top left pixel: (%d,
	%d)\n", Nikon.SensorHighSpeedCrop.cwidth,
	Nikon.SensorHighSpeedCrop.cheight, Nikon.SensorHighSpeedCrop.cleft,
	Nikon.SensorHighSpeedCrop.ctop);
	}
	*/
}

Project: LibRaw

int main(int ac, char *av[])
{
  int i, ret;
  int verbose = 1, autoscale = 0, use_gamma = 0, out_tiff = 0;
  char outfn[1024];

  LibRaw RawProcessor;
  if (ac < 2)
  {
  usage:
    printf("unprocessed_raw - LibRaw %s sample. %d cameras supported\n"
           "Usage: %s [-q] [-A] [-g] [-s N] raw-files....\n"
           "\t-q - be quiet\n"
           "\t-s N - select Nth image in file (default=0)\n"
           "\t-g - use gamma correction with gamma 2.2 (not precise,use for "
           "visual inspection only)\n"
           "\t-A - autoscaling (by integer factor)\n"
           "\t-T - write tiff instead of pgm\n",
           LibRaw::version(), LibRaw::cameraCount(), av[0]);
    return 0;
  }

#define S RawProcessor.imgdata.sizes
#define OUT RawProcessor.imgdata.params

  for (i = 1; i < ac; i++)
  {
    if (av[i][0] == '-')
    {
      if (av[i][1] == 'q' && av[i][2] == 0)
        verbose = 0;
      else if (av[i][1] == 'A' && av[i][2] == 0)
        autoscale = 1;
      else if (av[i][1] == 'g' && av[i][2] == 0)
        use_gamma = 1;
      else if (av[i][1] == 'T' && av[i][2] == 0)
        out_tiff = 1;
      else if (av[i][1] == 's' && av[i][2] == 0)
      {
        i++;
        OUT.shot_select = av[i] ? atoi(av[i]) : 0;
      }
      else
        goto usage;
      continue;
    }

    if (verbose)
      printf("Processing file %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 (verbose)
    {
      printf("Image size: %dx%d\nRaw size: %dx%d\n", S.width, S.height,
             S.raw_width, S.raw_height);
      printf("Margins: top=%d, left=%d\n", S.top_margin, S.left_margin);
    }

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

    if (verbose)
      printf("Unpacked....\n");

    if (!(RawProcessor.imgdata.idata.filters ||
          RawProcessor.imgdata.idata.colors == 1))
    {
      printf("Only Bayer-pattern RAW files supported, sorry....\n");
      continue;
    }

    if (autoscale)
    {
      unsigned max = 0, scale;
      for (int j = 0; j < S.raw_height * S.raw_width; j++)
        if (max < RawProcessor.imgdata.rawdata.raw_image[j])
          max = RawProcessor.imgdata.rawdata.raw_image[j];
      if (max > 0 && max < 1 << 15)
      {
        scale = (1 << 16) / max;
        if (verbose)
          printf("Scaling with multiplier=%d (max=%d)\n", scale, max);

        for (int j = 0; j < S.raw_height * S.raw_width; j++)
          RawProcessor.imgdata.rawdata.raw_image[j] *= scale;
      }
    }
    if (use_gamma)
    {
      unsigned short curve[0x10000];
      gamma_curve(curve);
      for (int j = 0; j < S.raw_height * S.raw_width; j++)
        RawProcessor.imgdata.rawdata.raw_image[j] =
            curve[RawProcessor.imgdata.rawdata.raw_image[j]];
      if (verbose)
        printf("Gamma-corrected....\n");
    }

    if (OUT.shot_select)
      snprintf(outfn, sizeof(outfn), "%s-%d.%s", av[i], OUT.shot_select,
               out_tiff ? "tiff" : "pgm");
    else
      snprintf(outfn, sizeof(outfn), "%s.%s", av[i], out_tiff ? "tiff" : "pgm");

    if (out_tiff)
      write_tiff(S.raw_width, S.raw_height,
                 RawProcessor.imgdata.rawdata.raw_image, outfn);
    else
      write_ppm(S.raw_width, S.raw_height,
                RawProcessor.imgdata.rawdata.raw_image, outfn);

    if (verbose)
      printf("Stored to file %s\n", outfn);
  }
  return 0;
}