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

int LibRaw::raw2image_ex(int do_subtract_black)
{

  CHECK_ORDER_LOW(LIBRAW_PROGRESS_LOAD_RAW);

  try
  {
    raw2image_start();

    // Compressed P1 files with bl data!
    if (is_phaseone_compressed() && imgdata.rawdata.raw_alloc)
    {
      phase_one_allocate_tempbuffer();
      int rc = phase_one_subtract_black((ushort *)imgdata.rawdata.raw_alloc,
                                        imgdata.rawdata.raw_image);
      if (rc == 0)
        rc = phase_one_correct();
      if (rc != 0)
      {
        phase_one_free_tempbuffer();
        return rc;
      }
    }

    // process cropping
    int do_crop = 0;
    unsigned save_width = S.width;
    if (~O.cropbox[2] && ~O.cropbox[3])
    {
      int crop[4], c, filt;
      for (int c = 0; c < 4; c++)
      {
        crop[c] = O.cropbox[c];
        if (crop[c] < 0)
          crop[c] = 0;
      }

      if (IO.fuji_width && imgdata.idata.filters >= 1000)
      {
        crop[0] = (crop[0] / 4) * 4;
        crop[1] = (crop[1] / 4) * 4;
        if (!libraw_internal_data.unpacker_data.fuji_layout)
        {
          crop[2] *= sqrt(2.0);
          crop[3] /= sqrt(2.0);
        }
        crop[2] = (crop[2] / 4 + 1) * 4;
        crop[3] = (crop[3] / 4 + 1) * 4;
      }
      else if (imgdata.idata.filters == 1)
      {
        crop[0] = (crop[0] / 16) * 16;
        crop[1] = (crop[1] / 16) * 16;
      }
      else if (imgdata.idata.filters == LIBRAW_XTRANS)
      {
        crop[0] = (crop[0] / 6) * 6;
        crop[1] = (crop[1] / 6) * 6;
      }
      do_crop = 1;

      crop[2] = MIN(crop[2], (signed)S.width - crop[0]);
      crop[3] = MIN(crop[3], (signed)S.height - crop[1]);
      if (crop[2] <= 0 || crop[3] <= 0)
        throw LIBRAW_EXCEPTION_BAD_CROP;

      // adjust sizes!
      S.left_margin += crop[0];
      S.top_margin += crop[1];
      S.width = crop[2];
      S.height = crop[3];

      S.iheight = (S.height + IO.shrink) >> IO.shrink;
      S.iwidth = (S.width + IO.shrink) >> IO.shrink;
      if (!IO.fuji_width && imgdata.idata.filters &&
          imgdata.idata.filters >= 1000)
      {
        for (filt = c = 0; c < 16; c++)
          filt |= FC((c >> 1) + (crop[1]), (c & 1) + (crop[0])) << c * 2;
        imgdata.idata.filters = filt;
      }
    }

    int alloc_width = S.iwidth;
    int alloc_height = S.iheight;

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

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

    libraw_decoder_info_t decoder_info;
    get_decoder_info(&decoder_info);

    // Adjust black levels
    unsigned short cblack[4] = {0, 0, 0, 0};
    unsigned short dmax = 0;
    if (do_subtract_black)
    {
      adjust_bl();
      for (int i = 0; i < 4; i++)
        cblack[i] = (unsigned short)C.cblack[i];
    }

    // Move saved bitmap to imgdata.image
    if ((imgdata.idata.filters || P1.colors == 1) && imgdata.rawdata.raw_image)
    {
      if (IO.fuji_width)
      {
        if (do_crop)
        {
          IO.fuji_width =
              S.width >> !libraw_internal_data.unpacker_data.fuji_layout;
          int IO_fwidth =
              (S.height >> libraw_internal_data.unpacker_data.fuji_layout) +
              IO.fuji_width;
          int IO_fheight = IO_fwidth - 1;

          int row, col;
          for (row = 0; row < S.height; row++)
          {
            for (col = 0; col < S.width; col++)
            {
              int r, c;
              if (libraw_internal_data.unpacker_data.fuji_layout)
              {
                r = IO.fuji_width - 1 - col + (row >> 1);
                c = col + ((row + 1) >> 1);
              }
              else
              {
                r = IO.fuji_width - 1 + row - (col >> 1);
                c = row + ((col + 1) >> 1);
              }

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

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

    if (do_subtract_black)
    {
      C.data_maximum = (int)dmax;
      C.maximum -= C.black;
      //        ZERO(C.cblack);
      C.cblack[0] = C.cblack[1] = C.cblack[2] = C.cblack[3] = 0;
      C.black = 0;
    }

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

Project: LibRaw

void print_timer(FILE* outfile, const starttime_t& started, int files)
{
	double elapsed = timer_elapsed(started);
	if (elapsed > 1.0)
		fprintf(outfile, "%d files processed in %5.3f sec, %5.3g files/sec\n", files, elapsed, files / elapsed);
	else if (elapsed > 0.001) // 1msec
	{
		double msec = elapsed * 1000.0;
		fprintf(outfile, "%d files processed in %5.3f msec, %5.3g files/sec\n", files, msec, files / elapsed);
	}
	else if (elapsed > 0.000001)
	{
		double usec = elapsed * 1000000.0;
		fprintf(outfile, "%d files processed in %5.3f usec, %5.3g files/sec\n", files, usec, files / elapsed);
	}
	else
		fprintf(outfile, "%d files processed, time too small to estimate\n", files);
}

Project: LibRaw

  virtual const char *fname() { return NULL; };

Project: LibRaw

  void set_memerror_handler(memory_callback cb, void *data)
  {
    callbacks.memcb_data = data;
    callbacks.mem_cb = cb;
  }

Project: LibRaw
File: sony.cpp

void LibRaw::parseSonyLensFeatures(uchar a, uchar b)
{

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

  if ((ilm.LensMount == LIBRAW_MOUNT_Canon_EF) ||
      (ilm.LensMount != LIBRAW_MOUNT_Sigma_X3F) || !features)
    return;

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

  if (!ilm.LensFormat && !ilm.LensMount)
  {
    ilm.LensFormat = LIBRAW_FORMAT_FF;
    ilm.LensMount = LIBRAW_MOUNT_Minolta_A;

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

  if (features & 0x4000)
    strnXcat(ilm.LensFeatures_pre, " PZ");

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

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

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

  if (features & 0x8000)
    strnXcat(ilm.LensFeatures_suf, " OSS");

  if (features & 0x2000)
    strnXcat(ilm.LensFeatures_suf, " LE");

  if (features & 0x0800)
    strnXcat(ilm.LensFeatures_suf, " II");

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

  return;
}

Project: LibRaw

  void set_dataerror_handler(data_callback func, void *data)
  {
    callbacks.datacb_data = data;
    callbacks.data_cb = func;
  }

Project: LibRaw

void LibRaw::dcb_copy_to_buffer(float (*image2)[3])
{
  int indx;

  for (indx = 0; indx < height * width; indx++)
  {
    image2[indx][0] = image[indx][0]; // R
    image2[indx][2] = image[indx][2]; // B
  }
}

Project: LibRaw

void DHT::make_rbhv(int i)
{
  int iwidth = libraw.imgdata.sizes.iwidth;
  int js = (libraw.COLOR(i, 0) & 1) ^ 1;
  for (int j = js; j < iwidth; j += 2)
  {
    int x = j + nr_leftmargin;
    int y = i + nr_topmargin;
    /*
     * поскольку сверху-снизу и справа-слева уже есть все необходимые красные и
     * синие, то можно выбрать наилучшее направление исходя из информации по
     * обоим цветам.
     */
    int dx, dy, dx2, dy2;
    float h1, h2;
    if (ndir[nr_offset(y, x)] & VER)
    {
      dx = dx2 = 0;
      dy = -1;
      dy2 = 1;
    }
    else
    {
      dy = dy2 = 0;
      dx = 1;
      dx2 = -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;
    g2 *= g2;
    float eg_r, eg_b;
    eg_r = nraw[nr_offset(y, x)][1] *
           (g1 * nraw[nr_offset(y + dy, x + dx)][0] /
                nraw[nr_offset(y + dy, x + dx)][1] +
            g2 * nraw[nr_offset(y + dy2, x + dx2)][0] /
                nraw[nr_offset(y + dy2, x + dx2)][1]) /
           (g1 + g2);
    eg_b = nraw[nr_offset(y, x)][1] *
           (g1 * nraw[nr_offset(y + dy, x + dx)][2] /
                nraw[nr_offset(y + dy, x + dx)][1] +
            g2 * nraw[nr_offset(y + dy2, x + dx2)][2] /
                nraw[nr_offset(y + dy2, x + dx2)][1]) /
           (g1 + g2);
    float min_r, max_r;
    min_r = MIN(nraw[nr_offset(y + dy, x + dx)][0],
                nraw[nr_offset(y + dy2, x + dx2)][0]);
    max_r = MAX(nraw[nr_offset(y + dy, x + dx)][0],
                nraw[nr_offset(y + dy2, x + dx2)][0]);
    float min_b, max_b;
    min_b = MIN(nraw[nr_offset(y + dy, x + dx)][2],
                nraw[nr_offset(y + dy2, x + dx2)][2]);
    max_b = MAX(nraw[nr_offset(y + dy, x + dx)][2],
                nraw[nr_offset(y + dy2, x + dx2)][2]);
    min_r /= 1.2;
    max_r *= 1.2;
    min_b /= 1.2;
    max_b *= 1.2;

    if (eg_r < min_r)
      eg_r = scale_under(eg_r, min_r);
    else if (eg_r > max_r)
      eg_r = scale_over(eg_r, max_r);
    if (eg_b < min_b)
      eg_b = scale_under(eg_b, min_b);
    else if (eg_b > max_b)
      eg_b = scale_over(eg_b, max_b);

    if (eg_r > channel_maximum[0])
      eg_r = channel_maximum[0];
    else if (eg_r < channel_minimum[0])
      eg_r = channel_minimum[0];
    if (eg_b > channel_maximum[2])
      eg_b = channel_maximum[2];
    else if (eg_b < channel_minimum[2])
      eg_b = channel_minimum[2];
    nraw[nr_offset(y, x)][0] = eg_r;
    nraw[nr_offset(y, x)][2] = eg_b;
  }
}

Project: LibRaw

size_t LibRaw::strnlen(const char *s, size_t n)
{
#if !defined(__FreeBSD__) && !defined(__OpenBSD__)
  const char *p = (const char *)memchr(s, 0, n);
  return (p ? p - s : n);
#else
  return ::strnlen(s, n);
#endif
}

Project: LibRaw

void LibRaw::ppm16_thumb()
{
  int i;
  char *thumb;
  thumb_length = thumb_width * thumb_height * 3;
  thumb = (char *)calloc(thumb_length, 2);
  merror(thumb, "ppm16_thumb()");
  read_shorts((ushort *)thumb, thumb_length);
  for (i = 0; i < thumb_length; i++)
    thumb[i] = ((ushort *)thumb)[i] >> 8;
  fprintf(ofp, "P6\n%d %d\n255\n", thumb_width, thumb_height);
  fwrite(thumb, 1, thumb_length, ofp);
  free(thumb);
}

Project: LibRaw

ushort LibRaw::sget2(uchar *s)
{
  if (order == 0x4949) /* "II" means little-endian */
    return s[0] | s[1] << 8;
  else /* "MM" means big-endian */
    return s[0] << 8 | s[1];
}

Project: LibRaw

void LibRaw::parse_smal(int offset, int fsize)
{
  int ver;

  fseek(ifp, offset + 2, SEEK_SET);
  order = 0x4949;
  ver = fgetc(ifp);
  if (ver == 6)
    fseek(ifp, 5, SEEK_CUR);
  if (get4() != fsize)
    return;
  if (ver > 6)
    data_offset = get4();
  raw_height = height = get2();
  raw_width = width = get2();
  strcpy(make, "SMaL");
  sprintf(model, "v%d %dx%d", ver, width, height);
  if (ver == 6)
    load_raw = &LibRaw::smal_v6_load_raw;
  if (ver == 9)
    load_raw = &LibRaw::smal_v9_load_raw;
}

Project: LibRaw

int LibRaw::parseCR3(unsigned long long oAtomList,
                     unsigned long long szAtomList, short &nesting,
                     char *AtomNameStack, short &nTrack, short &TrackType)
{
  /*
  Atom starts with 4 bytes for Atom size and 4 bytes containing Atom name
  Atom size includes the length of the header and the size of all "contained"
  Atoms if Atom size == 1, Atom has the extended size stored in 8 bytes located
  after the Atom name if Atom size == 0, it is the last top-level Atom extending
  to the end of the file Atom name is often a 4 symbol mnemonic, but can be a
  4-byte integer
  */
  const char UIID_Canon[17] =
      "\x85\xc0\xb6\x87\x82\x0f\x11\xe0\x81\x11\xf4\xce\x46\x2b\x6a\x48";
  const char UIID_Preview[17] =
      "\xea\xf4\x2b\x5e\x1c\x98\x4b\x88\xb9\xfb\xb7\xdc\x40\x6e\x4d\x16";

  /*
  AtomType = 0 - unknown: "unk."
  AtomType = 1 - container atom: "cont"
  AtomType = 2 - leaf atom: "leaf"
  AtomType = 3 - can be container, can be leaf: "both"
  */
  const char sAtomeType[4][5] = {"unk.", "cont", "leaf", "both"};
  short AtomType;
  static const struct
  {
    char AtomName[5];
    short AtomType;
  } AtomNamesList[] = {
      {"dinf", 1},
      {"edts", 1},
      {"fiin", 1},
      {"ipro", 1},
      {"iprp", 1},
      {"mdia", 1},
      {"meco", 1},
      {"mere", 1},
      {"mfra", 1},
      {"minf", 1},
      {"moof", 1},
      {"moov", 1},
      {"mvex", 1},
      {"paen", 1},
      {"schi", 1},
      {"sinf", 1},
      {"skip", 1},
      {"stbl", 1},
      {"stsd", 1},
      {"strk", 1},
      {"tapt", 1},
      {"traf", 1},
      {"trak", 1},

      {"cdsc", 2},
      {"colr", 2},
      {"dimg", 2},
      // {"dref", 2},
      {"free", 2},
      {"frma", 2},
      {"ftyp", 2},
      {"hdlr", 2},
      {"hvcC", 2},
      {"iinf", 2},
      {"iloc", 2},
      {"infe", 2},
      {"ipco", 2},
      {"ipma", 2},
      {"iref", 2},
      {"irot", 2},
      {"ispe", 2},
      {"meta", 2},
      {"mvhd", 2},
      {"pitm", 2},
      {"pixi", 2},
      {"schm", 2},
      {"thmb", 2},
      {"tkhd", 2},
      {"url ", 2},
      {"urn ", 2},

      {"CCTP", 1},
      {"CRAW", 1},

      {"JPEG", 2},
      {"CDI1", 2},
      {"CMP1", 2},

      {"CNCV", 2},
      {"CCDT", 2},
      {"CTBO", 2},
      {"CMT1", 2},
      {"CMT2", 2},
      {"CMT3", 2},
      {"CMT4", 2},
      {"THMB", 2},
      {"co64", 2},
      {"mdat", 2},
      {"mdhd", 2},
      {"nmhd", 2},
      {"stsc", 2},
      {"stsz", 2},
      {"stts", 2},
      {"vmhd", 2},

      {"dref", 3},
      {"uuid", 3},
  };

  const char sHandlerType[5][5] = {"unk.", "soun", "vide", "hint", "meta"};

  int c, err;

  ushort tL;                        // Atom length represented in 4 or 8 bytes
  char nmAtom[5];                   // Atom name
  unsigned long long oAtom, szAtom; // Atom offset and Atom size
  unsigned long long oAtomContent,
      szAtomContent; // offset and size of Atom content
  unsigned long long lHdr;

  char UIID[16];
  uchar CMP1[36];
  char HandlerType[5], MediaFormatID[5];
  unsigned ImageWidth, ImageHeight;
  long relpos_inDir, relpos_inBox;
  unsigned szItem, Tag, lTag;
  ushort tItem;

  nmAtom[0] = MediaFormatID[0] = nmAtom[4] = MediaFormatID[4] = '\0';
  strcpy(HandlerType, sHandlerType[0]);
  ImageWidth = ImageHeight = 0U;
  oAtom = oAtomList;
  nesting++;
  if (nesting > 31)
    return -14; // too deep nesting
  short s_order = order;

  while ((oAtom + 8ULL) <= (oAtomList + szAtomList))
  {
    lHdr = 0ULL;
    err = 0;
    order = 0x4d4d;
    fseek(ifp, oAtom, SEEK_SET);
    szAtom = get4();
    FORC4 nmAtom[c] = AtomNameStack[nesting * 4 + c] = fgetc(ifp);
    AtomNameStack[(nesting + 1) * 4] = '\0';
    tL = 4;
    AtomType = 0;

    for (c = 0; c < sizeof AtomNamesList / sizeof *AtomNamesList; c++)
      if (!strcmp(nmAtom, AtomNamesList[c].AtomName))
      {
        AtomType = AtomNamesList[c].AtomType;
        break;
      }

    if (!AtomType)
    {
      err = 1;
    }

    if (szAtom == 0ULL)
    {
      if (nesting != 0)
      {
        err = -2;
        goto fin;
      }
      szAtom = szAtomList - oAtom;
      oAtomContent = oAtom + 8ULL;
      szAtomContent = szAtom - 8ULL;
    }
    else if (szAtom == 1ULL)
    {
      if ((oAtom + 16ULL) > (oAtomList + szAtomList))
      {
        err = -3;
        goto fin;
      }
      tL = 8;
      szAtom = (((unsigned long long)get4()) << 32) | get4();
      oAtomContent = oAtom + 16ULL;
      szAtomContent = szAtom - 16ULL;
    }
    else
    {
      oAtomContent = oAtom + 8ULL;
      szAtomContent = szAtom - 8ULL;
    }

    if (!strcmp(nmAtom, "trak"))
    {
      nTrack++;
      TrackType = 0;
      if (nTrack >= LIBRAW_CRXTRACKS_MAXCOUNT)
        break;
    }
    if (!strcmp(AtomNameStack, "moovuuid"))
    {
      lHdr = 16ULL;
      fread(UIID, 1, lHdr, ifp);
      if (!strncmp(UIID, UIID_Canon, lHdr))
      {
        AtomType = 1;
      }
      else
        fseek(ifp, -lHdr, SEEK_CUR);
    }
    else if (!strcmp(AtomNameStack, "moovuuidCCTP"))
    {
      lHdr = 12ULL;
    }
    else if (!strcmp(AtomNameStack, "moovuuidCMT1"))
    {
      short q_order = order;
      order = get2();
      if ((tL != 4) || bad_hdr)
      {
        err = -4;
        goto fin;
      }
      parse_tiff_ifd(oAtomContent);
      order = q_order;
    }
    else if (!strcmp(AtomNameStack, "moovuuidCMT2"))
    {
      short q_order = order;
      order = get2();
      if ((tL != 4) || bad_hdr)
      {
        err = -5;
        goto fin;
      }
      parse_exif(oAtomContent);
      order = q_order;
    }
    else if (!strcmp(AtomNameStack, "moovuuidCMT3"))
    {
      short q_order = order;
      order = get2();
      if ((tL != 4) || bad_hdr)
      {
        err = -6;
        goto fin;
      }
      fseek(ifp, -12L, SEEK_CUR);
      parse_makernote(oAtomContent, 0);
      order = q_order;
    }
    else if (!strcmp(AtomNameStack, "moovuuidCMT4"))
    {
      short q_order = order;
      order = get2();
      if ((tL != 4) || bad_hdr)
      {
        err = -6;
        goto fin;
      }
      INT64 off = ftell(ifp);
      parse_gps(oAtomContent);
      fseek(ifp, off, SEEK_SET);
      parse_gps_libraw(oAtomContent);
      order = q_order;
    }
    else if (!strcmp(AtomNameStack, "moovtrakmdiahdlr"))
    {
      fseek(ifp, 8L, SEEK_CUR);
      FORC4 HandlerType[c] = fgetc(ifp);
      for (c = 1; c < sizeof sHandlerType / sizeof *sHandlerType; c++)
        if (!strcmp(HandlerType, sHandlerType[c]))
        {
          TrackType = c;
          break;
        }
    }
    else if (!strcmp(AtomNameStack, "moovtrakmdiaminfstblstsd"))
    {
      if (szAtomContent >= 16)
      {
        fseek(ifp, 12L, SEEK_CUR);
        lHdr = 8;
      }
      else
      {
        err = -7;
        goto fin;
      }
      FORC4 MediaFormatID[c] = fgetc(ifp);
      if ((TrackType == 2) && (!strcmp(MediaFormatID, "CRAW")))
      {
        if (szAtomContent >= 44)
          fseek(ifp, 24L, SEEK_CUR);
        else
        {
          err = -8;
          goto fin;
        }
      }
      else
      {
        AtomType = 2; // only continue for CRAW
        lHdr = 0;
      }
#define current_track libraw_internal_data.unpacker_data.crx_header[nTrack]

      ImageWidth = get2();
      ImageHeight = get2();
    }
    else if (!strcmp(AtomNameStack, "moovtrakmdiaminfstblstsdCRAW"))
    {
      lHdr = 82;
    }
    else if (!strcmp(AtomNameStack, "moovtrakmdiaminfstblstsdCRAWCMP1"))
    {
      if (szAtomContent >= 40)
        fread(CMP1, 1, 36, ifp);
      else
      {
        err = -7;
        goto fin;
      }
      if (!crxParseImageHeader(CMP1, nTrack))
        current_track.MediaType = 1;
    }
    else if (!strcmp(AtomNameStack, "moovtrakmdiaminfstblstsdCRAWJPEG"))
    {
      current_track.MediaType = 2;
    }
    else if (!strcmp(AtomNameStack, "moovtrakmdiaminfstblstsz"))
    {
      if (szAtomContent == 12)
        fseek(ifp, 4L, SEEK_CUR);
      else if (szAtomContent == 16)
        fseek(ifp, 12L, SEEK_CUR);
      else
      {
        err = -9;
        goto fin;
      }
      current_track.MediaSize = get4();
    }
    else if (!strcmp(AtomNameStack, "moovtrakmdiaminfstblco64"))
    {
      if (szAtomContent == 16)
        fseek(ifp, 8L, SEEK_CUR);
      else
      {
        err = -10;
        goto fin;
      }
      current_track.MediaOffset = (((unsigned long long)get4()) << 32) | get4();
    }

    if (current_track.MediaSize && current_track.MediaOffset &&
        ((oAtom + szAtom) >= (oAtomList + szAtomList)) &&
        !strncmp(AtomNameStack, "moovtrakmdiaminfstbl", 20))
    {
      if ((TrackType == 4) && (!strcmp(MediaFormatID, "CTMD")))
      {
        order = 0x4949;
        relpos_inDir = 0L;
        while (relpos_inDir + 6 < current_track.MediaSize)
        {
          fseek(ifp, current_track.MediaOffset + relpos_inDir, SEEK_SET);
          szItem = get4();
          tItem = get2();
          if ((relpos_inDir + szItem) > current_track.MediaSize)
          {
            err = -11;
            goto fin;
          }
          if ((tItem == 7) || (tItem == 8) || (tItem == 9))
          {
            relpos_inBox = relpos_inDir + 12L;
            while (relpos_inBox + 8 < relpos_inDir + szItem)
            {
              fseek(ifp, current_track.MediaOffset + relpos_inBox, SEEK_SET);
              lTag = get4();
              Tag = get4();
              if (lTag < 8)
              {
                err = -12;
                goto fin;
              }
              else if ((relpos_inBox + lTag) > (relpos_inDir + szItem))
              {
                err = -11;
                goto fin;
              }
              if ((Tag == 0x927c) && ((tItem == 7) || (tItem == 8)))
              {
                fseek(ifp, current_track.MediaOffset + relpos_inBox + 8L,
                      SEEK_SET);
                short q_order = order;
                order = get2();
                if (bad_hdr)
                {
                  err = -13;
                  goto fin;
                }
                fseek(ifp, -8L, SEEK_CUR);
                libraw_internal_data.unpacker_data.CR3_CTMDtag = 1;
                parse_makernote(current_track.MediaOffset + relpos_inBox + 8,
                                0);
                libraw_internal_data.unpacker_data.CR3_CTMDtag = 0;
                order = q_order;
              }
              relpos_inBox += lTag;
            }
          }
          relpos_inDir += szItem;
        }
        order = 0x4d4d;
      }
    }
#undef current_track
    if (AtomType == 1)
    {
      err = parseCR3(oAtomContent + lHdr, szAtomContent - lHdr, nesting,
                     AtomNameStack, nTrack, TrackType);
      if (err)
        goto fin;
    }
    oAtom += szAtom;
  }

fin:
  nesting--;
  if (nesting >= 0)
    AtomNameStack[nesting * 4] = '\0';
  order = s_order;
  return err;
}

Project: LibRaw

void LibRaw::initdata()
{
  tiff_flip = flip = filters = UINT_MAX; /* unknown */
  raw_height = raw_width = fuji_width = fuji_layout = cr2_slice[0] = 0;
  maximum = height = width = top_margin = left_margin = 0;
  cdesc[0] = desc[0] = artist[0] = make[0] = model[0] = model2[0] = 0;
  iso_speed = shutter = aperture = focal_len = 0;
  unique_id = 0ULL;
  tiff_nifds = 0;
  memset(tiff_ifd, 0, sizeof tiff_ifd);
  for (int i = 0; i < LIBRAW_IFD_MAXCOUNT; i++)
  {
    tiff_ifd[i].dng_color[0].illuminant = tiff_ifd[i].dng_color[1].illuminant =
        0xffff;
    for (int c = 0; c < 4; c++)
      tiff_ifd[i].dng_levels.analogbalance[c] = 1.0f;
  }
  for (int i = 0; i < 0x10000; i++)
    curve[i] = i;
  memset(gpsdata, 0, sizeof gpsdata);
  memset(cblack, 0, sizeof cblack);
  memset(white, 0, sizeof white);
  memset(mask, 0, sizeof mask);
  thumb_offset = thumb_length = thumb_width = thumb_height = 0;
  load_raw = thumb_load_raw = 0;
  write_thumb = &LibRaw::jpeg_thumb;
  data_offset = meta_offset = meta_length = tiff_bps = tiff_compress = 0;
  kodak_cbpp = zero_after_ff = dng_version = load_flags = 0;
  timestamp = shot_order = tiff_samples = black = is_foveon = 0;
  mix_green = profile_length = data_error = zero_is_bad = 0;
  pixel_aspect = is_raw = raw_color = 1;
  tile_width = tile_length = 0;
  metadata_blocks = 0;
  is_NikonTransfer = 0;
  is_Sony = 0;
  is_pana_raw = 0;
  maker_index = LIBRAW_CAMERAMAKER_Unknown;
  is_4K_RAFdata = 0;
  FujiCropMode = 0;
  is_PentaxRicohMakernotes = 0;
  normalized_model[0] = 0;
  normalized_make[0] = 0;
  CM_found = 0;
}

Project: LibRaw

int LibRaw::try_dngsdk()
{
#ifdef USE_DNGSDK
  if (!dnghost)
    return LIBRAW_UNSPECIFIED_ERROR;

  dng_host *host = static_cast<dng_host *>(dnghost);

  try
  {
    libraw_dng_stream stream(libraw_internal_data.internal_data.input);

    AutoPtr<dng_negative> negative;
    negative.Reset(host->Make_dng_negative());

    dng_info info;
    info.Parse(*host, stream);
    info.PostParse(*host);

    if (!info.IsValidDNG())
    {
      return LIBRAW_DATA_ERROR;
    }
    negative->Parse(*host, stream, info);
    negative->PostParse(*host, stream, info);
    dng_ifd *rawIFD = search_for_ifd(info,libraw_internal_data.unpacker_data.data_offset,imgdata.sizes.raw_width,imgdata.sizes.raw_height);
    if(!rawIFD)
        return LIBRAW_DATA_ERROR;

    AutoPtr<dng_simple_image> stage2(new dng_simple_image(rawIFD->Bounds (),rawIFD->fSamplesPerPixel,rawIFD->PixelType (), host->Allocator()));
#ifdef USE_GPRSDK
    if(libraw_internal_data.unpacker_data.tiff_compress == 9)
    {
        gpr_allocator allocator;
        allocator.Alloc = ::malloc;
        allocator.Free = ::free;
        gpr_buffer_auto vc5_image_obj( allocator.Alloc, allocator.Free );

        gpr_read_image reader(&vc5_image_obj);
        reader.Read(*host,*rawIFD,stream,*stage2.Get(),NULL,NULL);
    }
    else
#endif
    {
        dng_read_image reader;
        reader.Read(*host,*rawIFD,stream,*stage2.Get(),NULL,NULL);
    }

    if (stage2->Bounds().W() != S.raw_width ||
        stage2->Bounds().H() != S.raw_height)
    {
      return LIBRAW_DATA_ERROR;
    }

    int pplanes = stage2->Planes();
    int ptype = stage2->PixelType();

    dng_pixel_buffer buffer;
    stage2->GetPixelBuffer(buffer);

    int pixels = stage2->Bounds().H() * stage2->Bounds().W() * pplanes;
    bool zerocopy = false;

    if (ptype == ttShort && !is_curve_linear())
    {
      imgdata.rawdata.raw_alloc = malloc(pixels * TagTypeSize(ptype));
      ushort *src = (ushort *)buffer.fData;
      ushort *dst = (ushort *)imgdata.rawdata.raw_alloc;
      for (int i = 0; i < pixels; i++)
        dst[i] = imgdata.color.curve[src[i]];
      S.raw_pitch = S.raw_width * pplanes * TagTypeSize(ptype);
    }
    else if (ptype == ttByte)
    {
      imgdata.rawdata.raw_alloc = malloc(pixels * TagTypeSize(ttShort));
      unsigned char *src = (unsigned char *)buffer.fData;
      ushort *dst = (ushort *)imgdata.rawdata.raw_alloc;
      if (is_curve_linear())
      {
        for (int i = 0; i < pixels; i++)
          dst[i] = src[i];
      }
      else
      {
        for (int i = 0; i < pixels; i++)
          dst[i] = imgdata.color.curve[src[i]];
      }
      S.raw_pitch = S.raw_width * pplanes * TagTypeSize(ttShort);
    }
    else
    {
      // Alloc
      if (imgdata.params.raw_processing_options &
          LIBRAW_PROCESSING_DNGSDK_ZEROCOPY)
      {
        zerocopy = true;
      }
      else
      {
        imgdata.rawdata.raw_alloc = malloc(pixels * TagTypeSize(ptype));
        memmove(imgdata.rawdata.raw_alloc, buffer.fData,
                pixels * TagTypeSize(ptype));
      }
      S.raw_pitch = S.raw_width * pplanes * TagTypeSize(ptype);
    }

    if (zerocopy)
    {
      switch (ptype)
      {
      case ttFloat:
        if (pplanes == 1)
          imgdata.rawdata.float_image = (float *)buffer.fData;
        else if (pplanes == 3)
          imgdata.rawdata.float3_image = (float(*)[3])buffer.fData;
        else if (pplanes == 4)
          imgdata.rawdata.float4_image = (float(*)[4])buffer.fData;
        break;

      case ttShort:
        if (pplanes == 1)
          imgdata.rawdata.raw_image = (ushort *)buffer.fData;
        else if (pplanes == 3)
          imgdata.rawdata.color3_image = (ushort(*)[3])buffer.fData;
        else if (pplanes == 4)
          imgdata.rawdata.color4_image = (ushort(*)[4])buffer.fData;
        break;
      default:
        /* do nothing */
        break;
      }
    }
    else
    {
      switch (ptype)
      {
      case ttFloat:
        if (pplanes == 1)
          imgdata.rawdata.float_image = (float *)imgdata.rawdata.raw_alloc;
        else if (pplanes == 3)
          imgdata.rawdata.float3_image = (float(*)[3])imgdata.rawdata.raw_alloc;
        else if (pplanes == 4)
          imgdata.rawdata.float4_image = (float(*)[4])imgdata.rawdata.raw_alloc;
        break;

      case ttByte:
      case ttShort:
        if (pplanes == 1)
          imgdata.rawdata.raw_image = (ushort *)imgdata.rawdata.raw_alloc;
        else if (pplanes == 3)
          imgdata.rawdata.color3_image =
              (ushort(*)[3])imgdata.rawdata.raw_alloc;
        else if (pplanes == 4)
          imgdata.rawdata.color4_image =
              (ushort(*)[4])imgdata.rawdata.raw_alloc;
        break;
      default:
        /* do nothing */
        break;
      }
    }
    if (zerocopy)
    {
      dng_negative *stolen = negative.Release();
      dngnegative = stolen;
      dng_simple_image *simage = stage2.Release();
      dngimage = simage;
    }
  }
  catch (...)
  {
    return LIBRAW_UNSPECIFIED_ERROR;
  }
  return imgdata.rawdata.raw_alloc ? LIBRAW_SUCCESS : LIBRAW_UNSPECIFIED_ERROR;
#else
  return LIBRAW_UNSPECIFIED_ERROR;
#endif
}

Project: LibRaw

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

Project: LibRaw

unsigned LibRaw::ph1_bithuff(int nbits, ushort *huff)
{
#ifndef LIBRAW_NOTHREADS
#define bitbuf tls->ph1_bits.bitbuf
#define vbits tls->ph1_bits.vbits
#else
  static UINT64 bitbuf = 0;
  static int vbits = 0;
#endif
  unsigned c;

  if (nbits == -1)
    return bitbuf = vbits = 0;
  if (nbits == 0)
    return 0;
  if (vbits < nbits)
  {
    bitbuf = bitbuf << 32 | get4();
    vbits += 32;
  }
  c = bitbuf << (64 - vbits) >> (64 - nbits);
  if (huff)
  {
    vbits -= huff[c] >> 8;
    return (uchar)huff[c];
  }
  vbits -= nbits;
  return c;
#ifndef LIBRAW_NOTHREADS
#undef bitbuf
#undef vbits
#endif
}

Project: LibRaw

  int libraw_cameraCount() { return LibRaw::cameraCount(); }

Project: LibRaw

void LibRaw::fuji_decode_loop(const struct fuji_compressed_params *common_info,
                              int count, INT64 *raw_block_offsets,
                              unsigned *block_sizes)
{
  int cur_block;
#ifdef LIBRAW_USE_OPENMP
#pragma omp parallel for private(cur_block)
#endif
  for (cur_block = 0; cur_block < count; cur_block++)
  {
    fuji_decode_strip(common_info, cur_block, raw_block_offsets[cur_block],
                      block_sizes[cur_block]);
  }
}

Project: LibRaw

void LibRaw::dcb_hor(float (*image2)[3])
{
  int row, col, u = width, v = 2 * u, indx;

  for (row = 2; row < height - 2; row++)
    for (col = 2 + (FC(row, 2) & 1), indx = row * width + col; col < u - 2;
         col += 2, indx += 2)
    {

      image2[indx][1] = CLIP((image[indx + 1][1] + image[indx - 1][1]) / 2.0);
    }
}

Project: LibRaw
File: dcraw.c

  static float libraw_powf64l(float a, float b) { return powf_lim(a, b, 64.f); }

Project: LibRaw

  virtual INT64 size() { return streamsize; }

Project: LibRaw

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

Project: LibRaw
File: sony.cpp

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

Project: LibRaw

id2hr_t *lookup_id2hr(unsigned long long id, id2hr_t *table, ushort nEntries)
{
  for (int k = 0; k < nEntries; k++)
    if (id == table[k].id)
      return &table[k];
  return 0;
}

Project: LibRaw

void LibRaw::packed_dng_load_raw()
{
  ushort *pixel, *rp;
  int row, col;

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

  pixel = (ushort *)calloc(raw_width, tiff_samples * sizeof *pixel);
  merror(pixel, "packed_dng_load_raw()");
  try
  {
    for (row = 0; row < raw_height; row++)
    {
      checkCancel();
      if (tiff_bps == 16)
        read_shorts(pixel, raw_width * tiff_samples);
      else
      {
        getbits(-1);
        for (col = 0; col < raw_width * tiff_samples; col++)
          pixel[col] = getbits(tiff_bps);
      }
      for (rp = pixel, col = 0; col < raw_width; col++)
        adobe_copy_pixel(row, col, &rp);
    }
  }
  catch (...)
  {
    free(pixel);
    shot_select = ss;
    throw;
  }
  free(pixel);
  shot_select = ss;
}

Project: LibRaw

void LibRaw::kodak_thumb_load_raw()
{
  if (!image)
    throw LIBRAW_EXCEPTION_IO_CORRUPT;
  int row, col;
  colors = thumb_misc >> 5;
  for (row = 0; row < height; row++)
    for (col = 0; col < width; col++)
      read_shorts(image[row * width + col], colors);
  maximum = (1 << (thumb_misc & 31)) - 1;
}

Project: LibRaw

CameraMetaDataLR::CameraMetaDataLR(char *data, int sz) : CameraMetaData()
{
  ctxt = xmlNewParserCtxt();
  if (ctxt == NULL)
  {
    ThrowCME("CameraMetaData:Could not initialize context.");
  }

  xmlResetLastError();
  doc = xmlCtxtReadMemory(ctxt, data, sz, "", NULL, XML_PARSE_DTDVALID);

  if (doc == NULL)
  {
    ThrowCME("CameraMetaData: XML Document could not be parsed successfully. "
             "Error was: %s",
             ctxt->lastError.message);
  }

  if (ctxt->valid == 0)
  {
    if (ctxt->lastError.code == 0x5e)
    {
      // ignore this error code
    }
    else
    {
      ThrowCME("CameraMetaData: XML file does not validate. DTD Error was: %s",
               ctxt->lastError.message);
    }
  }

  xmlNodePtr cur;
  cur = xmlDocGetRootElement(doc);
  if (xmlStrcmp(cur->name, (const xmlChar *)"Cameras"))
  {
    ThrowCME("CameraMetaData: XML document of the wrong type, root node is not "
             "cameras.");
    return;
  }

  cur = cur->xmlChildrenNode;
  while (cur != NULL)
  {
    if ((!xmlStrcmp(cur->name, (const xmlChar *)"Camera")))
    {
      Camera *camera = new Camera(doc, cur);
      addCamera(camera);

      // Create cameras for aliases.
      for (unsigned int i = 0; i < camera->aliases.size(); i++)
      {
        addCamera(new Camera(camera, i));
      }
    }
    cur = cur->next;
  }
  if (doc)
    xmlFreeDoc(doc);
  doc = 0;
  if (ctxt)
    xmlFreeParserCtxt(ctxt);
  ctxt = 0;
}

Project: LibRaw

int main(int argc, char *argv[])
{
  if (argc == 1)
    usage(argv[0]);

  LibRaw RawProcessor;
  int i, arg, c, ret;
  char opm, opt, *cp, *sp;
  int use_bigfile = 0, use_timing = 0, use_mem = 0, use_mmap = 0;
  char *outext = NULL;
#ifdef USE_DNGSDK
  dng_host *dnghost = NULL;
#endif
  struct file_mapping mapping;
  void *iobuffer = 0;
#ifdef OUT
#undef OUT
#endif
#define OUT RawProcessor.imgdata.params

  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 *)"cnbrkStqmHABCgU", opt)) != 0)
      for (i = 0; i < "111411111144221"[cp - sp] - '0'; i++)
        if (!isdigit(argv[arg + i][0]) && !optstr[2])
        {
          fprintf(stderr, "Non-numeric argument to \"-%c\"\n", opt);
          return 1;
        }
    if (!strchr("ftdeam", opt) && argv[arg - 1][2])
      fprintf(stderr, "Unknown option \"%s\".\n", argv[arg - 1]);
    switch (opt)
    {
    case 'v':
      verbosity++;
      break;
    case 'G':
      OUT.green_matching = 1;
      break;
    case 'c':
      OUT.adjust_maximum_thr = (float)atof(argv[arg++]);
      break;
    case 'U':
      OUT.auto_bright_thr = (float)atof(argv[arg++]);
      break;
    case 'n':
      OUT.threshold = (float)atof(argv[arg++]);
      break;
    case 'b':
      OUT.bright = (float)atof(argv[arg++]);
      break;
    case 'P':
      OUT.bad_pixels = argv[arg++];
      break;
    case 'K':
      OUT.dark_frame = argv[arg++];
      break;
    case 'r':
      for (c = 0; c < 4; c++)
        OUT.user_mul[c] = (float)atof(argv[arg++]);
      break;
    case 'C':
      OUT.aber[0] = 1 / atof(argv[arg++]);
      OUT.aber[2] = 1 / atof(argv[arg++]);
      break;
    case 'g':
      OUT.gamm[0] = 1 / atof(argv[arg++]);
      OUT.gamm[1] = atof(argv[arg++]);
      break;
    case 'k':
      OUT.user_black = atoi(argv[arg++]);
      break;
    case 'S':
      OUT.user_sat = atoi(argv[arg++]);
      break;
    case 'R':
      OUT.raw_processing_options = atoi(argv[arg++]);
      break;
    case 't':
      if (!strcmp(optstr, "-timing"))
        use_timing = 1;
      else if (!argv[arg - 1][2])
        OUT.user_flip = atoi(argv[arg++]);
      else
        fprintf(stderr, "Unknown option \"%s\".\n", argv[arg - 1]);
      break;
    case 'q':
      OUT.user_qual = atoi(argv[arg++]);
      break;
    case 'm':
      if (!strcmp(optstr, "-mmap"))
        use_mmap = 1;
      else
          if (!strcmp(optstr, "-mem"))
        use_mem = 1;
      else
      {
        if (!argv[arg - 1][2])
          OUT.med_passes = atoi(argv[arg++]);
        else
          fprintf(stderr, "Unknown option \"%s\".\n", argv[arg - 1]);
      }
      break;
    case 'H':
      OUT.highlight = atoi(argv[arg++]);
      break;
    case 's':
      OUT.shot_select = abs(atoi(argv[arg++]));
      break;
    case 'o':
      if (isdigit(argv[arg][0]) && !isdigit(argv[arg][1]))
        OUT.output_color = atoi(argv[arg++]);
#ifndef NO_LCMS
      else
        OUT.output_profile = argv[arg++];
      break;
    case 'p':
      OUT.camera_profile = argv[arg++];
#endif
      break;
    case 'h':
      OUT.half_size = 1;
      break;
    case 'f':
      if (!strcmp(optstr, "-fbdd"))
        OUT.fbdd_noiserd = atoi(argv[arg++]);
      else
      {
        if (!argv[arg - 1][2])
          OUT.four_color_rgb = 1;
        else
          fprintf(stderr, "Unknown option \"%s\".\n", argv[arg - 1]);
      }
      break;
    case 'A':
      for (c = 0; c < 4; c++)
        OUT.greybox[c] = atoi(argv[arg++]);
      break;
    case 'B':
      for (c = 0; c < 4; c++)
        OUT.cropbox[c] = atoi(argv[arg++]);
      break;
    case 'a':
      if (!strcmp(optstr, "-aexpo"))
      {
        OUT.exp_correc = 1;
        OUT.exp_shift = (float)atof(argv[arg++]);
        OUT.exp_preser = (float)atof(argv[arg++]);
      }
      else if (!strcmp(optstr, "-apentax4shot"))
      {
        OUT.raw_processing_options |= LIBRAW_PROCESSING_PENTAX_PS_ALLFRAMES;
      }
      else if (!strcmp(optstr, "-apentax4shotorder"))
      {
        strncpy(OUT.p4shot_order, argv[arg++], 5);
      }
      else if (!argv[arg - 1][2])
        OUT.use_auto_wb = 1;
      else
        fprintf(stderr, "Unknown option \"%s\".\n", argv[arg - 1]);
      break;
    case 'w':
      OUT.use_camera_wb = 1;
      break;
    case 'M':
      OUT.use_camera_matrix = (opm == '+')?3:0;
      break;
    case 'j':
      OUT.use_fuji_rotate = 0;
      break;
    case 'W':
      OUT.no_auto_bright = 1;
      break;
    case 'T':
      OUT.output_tiff = 1;
      break;
    case '4':
      OUT.gamm[0] = OUT.gamm[1] = OUT.no_auto_bright = 1; /* no break here! */
    case '6':
      OUT.output_bps = 16;
      break;
    case 'F':
      use_bigfile = 1;
      break;
    case 'Z':
      outext = strdup(argv[arg++]);
      break;
    case 'd':
      if (!strcmp(optstr, "-dcbi"))
        OUT.dcb_iterations = atoi(argv[arg++]);
      else if (!strcmp(optstr, "-disars"))
        OUT.use_rawspeed = 0;
      else if (!strcmp(optstr, "-disinterp"))
        OUT.no_interpolation = 1;
      else if (!strcmp(optstr, "-dcbe"))
        OUT.dcb_enhance_fl = 1;
      else if (!strcmp(optstr, "-dsrawrgb1"))
      {
        OUT.raw_processing_options |= LIBRAW_PROCESSING_SRAW_NO_RGB;
        OUT.raw_processing_options &= ~LIBRAW_PROCESSING_SRAW_NO_INTERPOLATE;
      }
      else if (!strcmp(optstr, "-dsrawrgb2"))
      {
        OUT.raw_processing_options &= ~LIBRAW_PROCESSING_SRAW_NO_RGB;
        OUT.raw_processing_options |= LIBRAW_PROCESSING_SRAW_NO_INTERPOLATE;
      }
#ifdef USE_DNGSDK
      else if (!strcmp(optstr, "-dngsdk"))
      {
        dnghost = new dng_host;
        RawProcessor.set_dng_host(dnghost);
      }
      else if (!strcmp(optstr, "-dngflags"))
      {
        OUT.use_dngsdk = atoi(argv[arg++]);
      }
#endif
      else
        fprintf(stderr, "Unknown option \"%s\".\n", argv[arg - 1]);
      break;
    default:
      fprintf(stderr, "Unknown option \"-%c\".\n", opt);
      return 1;
    }
  }
#ifndef LIBRAW_WIN32_CALLS
  putenv((char *)"TZ=UTC"); // dcraw compatibility, affects TIFF datestamp field
#else
  _putenv(
      (char *)"TZ=UTC"); // dcraw compatibility, affects TIFF datestamp field
#endif
#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

  if (outext && !strcmp(outext, "-"))
    use_timing = verbosity = 0;

  if (verbosity > 1)
    RawProcessor.set_progress_handler(my_progress_callback,
                                      (void *)"Sample data passed");
#ifdef LIBRAW_USE_OPENMP
  if (verbosity)
    printf("Using %d threads\n", omp_get_max_threads());
#endif

  for (; arg < argc; arg++)
  {
    char outfn[1024];

    if (verbosity)
      printf("Processing file %s\n", argv[arg]);

    timerstart();

	if (use_mmap)
	{
		create_mapping(mapping, argv[arg]);
		if (!mapping.map)
		{
			fprintf(stderr, "Cannot map %s\n", argv[arg]);
			close_mapping(mapping);
			continue;
		}
      if ((ret = RawProcessor.open_buffer(mapping.map,mapping.fsize) !=
                 LIBRAW_SUCCESS))
      {
        fprintf(stderr, "Cannot open_buffer %s: %s\n", argv[arg], libraw_strerror(ret));
		close_mapping(mapping);
        continue; // no recycle b/c open file will recycle itself
      }
    }
    else  if (use_mem)
    {
      int file = open(argv[arg], O_RDONLY | O_BINARY);
      struct stat st;
      if (file < 0)
      {
        fprintf(stderr, "Cannot open %s: %s\n", argv[arg], strerror(errno));
        continue;
      }
      if (fstat(file, &st))
      {
        fprintf(stderr, "Cannot stat %s: %s\n", argv[arg], strerror(errno));
        close(file);
        continue;
      }
      if (!(iobuffer = malloc(st.st_size)))
      {
        fprintf(stderr, "Cannot allocate %d kbytes for memory buffer\n",
                (int)(st.st_size / 1024));
        close(file);
        continue;
      }
      int rd;
      if (st.st_size != (rd = read(file, iobuffer, st.st_size)))
      {
        fprintf(stderr,
                "Cannot read %d bytes instead of  %d to memory buffer\n",
                (int)rd, (int)st.st_size);
        close(file);
        free(iobuffer);
        continue;
      }
      close(file);
      if ((ret = RawProcessor.open_buffer(iobuffer, st.st_size)) !=
          LIBRAW_SUCCESS)
      {
        fprintf(stderr, "Cannot open_buffer %s: %s\n", argv[arg],
                libraw_strerror(ret));
        free(iobuffer);
        continue; // no recycle b/c open file will recycle itself
      }
    }
    else
    {
      if (use_bigfile)
        // force open_file switch to bigfile processing
        ret = RawProcessor.open_file(argv[arg], 1);
      else
        ret = RawProcessor.open_file(argv[arg]);

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

    if (use_timing)
      timerprint("LibRaw::open_file()", argv[arg]);

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

    if (use_timing)
      timerprint("LibRaw::unpack()", argv[arg]);

    timerstart();
    if (LIBRAW_SUCCESS != (ret = RawProcessor.dcraw_process()))
    {
      fprintf(stderr, "Cannot do postpocessing on %s: %s\n", argv[arg],
              libraw_strerror(ret));
      if (LIBRAW_FATAL_ERROR(ret))
        continue;
    }
    if (use_timing)
      timerprint("LibRaw::dcraw_process()", argv[arg]);

    if (!outext)
      snprintf(outfn, sizeof(outfn), "%s.%s", argv[arg],
               OUT.output_tiff ? "tiff" : (P1.colors > 1 ? "ppm" : "pgm"));
    else if (!strcmp(outext, "-"))
      snprintf(outfn, sizeof(outfn), "-");
    else
    {
      if (*outext == '.') // append
        snprintf(outfn, sizeof(outfn), "%s%s", argv[arg], outext);
      else if (strchr(outext, '.') && *outext != '.') // dot is not 1st char
        strncpy(outfn, outext, sizeof(outfn));
      else
      {
        strncpy(outfn, argv[arg], sizeof(outfn));
        if (strlen(outfn) > 0)
        {
          char *lastchar = outfn + strlen(outfn); // points to term 0
          while (--lastchar > outfn)
          {
            if (*lastchar == '/' || *lastchar == '\\')
              break;
            if (*lastchar == '.')
            {
              *lastchar = 0;
              break;
            };
          }
        }
        strncat(outfn, ".", sizeof(outfn) - strlen(outfn) - 1);
        strncat(outfn, outext, sizeof(outfn) - strlen(outfn) - 1);
      }
    }

    if (verbosity)
    {
      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));

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

	if (use_mmap && mapping.map)
		close_mapping(mapping);
    else if (use_mem && iobuffer)
    {
      free(iobuffer);
      iobuffer = 0;
    }
  }
#ifdef USE_DNGSDK
  if (dnghost)
    delete dnghost;
#endif
  return 0;
}

Project: LibRaw

int show_files(void *q)
{
  char *p;
  int cnt = 0;
  while ((p = get_next_file()))
  {
    printf("%s\n", p);
    cnt++;
  }
  return cnt;
}

Project: LibRaw

void LibRaw::lin_interpolate()
{
  int code[16][16][32], size = 16, *ip, sum[4];
  int f, c, x, y, row, col, shift, color;

  RUN_CALLBACK(LIBRAW_PROGRESS_INTERPOLATE, 0, 3);

  if (filters == 9)
    size = 6;
  border_interpolate(1);
  for (row = 0; row < size; row++)
    for (col = 0; col < size; col++)
    {
      ip = code[row][col] + 1;
      f = fcol(row, col);
      memset(sum, 0, sizeof sum);
      for (y = -1; y <= 1; y++)
        for (x = -1; x <= 1; x++)
        {
          shift = (y == 0) + (x == 0);
          color = fcol(row + y, col + x);
          if (color == f)
            continue;
          *ip++ = (width * y + x) * 4 + color;
          *ip++ = shift;
          *ip++ = color;
          sum[color] += 1 << shift;
        }
      code[row][col][0] = (ip - code[row][col]) / 3;
      FORCC
      if (c != f)
      {
        *ip++ = c;
        *ip++ = sum[c] > 0 ? 256 / sum[c] : 0;
      }
    }
  RUN_CALLBACK(LIBRAW_PROGRESS_INTERPOLATE, 1, 3);
  lin_interpolate_loop(code, size);
  RUN_CALLBACK(LIBRAW_PROGRESS_INTERPOLATE, 2, 3);
}

Project: LibRaw
File: libraw_cxx.cpp

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

Project: LibRaw

static dng_ifd* search_for_ifd(const dng_info& info, uint64 offset, ushort w, ushort h)
{
    dng_ifd *ret = 0;
    ret = search_single_ifd(info.fIFD,offset);
    if(!ret) ret = search_single_ifd(info.fChainedIFD,offset);
    if(!ret)
        for(int c = 0; !ret && c < info.fChainedSubIFD.size(); c++)
            ret = search_single_ifd(info.fChainedSubIFD[c],offset);
    if(ret && (ret->fImageLength == h) && ret->fImageWidth == w)
        return ret;
    return 0;
}

Project: LibRaw

void LibRaw::nikon_load_padded_packed_raw() // 12 bit per pixel, padded to 16
                                            // bytes
{
  // libraw_internal_data.unpacker_data.load_flags -> row byte count
  if (libraw_internal_data.unpacker_data.load_flags < 2000 ||
      libraw_internal_data.unpacker_data.load_flags > 64000)
    return;
  unsigned char *buf =
      (unsigned char *)malloc(libraw_internal_data.unpacker_data.load_flags);
  for (int row = 0; row < S.raw_height; row++)
  {
    checkCancel();
    libraw_internal_data.internal_data.input->read(
        buf, libraw_internal_data.unpacker_data.load_flags, 1);
    for (int icol = 0; icol < S.raw_width / 2; icol++)
    {
      imgdata.rawdata.raw_image[(row)*S.raw_width + (icol * 2)] =
          ((buf[icol * 3 + 1] & 0xf) << 8) | buf[icol * 3];
      imgdata.rawdata.raw_image[(row)*S.raw_width + (icol * 2 + 1)] =
          buf[icol * 3 + 2] << 4 | ((buf[icol * 3 + 1] & 0xf0) >> 4);
    }
  }
  free(buf);
}

Project: LibRaw

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

Project: LibRaw

float timerend()
{
  LARGE_INTEGER unit, end;
  QueryPerformanceCounter(&end);
  QueryPerformanceFrequency(&unit);
  float msec = (float)(end.QuadPart - start.QuadPart);
  msec /= (float)unit.QuadPart / 1000.0f;
  return msec;
}

Project: LibRaw

void LibRaw::parseAdobeRAFMakernote()
{

  uchar *PrivateMknBuf;
  unsigned posPrivateMknBuf;
  unsigned PrivateMknLength;
  unsigned PrivateOrder;
  unsigned PrivateEntries, PrivateTagID;
  unsigned PrivateTagBytes;
  unsigned wb_section_offset = 0;
  int posWB;
  int c;

#define CHECKSPACE(s)                                                          \
  if (posPrivateMknBuf + (s) > PrivateMknLength)                               \
  {                                                                            \
    free(PrivateMknBuf);                                                       \
    return;                                                                    \
  }
#define isWB(posWB)                                                            \
  sget2(posWB) != 0 && sget2(posWB + 2) != 0 && sget2(posWB + 4) != 0 &&       \
      sget2(posWB + 6) != 0 && sget2(posWB + 8) != 0 &&                        \
      sget2(posWB + 10) != 0 && sget2(posWB) != 0xff &&                        \
      sget2(posWB + 2) != 0xff && sget2(posWB + 4) != 0xff &&                  \
      sget2(posWB + 6) != 0xff && sget2(posWB + 8) != 0xff &&                  \
      sget2(posWB + 10) != 0xff && sget2(posWB) == sget2(posWB + 6) &&         \
      sget2(posWB) < sget2(posWB + 2) && sget2(posWB) < sget2(posWB + 4) &&    \
      sget2(posWB) < sget2(posWB + 8) && sget2(posWB) < sget2(posWB + 10)
#define icWBC imgdata.color.WB_Coeffs
#define imfRAFDataVersion imFuji.RAFDataVersion
#define imfRAFVersion imFuji.RAFVersion

  order = 0x4d4d;
  PrivateMknLength = get4();

  if ((PrivateMknLength > 4) && (PrivateMknLength < 10240000) &&
      (PrivateMknBuf = (uchar *)malloc(PrivateMknLength + 1024)))
  { // 1024b for safety
    fread(PrivateMknBuf, PrivateMknLength, 1, ifp);
    PrivateOrder = sget2(PrivateMknBuf);
    posPrivateMknBuf = sget4(PrivateMknBuf + 2) + 12;

    memcpy(imFuji.SerialSignature, PrivateMknBuf + 6, 0x0c);
    imFuji.SerialSignature[0x0c] = 0;
    memcpy(model, PrivateMknBuf + 0x12, 0x20);
    model[0x20] = 0;
    memcpy(model2, PrivateMknBuf + 0x32, 4);
    model2[4] = 0;
    strcpy(imFuji.RAFVersion, model2);
    PrivateEntries = sget2(PrivateMknBuf + posPrivateMknBuf);
    if ((PrivateEntries > 1000) ||
        ((PrivateOrder != 0x4d4d) && (PrivateOrder != 0x4949)))
    {
      free(PrivateMknBuf);
      return;
    }
    posPrivateMknBuf += 2;
    /*
     * because Adobe DNG converter strips or misplaces 0xfnnn tags,
     * Auto WB for following cameras is missing for now
     * - F550EXR
     * - F600EXR
     * - F770EXR
     * - F800EXR
     * - F900EXR
     * - HS10
     * - HS11
     * - HS20EXR
     * - HS30EXR
     * - HS50EXR
     * - S1
     * - SL1000
     **/
    while (PrivateEntries--)
    {
      order = 0x4d4d;
      CHECKSPACE(4);
      PrivateTagID = sget2(PrivateMknBuf + posPrivateMknBuf);
      PrivateTagBytes = sget2(PrivateMknBuf + posPrivateMknBuf + 2);
      posPrivateMknBuf += 4;
      order = PrivateOrder;

      if (PrivateTagID == 0x2000)
      {
        FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_Auto][c ^ 1] =
            sget2(PrivateMknBuf + posPrivateMknBuf + (c << 1));
      }
      else if (PrivateTagID == 0x2100)
      {
        FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_FineWeather][c ^ 1] =
            sget2(PrivateMknBuf + posPrivateMknBuf + (c << 1));
      }
      else if (PrivateTagID == 0x2200)
      {
        FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_Shade][c ^ 1] =
            sget2(PrivateMknBuf + posPrivateMknBuf + (c << 1));
      }
      else if (PrivateTagID == 0x2300)
      {
        FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_FL_D][c ^ 1] =
            sget2(PrivateMknBuf + posPrivateMknBuf + (c << 1));
      }
      else if (PrivateTagID == 0x2301)
      {
        FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_FL_N][c ^ 1] =
            sget2(PrivateMknBuf + posPrivateMknBuf + (c << 1));
      }
      else if (PrivateTagID == 0x2302)
      {
        FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_FL_WW][c ^ 1] =
            sget2(PrivateMknBuf + posPrivateMknBuf + (c << 1));
      }
      else if (PrivateTagID == 0x2310)
      {
        FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_FL_L][c ^ 1] =
            sget2(PrivateMknBuf + posPrivateMknBuf + (c << 1));
      }
      else if (PrivateTagID == 0x2311)
      {
        FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_FL_W][c ^ 1] =
            sget2(PrivateMknBuf + posPrivateMknBuf + (c << 1));
      }
      else if (PrivateTagID == 0x2400)
      {
        FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_Tungsten][c ^ 1] =
            sget2(PrivateMknBuf + posPrivateMknBuf + (c << 1));
      }
      else if (PrivateTagID == 0x2410)
      {
        FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_Flash][c ^ 1] =
            sget2(PrivateMknBuf + posPrivateMknBuf + (c << 1));
      }
      else if (PrivateTagID == 0x2f00)
      {
        int nWBs = MIN(sget4(PrivateMknBuf + posPrivateMknBuf), 6);
        posWB = posPrivateMknBuf + 4;
        for (int wb_ind = 0; wb_ind < nWBs; wb_ind++)
        {
          FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_Custom1 + wb_ind][c ^ 1] =
              sget2(PrivateMknBuf + posWB + (c << 1));
          posWB += 8;
        }
      }
      else if (PrivateTagID == 0x2ff0)
      {
        FORC4 cam_mul[c ^ 1] =
            sget2(PrivateMknBuf + posPrivateMknBuf + (c << 1));
      }

      else if (PrivateTagID == 0x9650)
      {
        CHECKSPACE(4);
        short a = (short)sget2(PrivateMknBuf + posPrivateMknBuf);
        float b = fMAX(1.0f, sget2(PrivateMknBuf + posPrivateMknBuf + 2));
        imFuji.ExpoMidPointShift = a / b;
      }
      else if ((PrivateTagID == 0xc000) && (PrivateTagBytes > 3) &&
               (PrivateTagBytes < 10240000))
      {
        order = 0x4949;
        if (PrivateTagBytes != 4096)
        { // not one of Fuji X-A3, X-A5, X-A7, X-A10, X-A20, X-T100, XF10
          if (!sget2(PrivateMknBuf + posPrivateMknBuf))
            imfRAFDataVersion = sget2(PrivateMknBuf + posPrivateMknBuf + 2);

          for (posWB = 0; posWB < PrivateTagBytes - 16; posWB++)
          {
            if ((!memcmp(PrivateMknBuf + posWB, "TSNERDTS", 8) &&
                 (sget2(PrivateMknBuf + posWB + 10) > 125)))
            {
              posWB += 10;
              imgdata.color.WB_Coeffs[LIBRAW_WBI_Auto][1] =
                  imgdata.color.WB_Coeffs[LIBRAW_WBI_Auto][3] =
                      sget2(PrivateMknBuf + posWB);
              imgdata.color.WB_Coeffs[LIBRAW_WBI_Auto][0] =
                  sget2(PrivateMknBuf + posWB + 2);
              imgdata.color.WB_Coeffs[LIBRAW_WBI_Auto][2] =
                  sget2(PrivateMknBuf + posWB + 4);
              break;
            }
          }

          if (imfRAFDataVersion == 0x0146 || // X20
              imfRAFDataVersion == 0x0149 || // X100S
              imfRAFDataVersion == 0x0249)
          { // X100S
            wb_section_offset = 0x1410;
          }
          else if (imfRAFDataVersion == 0x014d || // X-M1
                   imfRAFDataVersion == 0x014e)
          { // X-A1, X-A2
            wb_section_offset = 0x1474;
          }
          else if (imfRAFDataVersion == 0x014f || // X-E2
                   imfRAFDataVersion == 0x024f || // X-E2
                   imfRAFDataVersion == 0x025d)
          { // X-H1
            wb_section_offset = 0x1480;
          }
          else if (imfRAFDataVersion == 0x0150)
          { // XQ1, XQ2
            wb_section_offset = 0x1414;
          }
          else if (imfRAFDataVersion == 0x0151 || // X-T1 w/diff. fws
                   imfRAFDataVersion == 0x0251 || imfRAFDataVersion == 0x0351 ||
                   imfRAFDataVersion == 0x0451 || imfRAFDataVersion == 0x0551)
          {
            wb_section_offset = 0x14b0;
          }
          else if (imfRAFDataVersion == 0x0152 || // X30
                   imfRAFDataVersion == 0x0153)
          { // X100T
            wb_section_offset = 0x1444;
          }
          else if (imfRAFDataVersion == 0x0154)
          { // X-T10
            wb_section_offset = 0x1824;
          }
          else if (imfRAFDataVersion == 0x0155)
          { // X70
            wb_section_offset = 0x17b4;
          }
          else if (imfRAFDataVersion == 0x0255)
          { // X-Pro2
            wb_section_offset = 0x135c;
          }
          else if (imfRAFDataVersion == 0x0258 || // X-T2
                   imfRAFDataVersion == 0x025b)
          { // X-T20
            wb_section_offset = 0x13dc;
          }
          else if (imfRAFDataVersion == 0x0259)
          { // X100F
            wb_section_offset = 0x1370;
          }
          else if (imfRAFDataVersion == 0x025a)
          { // GFX 50S
            wb_section_offset = 0x1424;
          }
          else if (imfRAFDataVersion == 0x025c)
          { // X-E3
            wb_section_offset = 0x141c;
          }
          else if (imfRAFDataVersion == 0x025e)
          { // X-T3
            wb_section_offset = 0x2014;
          }
          else if (imfRAFDataVersion == 0x025f)
          { // X-T30, GFX 50R, GFX 100
            if (!strcmp(model, "X-T30"))
              wb_section_offset = 0x20b8;
            else if (!strcmp(model, "GFX 50R"))
              wb_section_offset = 0x1424;
            else if (!strcmp(model, "GFX 100"))
              wb_section_offset = 0x20e4;
          }
          else if (imfRAFDataVersion == 0x0355)
          { // X-E2S
            wb_section_offset = 0x1840;

            /* try for unknown RAF Data versions */
          }
          else if (!strcmp(model, "X20"))
          {
            if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x1410))
              wb_section_offset = 0x1410;
          }
          else if (!strcmp(model, "X100S"))
          {
            if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x1410))
              wb_section_offset = 0x1410;
          }
          else if (!strcmp(model, "X-M1"))
          {
            if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x1474))
              wb_section_offset = 0x1474;
          }
          else if (!strcmp(model, "X-A1"))
          {
            if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x1474))
              wb_section_offset = 0x1474;
          }
          else if (!strcmp(model, "X-A2"))
          {
            if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x1474))
              wb_section_offset = 0x1474;
          }
          else if (!strcmp(model, "X-E2"))
          {
            if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x1480))
              wb_section_offset = 0x1480;
          }
          else if (!strcmp(model, "X-H1"))
          {
            if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x1480))
              wb_section_offset = 0x1480;
          }
          else if (!strcmp(model, "XQ1"))
          {
            if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x1414))
              wb_section_offset = 0x1414;
          }
          else if (!strcmp(model, "XQ2"))
          {
            if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x1414))
              wb_section_offset = 0x1414;
          }
          else if (!strcmp(model, "X-T1"))
          {
            if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x14b0))
              wb_section_offset = 0x14b0;
          }
          else if (!strcmp(model, "X30"))
          {
            if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x1444))
              wb_section_offset = 0x1444;
          }
          else if (!strcmp(model, "X100T"))
          {
            if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x1444))
              wb_section_offset = 0x1444;
          }
          else if (!strcmp(model, "X-T10"))
          {
            if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x1824))
              wb_section_offset = 0x1824;
          }
          else if (!strcmp(model, "X70"))
          {
            if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x17b4))
              wb_section_offset = 0x17b4;
          }
          else if (!strcmp(model, "X-Pro2"))
          {
            if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x135c))
              wb_section_offset = 0x135c;
          }
          else if (!strcmp(model, "X-T2"))
          {
            if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x13dc))
              wb_section_offset = 0x13dc;
          }
          else if (!strcmp(model, "X-T20"))
          {
            if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x13dc))
              wb_section_offset = 0x13dc;
          }
          else if (!strcmp(model, "X100F"))
          {
            if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x1370))
              wb_section_offset = 0x1370;
          }
          else if (!strcmp(model, "GFX 50S"))
          {
            if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x1424))
              wb_section_offset = 0x1424;
          }
          else if (!strcmp(model, "GFX 50R"))
          {
            if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x1424))
              wb_section_offset = 0x1424;
          }
          else if (!strcmp(model, "X-T3"))
          {
            if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x2014))
              wb_section_offset = 0x2014;
          }
          else if (!strcmp(model, "X-T30"))
          {
            if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x20b8))
              wb_section_offset = 0x2014;
          }
          else if (!strcmp(model, "X-E3"))
          {
            if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x141c))
              wb_section_offset = 0x141c;
          }
          else if (!strcmp(model, "X-E2S"))
          {
            if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x1840))
              wb_section_offset = 0x1840;
          }
          else if (!strcmp(model, "GFX 100"))
          {
            if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x20e4))
              wb_section_offset = 0x20e4;

            /* no RAF Data version for the models below */
          }
          else if (!strcmp(model, "FinePix X100"))
          { // X100 0 0x19f0 0x19e8
            if (!strcmp(imfRAFVersion, "0069"))
              wb_section_offset = 0x19e8;
            else if (!strcmp(imfRAFVersion, "0100"))
              wb_section_offset = 0x19f0;
            else if (!strcmp(imfRAFVersion, "0110"))
              wb_section_offset = 0x19f0;
            else if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x19e8))
              wb_section_offset = 0x19e8;
            else if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x19f0))
              wb_section_offset = 0x19f0;
          }
          else if (!strcmp(model, "X-E1"))
          { // X-E1 0 0x13ac
            if (!strcmp(imfRAFVersion, "0101"))
              wb_section_offset = 0x13ac;
            else if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x13ac))
              wb_section_offset = 0x13ac;
          }
          else if (!strcmp(model, "X-Pro1"))
          { // X-Pro1 0 0x13a4
            if (!strcmp(imfRAFVersion, "0100"))
              wb_section_offset = 0x13a4;
            else if (!strcmp(imfRAFVersion, "0101"))
              wb_section_offset = 0x13a4;
            else if (!strcmp(imfRAFVersion, "0204"))
              wb_section_offset = 0x13a4;
            else if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x13a4))
              wb_section_offset = 0x13a4;
          }
          else if (!strcmp(model, "XF1"))
          { // XF1 0 0x138c
            if (!strcmp(imfRAFVersion, "0100"))
              wb_section_offset = 0x138c;
            else if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x138c))
              wb_section_offset = 0x138c;
          }
          else if (!strcmp(model, "X-S1"))
          { // X-S1 0 0x1284
            if (!strcmp(imfRAFVersion, "0100"))
              wb_section_offset = 0x1284;
            else if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x1284))
              wb_section_offset = 0x1284;
          }
          else if (!strcmp(model, "X10"))
          { // X10 0 0x1280 0x12d4
            if (!strcmp(imfRAFVersion, "0100"))
              wb_section_offset = 0x1280;
            else if (!strcmp(imfRAFVersion, "0102"))
              wb_section_offset = 0x1280;
            else if (!strcmp(imfRAFVersion, "0103"))
              wb_section_offset = 0x12d4;
            else if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x1280))
              wb_section_offset = 0x1280;
            else if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x12d4))
              wb_section_offset = 0x12d4;
          }
          else if (!strcmp(model, "XF1"))
          { // XF1 0 0x138c
            if (!strcmp(imfRAFVersion, "0100"))
              wb_section_offset = 0x138c;
            else if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x138c))
              wb_section_offset = 0x138c;
          }
          if (wb_section_offset &&
              isWB(PrivateMknBuf + posPrivateMknBuf + wb_section_offset))
          {

            if (!imfRAFDataVersion)
            {
              posWB = posPrivateMknBuf + wb_section_offset - 6;
              imgdata.color.WB_Coeffs[LIBRAW_WBI_Auto][1] =
                  imgdata.color.WB_Coeffs[LIBRAW_WBI_Auto][3] =
                      sget2(PrivateMknBuf + posWB);
              imgdata.color.WB_Coeffs[LIBRAW_WBI_Auto][0] =
                  sget2(PrivateMknBuf + posWB + 2);
              imgdata.color.WB_Coeffs[LIBRAW_WBI_Auto][2] =
                  sget2(PrivateMknBuf + posWB + 4);
            }

            posWB = posPrivateMknBuf + wb_section_offset;
            for (int wb_ind = 0; wb_ind < nFuji_wb_list1; posWB += 6, wb_ind++)
            {
              imgdata.color.WB_Coeffs[Fuji_wb_list1[wb_ind]][1] =
                  imgdata.color.WB_Coeffs[Fuji_wb_list1[wb_ind]][3] =
                      sget2(PrivateMknBuf + posWB);
              imgdata.color.WB_Coeffs[Fuji_wb_list1[wb_ind]][0] =
                  sget2(PrivateMknBuf + posWB + 2);
              imgdata.color.WB_Coeffs[Fuji_wb_list1[wb_ind]][2] =
                  sget2(PrivateMknBuf + posWB + 4);
            }

            int found = 0;
            posWB += 0xC0;
            ushort Gval = sget2(PrivateMknBuf + posWB);
            for (int posEndCCTsection = posWB; posEndCCTsection < (posWB + 30);
                 posEndCCTsection += 6)
            {
              if (sget2(PrivateMknBuf + posEndCCTsection) != Gval)
              {
                wb_section_offset = posEndCCTsection - 186;
                found = 1;
                break;
              }
            }

            if (found)
            {
              for (int iCCT = 0; iCCT < 31; iCCT++)
              {
                imgdata.color.WBCT_Coeffs[iCCT][0] = FujiCCT_K[iCCT];
                imgdata.color.WBCT_Coeffs[iCCT][1] =
                    sget2(PrivateMknBuf + wb_section_offset + iCCT * 6 + 2);
                imgdata.color.WBCT_Coeffs[iCCT][2] =
                    imgdata.color.WBCT_Coeffs[iCCT][4] =
                        sget2(PrivateMknBuf + wb_section_offset + iCCT * 6);
                imgdata.color.WBCT_Coeffs[iCCT][3] =
                    sget2(PrivateMknBuf + wb_section_offset + iCCT * 6 + 4);
              }
            }
          }
        }
        else
        { // process 4K raf data
          int wb[4];
          int nWB, tWB, pWB;
          int iCCT = 0;
          is_4K_RAFdata = 1; /* X-A3, X-A5, X-A7, X-A10, X-A20, X-T100, XF10 */
          posWB = posPrivateMknBuf + 0x200;
          for (int wb_ind = 0; wb_ind < 42; wb_ind++)
          {
            nWB = sget4(PrivateMknBuf + posWB);
            posWB += 4;
            tWB = sget4(PrivateMknBuf + posWB);
            posWB += 4;
            wb[0] = sget4(PrivateMknBuf + posWB) << 1;
            posWB += 4;
            wb[1] = sget4(PrivateMknBuf + posWB);
            posWB += 4;
            wb[3] = sget4(PrivateMknBuf + posWB);
            posWB += 4;
            wb[2] = sget4(PrivateMknBuf + posWB) << 1;
            posWB += 4;

            if (tWB && (iCCT < 255))
            {
              imgdata.color.WBCT_Coeffs[iCCT][0] = tWB;
              FORC4 imgdata.color.WBCT_Coeffs[iCCT][c + 1] = wb[c];
              iCCT++;
            }
            if (nWB != 0x46)
            {
              for (pWB = 1; pWB < nFuji_wb_list2; pWB += 2)
              {
                if (Fuji_wb_list2[pWB] == nWB)
                {
                  FORC4 imgdata.color.WB_Coeffs[Fuji_wb_list2[pWB - 1]][c] =
                      wb[c];
                  break;
                }
              }
            }
          }
        }
      }
      posPrivateMknBuf += PrivateTagBytes;
    }
    free(PrivateMknBuf);
  }
#undef imfRAFVersion
#undef imfRAFDataVersion
#undef icWBC
#undef CHECKSPACE
}

Project: LibRaw

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

Project: LibRaw

LibRaw_file_datastream::LibRaw_file_datastream(const char *fname)
    : filename(fname), _fsize(0)
#ifdef LIBRAW_WIN32_UNICODEPATHS
      ,
      wfilename()
#endif
      ,
      jas_file(NULL)
{
  if (filename.size() > 0)
  {
#ifndef LIBRAW_WIN32_CALLS
    struct stat st;
    if (!stat(filename.c_str(), &st))
      _fsize = st.st_size;
#else
    struct _stati64 st;
    if (!_stati64(filename.c_str(), &st))
      _fsize = st.st_size;
#endif
#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(filename.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

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

Project: LibRaw

  static inline float scale_over(float ec, float base)
  {
    float s = base * .4;
    float o = ec - base;
    return base + sqrt(s * (o + s)) - s;
  }

Project: LibRaw

  unsigned int nextpixel() { return current < 14 ? pixelbuffer[current++] : 0; }

Project: LibRaw

  void *realloc(void *ptr, size_t newsz)
  {
    void *ret = ::realloc(ptr, newsz + extra_bytes);
    forget_ptr(ptr);
    mem_ptr(ret);
    return ret;
  }

Project: LibRaw

int main(int ac, char *av[])
{
  int i, max_threads = 2;
  pthread_t *threads;
  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];
  }
  pthread_mutex_init(&qm, NULL);
  threads = calloc(max_threads, sizeof(threads[0]));
  for (i = 0; i < max_threads; i++)
    pthread_create(&threads[i], NULL, process_files, NULL);
  for (i = 0; i < max_threads; i++)
  {
    int *iptr;
    if (threads[i])
    {
      pthread_join(threads[i], (void *)&iptr);
    }
  }

  return 0;
}

Project: LibRaw

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

Project: LibRaw

AAHD::AAHD(LibRaw &_libraw) : libraw(_libraw)
{
  nr_height = libraw.imgdata.sizes.iheight + nr_margin * 2;
  nr_width = libraw.imgdata.sizes.iwidth + nr_margin * 2;
  rgb_ahd[0] = (ushort3 *)calloc(nr_height * nr_width,
                                 (sizeof(ushort3) * 2 + sizeof(int3) * 2 + 3));
  if (!rgb_ahd[0])
    throw LIBRAW_EXCEPTION_ALLOC;

  rgb_ahd[1] = rgb_ahd[0] + nr_height * nr_width;
  yuv[0] = (int3 *)(rgb_ahd[1] + nr_height * nr_width);
  yuv[1] = yuv[0] + nr_height * nr_width;
  ndir = (char *)(yuv[1] + nr_height * nr_width);
  homo[0] = ndir + nr_height * nr_width;
  homo[1] = homo[0] + nr_height * nr_width;
  channel_maximum[0] = channel_maximum[1] = channel_maximum[2] = 0;
  channel_minimum[0] = libraw.imgdata.image[0][0];
  channel_minimum[1] = libraw.imgdata.image[0][1];
  channel_minimum[2] = libraw.imgdata.image[0][2];
  int iwidth = libraw.imgdata.sizes.iwidth;
  for (int i = 0; i < 3; ++i)
    for (int j = 0; j < 3; ++j)
    {
      yuv_cam[i][j] = 0;
      for (int k = 0; k < 3; ++k)
        yuv_cam[i][j] += yuv_coeff[i][k] * libraw.imgdata.color.rgb_cam[k][j];
    }
  if (gammaLUT[0] < -0.1f)
  {
    float r;
    for (int i = 0; i < 0x10000; i++)
    {
      r = (float)i / 0x10000;
      gammaLUT[i] =
          0x10000 * (r < 0.0181 ? 4.5f * r : 1.0993f * pow(r, 0.45f) - .0993f);
    }
  }
  for (int i = 0; i < libraw.imgdata.sizes.iheight; ++i)
  {
    int col_cache[48];
    for (int j = 0; j < 48; ++j)
    {
      int c = libraw.COLOR(i, j);
      if (c == 3)
        c = 1;
      col_cache[j] = c;
    }
    int moff = nr_offset(i + nr_margin, nr_margin);
    for (int j = 0; j < iwidth; ++j, ++moff)
    {
      int c = col_cache[j % 48];
      unsigned short d = libraw.imgdata.image[i * iwidth + j][c];
      if (d != 0)
      {
        if (channel_maximum[c] < d)
          channel_maximum[c] = d;
        if (channel_minimum[c] > d)
          channel_minimum[c] = d;
        rgb_ahd[1][moff][c] = rgb_ahd[0][moff][c] = d;
      }
    }
  }
  channels_max =
      MAX(MAX(channel_maximum[0], channel_maximum[1]), channel_maximum[2]);
}

Project: LibRaw

void print_0fun(FILE* outfile, LibRaw& MyCoolRawProcessor, std::string& fn)
{
	/*
	printf ("filename\t%s\tmodel\t%s\tisTSNERDTS\t%d\tRAF
	version\t%s\tRAF data version\t0x%x\tis4K\t%d\n", av[i], P1.model,
	Fuji.isTSNERDTS, Fuji.RAFVersion, Fuji.RAFDataVersion,
	P2.is_4K_RAFdata);
	*/

}

Project: LibRaw

void LibRaw::canon_600_load_raw()
{
  uchar data[1120], *dp;
  ushort *pix;
  int irow, row;

  for (irow = row = 0; irow < height; irow++)
  {
    checkCancel();
    if (fread(data, 1, 1120, ifp) < 1120)
      derror();
    pix = raw_image + row * raw_width;
    for (dp = data; dp < data + 1120; dp += 10, pix += 8)
    {
      pix[0] = (dp[0] << 2) + (dp[1] >> 6);
      pix[1] = (dp[2] << 2) + (dp[1] >> 4 & 3);
      pix[2] = (dp[3] << 2) + (dp[1] >> 2 & 3);
      pix[3] = (dp[4] << 2) + (dp[1] & 3);
      pix[4] = (dp[5] << 2) + (dp[9] & 3);
      pix[5] = (dp[6] << 2) + (dp[9] >> 2 & 3);
      pix[6] = (dp[7] << 2) + (dp[9] >> 4 & 3);
      pix[7] = (dp[8] << 2) + (dp[9] >> 6);
    }
    if ((row += 2) > height)
      row = 1;
  }
}

Project: LibRaw

  DllDef float libraw_get_rgb_cam(libraw_data_t *lr, int index1, int index2)
  {
    if (!lr)
      return EINVAL;
    return lr->color.rgb_cam[LIM(index1, 0, 2)][LIM(index2, 0, 3)];
  }

Project: LibRaw

void LibRaw::parsePentaxMakernotes(int base, unsigned tag, unsigned type,
                                   unsigned len, unsigned dng_writer)
{

  int c;
  if (tag == 0x0005)
  {
    unique_id = get4();
    setPentaxBodyFeatures(unique_id);
  }
  else if (tag == 0x0008)
  { /* 4 is raw, 7 is raw w/ pixel shift, 8 is raw w/ dynamic pixel shift */
    imPentax.Quality = get2();
  }
  else if (tag == 0x000d)
  {
    imgdata.shootinginfo.FocusMode = imPentax.FocusMode = get2();
  }
  else if (tag == 0x000e)
  {
    imgdata.shootinginfo.AFPoint = imPentax.AFPointSelected = get2();
  }
  else if (tag == 0x000f)
  {
    imPentax.AFPointsInFocus = getint(type);
  }
  else if (tag == 0x0010)
  {
    imPentax.FocusPosition = get2();
  }
  else if (tag == 0x0013)
  {
    ilm.CurAp = (float)get2() / 10.0f;
  }
  else if (tag == 0x0014)
  {
    PentaxISO(get2());
  }
  else if (tag == 0x0017)
  {
    imgdata.shootinginfo.MeteringMode = get2();
  }
  else if (tag == 0x001b) {
    cam_mul[2] = get2() / 256.0;
  }
  else if (tag == 0x001c) {
    cam_mul[0] = get2() / 256.0;
  }
  else if (tag == 0x001d)
  {
    ilm.CurFocal = (float)get4() / 100.0f;
  }
  else if (tag == 0x0034)
  {
    uchar uc;
    FORC4
    {
      fread(&uc, 1, 1, ifp);
      imPentax.DriveMode[c] = uc;
    }
    imgdata.shootinginfo.DriveMode = imPentax.DriveMode[0];
  }
  else if (tag == 0x0038)
  {
    imgdata.sizes.raw_inset_crop.cleft = get2();
    imgdata.sizes.raw_inset_crop.ctop = get2();
  }
  else if (tag == 0x0039)
  {
    imgdata.sizes.raw_inset_crop.cwidth = get2();
    imgdata.sizes.raw_inset_crop.cheight = get2();
  }
  else if (tag == 0x003f)
  {
    unsigned a = fgetc(ifp) << 8;
    ilm.LensID = a | fgetc(ifp);
  }
  else if (tag == 0x0047)
  {
    imgdata.makernotes.common.CameraTemperature = (float)fgetc(ifp);
  }
  else if (tag == 0x004d)
  {
    if (type == 9)
      imgdata.makernotes.common.FlashEC = getreal(type) / 256.0f;
    else
      imgdata.makernotes.common.FlashEC = (float)((signed short)fgetc(ifp)) / 6.0f;
  }
  else if (tag == 0x005c)
  {
    fgetc(ifp);
    imgdata.shootinginfo.ImageStabilization = (short)fgetc(ifp);
  }
  else if (tag == 0x0072)
  {
    imPentax.AFAdjustment = get2();
  }
  else if ((tag == 0x007e) && (dng_writer == nonDNG))
  {
    imgdata.color.linear_max[0] = imgdata.color.linear_max[1] =
        imgdata.color.linear_max[2] = imgdata.color.linear_max[3] =
            get4();
  }
  else if (tag == 0x0080)
  {
    short a = (short)fgetc(ifp);
    switch (a)
    {
    case 0:
      imgdata.sizes.raw_inset_crop.aspect = LIBRAW_IMAGE_ASPECT_4to3;
      break;
    case 1:
      imgdata.sizes.raw_inset_crop.aspect = LIBRAW_IMAGE_ASPECT_3to2;
      break;
    case 2:
      imgdata.sizes.raw_inset_crop.aspect = LIBRAW_IMAGE_ASPECT_16to9;
      break;
    case 3:
      imgdata.sizes.raw_inset_crop.aspect = LIBRAW_IMAGE_ASPECT_1to1;
      break;
    }
  }

  else if ((tag == 0x0200) && (dng_writer == nonDNG)) { // Pentax black level
    FORC4 cblack[c ^ c >> 1] = get2();
  }

  else if ((tag == 0x0201) && (dng_writer == nonDNG)) { // Pentax As Shot WB
    FORC4 cam_mul[c ^ (c >> 1)] = get2();
  }

  else if ((tag == 0x0203) && (dng_writer == nonDNG))
  {
    for (int i = 0; i < 3; i++)
      FORC3 cmatrix[i][c] = ((short)get2()) / 8192.0;
  }
  else if (tag == 0x0205)
  { // Pentax K-m has multiexposure set to 8 when no multi-exposure is in effect
    if (len < 25)
    {
      fseek(ifp, 10, SEEK_CUR);
      imPentax.MultiExposure = fgetc(ifp) & 0x0f;
    }
  }
  else if (tag == 0x0207)
  {
    if (len < 65535) // Safety belt
      PentaxLensInfo(ilm.CamID, len);
  }
  else if ((tag >= 0x020d) && (tag <= 0x0214))
  {
    FORC4 imgdata.color.WB_Coeffs[Pentax_wb_list1[tag - 0x020d]][c ^ (c >> 1)] =
        get2();
  }

  else if ((tag == 0x0220) && (dng_writer == nonDNG)) {
    meta_offset = ftell(ifp);
  }

  else if (tag == 0x0221)
  {
    int nWB = get2();
    if (nWB <= sizeof(imgdata.color.WBCT_Coeffs) /
                   sizeof(imgdata.color.WBCT_Coeffs[0]))
      FORC(nWB)
      {
        imgdata.color.WBCT_Coeffs[c][0] = (unsigned)0xcfc6 - get2();
        fseek(ifp, 2, SEEK_CUR);
        imgdata.color.WBCT_Coeffs[c][1] = get2();
        imgdata.color.WBCT_Coeffs[c][2] = imgdata.color.WBCT_Coeffs[c][4] =
            0x2000;
        imgdata.color.WBCT_Coeffs[c][3] = get2();
      }
  }
  else if (tag == 0x0215)
  {
    fseek(ifp, 16, SEEK_CUR);
    sprintf(imgdata.shootinginfo.InternalBodySerial, "%d", get4());
  }
  else if (tag == 0x0229)
  {
    stmread(imgdata.shootinginfo.BodySerial, len, ifp);
  }
  else if (tag == 0x022d)
  {
    int wb_ind;
    getc(ifp);
    for (int wb_cnt = 0; wb_cnt < nPentax_wb_list2; wb_cnt++)
    {
      wb_ind = getc(ifp);
      if (wb_ind >= 0 && wb_ind < nPentax_wb_list2)
        FORC4 imgdata.color.WB_Coeffs[Pentax_wb_list2[wb_ind]][c ^ (c >> 1)] =
            get2();
    }
  }
  else if (tag == 0x0239)
  { // Q-series lens info (LensInfoQ)
    char LensInfo[20];
    fseek(ifp, 12, SEEK_CUR);
    stread(ilm.Lens, 30, ifp);
    strcat(ilm.Lens, " ");
    stread(LensInfo, 20, ifp);
    strcat(ilm.Lens, LensInfo);
  }
}

Project: LibRaw

void LibRaw::convert_to_rgb_loop(float out_cam[3][4]) {}

Project: LibRaw

void LibRaw::raw2image_start(){}

Project: LibRaw

  libraw_iparams_t *libraw_get_iparams(libraw_data_t *lr)
  {
    if (!lr)
      return NULL;
    return &(lr->idata);
  }

Project: LibRaw

void LibRaw::parseAdobePanoMakernote()
{
  uchar *PrivateMknBuf;
  unsigned posPrivateMknBuf;
  unsigned PrivateMknLength;
  unsigned PrivateOrder;
  unsigned PrivateEntries, PrivateTagID, PrivateTagType, PrivateTagCount;
  unsigned PrivateTagBytes;
  int truncated;

#define CHECKSPACE(s)                                                          \
  if (posPrivateMknBuf + (s) > PrivateMknLength)                               \
  {                                                                            \
    free(PrivateMknBuf);                                                       \
    return;                                                                    \
  }
#define icWBC imgdata.color.WB_Coeffs

  order = 0x4d4d;
  truncated = 0;
  PrivateMknLength = get4();

  if ((PrivateMknLength > 4) && (PrivateMknLength < 10240000) &&
      (PrivateMknBuf = (uchar *)malloc(PrivateMknLength + 1024)))
  { // 1024b for safety
    fread(PrivateMknBuf, PrivateMknLength, 1, ifp);
    PrivateOrder = sget2(PrivateMknBuf);
    PrivateEntries = sget2(PrivateMknBuf + 2);
    if ((PrivateEntries > 1000) ||
        ((PrivateOrder != 0x4d4d) && (PrivateOrder != 0x4949)))
    {
      free(PrivateMknBuf);
      return;
    }
    posPrivateMknBuf = 4;
    while (PrivateEntries--)
    {
      order = 0x4d4d;
      CHECKSPACE(8);
      PrivateTagID = sget2(PrivateMknBuf + posPrivateMknBuf);
      PrivateTagType = sget2(PrivateMknBuf + posPrivateMknBuf + 2);
      PrivateTagCount = sget4(PrivateMknBuf + posPrivateMknBuf + 4);
      posPrivateMknBuf += 8;
      order = PrivateOrder;

      if (truncated && !PrivateTagCount)
        continue;

      PrivateTagBytes =
          PrivateTagCount *
          ("11124811248484"[PrivateTagType < 14 ? PrivateTagType : 0] - '0');

      if (PrivateTagID == 0x0002)
      {
        posPrivateMknBuf += 2;
        CHECKSPACE(2);
        if (sget2(PrivateMknBuf + posPrivateMknBuf))
        {
          truncated = 1;
        }
        else
        {
          posPrivateMknBuf += 2;
        }
      }
      else if (PrivateTagID == 0x0013)
      {
        ushort nWB, cnt, tWB;
        CHECKSPACE(2);
        nWB = sget2(PrivateMknBuf + posPrivateMknBuf);
        posPrivateMknBuf += 2;
        if (nWB > 0x100)
          break;
        for (cnt = 0; cnt < nWB; cnt++)
        {
          CHECKSPACE(2);
          tWB = sget2(PrivateMknBuf + posPrivateMknBuf);
          if (tWB < 0x100)
          {
            CHECKSPACE(4);
            icWBC[tWB][0] = sget2(PrivateMknBuf + posPrivateMknBuf + 2);
            icWBC[tWB][2] = sget2(PrivateMknBuf + posPrivateMknBuf + 4);
            icWBC[tWB][1] = icWBC[tWB][3] = 0x100;
          }
          posPrivateMknBuf += 6;
        }
      }
      else if (PrivateTagID == 0x0027)
      {
        ushort nWB, cnt, tWB;
        CHECKSPACE(2);
        nWB = sget2(PrivateMknBuf + posPrivateMknBuf);
        posPrivateMknBuf += 2;
        if (nWB > 0x100)
          break;
        for (cnt = 0; cnt < nWB; cnt++)
        {
          CHECKSPACE(2);
          tWB = sget2(PrivateMknBuf + posPrivateMknBuf);
          if (tWB < 0x100)
          {
            CHECKSPACE(6);
            icWBC[tWB][0] = sget2(PrivateMknBuf + posPrivateMknBuf + 2);
            icWBC[tWB][1] = icWBC[tWB][3] =
                sget2(PrivateMknBuf + posPrivateMknBuf + 4);
            icWBC[tWB][2] = sget2(PrivateMknBuf + posPrivateMknBuf + 6);
          }
          posPrivateMknBuf += 8;
        }
      }
      else if (PrivateTagID == 0x0121)
      {
        CHECKSPACE(4);
        imPana.Multishot = sget4(PrivateMknBuf + posPrivateMknBuf);
        posPrivateMknBuf += 4;
      }
      else
      {
        if (PrivateTagBytes > 4)
          posPrivateMknBuf += PrivateTagBytes;
        else if (!truncated)
          posPrivateMknBuf += 4;
        else
        {
          if (PrivateTagBytes <= 2)
            posPrivateMknBuf += 2;
          else
            posPrivateMknBuf += 4;
        }
      }
    }
    free(PrivateMknBuf);
  }
#undef icWBC
#undef CHECKSPACE
}

Project: LibRaw

  int libraw_dcraw_process(libraw_data_t *lr)
  {
    if (!lr)
      return EINVAL;
    LibRaw *ip = (LibRaw *)lr->parent_class;
    return ip->dcraw_process();
  }

Project: LibRaw

void DHT::refine_diag_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)] & DIASH)
      continue;
    int nv = (ndir[nr_offset(y - 1, x)] & LURD) +
             (ndir[nr_offset(y + 1, x)] & LURD) +
             (ndir[nr_offset(y, x - 1)] & LURD) +
             (ndir[nr_offset(y, x + 1)] & LURD) +
             (ndir[nr_offset(y - 1, x - 1)] & LURD) +
             (ndir[nr_offset(y - 1, x + 1)] & LURD) +
             (ndir[nr_offset(y + 1, x - 1)] & LURD) +
             (ndir[nr_offset(y + 1, x + 1)] & LURD);
    int nh = (ndir[nr_offset(y - 1, x)] & RULD) +
             (ndir[nr_offset(y + 1, x)] & RULD) +
             (ndir[nr_offset(y, x - 1)] & RULD) +
             (ndir[nr_offset(y, x + 1)] & RULD) +
             (ndir[nr_offset(y - 1, x - 1)] & RULD) +
             (ndir[nr_offset(y - 1, x + 1)] & RULD) +
             (ndir[nr_offset(y + 1, x - 1)] & RULD) +
             (ndir[nr_offset(y + 1, x + 1)] & RULD);
    bool codir = (ndir[nr_offset(y, x)] & LURD)
                     ? ((ndir[nr_offset(y - 1, x - 1)] & LURD) ||
                        (ndir[nr_offset(y + 1, x + 1)] & LURD))
                     : ((ndir[nr_offset(y - 1, x + 1)] & RULD) ||
                        (ndir[nr_offset(y + 1, x - 1)] & RULD));
    nv /= LURD;
    nh /= RULD;
    if ((ndir[nr_offset(y, x)] & LURD) && (nh > 4 && !codir))
    {
      ndir[nr_offset(y, x)] &= ~LURD;
      ndir[nr_offset(y, x)] |= RULD;
    }
    if ((ndir[nr_offset(y, x)] & RULD) && (nv > 4 && !codir))
    {
      ndir[nr_offset(y, x)] &= ~RULD;
      ndir[nr_offset(y, x)] |= LURD;
    }
  }
}

Project: LibRaw

void LibRaw::ppm16_thumb(){}

Project: LibRaw

unsigned LibRaw::getint(int type) { return type == 3 ? get2() : get4(); }

Project: LibRaw

  int get_diag_grb(int x, int y, int kc)
  {
    float hlu =
        nraw[nr_offset(y - 1, x - 1)][1] / nraw[nr_offset(y - 1, x - 1)][kc];
    float hrd =
        nraw[nr_offset(y + 1, x + 1)][1] / nraw[nr_offset(y + 1, x + 1)][kc];
    float hru =
        nraw[nr_offset(y - 1, x + 1)][1] / nraw[nr_offset(y - 1, x + 1)][kc];
    float hld =
        nraw[nr_offset(y + 1, x - 1)][1] / nraw[nr_offset(y + 1, x - 1)][kc];
    float dlurd =
        calc_dist(hlu, hrd) *
        calc_dist(nraw[nr_offset(y - 1, x - 1)][1] *
                      nraw[nr_offset(y + 1, x + 1)][1],
                  nraw[nr_offset(y, x)][1] * nraw[nr_offset(y, x)][1]);
    float druld =
        calc_dist(hlu, hrd) *
        calc_dist(nraw[nr_offset(y - 1, x + 1)][1] *
                      nraw[nr_offset(y + 1, x - 1)][1],
                  nraw[nr_offset(y, x)][1] * nraw[nr_offset(y, x)][1]);
    float e = calc_dist(dlurd, druld);
    char d =
        druld < dlurd ? (e > T() ? RULDSH : RULD) : (e > T() ? LURDSH : LURD);
    return d;
  }

Project: LibRaw

void LibRaw::process_Sony_0x9400(uchar *buf, ushort len, unsigned long long id)
{

  uchar s[4];
  int c;
  uchar bufx = buf[0];

  if (((bufx == 0x23) || (bufx == 0x24) || (bufx == 0x26) || (bufx == 0x28)) &&
      (len >= 0x1f))
  { // 0x9400 'c' version

    if ((id == 0x166ULL) || // ILCE-9
        (id == 0x16aULL) || // ILCE-7RM3
        (id == 0x16bULL) || // ILCE-7M3
        (id == 0x16dULL) || // DSC-RX10M4
        (id == 0x16eULL) || // DSC-RX100M6
        (id == 0x171ULL) || // DSC-RX100M5A
        (id == 0x173ULL) || // ILCE-6400
        (id == 0x174ULL) || // DSC-RX0M2
        (id == 0x176ULL) || // DSC-RX100M7
        (id == 0x177ULL) || // ILCE-7RM4
        (id == 0x17aULL) || // ILCE-6600
        (id == 0x17bULL)    // ILCE-6100
    )
    {
      imSony.ShotNumberSincePowerUp = SonySubstitution[buf[0x0a]];
    }
    else
    {
      FORC4 s[c] = SonySubstitution[buf[0x0a + c]];
      imSony.ShotNumberSincePowerUp = sget4(s);
    }

    imSony.Sony0x9400_version = 0xc;

    imSony.Sony0x9400_ReleaseMode2 = SonySubstitution[buf[0x09]];

    FORC4 s[c] = SonySubstitution[buf[0x12 + c]];
    imSony.Sony0x9400_SequenceImageNumber = sget4(s);

    imSony.Sony0x9400_SequenceLength1 = SonySubstitution[buf[0x16]]; // shots

    FORC4 s[c] = SonySubstitution[buf[0x1a + c]];
    imSony.Sony0x9400_SequenceFileNumber = sget4(s);

    imSony.Sony0x9400_SequenceLength2 = SonySubstitution[buf[0x1e]]; // files
  }

  else if ((bufx == 0x0c) && (len >= 0x1f))
  { // 0x9400 'b' version
    imSony.Sony0x9400_version = 0xb;

    FORC4 s[c] = SonySubstitution[buf[0x08 + c]];
    imSony.Sony0x9400_SequenceImageNumber = sget4(s);

    FORC4 s[c] = SonySubstitution[buf[0x0c + c]];
    imSony.Sony0x9400_SequenceFileNumber = sget4(s);

    imSony.Sony0x9400_ReleaseMode2 = SonySubstitution[buf[0x10]];

    imSony.Sony0x9400_SequenceLength1 = SonySubstitution[buf[0x1e]];
  }

  else if ((bufx == 0x0a) && (len >= 0x23))
  { // 0x9400 'a' version
    imSony.Sony0x9400_version = 0xa;

    FORC4 s[c] = SonySubstitution[buf[0x08 + c]];
    imSony.Sony0x9400_SequenceImageNumber = sget4(s);

    FORC4 s[c] = SonySubstitution[buf[0x0c + c]];
    imSony.Sony0x9400_SequenceFileNumber = sget4(s);

    imSony.Sony0x9400_ReleaseMode2 = SonySubstitution[buf[0x10]];

    imSony.Sony0x9400_SequenceLength1 = SonySubstitution[buf[0x22]];
  }

  else
    return;
}

Project: LibRaw

void LibRaw::imacon_full_load_raw()
{
  if (!image)
    throw LIBRAW_EXCEPTION_IO_CORRUPT;
  int row, col;

  unsigned short *buf =
      (unsigned short *)malloc(width * 3 * sizeof(unsigned short));
  merror(buf, "imacon_full_load_raw");

  for (row = 0; row < height; row++)
  {
    checkCancel();
    read_shorts(buf, width * 3);
    unsigned short(*rowp)[4] = &image[row * width];
    for (col = 0; col < width; col++)
    {
      rowp[col][0] = buf[col * 3];
      rowp[col][1] = buf[col * 3 + 1];
      rowp[col][2] = buf[col * 3 + 2];
      rowp[col][3] = 0;
    }
  }
  free(buf);
}

Project: LibRaw

void LibRaw::pseudoinverse(double (*in)[3], double (*out)[3], int size)
{
  double work[3][6], num;
  int i, j, k;

  for (i = 0; i < 3; i++)
  {
    for (j = 0; j < 6; j++)
      work[i][j] = j == i + 3;
    for (j = 0; j < 3; j++)
      for (k = 0; k < size; k++)
        work[i][j] += in[k][i] * in[k][j];
  }
  for (i = 0; i < 3; i++)
  {
    num = work[i][i];
    for (j = 0; j < 6; j++)
      if (fabs(num) > 0.00001f)
        work[i][j] /= num;
    for (k = 0; k < 3; k++)
    {
      if (k == i)
        continue;
      num = work[k][i];
      for (j = 0; j < 6; j++)
        work[k][j] -= work[i][j] * num;
    }
  }
  for (i = 0; i < size; i++)
    for (j = 0; j < 3; j++)
      for (out[i][j] = k = 0; k < 3; k++)
        out[i][j] += work[j][k + 3] * in[i][k];
}

Project: LibRaw

void LibRaw::phase_one_load_raw_c()
{
  static const int length[] = {8, 7, 6, 9, 11, 10, 5, 12, 14, 13};
  int *offset, len[2], pred[2], row, col, i, j;
  ushort *pixel;
  short(*c_black)[2], (*r_black)[2];
  if (ph1.format == 6)
    throw LIBRAW_EXCEPTION_IO_CORRUPT;

  pixel = (ushort *)calloc(raw_width * 3 + raw_height * 4, 2);
  merror(pixel, "phase_one_load_raw_c()");
  offset = (int *)(pixel + raw_width);
  fseek(ifp, strip_offset, SEEK_SET);
  for (row = 0; row < raw_height; row++)
    offset[row] = get4();
  c_black = (short(*)[2])(offset + raw_height);
  fseek(ifp, ph1.black_col, SEEK_SET);
  if (ph1.black_col)
    read_shorts((ushort *)c_black[0], raw_height * 2);
  r_black = c_black + raw_height;
  fseek(ifp, ph1.black_row, SEEK_SET);
  if (ph1.black_row)
    read_shorts((ushort *)r_black[0], raw_width * 2);

  // Copy data to internal copy (ever if not read)
  if (ph1.black_col || ph1.black_row)
  {
    imgdata.rawdata.ph1_cblack =
        (short(*)[2])calloc(raw_height * 2, sizeof(ushort));
    merror(imgdata.rawdata.ph1_cblack, "phase_one_load_raw_c()");
    memmove(imgdata.rawdata.ph1_cblack, (ushort *)c_black[0],
            raw_height * 2 * sizeof(ushort));
    imgdata.rawdata.ph1_rblack =
        (short(*)[2])calloc(raw_width * 2, sizeof(ushort));
    merror(imgdata.rawdata.ph1_rblack, "phase_one_load_raw_c()");
    memmove(imgdata.rawdata.ph1_rblack, (ushort *)r_black[0],
            raw_width * 2 * sizeof(ushort));
  }

  for (i = 0; i < 256; i++)
    curve[i] = i * i / 3.969 + 0.5;
  try
  {
    for (row = 0; row < raw_height; row++)
    {
      checkCancel();
      fseek(ifp, data_offset + offset[row], SEEK_SET);
      ph1_bits(-1);
      pred[0] = pred[1] = 0;
      for (col = 0; col < raw_width; col++)
      {
        if (col >= (raw_width & -8))
          len[0] = len[1] = 14;
        else if ((col & 7) == 0)
          for (i = 0; i < 2; i++)
          {
            for (j = 0; j < 5 && !ph1_bits(1); j++)
              ;
            if (j--)
              len[i] = length[j * 2 + ph1_bits(1)];
          }
        if ((i = len[col & 1]) == 14)
          pixel[col] = pred[col & 1] = ph1_bits(16);
        else
          pixel[col] = pred[col & 1] += ph1_bits(i) + 1 - (1 << (i - 1));
        if (pred[col & 1] >> 16)
          derror();
        if (ph1.format == 5 && pixel[col] < 256)
          pixel[col] = curve[pixel[col]];
      }
      if (ph1.format == 8)
        memmove(&RAW(row, 0), &pixel[0], raw_width * 2);
      else
        for (col = 0; col < raw_width; col++)
          RAW(row, col) = pixel[col] << 2;
    }
  }
  catch (...)
  {
    free(pixel);
    throw;
  }
  free(pixel);
  maximum = 0xfffc - ph1.t_black;
}

Project: LibRaw

void LibRaw::parseRicohMakernotes(int base, unsigned tag, unsigned type,
                                  unsigned len, unsigned dng_writer)
{
  char buffer[17];
  if (tag == 0x0005)
  {
    int c;
    int count = 0;
    fread(buffer, 16, 1, ifp);
    buffer[16] = 0;
    FORC(16)
    {
      if ((isspace(buffer[c])) || (buffer[c] == 0x2D) || (isalnum(buffer[c])))
        count++;
      else
        break;
    }
    if (count == 16)
    {
      if (strncmp(model, "GXR", 3))
      {
        sprintf(imgdata.shootinginfo.BodySerial, "%8s", buffer + 8);
      }
      buffer[8] = 0;
      sprintf(imgdata.shootinginfo.InternalBodySerial, "%8s", buffer);
    }
    else
    {
      sprintf(imgdata.shootinginfo.BodySerial, "%02x%02x%02x%02x", buffer[4],
              buffer[5], buffer[6], buffer[7]);
      sprintf(imgdata.shootinginfo.InternalBodySerial, "%02x%02x%02x%02x",
              buffer[8], buffer[9], buffer[10], buffer[11]);
    }
  }
  else if ((tag == 0x1001) && (type == 3))
  {
    ilm.CameraMount = LIBRAW_MOUNT_FixedLens;
    ilm.LensMount = LIBRAW_MOUNT_FixedLens;
    ilm.CameraFormat = LIBRAW_FORMAT_APSC;
    ilm.LensID = -1;
    ilm.FocalType = LIBRAW_FT_PRIME_LENS;
    imgdata.shootinginfo.ExposureProgram = get2();
  }
  else if (tag == 0x1002)
  {
    imgdata.shootinginfo.DriveMode = get2();
  }
  else if (tag == 0x1006)
  {
    imgdata.shootinginfo.FocusMode = get2();
  }
  else if ((tag == 0x100b) && (type == 10))
  {
    imgdata.makernotes.common.FlashEC = getreal(type);
  }
  else if ((tag == 0x1017) && (get2() == 2))
  {
    strcpy(ilm.Attachment, "Wide-Angle Adapter");
  }
  else if (tag == 0x1500)
  {
    ilm.CurFocal = getreal(type);
  }
  else if ((tag == 0x2001) && !strncmp(model, "GXR", 3))
  {
    short ntags, cur_tag;
    fseek(ifp, 20, SEEK_CUR);
    ntags = get2();
    cur_tag = get2();
    while (cur_tag != 0x002c)
    {
      fseek(ifp, 10, SEEK_CUR);
      cur_tag = get2();
    }
    fseek(ifp, 6, SEEK_CUR);
    fseek(ifp, get4(), SEEK_SET);
    for (int i=0; i<4; i++) {
      stread(buffer, 16, ifp);
      if ((buffer[0] == 'S') && (buffer[1] == 'I') && (buffer[2] == 'D'))
			  memcpy(imgdata.shootinginfo.BodySerial, buffer+4, 12);
      else if ((buffer[0] == 'R') && (buffer[1] == 'L'))
			  ilm.LensID = buffer[2] - '0';
      else if ((buffer[0] == 'L') && (buffer[1] == 'I') && (buffer[2] == 'D'))
			  memcpy(imgdata.lens.LensSerial, buffer+4, 12);
    }
  }
}

Project: LibRaw

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

Project: LibRaw

void LibRaw::bad_pixels(const char *cfname)
{
  FILE *fp = NULL;
  char *cp, line[128];
  int time, row, col, r, c, rad, tot, n;

  if (!filters)
    return;
  RUN_CALLBACK(LIBRAW_PROGRESS_BAD_PIXELS, 0, 2);
  if (cfname)
    fp = fopen(cfname, "r");
  if (!fp)
  {
    imgdata.process_warnings |= LIBRAW_WARN_NO_BADPIXELMAP;
    return;
  }
  while (fgets(line, 128, fp))
  {
    cp = strchr(line, '#');
    if (cp)
      *cp = 0;
    if (sscanf(line, "%d %d %d", &col, &row, &time) != 3)
      continue;
    if ((unsigned)col >= width || (unsigned)row >= height)
      continue;
    if (time > timestamp)
      continue;
    for (tot = n = 0, rad = 1; rad < 3 && n == 0; rad++)
      for (r = row - rad; r <= row + rad; r++)
        for (c = col - rad; c <= col + rad; c++)
          if ((unsigned)r < height && (unsigned)c < width &&
              (r != row || c != col) && fcol(r, c) == fcol(row, col))
          {
            tot += BAYER2(r, c);
            n++;
          }
    if (n > 0)
      BAYER2(row, col) = tot / n;
  }
  fclose(fp);
  RUN_CALLBACK(LIBRAW_PROGRESS_BAD_PIXELS, 1, 2);
}

Project: LibRaw

void DHT::make_rb()
{
#if defined(LIBRAW_USE_OPENMP)
#pragma omp barrier
#pragma omp parallel for schedule(guided)
#endif
  for (int i = 0; i < libraw.imgdata.sizes.iheight; ++i)
  {
    make_rbdiag(i);
  }
#if defined(LIBRAW_USE_OPENMP)
#pragma omp barrier
#pragma omp parallel for schedule(guided)
#endif
  for (int i = 0; i < libraw.imgdata.sizes.iheight; ++i)
  {
    make_rbhv(i);
  }
}

Project: LibRaw

const char *LibRaw::cameramakeridx2maker(unsigned maker)
{
    for (int i = 0; i < sizeof CorpTable / sizeof *CorpTable; i++)
        if(CorpTable[i].CorpId == maker)
            return CorpTable[i].CorpName;
    return 0;
}

Project: LibRaw

int LibRaw_bigfile_datastream::scanf_one(const char *fmt, void *val)
{
  LR_BF_CHK();
  return 
#ifndef WIN32SECURECALLS
                   fscanf(f, fmt, val)
#else
                   fscanf_s(f, fmt, val)
#endif
      ;
}

Project: LibRaw

void print_unpackfun(FILE* outfile, LibRaw& MyCoolRawProcessor, int print_frame, std::string& fn)
{
	char frame[48] = "";
	if (print_frame)
	{
		ushort right_margin = S.raw_width - S.width - S.left_margin;
		ushort bottom_margin = S.raw_height - S.height - S.top_margin;
		snprintf(frame, 48, "F=%dx%dx%dx%d RS=%dx%d", S.left_margin,
			S.top_margin, right_margin, bottom_margin, S.raw_width,
			S.raw_height);
	}
	fprintf(outfile, "%s\t%s\t%s\t%s/%s\n", fn.c_str(),MyCoolRawProcessor.unpack_function_name(), frame, P1.make,	P1.model);
}

Project: LibRaw

void LibRaw::get_timestamp(int reversed)
{
  struct tm t;
  char str[20];
  int i;

  str[19] = 0;
  if (reversed)
    for (i = 19; i--;)
      str[i] = fgetc(ifp);
  else
    fread(str, 19, 1, ifp);
  memset(&t, 0, sizeof t);
  if (sscanf(str, "%d:%d:%d %d:%d:%d", &t.tm_year, &t.tm_mon, &t.tm_mday,
             &t.tm_hour, &t.tm_min, &t.tm_sec) != 6)
    return;
  t.tm_year -= 1900;
  t.tm_mon -= 1;
  t.tm_isdst = -1;
  if (mktime(&t) > 0)
    timestamp = mktime(&t);
}

Project: LibRaw

void LibRaw::nikon_coolscan_load_raw()
{
  if (!image)
    throw LIBRAW_EXCEPTION_IO_CORRUPT;

  int bypp = tiff_bps <= 8 ? 1 : 2;
  int bufsize = width * 3 * bypp;
  unsigned char *buf = (unsigned char *)malloc(bufsize);
  unsigned short *ubuf = (unsigned short *)buf;

  if (tiff_bps <= 8)
    gamma_curve(1.0 / imgdata.params.coolscan_nef_gamma, 0., 1, 255);
  else
    gamma_curve(1.0 / imgdata.params.coolscan_nef_gamma, 0., 1, 65535);
  fseek(ifp, data_offset, SEEK_SET);
  for (int row = 0; row < raw_height; row++)
  {
      if(tiff_bps <=8)
        fread(buf, 1, bufsize, ifp);
      else
          read_shorts(ubuf,width*3);
    unsigned short(*ip)[4] = (unsigned short(*)[4])image + row * width;
    if (is_NikonTransfer == 2)
    { // it is also (tiff_bps == 8)
      for (int col = 0; col < width; col++)
      {
        ip[col][0] = ((float)curve[buf[col * 3]]) / 255.0f;
        ip[col][1] = ((float)curve[buf[col * 3 + 1]]) / 255.0f;
        ip[col][2] = ((float)curve[buf[col * 3 + 2]]) / 255.0f;
        ip[col][3] = 0;
      }
    }
    else if (tiff_bps <= 8)
    {
      for (int col = 0; col < width; col++)
      {
        ip[col][0] = curve[buf[col * 3]];
        ip[col][1] = curve[buf[col * 3 + 1]];
        ip[col][2] = curve[buf[col * 3 + 2]];
        ip[col][3] = 0;
      }
    }
    else
    {
      for (int col = 0; col < width; col++)
      {
        ip[col][0] = curve[ubuf[col * 3]];
        ip[col][1] = curve[ubuf[col * 3 + 1]];
        ip[col][2] = curve[ubuf[col * 3 + 2]];
        ip[col][3] = 0;
      }
    }
  }
  free(buf);
}

Project: LibRaw

int LibRaw::canon_s2is()
{
  unsigned row;

  for (row = 0; row < 100; row++)
  {
    fseek(ifp, row * 3340 + 3284, SEEK_SET);
    if (getc(ifp) > 15)
      return 1;
  }
  return 0;
}

Project: LibRaw

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

  ushort *rafdata;

  if (tiff_nifds >= sizeof tiff_ifd / sizeof tiff_ifd[0])
    return 1;
  ifd = tiff_nifds++;
  for (j = 0; j < 4; j++)
    for (i = 0; i < 4; i++)
      cc[j][i] = i == j;
  entries = get2();
  if (entries > 512)
    return 1;

  INT64 fsize = ifp->size();

  while (entries--)
  {
    tiff_get(base, &tag, &type, &len, &save);
    INT64 savepos = ftell(ifp);
    if (len > 8 && savepos + len > 2 * fsize)
    {
      fseek(ifp, save, SEEK_SET); // Recover tiff-read position!!
      continue;
    }
    if (callbacks.exif_cb)
    {
      callbacks.exif_cb(callbacks.exifparser_data,
                        tag | (is_pana_raw ? 0x30000 : ((ifd + 1) << 20)), type,
                        len, order, ifp, base);
      fseek(ifp, savepos, SEEK_SET);
    }

    if (!is_pana_raw)
    { /* processing of EXIF tags that collide w/ PanasonicRaw tags */
      switch (tag)
      {
      case 0x0001:
        if (len == 4)
          is_pana_raw = get4();
        break;
      case 0x000b: /* 11, Std. EXIF Software tag */
        fgets(software, 64, ifp);
        if (!strncmp(software, "Adobe", 5) || !strncmp(software, "dcraw", 5) ||
            !strncmp(software, "UFRaw", 5) || !strncmp(software, "Bibble", 6) ||
            !strcmp(software, "Digital Photo Professional"))
          is_raw = 0;
        break;
      case 0x001c: /*  28, safeguard, probably not needed */
      case 0x001d: /*  29, safeguard, probably not needed */
      case 0x001e: /*  30, safeguard, probably not needed */
        cblack[tag - 0x001c] = get2();
        cblack[3] = cblack[1];
        break;

      case 0x0111: /* 273, StripOffset */
        if (len > 1 && len < 16384)
        {
          off_t sav = ftell(ifp);
          tiff_ifd[ifd].strip_offsets = (int *)calloc(len, sizeof(int));
          tiff_ifd[ifd].strip_offsets_count = len;
          for (int i = 0; i < len; i++)
            tiff_ifd[ifd].strip_offsets[i] = get4() + base;
          fseek(ifp, sav, SEEK_SET); // restore position
        }
        /* fallback */
      case 0x0201: /* 513, JpegIFOffset */
      case 0xf007: // 61447
        tiff_ifd[ifd].offset = get4() + base;
        if (!tiff_ifd[ifd].bps && tiff_ifd[ifd].offset > 0)
        {
          fseek(ifp, tiff_ifd[ifd].offset, SEEK_SET);
          if (ljpeg_start(&jh, 1))
          {
            tiff_ifd[ifd].comp = 6;
            tiff_ifd[ifd].t_width = jh.wide;
            tiff_ifd[ifd].t_height = jh.high;
            tiff_ifd[ifd].bps = jh.bits;
            tiff_ifd[ifd].samples = jh.clrs;
            if (!(jh.sraw || (jh.clrs & 1)))
              tiff_ifd[ifd].t_width *= jh.clrs;
            if ((tiff_ifd[ifd].t_width > 4 * tiff_ifd[ifd].t_height) & ~jh.clrs)
            {
              tiff_ifd[ifd].t_width /= 2;
              tiff_ifd[ifd].t_height *= 2;
            }
            i = order;
            parse_tiff(tiff_ifd[ifd].offset + 12);
            order = i;
          }
        }
        break;
      }
    }
    else
    { /* processing Panasonic-specific "PanasonicRaw" tags */
      switch (tag)
      {
      case 0x0004: /*   4, SensorTopBorder */
        imgdata.sizes.raw_inset_crop.ctop = get2();
        break;
      case 0x000a: /*  10, BitsPerSample */
        pana_bpp = get2();
        break;
      case 0x000b: /*  11, Compression */
        imPana.Compression = get2();
        break;
      case 0x000e: /*  14, LinearityLimitRed */
      case 0x000f: /*  15, LinearityLimitGreen */
      case 0x0010: /*  16, LinearityLimitBlue */
        imgdata.color.linear_max[tag - 14] = get2();
        if (tag == 0x000f) // 15, LinearityLimitGreen
          imgdata.color.linear_max[3] = imgdata.color.linear_max[1];
        break;
      case 0x0013: /*  19, WBInfo */
        if ((i = get2()) > 0x100)
          break;
        for (c = 0; c < i; c++)
        {
          if ((j = get2()) < 0x100)
          {
            imgdata.color.WB_Coeffs[j][0] = get2();
            imgdata.color.WB_Coeffs[j][2] = get2();
            imgdata.color.WB_Coeffs[j][1] = imgdata.color.WB_Coeffs[j][3] =
                0x100;
          }
          else // light source out of EXIF numbers range
            get4();
        }
        break;
      case 0x0018: /* 24, HighISOMultiplierRed */
      case 0x0019: /* 25, HighISOMultiplierGreen */
      case 0x001a: /* 26, HighISOMultiplierBlue */
        imPana.HighISOMultiplier[tag - 0x0018] = get2();
        break;
      case 0x001c: /*  28, BlackLevelRed */
      case 0x001d: /*  29, BlackLevelGreen */
      case 0x001e: /*  30, BlackLevelBlue */
        pana_black[tag - 0x001c] = get2();
        break;
      case 0x002d: /*  45, RawFormat */
                   /* pana_encoding: tag 0x002d (45dec)
                        not used - DMC-LX1/FZ30/FZ50/L1/LX1/LX2
                        2 - RAW DMC-FZ8/FZ18
                        3 - RAW DMC-L10
                        4 - RW2 for most other models, including G9 in "pixel shift off"
                      mode and YUNEEC CGO4            (must add 15 to black levels for RawFormat == 4)
                        5 - RW2 DC-GH5s; G9 in "pixel shift on" mode
                        6 - RW2 DC-S1, DC-S1R in "pixel shift off" mode
                        7 - RW2 DC-S1R (probably DC-S1 too) in "pixel shift on" mode
                   */
        pana_encoding = get2();
        break;
      case 0x002f: /*  47, CropTop */
        imgdata.sizes.raw_inset_crop.ctop = get2();
        break;
      case 0x0030: /*  48, CropLeft */
        imgdata.sizes.raw_inset_crop.cleft = get2();
        break;
      case 0x0031: /*  49, CropBottom */
        imgdata.sizes.raw_inset_crop.cheight =
            get2() - imgdata.sizes.raw_inset_crop.ctop;
        break;
      case 0x0032: /*  50, CropRight */
        imgdata.sizes.raw_inset_crop.cwidth =
            get2() - imgdata.sizes.raw_inset_crop.cleft;
        break;
      case 0x0037: /*  55, ISO if  ISO in 0x8827 & ISO in 0x0017 == 65535 */
        if (iso_speed == 65535)
          iso_speed = get4();
        break;
      case 0x011c: /* 284, Gamma */
      {
        int n = get2();
        if (n >= 1024)
          imPana.gamma = (float)n / 1024.0f;
        else if (n >= 256)
          imPana.gamma = (float)n / 256.0f;
        else
          imPana.gamma = (float)n / 100.0f;
      }
      break;
      case 0x0120: /* 288, CameraIFD, contains tags 0x1xxx, 0x2xxx, 0x3xxx */
      {
        unsigned sorder = order;
        unsigned long sbase = base;
        base = ftell(ifp);
        order = get2();
        fseek(ifp, 2, SEEK_CUR);
        fseek(ifp, get4() - 8, SEEK_CUR);
        parse_tiff_ifd(base);
        base = sbase;
        order = sorder;
      }
      break;
      case 0x0121: /* 289, Multishot, 0 is Off, 65536 is Pixel Shift */
        imPana.Multishot = get4();
        break;
      case 0x1203: /* 4611, FocalLengthIn35mmFormat, contained in 0x0120
                      CameraIFD */
        if (imgdata.lens.FocalLengthIn35mmFormat < 0.65f)
          imgdata.lens.FocalLengthIn35mmFormat = get2();
        break;
      case 0x2009: /* 8201, contained in 0x0120 CameraIFD */
        if ((pana_encoding == 4) || (pana_encoding == 5))
        {
          i = MIN(8, len);
          int permut[8] = {3, 2, 1, 0, 3 + 4, 2 + 4, 1 + 4, 0 + 4};
          imPana.BlackLevelDim = len;
          for (j = 0; j < i; j++)
          {
            imPana.BlackLevel[permut[j]] =
                (float)(get2()) / (float)(powf(2.f, 14.f - pana_bpp));
          }
        }
        break;
      case 0x3420: /* 13344, WB_RedLevelAuto, contained in 0x0120 CameraIFD */
        imgdata.color.WB_Coeffs[LIBRAW_WBI_Auto][0] = get2();
        imgdata.color.WB_Coeffs[LIBRAW_WBI_Auto][1] =
            imgdata.color.WB_Coeffs[LIBRAW_WBI_Auto][3] = 1024.0f;
        break;
      case 0x3421: /* 13345, WB_BlueLevelAuto, contained in 0x0120 CameraIFD */
        imgdata.color.WB_Coeffs[LIBRAW_WBI_Auto][2] = get2();
        break;
      case 0x0002: /*   2, ImageWidth */
        tiff_ifd[ifd].t_width = getint(type);
        break;
      case 0x0003: /*   3, ImageHeight */
        tiff_ifd[ifd].t_height = getint(type);
        break;
      case 0x0005: /*   5, SensorLeftBorder */
        width = get2();
        imgdata.sizes.raw_inset_crop.cleft = width;
        break;
      case 0x0006: /*   6, SensorBottomBorder */
        height = get2();
        imgdata.sizes.raw_inset_crop.cheight =
            height - imgdata.sizes.raw_inset_crop.ctop;
        break;
      case 0x0007: /*   7, SensorRightBorder */
        i = get2();
        width += i;
        imgdata.sizes.raw_inset_crop.cwidth =
            i - imgdata.sizes.raw_inset_crop.cleft;
        break;
      case 0x0009: /*   9, CFAPattern */
        if ((i = get2()))
          filters = i;
        break;
      case 0x0011: /*  17, RedBalance */
      case 0x0012: /*  18, BlueBalance */
        if (type == 3 && len == 1)
          cam_mul[(tag - 0x0011) * 2] = get2() / 256.0;
        break;
      case 0x0017: /*  23, ISO */
        if (type == 3)
          iso_speed = get2();
        break;
      case 0x0024: /*  36, WBRedLevel */
      case 0x0025: /*  37, WBGreenLevel */
      case 0x0026: /*  38, WBBlueLevel */
        cam_mul[tag - 0x0024] = get2();
        break;
      case 0x0027: /*  39, WBInfo2 */
        if ((i = get2()) > 0x100)
          break;
        for (c = 0; c < i; c++)
        {
          if ((j = get2()) < 0x100)
          {
            imgdata.color.WB_Coeffs[j][0] = get2();
            imgdata.color.WB_Coeffs[j][1] = imgdata.color.WB_Coeffs[j][3] =
                get2();
            imgdata.color.WB_Coeffs[j][2] = get2();
          }
          else
            fseek(ifp, 6, SEEK_CUR);
        }
        break;
        if (len < 50 || cam_mul[0] > 0.001f)
          break;
        fseek(ifp, 12, SEEK_CUR);
        FORC3 cam_mul[c] = get2();
        break;
      case 0x002e: /*  46, JpgFromRaw */
        if (type != 7 || fgetc(ifp) != 0xff || fgetc(ifp) != 0xd8)
          break;
        thumb_offset = ftell(ifp) - 2;
        thumb_length = len;
        break;

      case 0x0118: /* 280, Panasonic RW2 offset */
        if (type != 4)
          break;
        load_raw = &LibRaw::panasonic_load_raw;
        load_flags = 0x2008;
      case 0x0111: /* 273, StripOffset */
        if (len > 1 && len < 16384)
        {
          off_t sav = ftell(ifp);
          tiff_ifd[ifd].strip_offsets = (int *)calloc(len, sizeof(int));
          tiff_ifd[ifd].strip_offsets_count = len;
          for (int i = 0; i < len; i++)
            tiff_ifd[ifd].strip_offsets[i] = get4() + base;
          fseek(ifp, sav, SEEK_SET); // restore position
        }
        /* fallthrough */
        tiff_ifd[ifd].offset = get4() + base;
        if (!tiff_ifd[ifd].bps && tiff_ifd[ifd].offset > 0)
        {
          fseek(ifp, tiff_ifd[ifd].offset, SEEK_SET);
          if (ljpeg_start(&jh, 1))
          {
            tiff_ifd[ifd].comp = 6;
            tiff_ifd[ifd].t_width = jh.wide;
            tiff_ifd[ifd].t_height = jh.high;
            tiff_ifd[ifd].bps = jh.bits;
            tiff_ifd[ifd].samples = jh.clrs;
            if (!(jh.sraw || (jh.clrs & 1)))
              tiff_ifd[ifd].t_width *= jh.clrs;
            if ((tiff_ifd[ifd].t_width > 4 * tiff_ifd[ifd].t_height) & ~jh.clrs)
            {
              tiff_ifd[ifd].t_width /= 2;
              tiff_ifd[ifd].t_height *= 2;
            }
            i = order;
            parse_tiff(tiff_ifd[ifd].offset + 12);
            order = i;
          }
        }
        break;
      }

    } /* processing of Panasonic-specific tags finished */

    switch (tag)
    {            /* processing of general EXIF tags */
    case 0xf000: /* 61440, Fuji HS10 table */
      fseek(ifp, get4() + base, SEEK_SET);
      parse_tiff_ifd(base);
      break;
    case 0x00fe: /* NewSubfileType */
        tiff_ifd[ifd].newsubfiletype = getreal(type);
        break;
    case 0x0100: /* 256, ImageWidth */
    case 0xf001: /* 61441, Fuji RAF IFD 0xf001 RawImageFullWidth */
      tiff_ifd[ifd].t_width = getint(type);
      break;
    case 0x0101: /* 257, ImageHeight */
    case 0xf002: /* 61442, Fuji RAF IFD 0xf002 RawImageFullHeight */
      tiff_ifd[ifd].t_height = getint(type);
      break;
    case 0x0102: /* 258, BitsPerSample */
    case 0xf003: /* 61443, Fuji RAF IFD 0xf003 */
      tiff_ifd[ifd].samples = len & 7;
      tiff_ifd[ifd].bps = getint(type);
      if (tiff_bps < tiff_ifd[ifd].bps)
        tiff_bps = tiff_ifd[ifd].bps;
      break;
    case 0xf006: /* 61446, Fuji RAF IFD 0xf006 */
      raw_height = 0;
      if (tiff_ifd[ifd].bps > 12)
        break;
      load_raw = &LibRaw::packed_load_raw;
      load_flags = get4() ? 24 : 80;
      break;
    case 0x0103: /* 259, Compression */
                 /*
                  262	  = Kodak 262
                  32767  = Sony ARW Compressed
                  32769  = Packed RAW
                  32770  = Samsung SRW Compressed
                  32772  = Samsung SRW Compressed 2
                  32867  = Kodak KDC Compressed
                  34713  = Nikon NEF Compressed
                  65000  = Kodak DCR Compressed
                  65535  = Pentax PEF Compressed
                 */
      tiff_ifd[ifd].comp = getint(type);
      break;
    case 0x0106: /* 262, PhotometricInterpretation */
      tiff_ifd[ifd].phint = get2();
      break;
    case 0x010e: /* 270, ImageDescription */
      fread(desc, 512, 1, ifp);
      break;
    case 0x010f: /* 271, Make */
      fgets(make, 64, ifp);
      break;
    case 0x0110: /* 272, Model */
      if (!strncmp(make, "Hasselblad", 10) &&
          model[0] &&
          (imHassy.format != LIBRAW_HF_Imacon))
        break;
      fgets(model, 64, ifp);
      break;
    case 0x0116: // 278
      tiff_ifd[ifd].rows_per_strip = getint(type);
      break;
    case 0x0112: /* 274, Orientation */
      tiff_ifd[ifd].t_flip = "50132467"[get2() & 7] - '0';
      break;
    case 0x0115: /* 277, SamplesPerPixel */
      tiff_ifd[ifd].samples = getint(type) & 7;
      break;
    case 0x0117: /* 279, StripByteCounts */
      if (len > 1 && len < 16384)
      {
        off_t sav = ftell(ifp);
        tiff_ifd[ifd].strip_byte_counts = (int *)calloc(len, sizeof(int));
        tiff_ifd[ifd].strip_byte_counts_count = len;
        for (int i = 0; i < len; i++)
          tiff_ifd[ifd].strip_byte_counts[i] = get4();
        fseek(ifp, sav, SEEK_SET); // restore position
      }
      /* fallback */
    case 0x0202: // 514
    case 0xf008: // 61448
      tiff_ifd[ifd].bytes = get4();
      break;
    case 0xf00e: // 61454, FujiFilm "As Shot"
      FORC3 cam_mul[(4 - c) % 3] = getint(type);
      break;
    case 0x0131: /* 305, Software */
      fgets(software, 64, ifp);
      if (!strncmp(software, "Adobe", 5) || !strncmp(software, "dcraw", 5) ||
          !strncmp(software, "UFRaw", 5) || !strncmp(software, "Bibble", 6) ||
          !strcmp(software, "Digital Photo Professional"))
        is_raw = 0;
      break;
    case 0x0132: /* 306, DateTime */
      get_timestamp(0);
      break;
    case 0x013b: /* 315, Artist */
      fread(artist, 64, 1, ifp);
      break;
    case 0x013d: // 317
      tiff_ifd[ifd].predictor = getint(type);
      break;
    case 0x0142: /* 322, TileWidth */
      tiff_ifd[ifd].t_tile_width = getint(type);
      break;
    case 0x0143: /* 323, TileLength */
      tiff_ifd[ifd].t_tile_length = getint(type);
      break;
    case 0x0144: /* 324, TileOffsets */
      tiff_ifd[ifd].offset = len > 1 ? ftell(ifp) : get4();
      if (len == 1)
        tiff_ifd[ifd].t_tile_width = tiff_ifd[ifd].t_tile_length = 0;
      if (len == 4)
      {
        load_raw = &LibRaw::sinar_4shot_load_raw;
        is_raw = 5;
      }
      break;
    case 0x0145: // 325
      tiff_ifd[ifd].bytes = len > 1 ? ftell(ifp) : get4();
      break;
    case 0x014a: /* 330, SubIFDs */
      if (!strcmp(model, "DSLR-A100") && tiff_ifd[ifd].t_width == 3872)
      {
        load_raw = &LibRaw::sony_arw_load_raw;
        data_offset = get4() + base;
        ifd++;
        if (ifd >= sizeof tiff_ifd / sizeof tiff_ifd[0])
          throw LIBRAW_EXCEPTION_IO_CORRUPT;
        break;
      }
      if (!strncmp(make, "Hasselblad", 10) &&
          libraw_internal_data.unpacker_data.hasselblad_parser_flag)
      {
        fseek(ifp, ftell(ifp) + 4, SEEK_SET);
        fseek(ifp, get4() + base, SEEK_SET);
        parse_tiff_ifd(base);
        break;
      }
      if (len > 1000)
        len = 1000; /* 1000 SubIFDs is enough */
      while (len--)
      {
        i = ftell(ifp);
        fseek(ifp, get4() + base, SEEK_SET);
        if (parse_tiff_ifd(base))
          break;
        fseek(ifp, i + 4, SEEK_SET);
      }
      break;
    case 0x0153: // 339
      tiff_ifd[ifd].sample_format = getint(type);
      break;
    case 0x0190: // 400
      strcpy(make, "Sarnoff");
      maximum = 0xfff;
      break;
    case 0x02bc: // 700
      if ((type == 1 || type == 2 || type == 6 || type == 7) && len > 1 &&
          len < 5100000)
      {
        xmpdata = (char *)malloc(xmplen = len + 1);
        fread(xmpdata, len, 1, ifp);
        xmpdata[len] = 0;
      }
      break;
    case 0x7000:
      imSony.SonyRawFileType = get2();
      break;
    case 0x7010: // 28688
      FORC4 sony_curve[c + 1] = get2() >> 2 & 0xfff;
      for (i = 0; i < 5; i++)
        for (j = sony_curve[i] + 1; j <= sony_curve[i + 1]; j++)
          curve[j] = curve[j - 1] + (1 << i);
      break;
    case 0x7200: // 29184, Sony SR2Private
      sony_offset = get4();
      break;
    case 0x7201: // 29185, Sony SR2Private
      sony_length = get4();
      break;
    case 0x7221: // 29217, Sony SR2Private
      sony_key = get4();
      break;
    case 0x7250: // 29264, Sony SR2Private
      parse_minolta(ftell(ifp));
      raw_width = 0;
      break;
    case 0x7303: // 29443, Sony SR2SubIFD
      FORC4 cam_mul[c ^ (c < 2)] = get2();
      break;
    case 0x7313: // 29459, Sony SR2SubIFD
      FORC4 cam_mul[c ^ (c >> 1)] = get2();
      break;
    case 0x7310: // 29456, Sony SR2SubIFD
      FORC4 cblack[c ^ c >> 1] = get2();
      i = cblack[3];
      FORC3 if (i > cblack[c]) i = cblack[c];
      FORC4 cblack[c] -= i;
      black = i;
      break;
    case 0x827d: /* 33405, Model2 */
                 /*
                  for Kodak ProBack 645 PB645x-yyyy 'x' is:
                  'M' for Mamiya 645
                  'C' for Contax 645
                  'H' for Hasselblad H-series
                 */
      fgets(model2, 64, ifp);
      break;
    case 0x828d: /* 33421, CFARepeatPatternDim */
      if (get2() == 6 && get2() == 6)
        tiff_ifd[ifd].t_filters = filters = 9;
      break;
    case 0x828e: /* 33422, CFAPattern */
      if (filters == 9)
      {
        FORC(36)((char *)xtrans)[c] = fgetc(ifp) & 3;
        break;
      }
    case 0xfd09: /* 64777, Kodak P-series */
      if (len == 36)
      {
        tiff_ifd[ifd].t_filters = filters = 9;
        colors = 3;
        FORC(36) xtrans[0][c] = fgetc(ifp) & 3;
      }
      else if (len > 0)
      {
        if ((plen = len) > 16)
          plen = 16;
        fread(cfa_pat, 1, plen, ifp);
        for (colors = cfa = i = 0; i < plen && colors < 4; i++)
        {
          if (cfa_pat[i] > 31)
            continue; // Skip wrong data
          colors += !(cfa & (1 << cfa_pat[i]));
          cfa |= 1 << cfa_pat[i];
        }
        if (cfa == 070)
          memcpy(cfa_pc, "\003\004\005", 3); /* CMY */
        if (cfa == 072)
          memcpy(cfa_pc, "\005\003\004\001", 4); /* GMCY */
        goto guess_cfa_pc;
      }
      break;
    case 0x8290: // 33424
    case 0xfe00: // 65024
      fseek(ifp, get4() + base, SEEK_SET);
      parse_kodak_ifd(base);
      break;
    case 0x829a: /* 33434, ExposureTime */
      tiff_ifd[ifd].t_shutter = shutter = getreal(type);
      break;
    case 0x829d: /* 33437, FNumber */
      aperture = getreal(type);
      break;
    case 0x9400:
      imgdata.makernotes.common.exifAmbientTemperature = getreal(type);
      if ((imgdata.makernotes.common.CameraTemperature > -273.15f) &&
          ((OlyID == 0x4434353933ULL) || (OlyID == 0x4434363033ULL))) // TG-5/6
        imgdata.makernotes.common.CameraTemperature += imgdata.makernotes.common.exifAmbientTemperature;
      break;
    case 0x9401:
      imgdata.makernotes.common.exifHumidity = getreal(type);
      break;
    case 0x9402:
      imgdata.makernotes.common.exifPressure = getreal(type);
      break;
    case 0x9403:
      imgdata.makernotes.common.exifWaterDepth = getreal(type);
      break;
    case 0x9404:
      imgdata.makernotes.common.exifAcceleration = getreal(type);
      break;
    case 0x9405:
      imgdata.makernotes.common.exifCameraElevationAngle = getreal(type);
      break;
    case 0xa405: // FocalLengthIn35mmFormat
      imgdata.lens.FocalLengthIn35mmFormat = get2();
      break;
    case 0xa431: // BodySerialNumber
    case 0xc62f:
      stmread(imgdata.shootinginfo.BodySerial, len, ifp);
      break;
    case 0xa432: // LensInfo, 42034dec, Lens Specification per EXIF standard
      imgdata.lens.MinFocal = getreal(type);
      imgdata.lens.MaxFocal = getreal(type);
      imgdata.lens.MaxAp4MinFocal = getreal(type);
      imgdata.lens.MaxAp4MaxFocal = getreal(type);
      break;
    case 0xa435: // LensSerialNumber
      stmread(imgdata.lens.LensSerial, len, ifp);
      break;
    case 0xc630: // DNG LensInfo, Lens Specification per EXIF standard
      imgdata.lens.MinFocal = getreal(type);
      imgdata.lens.MaxFocal = getreal(type);
      imgdata.lens.MaxAp4MinFocal = getreal(type);
      imgdata.lens.MaxAp4MaxFocal = getreal(type);
      break;
    case 0xa420: /* 42016, ImageUniqueID */
      stmread(imgdata.color.ImageUniqueID, len, ifp);
      break;
    case 0xc65d: /* 50781, RawDataUniqueID */
      imgdata.color.RawDataUniqueID[16] = 0;
      fread(imgdata.color.RawDataUniqueID, 1, 16, ifp);
      break;
    case 0xa433: // LensMake
      stmread(imgdata.lens.LensMake, len, ifp);
      break;
    case 0xa434: // LensModel
      stmread(imgdata.lens.Lens, len, ifp);
      if (!strncmp(imgdata.lens.Lens, "----", 4))
        imgdata.lens.Lens[0] = 0;
      break;
    case 0x9205:
      imgdata.lens.EXIF_MaxAp = libraw_powf64l(2.0f, (getreal(type) / 2.0f));
      break;
    case 0x8602: /* 34306, Leaf white balance */
      FORC4
      {
        int q = get2();
        if (q)
          cam_mul[c ^ 1] = 4096.0 / q;
      }
      break;
    case 0x8603: /* 34307, Leaf CatchLight color matrix */
      fread(software, 1, 7, ifp);
      if (strncmp(software, "MATRIX", 6))
        break;
      colors = 4;
      for (raw_color = i = 0; i < 3; i++)
      {
        FORC4 fscanf(ifp, "%f", &rgb_cam[i][c ^ 1]);
        if (!use_camera_wb)
          continue;
        num = 0;
        FORC4 num += rgb_cam[i][c];
        FORC4 rgb_cam[i][c] /= MAX(1, num);
      }
      break;
    case 0x8606: /* 34310, Leaf metadata */
      parse_mos(ftell(ifp));
    case 0x85ff: // 34303
      strcpy(make, "Leaf");
      break;
    case 0x8769: /* 34665, EXIF tag */
      fseek(ifp, get4() + base, SEEK_SET);
      parse_exif(base);
      break;
    case 0x8825: /* 34853, GPSInfo tag */
    {
      unsigned pos;
      fseek(ifp, pos = (get4() + base), SEEK_SET);
      parse_gps(base);
      fseek(ifp, pos, SEEK_SET);
      parse_gps_libraw(base);
    }
    break;
    case 0x8773: /* 34675, InterColorProfile */
    case 0xc68f: /* 50831, AsShotICCProfile */
      profile_offset = ftell(ifp);
      profile_length = len;
      break;
    case 0x9102: /* 37122, CompressedBitsPerPixel */
      kodak_cbpp = get4();
      break;
    case 0x920a: /* 37386, FocalLength */
      focal_len = getreal(type);
      break;
    case 0x9211: /* 37393, ImageNumber */
      shot_order = getint(type);
      break;
    case 0x9215: /* 37397, ExposureIndex */
      imgdata.makernotes.common.exifExposureIndex = getreal(type);
      break;
    case 0x9218: /* 37400, old Kodak KDC tag */
      for (raw_color = i = 0; i < 3; i++)
      {
        getreal(type);
        FORC3 rgb_cam[i][c] = getreal(type);
      }
      break;
    case 0xa010: // 40976
      strip_offset = get4();
      switch (tiff_ifd[ifd].comp)
      {
      case 0x8002: // 32770
        load_raw = &LibRaw::samsung_load_raw;
        break;
      case 0x8004: // 32772
        load_raw = &LibRaw::samsung2_load_raw;
        break;
      case 0x8005: // 32773
        load_raw = &LibRaw::samsung3_load_raw;
        break;
      }
      break;
    case 0xb4c3: /* 46275, Imacon tags */
      imHassy.format = LIBRAW_HF_Imacon;
      strcpy(make, "Imacon");
      data_offset = ftell(ifp);
      ima_len = len;
      break;
    case 0xb4c7: // 46279
      if (!ima_len)
        break;
      fseek(ifp, 38, SEEK_CUR);
    case 0xb4c2: // 46274
      fseek(ifp, 40, SEEK_CUR);
      raw_width = get4();
      raw_height = get4();
      left_margin = get4() & 7;
      width = raw_width - left_margin - (get4() & 7);
      top_margin = get4() & 7;
      height = raw_height - top_margin - (get4() & 7);
      if (raw_width == 7262 && ima_len == 234317952)
      {
        height = 5412;
        width = 7216;
        left_margin = 7;
        filters = 0;
      }
      else if (raw_width == 7262)
      {
        height = 5444;
        width = 7244;
        left_margin = 7;
      }
      fseek(ifp, 52, SEEK_CUR);
      FORC3 cam_mul[c] = getreal(11);
      fseek(ifp, 114, SEEK_CUR);
      flip = (get2() >> 7) * 90;
      if (width * height * 6 == ima_len)
      {
        if (flip % 180 == 90)
          SWAP(width, height);
        raw_width = width;
        raw_height = height;
        left_margin = top_margin = filters = flip = 0;
      }
      c = height * width / 1000000;
      if (c == 32) c--;
      sprintf(model, "Ixpress %d-Mp", c);
      load_raw = &LibRaw::imacon_full_load_raw;
      if (filters)
      {
        if (left_margin & 1)
          filters = 0x61616161;
        load_raw = &LibRaw::unpacked_load_raw;
      }
      maximum = 0xffff;
      break;
    case 0xc516: /* 50454, Sinar tag */
    case 0xc517: // 50455
      if (len < 1 || len > 2560000 || !(cbuf = (char *)malloc(len)))
        break;
      if (fread(cbuf, 1, len, ifp) != len)
        throw LIBRAW_EXCEPTION_IO_CORRUPT; // cbuf to be free'ed in recycle
      cbuf[len - 1] = 0;
      for (cp = cbuf - 1; cp && cp < cbuf + len; cp = strchr(cp, '\n'))
        if (!strncmp(++cp, "Neutral ", 8))
          sscanf(cp + 8, "%f %f %f", cam_mul, cam_mul + 1, cam_mul + 2);
      free(cbuf);
      break;
    case 0xc51a: // 50458
      if (!make[0])
        strcpy(make, "Hasselblad");
      break;
    case 0xc51b: /* 50459, Hasselblad tag */
      if (!libraw_internal_data.unpacker_data.hasselblad_parser_flag)
      {
        libraw_internal_data.unpacker_data.hasselblad_parser_flag = 1;
        i = order;
        j = ftell(ifp);
        c = tiff_nifds;
        order = get2();
        fseek(ifp, j + (get2(), get4()), SEEK_SET);
        parse_tiff_ifd(j);
        maximum = 0xffff;
        tiff_nifds = c;
        order = i;
        break;
      }
    case 0xc612: /* 50706, DNGVersion */
      FORC4 dng_version = (dng_version << 8) + fgetc(ifp);
      if (!make[0])
        strcpy(make, "DNG");
      is_raw = 1;
      break;
    case 0xc614: /* 50708, UniqueCameraModel */
      stmread(imgdata.color.UniqueCameraModel, len, ifp);
      if (model[0])
        break;
      strncpy(make, imgdata.color.UniqueCameraModel,
              MIN(len, sizeof(imgdata.color.UniqueCameraModel)));
      if ((cp = strchr(make, ' ')))
      {
        strcpy(model, cp + 1);
        *cp = 0;
      }
      break;
    case 0xc616: /* 50710, CFAPlaneColor */
      if (filters == 9)
        break;
      if (len > 4)
        len = 4;
      colors = len;
      fread(cfa_pc, 1, colors, ifp);
    guess_cfa_pc:
      FORCC tab[cfa_pc[c]] = c;
      cdesc[c] = 0;
      for (i = 16; i--;)
        filters = filters << 2 | tab[cfa_pat[i % plen]];
      filters -= !filters;
      tiff_ifd[ifd].t_filters = filters;
      break;
    case 0xc617: /* 50711, CFALayout */
      if (get2() == 2)
       tiff_ifd[ifd].t_fuji_width = fuji_width = 1;
      break;
    case 0x0123: // 291
    case 0xc618: /* 50712, LinearizationTable */
      tiff_ifd[ifd].dng_levels.parsedfields |= LIBRAW_DNGFM_LINTABLE;
      tiff_ifd[ifd].lineartable_offset = ftell(ifp);
      tiff_ifd[ifd].lineartable_len = len;
      linear_table(len);
      break;
    case 0xc619: /* 50713, BlackLevelRepeatDim */
      tiff_ifd[ifd].dng_levels.parsedfields |= LIBRAW_DNGFM_BLACK;
      tiff_ifd[ifd].dng_levels.dng_fcblack[4] =
          tiff_ifd[ifd].dng_levels.dng_cblack[4] = cblack[4] = get2();
      tiff_ifd[ifd].dng_levels.dng_fcblack[5] =
          tiff_ifd[ifd].dng_levels.dng_cblack[5] = cblack[5] = get2();
      if (cblack[4] * cblack[5] > (LIBRAW_CBLACK_SIZE - 7)) // Use last cblack item as DNG black level count
        tiff_ifd[ifd].dng_levels.dng_fcblack[4] =
            tiff_ifd[ifd].dng_levels.dng_fcblack[5] =
                tiff_ifd[ifd].dng_levels.dng_cblack[4] =
                    tiff_ifd[ifd].dng_levels.dng_cblack[5] = cblack[4] =
                        cblack[5] = 1;
      break;

    case 0xf00c:
      if (!is_4K_RAFdata)
      {
        unsigned fwb[4];
        FORC4 fwb[c] = get4();
        if (fwb[3] < 0x100)
        {
          imgdata.color.WB_Coeffs[fwb[3]][0] = fwb[1];
          imgdata.color.WB_Coeffs[fwb[3]][1] =
              imgdata.color.WB_Coeffs[fwb[3]][3] = fwb[0];
          imgdata.color.WB_Coeffs[fwb[3]][2] = fwb[2];
          if ((fwb[3] == 17) &&
              (libraw_internal_data.unpacker_data.lenRAFData > 3) &&
              (libraw_internal_data.unpacker_data.lenRAFData < 10240000))
          {
            INT64 f_save = ftell(ifp);
            rafdata = (ushort *)malloc(
                sizeof(ushort) * libraw_internal_data.unpacker_data.lenRAFData);
            fseek(ifp, libraw_internal_data.unpacker_data.posRAFData, SEEK_SET);
            fread(rafdata, sizeof(ushort),
                  libraw_internal_data.unpacker_data.lenRAFData, ifp);
            fseek(ifp, f_save, SEEK_SET);

            uchar *PrivateMknBuf = (uchar *)rafdata;
            int PrivateMknLength = libraw_internal_data.unpacker_data.lenRAFData
                                   << 1;
            for (int pos = 0; pos < PrivateMknLength - 16; pos++)
            {
              if (!memcmp(PrivateMknBuf + pos, "TSNERDTS", 8))
              {
                imFuji.isTSNERDTS = 1;
                break;
              }
            }

            /* 0xc000 tag version, second ushort; valid if the first ushort is 0
             */
            if (!rafdata[0])
              imFuji.RAFDataVersion = rafdata[1];
            int fj;
            for (int fi = 0;
                 fi < (libraw_internal_data.unpacker_data.lenRAFData - 3); fi++)
            { // find Tungsten WB
              if ((fwb[0] == rafdata[fi]) && (fwb[1] == rafdata[fi + 1]) &&
                  (fwb[2] == rafdata[fi + 2]))
              {
                if (rafdata[fi - 15] !=
                    fwb[0]) // 15 is offset of Tungsten WB from the first
                            // preset, Fine Weather WB
                  continue;
                for (int wb_ind = 0, ofst = fi - 15; wb_ind < nFuji_wb_list1;
                     wb_ind++, ofst += 3)
                {
                  imgdata.color.WB_Coeffs[Fuji_wb_list1[wb_ind]][1] =
                      imgdata.color.WB_Coeffs[Fuji_wb_list1[wb_ind]][3] =
                          rafdata[ofst];
                  imgdata.color.WB_Coeffs[Fuji_wb_list1[wb_ind]][0] =
                      rafdata[ofst + 1];
                  imgdata.color.WB_Coeffs[Fuji_wb_list1[wb_ind]][2] =
                      rafdata[ofst + 2];
                }

                if (imFuji.RAFDataVersion == 0x260) { // X-Pro3
                  for (int iCCT = 0, ofst = fi+24; iCCT < 31; iCCT++, ofst += 3)  {
                    imgdata.color.WBCT_Coeffs[iCCT][0] = FujiCCT_K[iCCT];
                    imgdata.color.WBCT_Coeffs[iCCT][1] =
                        rafdata[ofst+1];
                    imgdata.color.WBCT_Coeffs[iCCT][2] =
                        imgdata.color.WBCT_Coeffs[iCCT][4] =
                            rafdata[ofst];
                    imgdata.color.WBCT_Coeffs[iCCT][3] =
                        rafdata[ofst+2];
                  }
                  free(rafdata);
                  break;
                }
                fi += 96;
                for (fj = fi; fj < (fi + 15); fj += 3) {
                  if (rafdata[fj] != rafdata[fi]) {
                    for (int iCCT = 0, ofst = fj - 93; iCCT < 31; iCCT++, ofst += 3) {
                      imgdata.color.WBCT_Coeffs[iCCT][0] = FujiCCT_K[iCCT];
                      imgdata.color.WBCT_Coeffs[iCCT][1] =
                          rafdata[ofst+1];
                      imgdata.color.WBCT_Coeffs[iCCT][2] =
                          imgdata.color.WBCT_Coeffs[iCCT][4] =
                              rafdata[ofst];
                      imgdata.color.WBCT_Coeffs[iCCT][3] =
                          rafdata[ofst+2];
                    }
                    break;
                  }
                }
                free(rafdata);
                break;
              }
            }
          }
        }
        FORC4 fwb[c] = get4();
        if (fwb[3] < 0x100)
        {
          imgdata.color.WB_Coeffs[fwb[3]][0] = fwb[1];
          imgdata.color.WB_Coeffs[fwb[3]][1] =
              imgdata.color.WB_Coeffs[fwb[3]][3] = fwb[0];
          imgdata.color.WB_Coeffs[fwb[3]][2] = fwb[2];
        }
      }
      break;
    case 0xf00d:
      if (!is_4K_RAFdata)
      {
        FORC3 imgdata.color.WB_Coeffs[LIBRAW_WBI_Auto][(4 - c) % 3] =
            getint(type);
        imgdata.color.WB_Coeffs[LIBRAW_WBI_Auto][3] =
            imgdata.color.WB_Coeffs[LIBRAW_WBI_Auto][1];
        //        free(rafdata);
      }
      break;
    case 0xc615: /* 50709, LocalizedCameraModel */
      stmread(imgdata.color.LocalizedCameraModel, len, ifp);
      break;
    case 0xf00a: // 61450
      cblack[4] = cblack[5] = MIN(sqrt((double)len), 64);
    case 0xc61a: /* 50714, BlackLevel */
      if (tiff_ifd[ifd].samples > 1 &&
          tiff_ifd[ifd].samples == len) // LinearDNG, per-channel black
      {
        tiff_ifd[ifd].dng_levels.parsedfields |= LIBRAW_DNGFM_BLACK;
        for (i = 0; i < 4 && i < len; i++)
        {
          tiff_ifd[ifd].dng_levels.dng_fcblack[i] = getreal(type);
          tiff_ifd[ifd].dng_levels.dng_cblack[i] = cblack[i] =
              tiff_ifd[ifd].dng_levels.dng_fcblack[i] + 0.5;
        }

        tiff_ifd[ifd].dng_levels.dng_fblack =
            tiff_ifd[ifd].dng_levels.dng_black = black = 0;
      }
      else if( tiff_ifd[ifd].samples > 1  // Linear DNG w repeat dim
          && (tiff_ifd[ifd].samples * cblack[4] * cblack[5] == len))
      {
          tiff_ifd[ifd].dng_levels.parsedfields |= LIBRAW_DNGFM_BLACK;
          tiff_ifd[ifd].dng_levels.dng_cblack[LIBRAW_CBLACK_SIZE-1] = cblack[LIBRAW_CBLACK_SIZE-1] = len;
          for (i = 0; i < len && i < LIBRAW_CBLACK_SIZE-7; i++)
          {
              tiff_ifd[ifd].dng_levels.dng_fcblack[i+6] = getreal(type);
              tiff_ifd[ifd].dng_levels.dng_cblack[i+6] = cblack[i+6] =
                  tiff_ifd[ifd].dng_levels.dng_fcblack[i+6] + 0.5;
          }
      }
      else if ((cblack[4] * cblack[5] < 2) && len == 1)
      {
        tiff_ifd[ifd].dng_levels.parsedfields |= LIBRAW_DNGFM_BLACK;
        tiff_ifd[ifd].dng_levels.dng_fblack = getreal(type);
        black = tiff_ifd[ifd].dng_levels.dng_black =
            tiff_ifd[ifd].dng_levels.dng_fblack;
      }
      else if (cblack[4] * cblack[5] <= len)
      {
        FORC(cblack[4] * cblack[5])
        {
          tiff_ifd[ifd].dng_levels.dng_fcblack[6 + c] = getreal(type);
          cblack[6 + c] = tiff_ifd[ifd].dng_levels.dng_fcblack[6 + c];
        }
        black = 0;
        FORC4
        cblack[c] = 0;

        if (tag == 0xc61a)
        {
          tiff_ifd[ifd].dng_levels.parsedfields |= LIBRAW_DNGFM_BLACK;
          FORC(cblack[4] * cblack[5])
          tiff_ifd[ifd].dng_levels.dng_cblack[6 + c] = cblack[6 + c];
          tiff_ifd[ifd].dng_levels.dng_fblack = 0;
          tiff_ifd[ifd].dng_levels.dng_black = 0;
          FORC4
          tiff_ifd[ifd].dng_levels.dng_fcblack[c] =
              tiff_ifd[ifd].dng_levels.dng_cblack[c] = 0;
        }
      }
      break;
    case 0xc61b: /* 50715, BlackLevelDeltaH */
    case 0xc61c: /* 50716, BlackLevelDeltaV */
      for (num = i = 0; i < len && i < 65536; i++)
        num += getreal(type);
      if (len > 0)
      {
        black += num / len + 0.5;
        tiff_ifd[ifd].dng_levels.dng_fblack += num / float(len);
        tiff_ifd[ifd].dng_levels.dng_black += num / len + 0.5;
        tiff_ifd[ifd].dng_levels.parsedfields |= LIBRAW_DNGFM_BLACK;
      }
      break;
    case 0xc61d: /* 50717, WhiteLevel */
      tiff_ifd[ifd].dng_levels.parsedfields |= LIBRAW_DNGFM_WHITE;
      tiff_ifd[ifd].dng_levels.dng_whitelevel[0] = maximum = getint(type);
      if (tiff_ifd[ifd].samples > 1) // Linear DNG case
        for (i = 1; i < 4 && i < len; i++)
          tiff_ifd[ifd].dng_levels.dng_whitelevel[i] = getint(type);
      break;
    case 0xc61e: /* DefaultScale */
    {
      float q1 = getreal(type);
      float q2 = getreal(type);
      if (q1 > 0.00001f && q2 > 0.00001f)
      {
        pixel_aspect = q1 / q2;
        if (pixel_aspect > 0.995 && pixel_aspect < 1.005)
          pixel_aspect = 1.0;
      }
    }
    break;
    case 0xc61f: /* 50719, DefaultCropOrigin */
      if (len == 2)
      {
        tiff_ifd[ifd].dng_levels.parsedfields |= LIBRAW_DNGFM_CROPORIGIN;
        tiff_ifd[ifd].dng_levels.default_crop[0] = getreal(type);
        tiff_ifd[ifd].dng_levels.default_crop[1] = getreal(type);
        if (!strncasecmp(make, "SONY", 4))
        {
          imgdata.sizes.raw_inset_crop.cleft =
              tiff_ifd[ifd].dng_levels.default_crop[0];
          imgdata.sizes.raw_inset_crop.ctop =
              tiff_ifd[ifd].dng_levels.default_crop[1];
        }
      }
      break;

    case 0xc620: /* 50720, DefaultCropSize */
      if (len == 2)
      {
        tiff_ifd[ifd].dng_levels.parsedfields |= LIBRAW_DNGFM_CROPSIZE;
        tiff_ifd[ifd].dng_levels.default_crop[2] = getreal(type);
        tiff_ifd[ifd].dng_levels.default_crop[3] = getreal(type);
        if (!strncasecmp(make, "SONY", 4))
        {
          imgdata.sizes.raw_inset_crop.cwidth =
              tiff_ifd[ifd].dng_levels.default_crop[2];
          imgdata.sizes.raw_inset_crop.cheight =
              tiff_ifd[ifd].dng_levels.default_crop[3];
        }
      }
      break;

    case 0x74c7:
      if ((len == 2) && !strncasecmp(make, "SONY", 4))
      {
        imgdata.sizes.raw_inset_crop.cleft = get4();
        imgdata.sizes.raw_inset_crop.ctop = get4();
      }
      break;

    case 0x74c8:
      if ((len == 2) && !strncasecmp(make, "SONY", 4))
      {
        imgdata.sizes.raw_inset_crop.cwidth = get4();
        imgdata.sizes.raw_inset_crop.cheight = get4();
      }
      break;

    case 0xc65a: // 50778
      tiff_ifd[ifd].dng_color[0].illuminant = get2();
      tiff_ifd[ifd].dng_color[0].parsedfields |= LIBRAW_DNGFM_ILLUMINANT;
      break;
    case 0xc65b: // 50779
      tiff_ifd[ifd].dng_color[1].illuminant = get2();
      tiff_ifd[ifd].dng_color[1].parsedfields |= LIBRAW_DNGFM_ILLUMINANT;
      break;

    case 0xc621: /* 50721, ColorMatrix1 */
    case 0xc622: /* 50722, ColorMatrix2 */
    {
      int chan = (len == 9) ? 3 : (len == 12 ? 4 : 0);
      i = tag == 0xc621 ? 0 : 1;
      if (chan) {
        tiff_ifd[ifd].dng_color[i].parsedfields |= LIBRAW_DNGFM_COLORMATRIX;
        imHassy.nIFD_CM[i] = ifd;
      }
      FORC(chan) for (j = 0; j < 3; j++)
      {
        tiff_ifd[ifd].dng_color[i].colormatrix[c][j] = cm[c][j] = getreal(type);
      }
      use_cm = 1;
    }
    break;

    case 0xc714: /* ForwardMatrix1 */
    case 0xc715: /* ForwardMatrix2 */
    {
      int chan = (len == 9) ? 3 : (len == 12 ? 4 : 0);
      i = tag == 0xc714 ? 0 : 1;
      if (chan)
        tiff_ifd[ifd].dng_color[i].parsedfields |= LIBRAW_DNGFM_FORWARDMATRIX;
      for (j = 0; j < 3; j++)
        FORC(chan)
        {
          tiff_ifd[ifd].dng_color[i].forwardmatrix[j][c] = fm[j][c] =
              getreal(type);
        }
    }
    break;

    case 0xc623: /* 50723, CameraCalibration1 */
    case 0xc624: /* 50724, CameraCalibration2 */
    {
      int chan = (len == 9) ? 3 : (len == 16 ? 4 : 0);
      j = tag == 0xc623 ? 0 : 1;
      if (chan)
        tiff_ifd[ifd].dng_color[j].parsedfields |= LIBRAW_DNGFM_CALIBRATION;
      for (i = 0; i < chan; i++)
        FORC(chan)
        {
          tiff_ifd[ifd].dng_color[j].calibration[i][c] = cc[i][c] =
              getreal(type);
        }
    }
    break;
    case 0xc627: /* 50727, AnalogBalance */
      if (len >= 3)
        tiff_ifd[ifd].dng_levels.parsedfields |= LIBRAW_DNGFM_ANALOGBALANCE;
      for (c = 0; c < len && c < 4; c++)
      {
        tiff_ifd[ifd].dng_levels.analogbalance[c] = ab[c] = getreal(type);
      }
      break;
    case 0xc628: /* 50728, AsShotNeutral */
      if (len >= 3)
        tiff_ifd[ifd].dng_levels.parsedfields |= LIBRAW_DNGFM_ASSHOTNEUTRAL;
      for (c = 0; c < len && c < 4; c++)
        tiff_ifd[ifd].dng_levels.asshotneutral[c] = asn[c] = getreal(type);
      break;
    case 0xc629: /* 50729, AsShotWhiteXY */
      xyz[0] = getreal(type);
      xyz[1] = getreal(type);
      xyz[2] = 1 - xyz[0] - xyz[1];
      FORC3 xyz[c] /= LibRaw_constants::d65_white[c];
      break;
    case 0xc62a: /* DNG: 50730 BaselineExposure */
      tiff_ifd[ifd].dng_levels.parsedfields |= LIBRAW_DNGFM_BASELINEEXPOSURE;
      tiff_ifd[ifd].dng_levels.baseline_exposure = getreal(type);
      break;
    case 0xc62e: /* DNG: 50734 LinearResponseLimit */
      tiff_ifd[ifd].dng_levels.parsedfields |= LIBRAW_DNGFM_LINEARRESPONSELIMIT;
      tiff_ifd[ifd].dng_levels.LinearResponseLimit = getreal(type);
      break;

    case 0xc634: /* 50740 : DNG Adobe, DNG Pentax, Sony SR2, DNG Private */
      if (!(imgdata.params.raw_processing_options &
            LIBRAW_PROCESSING_SKIP_MAKERNOTES))
      {
        char mbuf[64];
        unsigned short makernote_found = 0;
        INT64 curr_pos, start_pos = ftell(ifp);
        unsigned MakN_order, m_sorder = order;
        unsigned MakN_length;
        unsigned pos_in_original_raw;
        fread(mbuf, 1, 6, ifp);

        if (!strcmp(mbuf, "Adobe"))
        {
          order = 0x4d4d; // Adobe header is always in "MM" / big endian
          curr_pos = start_pos + 6;
          while (curr_pos + 8 - start_pos <= len)
          {
            fread(mbuf, 1, 4, ifp);
            curr_pos += 8;

            if (!strncmp(mbuf, "Pano", 4))
            { // PanasonicRaw, yes, they use "Pano" as signature
              parseAdobePanoMakernote();
            }

            if (!strncmp(mbuf, "MakN", 4))
            {
              makernote_found = 1;
              MakN_length = get4();
              MakN_order = get2();
              pos_in_original_raw = get4();
              order = MakN_order;

              INT64 save_pos = ifp->tell();
              parse_makernote_0xc634(curr_pos + 6 - pos_in_original_raw, 0,
                                     AdobeDNG);

              curr_pos = save_pos + MakN_length - 6;
              fseek(ifp, curr_pos, SEEK_SET);

              fread(mbuf, 1, 4, ifp);
              curr_pos += 8;

              if (!strncmp(mbuf, "Pano ", 4))
              {
                parseAdobePanoMakernote();
              }

              if (!strncmp(mbuf, "RAF ", 4))
              { // Fujifilm Raw, AdobeRAF
                parseAdobeRAFMakernote();
              }

              if (!strncmp(mbuf, "SR2 ", 4))
              {
                order = 0x4d4d;
                MakN_length = get4();
                MakN_order = get2();
                pos_in_original_raw = get4();
                order = MakN_order;

                unsigned *buf_SR2;
                unsigned entries, tag, type, len, save;
                unsigned SR2SubIFDOffset = 0;
                unsigned SR2SubIFDLength = 0;
                unsigned SR2SubIFDKey = 0;
                int base = curr_pos + 6 - pos_in_original_raw;
                entries = get2();
                while (entries--)
                {
                  tiff_get(base, &tag, &type, &len, &save);

                  if (tag == 0x7200)
                  {
                    SR2SubIFDOffset = get4();
                  }
                  else if (tag == 0x7201)
                  {
                    SR2SubIFDLength = get4();
                  }
                  else if (tag == 0x7221)
                  {
                    SR2SubIFDKey = get4();
                  }
                  fseek(ifp, save, SEEK_SET);
                }

                if (SR2SubIFDLength && (SR2SubIFDLength < 10240000) &&
                    (buf_SR2 = (unsigned *)malloc(SR2SubIFDLength + 1024)))
                { // 1024b for safety
                  fseek(ifp, SR2SubIFDOffset + base, SEEK_SET);
                  fread(buf_SR2, SR2SubIFDLength, 1, ifp);
                  sony_decrypt(buf_SR2, SR2SubIFDLength / 4, 1, SR2SubIFDKey);
                  parseSonySR2((uchar *)buf_SR2, SR2SubIFDOffset,
                               SR2SubIFDLength, AdobeDNG);

                  free(buf_SR2);
                }

              } /* SR2 processed */
              break;
            }
          }
        }
        else
        {
          fread(mbuf + 6, 1, 2, ifp);
          if (!strcmp(mbuf, "RICOH") && ((sget2((uchar *)mbuf + 6) == 0x4949) ||
                                         (sget2((uchar *)mbuf + 6) == 0x4d4d)))
          {
            is_PentaxRicohMakernotes = 1;
          }
          if (!strcmp(mbuf, "PENTAX ") || !strcmp(mbuf, "SAMSUNG") ||
              is_PentaxRicohMakernotes)
          {
            makernote_found = 1;
            fseek(ifp, start_pos, SEEK_SET);
            parse_makernote_0xc634(base, 0, CameraDNG);
          }
        }
        fseek(ifp, start_pos, SEEK_SET);
        order = m_sorder;
      }
      if (dng_version)
      {
        break;
      }
      parse_minolta(j = get4() + base);
      fseek(ifp, j, SEEK_SET);
      parse_tiff_ifd(base);
      break;
    case 0xc640: // 50752
      read_shorts(cr2_slice, 3);
      break;
    case 0xc68b: /* 50827, OriginalRawFileName */
      stmread(imgdata.color.OriginalRawFileName, len, ifp);
      break;
    case 0xc68d: /* 50829 ActiveArea */
        tiff_ifd[ifd].t_tm=top_margin = getint(type);
        tiff_ifd[ifd].t_lm = left_margin = getint(type);
        tiff_ifd[ifd].t_vheight = height = getint(type) - top_margin;
        tiff_ifd[ifd].t_vwidth = width = getint(type) - left_margin;
      break;
    case 0xc68e: /* 50830 MaskedAreas */
      for (i = 0; i < len && i < 32; i++)
        ((int *)mask)[i] = getint(type);
      black = 0;
      break;
    case 0xc71a: /* 50970, PreviewColorSpace */
      tiff_ifd[ifd].dng_levels.parsedfields |= LIBRAW_DNGFM_PREVIEWCS;
      tiff_ifd[ifd].dng_levels.preview_colorspace = getint(type);
      break;
    case 0xc741: /* 51009, OpcodeList2 */
      tiff_ifd[ifd].dng_levels.parsedfields |= LIBRAW_DNGFM_OPCODE2;
      tiff_ifd[ifd].opcode2_offset = meta_offset = ftell(ifp);
      break;
    case 0xfd04: /* 64772, Kodak P-series */
      if (len < 13)
        break;
      fseek(ifp, 16, SEEK_CUR);
      data_offset = get4();
      fseek(ifp, 28, SEEK_CUR);
      data_offset += get4();
      load_raw = &LibRaw::packed_load_raw;
      break;
    case 0xfe02: // 65026
      if (type == 2)
        fgets(model2, 64, ifp);
    }
    fseek(ifp, save, SEEK_SET);
  }
  if (sony_length && sony_length < 10240000 &&
      (buf = (unsigned *)malloc(sony_length)))
  {
    fseek(ifp, sony_offset, SEEK_SET);
    fread(buf, sony_length, 1, ifp);
    sony_decrypt(buf, sony_length / 4, 1, sony_key);
    parseSonySR2((uchar *)buf, sony_offset, sony_length, nonDNG);
    free(buf);
  }
  for (i = 0; i < colors; i++)
    FORCC cc[i][c] *= ab[i];
  if (use_cm)
  {
    FORCC for (i = 0; i < 3; i++) for (cam_xyz[c][i] = j = 0; j < colors; j++)
        cam_xyz[c][i] += cc[c][j] * cm[j][i] * xyz[i];
    cam_xyz_coeff(cmatrix, cam_xyz);
  }
  if (asn[0])
  {
    cam_mul[3] = 0;
    FORCC
    if (fabs(asn[c]) > 0.0001)
      cam_mul[c] = 1 / asn[c];
  }
  if (!use_cm)
    FORCC if (fabs(cc[c][c]) > 0.0001) pre_mul[c] /= cc[c][c];
  return 0;
}

Project: LibRaw
File: sony.cpp

void LibRaw::process_Sony_0x940c(uchar *buf, ushort len)
{
  if ((imSony.CameraType != LIBRAW_SONY_ILCE) &&
      (imSony.CameraType != LIBRAW_SONY_NEX))
    return;
  if (len <= 0x000a)
    return;

  ushort lid2;
  if ((ilm.LensMount != LIBRAW_MOUNT_Canon_EF) &&
      (ilm.LensMount != LIBRAW_MOUNT_Sigma_X3F))
  {
    switch (SonySubstitution[buf[0x0008]])
    {
    case 1:
    case 5:
      ilm.LensMount = LIBRAW_MOUNT_Minolta_A;
      break;
    case 4:
      ilm.LensMount = LIBRAW_MOUNT_Sony_E;
      break;
    }
  }
  lid2 = (((ushort)SonySubstitution[buf[0x000a]]) << 8) |
         ((ushort)SonySubstitution[buf[0x0009]]);
  if ((lid2 > 0) &&
      ((lid2 < 32784) || (ilm.LensID == 0x1999) || (ilm.LensID == 0xffff)))
    parseSonyLensType2(
        SonySubstitution[buf[0x000a]], // LensType2 - Sony lens ids
        SonySubstitution[buf[0x0009]]);
  if ((lid2 == 44) || (lid2 == 78) || (lid2 == 184) || (lid2 == 234) ||
      (lid2 == 239))
    ilm.AdapterID = lid2;
  return;
}

Project: LibRaw

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

Project: LibRaw

  void libraw_set_exifparser_handler(libraw_data_t *lr, exif_parser_callback cb,
                                     void *data)
  {
    if (!lr)
      return;
    LibRaw *ip = (LibRaw *)lr->parent_class;
    ip->set_exifparser_handler(cb, data);
  }

Project: LibRaw

char *LibRaw_buffer_datastream::gets(char *s, int sz)
{
  unsigned char *psrc, *pdest, *str;
  str = (unsigned char *)s;
  psrc = buf + streampos;
  pdest = str;
  if(streampos >= streamsize) return NULL;
  while ((size_t(psrc - buf) < streamsize) && ((pdest - str) < sz))
  {
    *pdest = *psrc;
    if (*psrc == '\n')
      break;
    psrc++;
    pdest++;
  }
  if (size_t(psrc - buf) < streamsize)
    psrc++;
  if ((pdest - str) < sz)
    *(++pdest) = 0;
  streampos = psrc - buf;
  return s;
}

Project: LibRaw

void LibRaw::parse_kyocera()
{

  int c;
  static const ushort table[13] = {25,  32,  40,  50,  64,  80, 100,
                                   125, 160, 200, 250, 320, 400};

  fseek(ifp, 33, SEEK_SET);
  get_timestamp(1);
  fseek(ifp, 52, SEEK_SET);
  c = get4();
  if ((c > 6) && (c < 20))
    iso_speed = table[c - 7];
  shutter = libraw_powf64l(2.0f, (((float)get4()) / 8.0f)) / 16000.0f;
  FORC4 cam_mul[c ^ (c >> 1)] = get4();
  fseek(ifp, 88, SEEK_SET);
  aperture = libraw_powf64l(2.0f, ((float)get4()) / 16.0f);
  fseek(ifp, 112, SEEK_SET);
  focal_len = get4();

  fseek(ifp, 104, SEEK_SET);
  ilm.MaxAp4CurFocal = libraw_powf64l(2.0f, ((float)get4()) / 16.0f);
  fseek(ifp, 124, SEEK_SET);
  stmread(ilm.Lens, 32, ifp);
  ilm.CameraMount = LIBRAW_MOUNT_Contax_N;
  ilm.CameraFormat = LIBRAW_FORMAT_FF;
  if (ilm.Lens[0])
  {
    ilm.LensMount = LIBRAW_MOUNT_Contax_N;
    ilm.LensFormat = LIBRAW_FORMAT_FF;
  }
}

Project: LibRaw

void LibRaw::write_ppm_tiff(){}

Project: LibRaw

void AAHD::illustrate_dline(int i)
{
  int iwidth = libraw.imgdata.sizes.iwidth;
  for (int j = 0; j < iwidth; j++)
  {
    int x = j + nr_margin;
    int y = i + nr_margin;
    rgb_ahd[1][nr_offset(y, x)][0] = rgb_ahd[1][nr_offset(y, x)][1] =
        rgb_ahd[1][nr_offset(y, x)][2] = rgb_ahd[0][nr_offset(y, x)][0] =
            rgb_ahd[0][nr_offset(y, x)][1] = rgb_ahd[0][nr_offset(y, x)][2] = 0;
    int l = ndir[nr_offset(y, x)] & HVSH;
    l /= HVSH;
    if (ndir[nr_offset(y, x)] & VER)
      rgb_ahd[1][nr_offset(y, x)][0] =
          l * channel_maximum[0] / 4 + channel_maximum[0] / 4;
    else
      rgb_ahd[0][nr_offset(y, x)][2] =
          l * channel_maximum[2] / 4 + channel_maximum[2] / 4;
  }
}

Project: LibRaw

  int libraw_versionNumber() { return LibRaw::versionNumber(); }

Project: LibRaw

void print_usage(const char *pname)
{
	printf("Usage: %s [options] inputfiles\n", pname);
	printf("Options:\n"
		"\t-c\tcompact output\n"
		"\t-v\tverbose output\n"
		"\t-w\tprint white balance\n"
		"\t-u\tprint unpack function\n"
		"\t-f\tprint frame size (only w/ -u)\n"
		"\t-s\tprint output image size\n"
		"\t-h\tforce half-size mode (only for -s)\n"
		"\t-M\tdisable use of raw-embedded color data\n"
		"\t+M\tforce use of raw-embedded color data\n"
		"\t-L filename\tread input files list from filename\n"
		"\t-o filename\toutput to filename\n");
}

Project: LibRaw

static void fuji_extend_green(ushort *linebuf[_ltotal], int line_width)
{
  fuji_extend_generic(linebuf, line_width, _G2, _G7);
}

Project: LibRaw

  const char *libraw_strprogress(enum LibRaw_progress p)
  {
    return LibRaw::strprogress(p);
  }

Project: LibRaw

void *LibRaw_bigfile_datastream::make_jas_stream()
{
#ifdef NO_JASPER
  return NULL;
#else
  return jas_stream_fdopen(fileno(f), "rb");
#endif
}

Project: LibRaw

void LibRaw::parse_kodak_ifd(int base)
{
  unsigned entries, tag, type, len, save;
  int j, c, wbi = -1;
  float mul[3] = {1, 1, 1}, num;

  static const int wbtag_kdc[] = {
      LIBRAW_WBI_Auto,        // 64037 / 0xfa25
      LIBRAW_WBI_Fluorescent, // 64040 / 0xfa28
      LIBRAW_WBI_Tungsten,    // 64039 / 0xfa27
      LIBRAW_WBI_Daylight,    // 64041 / 0xfa29
      -1,
      -1,
      LIBRAW_WBI_Shade // 64042 / 0xfa2a
  };

  static const int wbtag_dcr[] = {
      LIBRAW_WBI_Daylight,    // 2120 / 0x0848
      LIBRAW_WBI_Tungsten,    // 2121 / 0x0849
      LIBRAW_WBI_Fluorescent, // 2122 / 0x084a
      LIBRAW_WBI_Flash,       // 2123 / 0x084b
      LIBRAW_WBI_Custom,      // 2124 / 0x084c
      LIBRAW_WBI_Auto         // 2125 / 0x084d
  };

  //  int a_blck = 0;

  entries = get2();
  if (entries > 1024)
    return;
  INT64 fsize = ifp->size();
  while (entries--)
  {
    tiff_get(base, &tag, &type, &len, &save);
    INT64 savepos = ftell(ifp);
    if (len > 8 && len + savepos > 2 * fsize)
    {
      fseek(ifp, save, SEEK_SET); // Recover tiff-read position!!
      continue;
    }
    if (callbacks.exif_cb)
    {
      callbacks.exif_cb(callbacks.exifparser_data, tag | 0x20000, type, len,
                        order, ifp, base);
      fseek(ifp, savepos, SEEK_SET);
    }
    if (tag == 0x03eb) // 1003
      imgdata.sizes.raw_inset_crop.cleft = get2();
    else if (tag == 0x03ec) // 1004
      imgdata.sizes.raw_inset_crop.ctop = get2();
    else if (tag == 0x03ed) // 1005
      imgdata.sizes.raw_inset_crop.cwidth = get2();
    else if (tag == 0x03ee) // 1006
      imgdata.sizes.raw_inset_crop.cheight = get2();
    else if (tag == 0x03ef) // 1007
    {
      if (!strcmp(model, "EOS D2000C"))
        black = get2();
      else
        imKodak.BlackLevelTop = get2();
    }
    else if (tag == 0x03f0) // 1008
    {
      if (!strcmp(model, "EOS D2000C"))
      {
        if (black) // already set by tag 1007 (0x03ef)
          black = (black + get2()) / 2;
        else
          black = get2();
      }
      else
        imKodak.BlackLevelBottom = get2();
    }

    else if (tag == 0x03f1)
    { // 1009 Kodak TextualInfo
      if (len > 0)
      {
        char kti[1024];
        char *pkti;
        int nsym = MIN(len, 1023);
        fread(kti, 1, nsym, ifp);
        kti[nsym] = 0;
#ifdef LIBRAW_WIN32_CALLS
        pkti = strtok(kti, "\x0a");
#else
        char *last = 0;
        pkti = strtok_r(kti, "\x0a", &last);
#endif
        while (pkti != NULL)
        {
          c = 12;
          if ((strlen(pkti) > c) && (!strncasecmp(pkti, "Camera body:", c)))
          {
            while ((pkti[c] == ' ') && (c < strlen(pkti)))
            {
              c++;
            }
            strcpy(ilm.body, pkti + c);
          }
          c = 5;
          if ((strlen(pkti) > c) && (!strncasecmp(pkti, "Lens:", c)))
          {
            ilm.CurFocal = atoi(pkti + c);
          }
          c = 9;
          if ((strlen(pkti) > c) && (!strncasecmp(pkti, "Aperture:", c)))
          {
            while (((pkti[c] == ' ') || (pkti[c] == 'f')) && (c < strlen(pkti)))
            {
              c++;
            }
            ilm.CurAp = atof(pkti + c);
          }
          c = 10;
          if ((strlen(pkti) > c) && (!strncasecmp(pkti, "ISO Speed:", c)))
          {
            iso_speed = atoi(pkti + c);
          }
          c = 13;
          if ((strlen(pkti) > c) && (!strncasecmp(pkti, "Focal Length:", c)))
          {
            ilm.CurFocal = atoi(pkti + c);
          }
          c = 13;
          if ((strlen(pkti) > c) && (!strncasecmp(pkti, "Max Aperture:", c)))
          {
            while (((pkti[c] == ' ') || (pkti[c] == 'f')) && (c < strlen(pkti)))
            {
              c++;
            }
            ilm.MaxAp4CurFocal = atof(pkti + c);
          }
          c = 13;
          if ((strlen(pkti) > c) && (!strncasecmp(pkti, "Min Aperture:", c)))
          {
            while (((pkti[c] == ' ') || (pkti[c] == 'f')) && (c < strlen(pkti)))
            {
              c++;
            }
            ilm.MinAp4CurFocal = atof(pkti + c);
          }
#ifdef LIBRAW_WIN32_CALLS
          pkti = strtok(NULL, "\x0a");
#else
          pkti = strtok_r(NULL, "\x0a", &last);
#endif
        }
      }
    }

    else if (tag == 0x03f3) // 1011
      imgdata.makernotes.common.FlashEC = getreal(type);

    else if (tag == 0x03fc) // 1020
    {
      wbi = getint(type);
      if ((wbi >= 0) && (wbi < 6) && (wbi != -2))
        wbi = wbtag_dcr[wbi];
    }
    else if (tag == 0x03fd && len == 72) // 1021
    {                                    /* WB set in software */
      fseek(ifp, 40, SEEK_CUR);
      FORC3 cam_mul[c] = 2048.0 / fMAX(1.0f, get2());
      wbi = -2;
    }

    else if ((tag == 0x0406) && (len == 1)) // 1030
      imgdata.makernotes.common.CameraTemperature = getreal(type);
    else if ((tag == 0x0413) && (len == 1)) // 1043
      imgdata.makernotes.common.SensorTemperature = getreal(type);
    else if (tag == 0x0848) // 2120
      Kodak_DCR_WBtags(LIBRAW_WBI_Daylight, type, wbi);
    else if (tag == 0x0849) // 2121
      Kodak_DCR_WBtags(LIBRAW_WBI_Tungsten, type, wbi);
    else if (tag == 0x084a) // 2122
      Kodak_DCR_WBtags(LIBRAW_WBI_Fluorescent, type, wbi);
    else if (tag == 0x084b) // 2123
      Kodak_DCR_WBtags(LIBRAW_WBI_Flash, type, wbi);
    else if (tag == 0x084c) // 2124
      Kodak_DCR_WBtags(LIBRAW_WBI_Custom, type, wbi);
    else if (tag == 0x084d) // 2125
    {
      if (wbi == -1)
        wbi = LIBRAW_WBI_Auto;
      Kodak_DCR_WBtags(LIBRAW_WBI_Auto, type, wbi);
    }
    else if (tag == 0x089f) // 2207
      imKodak.ISOCalibrationGain = getreal(type);
    else if (tag == 0x0903) // 2307
      imKodak.AnalogISO = iso_speed = getreal(type);
    else if (tag == 0x090d) // 2317
      linear_table(len);
    else if (tag == 0x09ce) // 2510
      stmread(imgdata.shootinginfo.InternalBodySerial, len, ifp);
    else if (tag == 0x0e92) // 3730
    {
      imKodak.val018percent = get2();
      imgdata.color.linear_max[0] = imgdata.color.linear_max[1] =
          imgdata.color.linear_max[2] = imgdata.color.linear_max[3] =
              (int)(((float)imKodak.val018percent) / 18.0f * 170.0f);
    }
    else if (tag == 0x0e93) // 3731
      imgdata.color.linear_max[0] = imgdata.color.linear_max[1] =
          imgdata.color.linear_max[2] = imgdata.color.linear_max[3] =
              imKodak.val170percent = get2();
    else if (tag == 0x0e94) // 3732
      imKodak.val100percent = get2();
    /*
        else if (tag == 0x1784)    // 6020
          iso_speed = getint(type);
    */
    else if (tag == 0xfa00) // 64000
      stmread(imgdata.shootinginfo.BodySerial, len, ifp);
    else if (tag == 0xfa0d) // 64013
    {
      wbi = fgetc(ifp);
      if ((wbi >= 0) && (wbi < 7))
        wbi = wbtag_kdc[wbi];
    }
    else if (tag == 0xfa13) // 64019
      width = getint(type);
    else if (tag == 0xfa14) // 64020
      height = (getint(type) + 1) & -2;
    /*
          height = getint(type);

        else if (tag == 0xfa16)  // 64022
          raw_width = get2();
        else if (tag == 0xfa17)  // 64023
          raw_height = get2();
    */
    else if (tag == 0xfa18) // 64024
    {
      imKodak.offset_left = getint(8);
      if (type != 8)
        imKodak.offset_left += 1;
    }
    else if (tag == 0xfa19) // 64025
    {
      imKodak.offset_top = getint(8);
      if (type != 8)
        imKodak.offset_top += 1;
    }

    else if (tag == 0xfa25) // 64037
      Kodak_KDC_WBtags(LIBRAW_WBI_Auto, wbi);
    else if (tag == 0xfa27) // 64039
      Kodak_KDC_WBtags(LIBRAW_WBI_Tungsten, wbi);
    else if (tag == 0xfa28) // 64040
      Kodak_KDC_WBtags(LIBRAW_WBI_Fluorescent, wbi);
    else if (tag == 0xfa29) // 64041
      Kodak_KDC_WBtags(LIBRAW_WBI_Daylight, wbi);
    else if (tag == 0xfa2a) // 64042
      Kodak_KDC_WBtags(LIBRAW_WBI_Shade, wbi);

    else if (tag == 0xfa31) // 64049
      imgdata.sizes.raw_inset_crop.cwidth = get2();
    else if (tag == 0xfa32) // 64050
      imgdata.sizes.raw_inset_crop.cheight = get2();
    else if (tag == 0xfa3e) // 64062
      imgdata.sizes.raw_inset_crop.cleft = get2();
    else if (tag == 0xfa3f) // 64063
      imgdata.sizes.raw_inset_crop.ctop = get2();

    else if (((tag == 0x07e4) || (tag == 0xfb01)) &&
             (len == 9)) // 2020 or 64257
    {
      if (KodakIllumMatrix(type, (float *)imKodak.romm_camDaylight))
      {
        romm_coeff(imKodak.romm_camDaylight);
      }
    }
    else if (((tag == 0x07e5) || (tag == 0xfb02)) &&
             (len == 9)) // 2021 or 64258
      KodakIllumMatrix(type, (float *)imKodak.romm_camTungsten);
    else if (((tag == 0x07e6) || (tag == 0xfb03)) &&
             (len == 9)) // 2022 or 64259
      KodakIllumMatrix(type, (float *)imKodak.romm_camFluorescent);
    else if (((tag == 0x07e7) || (tag == 0xfb04)) &&
             (len == 9)) // 2023 or 64260
      KodakIllumMatrix(type, (float *)imKodak.romm_camFlash);
    else if (((tag == 0x07e8) || (tag == 0xfb05)) &&
             (len == 9)) // 2024 or 64261
      KodakIllumMatrix(type, (float *)imKodak.romm_camCustom);
    else if (((tag == 0x07e9) || (tag == 0xfb06)) &&
             (len == 9)) // 2025 or 64262
      KodakIllumMatrix(type, (float *)imKodak.romm_camAuto);

    fseek(ifp, save, SEEK_SET);
  }
}

Project: LibRaw

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

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

  while ((fn = get_next_file()))
  {

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

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

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

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

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

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

Project: LibRaw

int ifd_size_t_cmp(const void *a, const void *b)
{
    if(!a || !b) return 0;
    const ifd_size_t *ai = (ifd_size_t*)a;
    const ifd_size_t *bi = (ifd_size_t*)b;
    return bi->databits > ai->databits ? 1 : (bi->databits < ai->databits? -1 : 0);
}

Project: LibRaw

void LibRaw::setOlympusBodyFeatures(unsigned long long id)
{
  ilm.CamID = id;

  if ((id == 0x4434303430ULL) || // E-1
      (id == 0x4434303431ULL) || // E-300
      ((id & 0x00ffff0000ULL) == 0x0030300000ULL))
  {
    ilm.CameraFormat = LIBRAW_FORMAT_FT;

    if ((id == 0x4434303430ULL) || // E-1
        (id == 0x4434303431ULL) || // E-330
        ((id >= 0x5330303033ULL) && (id <= 0x5330303138ULL)) || // E-330 to E-520
        (id == 0x5330303233ULL) || // E-620
        (id == 0x5330303239ULL) || // E-450
        (id == 0x5330303330ULL) || // E-600
        (id == 0x5330303333ULL))   // E-5
    {
      ilm.CameraMount = LIBRAW_MOUNT_FT;
    }
    else
    {
      ilm.CameraMount = LIBRAW_MOUNT_mFT;
    }
  }
  else
  {
    ilm.LensMount = ilm.CameraMount = LIBRAW_MOUNT_FixedLens;
  }
  return;
}

Project: LibRaw

  virtual INT64 size() { return _fsize; }

Project: LibRaw

void print_compactfun(FILE* outfile, LibRaw& MyCoolRawProcessor, std::string& fn)
{
	trimSpaces(P1.make);
	trimSpaces(P1.model);
	trimSpaces(C.model2);
	trimSpaces(ShootingInfo.BodySerial);
	trimSpaces(ShootingInfo.InternalBodySerial);
	fprintf(outfile, "%s=%s", P1.make, P1.model);
	if (ShootingInfo.BodySerial[0] &&
		!(ShootingInfo.BodySerial[0] == 48 && !ShootingInfo.BodySerial[1]))
		fprintf(outfile, "=Body#: %s", ShootingInfo.BodySerial);
	else if (C.model2[0] && (!strncasecmp(P1.normalized_make, "Kodak", 5)))
		fprintf(outfile, "=Body#: %s", C.model2);
	if (ShootingInfo.InternalBodySerial[0])
		fprintf(outfile, "=Assy#: %s", ShootingInfo.InternalBodySerial);
	if (exifLens.LensSerial[0])
		fprintf(outfile, "=Lens#: %s", exifLens.LensSerial);
	if (exifLens.InternalLensSerial[0])
		fprintf(outfile, "=LensAssy#: %s", exifLens.InternalLensSerial);
	fprintf(outfile, "=\n");
}

Project: LibRaw
File: libraw_cxx.cpp

int LibRaw::cameraCount()
{
  return (sizeof(static_camera_list) / sizeof(static_camera_list[0])) - 1;
}

Project: LibRaw

void LibRaw::parseSonySRF(unsigned len)
{

  if ((len > 0xfffff) || (len == 0))
    return;

  INT64 save = ftell(ifp);
  INT64 offset =
      0x0310c0 - save; /* for non-DNG this value normally is 0x8ddc */
  if (len < offset || offset < 0)
    return;
  INT64 decrypt_len = offset >> 2; /* master key offset value is the next
                                      un-encrypted metadata field after SRF0 */

  unsigned i;
  unsigned MasterKey, SRF2Key, RawDataKey;
  INT64 srf_offset;
  uchar *srf_buf;
  short entries;
  unsigned tag_id, tag_type, tag_datalen, tag_val;

  srf_buf = (uchar *)malloc(len);
  fread(srf_buf, len, 1, ifp);

  offset += srf_buf[offset] << 2;

#define CHECKBUFFER_SGET4(offset)                                              \
  do                                                                           \
  {                                                                            \
    if ((offset + 4) > len)                                                    \
      goto restore_after_parseSonySRF;                                         \
  } while (0)
#define CHECKBUFFER_SGET2(offset)                                              \
  do                                                                           \
  {                                                                            \
    if ((offset + 2) > len)                                                    \
      goto restore_after_parseSonySRF;                                         \
  } while (0)

  CHECKBUFFER_SGET4(offset);

  /* master key is stored in big endian */
  MasterKey = ((unsigned)srf_buf[offset] << 24) |
              ((unsigned)srf_buf[offset + 1] << 16) |
              ((unsigned)srf_buf[offset + 2] << 8) |
              (unsigned)srf_buf[offset + 3];

  /* skip SRF0 */
  srf_offset = 0;
  CHECKBUFFER_SGET2(srf_offset);
  entries = sget2(srf_buf + srf_offset);
  if (entries > 1000)
    goto restore_after_parseSonySRF;
  offset = srf_offset + 2;
  CHECKBUFFER_SGET4(offset + 12 * entries);
  srf_offset = sget4(srf_buf + offset + 12 * entries) -
               save; /* SRF0 ends with SRF1 abs. position */

  /* get SRF1, it has fixed 40 bytes length and contains keys to decode metadata
   * and raw data */
  if (srf_offset < 0 || decrypt_len < srf_offset / 4)
    goto restore_after_parseSonySRF;
  sony_decrypt((unsigned *)(srf_buf + srf_offset), decrypt_len - srf_offset / 4,
               1, MasterKey);
  CHECKBUFFER_SGET2(srf_offset);
  entries = sget2(srf_buf + srf_offset);
  if (entries > 1000)
    goto restore_after_parseSonySRF;
  offset = srf_offset + 2;

  while (entries--)
  {
    CHECKBUFFER_SGET4(srf_offset + 8);
    tag_id = sget2(srf_buf + offset);
    tag_type = sget2(srf_buf + offset + 2);
    tag_datalen = sget4(srf_buf + offset + 4);
    tag_val = sget4(srf_buf + offset + 8);
    if (tag_id == 0x0000)
      SRF2Key = tag_val;
    else if (tag_id == 0x0001)
      RawDataKey = tag_val;
    offset += 12;
  }

  /* get SRF2 */
  CHECKBUFFER_SGET4(offset);
  srf_offset =
      sget4(srf_buf + offset) - save; /* SRFn ends with SRFn+1 position */
  if (srf_offset < 0 || decrypt_len < srf_offset / 4)
    goto restore_after_parseSonySRF;
  sony_decrypt((unsigned *)(srf_buf + srf_offset), decrypt_len - srf_offset / 4,
               1, SRF2Key);
  CHECKBUFFER_SGET2(srf_offset);
  entries = sget2(srf_buf + srf_offset);
  if (entries > 1000)
    goto restore_after_parseSonySRF;
  offset = srf_offset + 2;
  while (entries--)
  {
    CHECKBUFFER_SGET4(srf_offset + 8);
    tag_id = sget2(srf_buf + offset);
    tag_type = sget2(srf_buf + offset + 2);
    tag_datalen = sget4(srf_buf + offset + 4);
    tag_val = sget4(srf_buf + offset + 8);
    switch (tag_id)
    {
      /*
      0x0002	SRF6Offset
      0x0003	SRFDataOffset (?)
      0x0004	RawDataOffset
      0x0005	RawDataLength
      */
    case 0x0043:
      CHECKBUFFER_SGET4(tag_val - save + 4);
      i = sget4(srf_buf + tag_val - save + 4);
      // next sget4 already checked b/c offset is less
      if (i)
        ilm.MaxAp4MaxFocal =
            ((float)sget4(srf_buf + tag_val - save)) / ((float)i);
      break;
    case 0x0044:
      CHECKBUFFER_SGET4(tag_val - save + 4);
      i = sget4(srf_buf + tag_val - save + 4);
      if (i)
        ilm.MaxAp4MinFocal =
            ((float)sget4(srf_buf + tag_val - save)) / ((float)i);
      break;
    case 0x0045:
      CHECKBUFFER_SGET4(tag_val - save + 4);
      i = sget4(srf_buf + tag_val - save + 4);
      if (i)
        ilm.MinFocal = ((float)sget4(srf_buf + tag_val - save)) / ((float)i);
      break;
    case 0x0046:
      CHECKBUFFER_SGET4(tag_val - save + 4);
      i = sget4(srf_buf + tag_val - save + 4);
      if (i)
        ilm.MaxFocal = ((float)sget4(srf_buf + tag_val - save)) / ((float)i);
      break;

    case 0x00c0:
      icWBC[LIBRAW_WBI_Daylight][0] = tag_val;
      break;
    case 0x00c1:
      icWBC[LIBRAW_WBI_Daylight][1] = icWBC[LIBRAW_WBI_Daylight][3] = tag_val;
      break;
    case 0x00c2:
      icWBC[LIBRAW_WBI_Daylight][2] = tag_val;
      break;
    case 0x00c3:
      icWBC[LIBRAW_WBI_Cloudy][0] = tag_val;
      break;
    case 0x00c4:
      icWBC[LIBRAW_WBI_Cloudy][1] = icWBC[LIBRAW_WBI_Cloudy][3] = tag_val;
      break;
    case 0x00c5:
      icWBC[LIBRAW_WBI_Cloudy][2] = tag_val;
      break;
    case 0x00c6:
      icWBC[LIBRAW_WBI_Fluorescent][0] = tag_val;
      break;
    case 0x00c7:
      icWBC[LIBRAW_WBI_Fluorescent][1] = icWBC[LIBRAW_WBI_Fluorescent][3] =
          tag_val;
      break;
    case 0x00c8:
      icWBC[LIBRAW_WBI_Fluorescent][2] = tag_val;
      break;
    case 0x00c9:
      icWBC[LIBRAW_WBI_Tungsten][0] = tag_val;
      break;
    case 0x00ca:
      icWBC[LIBRAW_WBI_Tungsten][1] = icWBC[LIBRAW_WBI_Tungsten][3] = tag_val;
      break;
    case 0x00cb:
      icWBC[LIBRAW_WBI_Tungsten][2] = tag_val;
      break;
    case 0x00cc:
      icWBC[LIBRAW_WBI_Flash][0] = tag_val;
      break;
    case 0x00cd:
      icWBC[LIBRAW_WBI_Flash][1] = icWBC[LIBRAW_WBI_Flash][3] = tag_val;
      break;
    case 0x00ce:
      icWBC[LIBRAW_WBI_Flash][2] = tag_val;
      break;
    case 0x00d0:
      cam_mul[0] = tag_val;
      break;
    case 0x00d1:
      cam_mul[1] = cam_mul[3] = tag_val;
      break;
    case 0x00d2:
      cam_mul[2] = tag_val;
      break;
    }
    offset += 12;
  }

restore_after_parseSonySRF:
  free(srf_buf);
  fseek(ifp, save, SEEK_SET);
#undef CHECKBUFFER_SGET4
#undef CHECKBUFFER_SGET2
}

Project: LibRaw

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

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

Project: LibRaw

void LibRaw::fbdd_green()
{
  int row, col, c, u = width, v = 2 * u, w = 3 * u, x = 4 * u, y = 5 * u, indx,
                   min, max, current;
  float f[4], g[4];

  for (row = 5; row < height - 5; row++)
    for (col = 5 + (FC(row, 1) & 1), indx = row * width + col, c = FC(row, col);
         col < u - 5; col += 2, indx += 2)
    {

      f[0] = 1.0 / (1.0 + abs(image[indx - u][1] - image[indx - w][1]) +
                    abs(image[indx - w][1] - image[indx + y][1]));
      f[1] = 1.0 / (1.0 + abs(image[indx + 1][1] - image[indx + 3][1]) +
                    abs(image[indx + 3][1] - image[indx - 5][1]));
      f[2] = 1.0 / (1.0 + abs(image[indx - 1][1] - image[indx - 3][1]) +
                    abs(image[indx - 3][1] - image[indx + 5][1]));
      f[3] = 1.0 / (1.0 + abs(image[indx + u][1] - image[indx + w][1]) +
                    abs(image[indx + w][1] - image[indx - y][1]));

      g[0] = CLIP((23 * image[indx - u][1] + 23 * image[indx - w][1] +
                   2 * image[indx - y][1] +
                   8 * (image[indx - v][c] - image[indx - x][c]) +
                   40 * (image[indx][c] - image[indx - v][c])) /
                  48.0);
      g[1] = CLIP((23 * image[indx + 1][1] + 23 * image[indx + 3][1] +
                   2 * image[indx + 5][1] +
                   8 * (image[indx + 2][c] - image[indx + 4][c]) +
                   40 * (image[indx][c] - image[indx + 2][c])) /
                  48.0);
      g[2] = CLIP((23 * image[indx - 1][1] + 23 * image[indx - 3][1] +
                   2 * image[indx - 5][1] +
                   8 * (image[indx - 2][c] - image[indx - 4][c]) +
                   40 * (image[indx][c] - image[indx - 2][c])) /
                  48.0);
      g[3] = CLIP((23 * image[indx + u][1] + 23 * image[indx + w][1] +
                   2 * image[indx + y][1] +
                   8 * (image[indx + v][c] - image[indx + x][c]) +
                   40 * (image[indx][c] - image[indx + v][c])) /
                  48.0);

      image[indx][1] =
          CLIP((f[0] * g[0] + f[1] * g[1] + f[2] * g[2] + f[3] * g[3]) /
               (f[0] + f[1] + f[2] + f[3]));

      min = MIN(
          image[indx + 1 + u][1],
          MIN(image[indx + 1 - u][1],
              MIN(image[indx - 1 + u][1],
                  MIN(image[indx - 1 - u][1],
                      MIN(image[indx - 1][1],
                          MIN(image[indx + 1][1],
                              MIN(image[indx - u][1], image[indx + u][1])))))));

      max = MAX(
          image[indx + 1 + u][1],
          MAX(image[indx + 1 - u][1],
              MAX(image[indx - 1 + u][1],
                  MAX(image[indx - 1 - u][1],
                      MAX(image[indx - 1][1],
                          MAX(image[indx + 1][1],
                              MAX(image[indx - u][1], image[indx + u][1])))))));

      image[indx][1] = ULIM(image[indx][1], max, min);
    }
}

Project: LibRaw

void LibRaw::processCanonCameraInfo(unsigned long long id, uchar *CameraInfo,
                                    unsigned maxlen, unsigned type, unsigned dng_writer)
{
  ushort iCanonLensID = 0, iCanonMaxFocal = 0, iCanonMinFocal = 0,
         iCanonLens = 0, iCanonCurFocal = 0, iCanonFocalType = 0;

  if (maxlen < 16)
    return; // too short

 if (type == 7 && (sget2(CameraInfo) == 0xaaaa) && (dng_writer == nonDNG)) { // CameraOrientation
    int c, i;
    for (c = i = 2; (ushort)c != 0xbbbb && i < maxlen; i++)
      c = c << 8 | CameraInfo[i];
    while (i < (maxlen - 5))
      if ((sget4(CameraInfo+i) == 257) && ((c = CameraInfo[i+8]) < 3)) {
        imCanon.MakernotesFlip = "065"[c] - '0';
        break;
      } else i+=4;
  }

  CameraInfo[0] = 0;
  CameraInfo[1] = 0;
  if (type == 4) {
    if ((maxlen == 94)  || (maxlen == 138) || (maxlen == 148) ||
        (maxlen == 156) || (maxlen == 162) || (maxlen == 167) ||
        (maxlen == 171) || (maxlen == 264) || (maxlen > 400))
      imgdata.makernotes.common.CameraTemperature = sget4(CameraInfo + ((maxlen - 3) << 2));
    else if (maxlen == 72)
      imgdata.makernotes.common.CameraTemperature = sget4(CameraInfo + ((maxlen - 1) << 2));
    else if ((maxlen == 85) || (maxlen == 93))
      imgdata.makernotes.common.CameraTemperature = sget4(CameraInfo + ((maxlen - 2) << 2));
    else if ((maxlen == 96) || (maxlen == 104))
      imgdata.makernotes.common.CameraTemperature = sget4(CameraInfo + ((maxlen - 4) << 2));
  }

  switch (id)
  {
  case 0x80000001: // 1D
  case 0x80000167: // 1DS
    iCanonCurFocal = 10;
    iCanonLensID = 13;
    iCanonMinFocal = 14;
    iCanonMaxFocal = 16;
    if (!ilm.CurFocal)
      ilm.CurFocal = sget2(CameraInfo + iCanonCurFocal);
    if (!ilm.MinFocal)
      ilm.MinFocal = sget2(CameraInfo + iCanonMinFocal);
    if (!ilm.MaxFocal)
      ilm.MaxFocal = sget2(CameraInfo + iCanonMaxFocal);
    imgdata.makernotes.common.CameraTemperature = 0.0f;
    break;
  case 0x80000174: // 1DMkII
  case 0x80000188: // 1DsMkII
    iCanonCurFocal = 9;
    iCanonLensID = 12;
    iCanonMinFocal = 17;
    iCanonMaxFocal = 19;
    iCanonFocalType = 45;
    break;
  case 0x80000232: // 1DMkII N
    iCanonCurFocal = 9;
    iCanonLensID = 12;
    iCanonMinFocal = 17;
    iCanonMaxFocal = 19;
    break;
  case 0x80000169: // 1DMkIII
  case 0x80000215: // 1DsMkIII
    iCanonCurFocal = 29;
    iCanonLensID = 273;
    iCanonMinFocal = 275;
    iCanonMaxFocal = 277;
    break;
  case 0x80000281: // 1DMkIV
    iCanonCurFocal = 30;
    iCanonLensID = 335;
    iCanonMinFocal = 337;
    iCanonMaxFocal = 339;
    break;
  case 0x80000269: // 1D X
    iCanonCurFocal = 35;
    iCanonLensID = 423;
    iCanonMinFocal = 425;
    iCanonMaxFocal = 427;
    break;
  case 0x80000213: // 5D
    iCanonCurFocal = 40;
    if (!sget2Rev(CameraInfo + 12))
      iCanonLensID = 151;
    else
      iCanonLensID = 12;
    iCanonMinFocal = 147;
    iCanonMaxFocal = 149;
    break;
  case 0x80000218: // 5DMkII
    iCanonCurFocal = 30;
    iCanonLensID = 230;
    iCanonMinFocal = 232;
    iCanonMaxFocal = 234;
    break;
  case 0x80000285: // 5DMkIII
    iCanonCurFocal = 35;
    iCanonLensID = 339;
    iCanonMinFocal = 341;
    iCanonMaxFocal = 343;
    break;
  case 0x80000302: // 6D
    iCanonCurFocal = 35;
    iCanonLensID = 353;
    iCanonMinFocal = 355;
    iCanonMaxFocal = 357;
    break;
  case 0x80000250: // 7D
    iCanonCurFocal = 30;
    iCanonLensID = 274;
    iCanonMinFocal = 276;
    iCanonMaxFocal = 278;
    break;
  case 0x80000190: // 40D
    iCanonCurFocal = 29;
    iCanonLensID = 214;
    iCanonMinFocal = 216;
    iCanonMaxFocal = 218;
    iCanonLens = 2347;
    break;
  case 0x80000261: // 50D
    iCanonCurFocal = 30;
    iCanonLensID = 234;
    iCanonMinFocal = 236;
    iCanonMaxFocal = 238;
    break;
  case 0x80000287: // 60D
    iCanonCurFocal = 30;
    iCanonLensID = 232;
    iCanonMinFocal = 234;
    iCanonMaxFocal = 236;
    break;
  case 0x80000325: // 70D
    iCanonCurFocal = 35;
    iCanonLensID = 358;
    iCanonMinFocal = 360;
    iCanonMaxFocal = 362;
    break;
  case 0x80000176: // 450D
    iCanonCurFocal = 29;
    iCanonLensID = 222;
    iCanonLens = 2355;
    break;
  case 0x80000252: // 500D
    iCanonCurFocal = 30;
    iCanonLensID = 246;
    iCanonMinFocal = 248;
    iCanonMaxFocal = 250;
    break;
  case 0x80000270: // 550D
    iCanonCurFocal = 30;
    iCanonLensID = 255;
    iCanonMinFocal = 257;
    iCanonMaxFocal = 259;
    break;
  case 0x80000286: // 600D
  case 0x80000288: // 1100D
    iCanonCurFocal = 30;
    iCanonLensID = 234;
    iCanonMinFocal = 236;
    iCanonMaxFocal = 238;
    break;
  case 0x80000301: // 650D
  case 0x80000326: // 700D
    iCanonCurFocal = 35;
    iCanonLensID = 295;
    iCanonMinFocal = 297;
    iCanonMaxFocal = 299;
    break;
  case 0x80000254: // 1000D
    iCanonCurFocal = 29;
    iCanonLensID = 226;
    iCanonMinFocal = 228;
    iCanonMaxFocal = 230;
    iCanonLens = 2359;
    break;
  }
  if (iCanonFocalType)
  {
    if (iCanonFocalType >= maxlen)
      return; // broken;
    ilm.FocalType = CameraInfo[iCanonFocalType];
    if (!ilm.FocalType) // zero means 'prime' here, replacing with standard '1'
      ilm.FocalType = LIBRAW_FT_PRIME_LENS;
  }
  if (!ilm.CurFocal)
  {
    if (iCanonCurFocal >= maxlen)
      return; // broken;
    ilm.CurFocal = sget2Rev(CameraInfo + iCanonCurFocal);
  }
  if (!ilm.LensID)
  {
    if (iCanonLensID >= maxlen)
      return; // broken;
    ilm.LensID = sget2Rev(CameraInfo + iCanonLensID);
  }
  if (!ilm.MinFocal)
  {
    if (iCanonMinFocal >= maxlen)
      return; // broken;
    ilm.MinFocal = sget2Rev(CameraInfo + iCanonMinFocal);
  }
  if (!ilm.MaxFocal)
  {
    if (iCanonMaxFocal >= maxlen)
      return; // broken;
    ilm.MaxFocal = sget2Rev(CameraInfo + iCanonMaxFocal);
  }
  if (!ilm.Lens[0] && iCanonLens)
  {
    if (iCanonLens + 64 >= maxlen) // broken;
      return;

    char *pl = (char *)CameraInfo + iCanonLens;
    if (!strncmp(pl, "EF-S", 4))
    {
      memcpy(ilm.Lens, pl, 4);
      ilm.Lens[4] = ' ';
      memcpy(ilm.LensFeatures_pre, pl, 4);
      ilm.LensMount = LIBRAW_MOUNT_Canon_EF_S;
      ilm.LensFormat = LIBRAW_FORMAT_APSC;
      memcpy(ilm.Lens + 5, pl + 4, 60);
    }
    else if (!strncmp(pl, "EF-M", 4))
    {
      memcpy(ilm.Lens, pl, 4);
      ilm.Lens[4] = ' ';
      memcpy(ilm.LensFeatures_pre, pl, 4);
      ilm.LensMount = LIBRAW_MOUNT_Canon_EF_M;
      ilm.LensFormat = LIBRAW_FORMAT_APSC;
      memcpy(ilm.Lens + 5, pl + 4, 60);
    }
    else if (!strncmp(pl, "EF", 2))
    {
      memcpy(ilm.Lens, pl, 2);
      ilm.Lens[2] = ' ';
      memcpy(ilm.LensFeatures_pre, pl, 2);
      ilm.LensMount = LIBRAW_MOUNT_Canon_EF;
      ilm.LensFormat = LIBRAW_FORMAT_FF;
      memcpy(ilm.Lens + 3, pl + 2, 62);
    }
    else if (!strncmp(ilm.Lens, "CN-E", 4))
    {
      memmove(ilm.Lens + 5, ilm.Lens + 4, 60);
      ilm.Lens[4] = ' ';
      memcpy(ilm.LensFeatures_pre, ilm.Lens, 4);
      ilm.LensMount = LIBRAW_MOUNT_Canon_EF;
      ilm.LensFormat = LIBRAW_FORMAT_FF;
    }
    else if (!strncmp(pl, "TS-E", 4))
    {
      memcpy(ilm.Lens, pl, 4);
      ilm.Lens[4] = ' ';
      memcpy(ilm.LensFeatures_pre, pl, 4);
      ilm.LensMount = LIBRAW_MOUNT_Canon_EF;
      ilm.LensFormat = LIBRAW_FORMAT_FF;
      memcpy(ilm.Lens + 5, pl + 4, 60);
    }
    else if (!strncmp(pl, "MP-E", 4))
    {
      memcpy(ilm.Lens, pl, 4);
      ilm.Lens[4] = ' ';
      memcpy(ilm.LensFeatures_pre, pl, 4);
      ilm.LensMount = LIBRAW_MOUNT_Canon_EF;
      ilm.LensFormat = LIBRAW_FORMAT_FF;
      memcpy(ilm.Lens + 5, pl + 4, 60);
    }
    else // non-Canon lens
      memcpy(ilm.Lens, pl, 64);
  }
  return;
}

Project: LibRaw

unsigned LibRaw::parse_custom_cameras(unsigned limit,
                                      libraw_custom_camera_t table[],
                                      char **list)
{
  if (!list)
    return 0;
  unsigned index = 0;
  for (int i = 0; i < limit; i++)
  {
    if (!list[i])
      break;
    if (strlen(list[i]) < 10)
      continue;
    char *string = (char *)malloc(strlen(list[i]) + 1);
    strcpy(string, list[i]);
    char *start = string;
    memset(&table[index], 0, sizeof(table[0]));
    for (int j = 0; start && j < 14; j++)
    {
      char *end = strchr(start, ',');
      if (end)
      {
        *end = 0;
        end++;
      } // move to next char
      while (isspace(*start) && *start)
        start++; // skip leading spaces?
      unsigned val = strtol(start, 0, 10);
      switch (j)
      {
      case 0:
        table[index].fsize = val;
        break;
      case 1:
        table[index].rw = val;
        break;
      case 2:
        table[index].rh = val;
        break;
      case 3:
        table[index].lm = val;
        break;
      case 4:
        table[index].tm = val;
        break;
      case 5:
        table[index].rm = val;
        break;
      case 6:
        table[index].bm = val;
        break;
      case 7:
        table[index].lf = val;
        break;
      case 8:
        table[index].cf = val;
        break;
      case 9:
        table[index].max = val;
        break;
      case 10:
        table[index].flags = val;
        break;
      case 11:
        strncpy(table[index].t_make, start, sizeof(table[index].t_make) - 1);
        break;
      case 12:
        strncpy(table[index].t_model, start, sizeof(table[index].t_model) - 1);
        break;
      case 13:
        table[index].offset = val;
        break;
      default:
        break;
      }
      start = end;
    }
    free(string);
    if (table[index].t_make[0])
      index++;
  }
  return index;
}