Commit message: merged dcraw 9.23 and lens identify
CVE: CVE-2018-5815
Vulnerability description: An integer overflow error within the "parse_qt()" function (internal/dcraw_common.cpp) in LibRaw versions prior to 0.18.12 can be exploited to trigger an infinite loop via a specially crafted Apple QuickTime file.

Project: LibRaw
File: dcraw.c

void CLASS parse_makernote (int base, int uptag)
{
  unsigned offset=0, entries, tag, type, len, save, c;
  unsigned ver97=0, serial=0, i, wbi=0, wb[4]={0,0,0,0};
  uchar buf97[324], ci, cj, ck;
  short morder, sorder=order;
  char buf[10];
  unsigned SamsungKey[11];
  static const double rgb_adobe[3][3] =		// inv(sRGB2XYZ_D65) * AdobeRGB2XYZ_D65
    {{ 1.398283396477404,     -0.398283116703571, 4.427165001263944E-08},
     {-1.233904514232401E-07,  0.999999995196570, 3.126724276714121e-08},
     { 4.561487232726535E-08, -0.042938290466635, 1.042938250416105    }};

  float adobe_cam [3][3];
  uchar NikonKey;

#ifdef LIBRAW_LIBRARY_BUILD
  unsigned NikonLensDataVersion = 0;
  unsigned lenNikonLensData = 0;

  uchar *CanonCameraInfo;
  unsigned lenCanonCameraInfo = 0;

  unsigned uidPentax = 0;
  unsigned long long tLensID;

  uchar *table_buf;
  uchar *table_buf_0x9050;
  ushort table_buf_0x9050_present = 0;
  uchar *table_buf_0x940c;
  ushort table_buf_0x940c_present = 0;
#endif
/*
   The MakerNote might have its own TIFF header (possibly with
   its own byte-order!), or it might just be a table.
 */
  if (!strcmp(make,"Nokia")) return;
  fread (buf, 1, 10, ifp);
  if (!strncmp (buf,"KDK" ,3) ||	/* these aren't TIFF tables */
      !strncmp (buf,"VER" ,3) ||
      !strncmp (buf,"IIII",4) ||
      !strncmp (buf,"MMMM",4)) return;
  if (!strncmp (buf,"KC"  ,2) ||	/* Konica KD-400Z, KD-510Z */
      !strncmp (buf,"MLY" ,3)) {	/* Minolta DiMAGE G series */
    order = 0x4d4d;
    while ((i=ftell(ifp)) < data_offset && i < 16384) {
      wb[0] = wb[2];  wb[2] = wb[1];  wb[1] = wb[3];
      wb[3] = get2();
      if (wb[1] == 256 && wb[3] == 256 &&
	  wb[0] > 256 && wb[0] < 640 && wb[2] > 256 && wb[2] < 640)
	FORC4 cam_mul[c] = wb[c];
    }
    goto quit;
  }
  if (!strcmp (buf,"Nikon")) {
    base = ftell(ifp);
    order = get2();
    if (get2() != 42) goto quit;
    offset = get4();
    fseek (ifp, offset-8, SEEK_CUR);
  } else if (!strcmp (buf,"OLYMPUS") ||
             !strcmp (buf,"PENTAX ")) {
    base = ftell(ifp)-10;
    fseek (ifp, -2, SEEK_CUR);
    order = get2();
    if (buf[0] == 'O') get2();
  } else if (!strncmp (buf,"SONY",4) ||
						 !strcmp  (buf,"Panasonic")) {
    goto nf;
  } else if (!strncmp (buf,"FUJIFILM",8)) {
    base = ftell(ifp)-10;
	nf: order = 0x4949;
    fseek (ifp,  2, SEEK_CUR);
  } else if (!strcmp (buf,"OLYMP") ||
						 !strcmp (buf,"LEICA") ||
						 !strcmp (buf,"Ricoh") ||
						 !strcmp (buf,"EPSON"))
    fseek (ifp, -2, SEEK_CUR);
  else if (!strcmp (buf,"AOC") ||
					 !strcmp (buf,"QVC"))
    fseek (ifp, -4, SEEK_CUR);
  else {
    fseek (ifp, -10, SEEK_CUR);
    if (!strncmp(make,"SAMSUNG",7))
      base = ftell(ifp);
  }

  // adjust pos & base for Leica M8/M9/M Mono tags and dir in tag 0x3400
  if (!strncasecmp(make, "LEICA", 5))
    {
      if (!strncmp(model, "M8", 2))
        {
          base = ftell(ifp)-8;
        }
      else if (!strncmp(model, "M9", 2) ||
               !strncmp(model, "M Monochrom", 11))
        {
          if (!uptag)
            {
              base = ftell(ifp) - 10;
              fseek (ifp, 8, SEEK_CUR);
            }
          else if (uptag == 0x3400)
            {
              fseek (ifp, 10, SEEK_CUR);
              base += 10;
            }
        }
    }

  entries = get2();

//   printf("\n*** parse_makernote\n\tmake  =%s=\n\tmodel =%s= \n\tentries: %d\n",
// 		make, model, entries);

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

// 	printf ("\n\tbase: 0x%x tag: 0x%04x type: 0x%x len: 0x%x pos: 0x%llx",
// 		base, tag, type, len, ftell(ifp));

#ifdef LIBRAW_LIBRARY_BUILD

    if (!strcmp(make, "Canon"))
      {
        if (tag == 0x0001)				// camera settings
          {
            fseek(ifp, 44, SEEK_CUR);
            imgdata.lens.makernotes.LensID = get2();
            imgdata.lens.makernotes.MaxFocal = get2();
            imgdata.lens.makernotes.MinFocal = get2();
            imgdata.lens.canon.CanonFocalUnits = get2();
            if (imgdata.lens.canon.CanonFocalUnits != 1)
              {
                imgdata.lens.makernotes.MaxFocal /= (float)imgdata.lens.canon.CanonFocalUnits;
                imgdata.lens.makernotes.MinFocal /= (float)imgdata.lens.canon.CanonFocalUnits;
              }
            imgdata.lens.makernotes.MaxAp = powf64(2.0f, _CanonConvert2EV(get2()) / 2.0f);
            imgdata.lens.makernotes.MinAp = powf64(2.0f, _CanonConvert2EV(get2()) / 2.0f);
          }

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

        else if (tag == 0x0004)			// shot info
          {
            fseek(ifp, 42, SEEK_CUR);
            imgdata.lens.makernotes.CurAp = powf64(2.0f, _CanonConvert2EV(get2()) / 2.0f);
          }

        else if (tag == 0x000d)			// camera info
          {
            CanonCameraInfo = (uchar*)malloc(len);
            fread(CanonCameraInfo, len, 1, ifp);
            lenCanonCameraInfo = len;
          }

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

        else if (tag == 0x4021)			// multi-exposure tag
          {
            get4();
            if (get4() == 2)
              {
                imgdata.color.wb_applied = 1;
              }
          }
      }

    else if (!strncmp(make, "FUJI", 4))
      switch (tag) {
      case 0x1404: imgdata.lens.makernotes.MinFocal = getreal(type); break;
      case 0x1405: imgdata.lens.makernotes.MaxFocal = getreal(type); break;
      case 0x1406: imgdata.lens.makernotes.MaxAp4MinFocal = getreal(type); break;
      case 0x1407: imgdata.lens.makernotes.MaxAp4MaxFocal = getreal(type); break;
      }

    else if (!strncasecmp(make, "LEICA", 5))
      {
        if ((tag == 0x0303) && (type != 4))
          {
            fread(imgdata.lens.makernotes.Lens, len, 1, ifp);
          }

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

        else if (
                 ((tag == 0x0313) || (tag == 0x34003406)) &&
                 (fabs(imgdata.lens.makernotes.CurAp) < 0.5f)
                 )
          {
            imgdata.lens.makernotes.CurAp = getreal(5);
          }

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

    else if (!strncmp(make, "NIKON",5))
      {
        if (tag == 0x0082)						// lens attachment
          {
            fread(imgdata.lens.makernotes.Attachment, len, 1, ifp);
          }
        else if (tag == 0x0083)				// lens type
          {
            imgdata.lens.nikon.NikonLensType = fgetc(ifp);
            if (!(imgdata.lens.nikon.NikonLensType & 0x01))
              {
                imgdata.lens.makernotes.LensFeatures_pre[0] = 'A';
                imgdata.lens.makernotes.LensFeatures_pre[1] = 'F';
              }
            if (imgdata.lens.nikon.NikonLensType & 0x02)
              {
                if (imgdata.lens.nikon.NikonLensType & 0x04)
                  imgdata.lens.makernotes.LensFeatures_suf[0] = 'G';
                else
                  imgdata.lens.makernotes.LensFeatures_suf[0] = 'D';
                imgdata.lens.makernotes.LensFeatures_suf[1] = ' ';
              }
            if (imgdata.lens.nikon.NikonLensType & 0x08)
              {
                imgdata.lens.makernotes.LensFeatures_suf[2] = 'V';
                imgdata.lens.makernotes.LensFeatures_suf[3] = 'R';
              }
            if (imgdata.lens.nikon.NikonLensType & 0x10)
              {
                imgdata.lens.makernotes.LensMount = Nikon_CX;
              }
            if (imgdata.lens.nikon.NikonLensType & 0x20)
              {
                strcpy(imgdata.lens.makernotes.Adapter, "FT-1");
              }
            imgdata.lens.nikon.NikonLensType = imgdata.lens.nikon.NikonLensType & 0xdf;
          }
        else if (tag == 0x0084)				// lens
          {
            imgdata.lens.makernotes.MinFocal = getreal(type);
            imgdata.lens.makernotes.MaxFocal = getreal(type);
            imgdata.lens.makernotes.MaxAp4MinFocal = getreal(type);
            imgdata.lens.makernotes.MaxAp4MaxFocal = getreal(type);
          }
        else if (tag == 0x008b)				// lens f-stops
          {
            uchar a, b, c;
            a = fgetc(ifp);
            b = fgetc(ifp);
            c = fgetc(ifp);
            if (c)
              {
                imgdata.lens.nikon.NikonLensFStops = a*b*(12/c);
                imgdata.lens.makernotes.LensFStops =
                  (float)imgdata.lens.nikon.NikonLensFStops /12.0f;
              }
          }
        else if ((tag == 0x0093) &&		// compression
                 (get2() == 8))				// sRAW
          {
            imgdata.color.wb_applied = 1;
            imgdata.color.gamma_applied = 1;
          }
        else if (tag == 0x0098)				// contains lens data
          {
            for (i = 0; i < 4; i++)
              {
                NikonLensDataVersion = NikonLensDataVersion * 10 + fgetc(ifp) - '0';
              }
            switch (NikonLensDataVersion)
              {
              case 100: lenNikonLensData = 9; imgdata.lens.makernotes.LensMount = Nikon_F; break;
              case 101:
              case 201:	// encrypted, starting from v.201
              case 202:
              case 203: lenNikonLensData = 15; imgdata.lens.makernotes.LensMount = Nikon_F; break;
              case 204: lenNikonLensData = 16; imgdata.lens.makernotes.LensMount = Nikon_F; break;
              case 400: lenNikonLensData = 459; break;
              case 401: lenNikonLensData = 590; break;
              case 402: lenNikonLensData = 509; break;
              case 403: lenNikonLensData = 879; break;
              }
            table_buf = (uchar*)malloc(lenNikonLensData);
            fread(table_buf, lenNikonLensData, 1, ifp);
            if ((NikonLensDataVersion < 201) && lenNikonLensData)
            {
              processNikonLensData(table_buf, lenNikonLensData);
              lenNikonLensData = 0;
            }
          }
      }

    else if (!strncmp(make, "OLYMPUS", 7))
      {
        switch (tag) {
        case 0x0207:
        case 0x20100100:
          {
            uchar sOlyID[7];
            long unsigned OlyID;
            fread (sOlyID, len, 1, ifp);
            OlyID = sOlyID[0];
            i = 1;
            while (sOlyID[i])
              {
                OlyID = OlyID << 8 | sOlyID[i];
                i++;
              }
            setOlympusBodyFeatures(OlyID);
          }
          break;
        case 0x1002:
          imgdata.lens.makernotes.CurAp = powf64(2.0f, getreal(type)/2);
          break;
        case 0x20100201:
          imgdata.lens.makernotes.LensID =
            (unsigned long long)fgetc(ifp)<<16 |
            (unsigned long long)(fgetc(ifp), fgetc(ifp))<<8 |
            (unsigned long long)fgetc(ifp);
          imgdata.lens.makernotes.LensMount = FT;
          imgdata.lens.makernotes.LensFormat = FT;
          if (((imgdata.lens.makernotes.LensID < 0x20000) ||
               (imgdata.lens.makernotes.LensID > 0x4ffff)) &&
              (imgdata.lens.makernotes.LensID & 0x10))
            {
              imgdata.lens.makernotes.LensMount = mFT;
            }
          break;
        case 0x20100203:
          fread(imgdata.lens.makernotes.Lens, len, 1, ifp);
          break;
        case 0x20100205:
          imgdata.lens.makernotes.MaxAp4MinFocal = powf64(sqrt(2.0f), get2() / 256.0f);
          break;
        case 0x20100206:
          imgdata.lens.makernotes.MaxAp4MaxFocal = powf64(sqrt(2.0f), get2() / 256.0f);
          break;
        case 0x20100207:
          imgdata.lens.makernotes.MinFocal = (float)get2();
          break;
        case 0x20100208:
          imgdata.lens.makernotes.MaxFocal = (float)get2();
          if (imgdata.lens.makernotes.MaxFocal > 1000.0f)
            imgdata.lens.makernotes.MaxFocal = imgdata.lens.makernotes.MinFocal;
          break;
        case 0x2010020a:
          imgdata.lens.makernotes.MaxAp4CurFocal = powf64(sqrt(2.0f), get2() / 256.0f);
          break;
        case 0x20100301:
          imgdata.lens.makernotes.TeleconverterID = fgetc(ifp) << 8;
          fgetc(ifp);
          imgdata.lens.makernotes.TeleconverterID =
            imgdata.lens.makernotes.TeleconverterID | fgetc(ifp);
          break;
        case 0x20100303:
          fread(imgdata.lens.makernotes.Teleconverter, len, 1, ifp);
          break;
        case 0x20100403:
          fread(imgdata.lens.makernotes.Attachment, len, 1, ifp);
          break;
        }
      }

    else if (!strncmp(make, "PENTAX", 6) &&
             !strncmp(model, "GR", 2))
      {
        if ((tag == 0x1001) && (type == 3))
          {
            imgdata.lens.makernotes.CameraMount = FixedLens;
            imgdata.lens.makernotes.LensMount = FixedLens;
            imgdata.lens.makernotes.CameraFormat = APSC;
            imgdata.lens.makernotes.LensID = -1;
            imgdata.lens.makernotes.FocalType = 1;
          }
        else if ((tag == 0x1017) && (get2() == 2))
          {
            strcpy(imgdata.lens.makernotes.Attachment, "Wide-Angle Adapter");
          }
        else if (tag == 0x1500)
          {
            imgdata.lens.makernotes.CurFocal = getreal(type);
          }
      }

    else if (!strncmp(make, "RICOH", 5) &&
             strncmp(model, "PENTAX", 6))
      {
        if ((tag == 0x1017) && (get2() == 2))
          {
            strcpy(imgdata.lens.makernotes.Attachment, "Wide-Angle Adapter");
          }

        else if (tag == 0x1500)
          {
            imgdata.lens.makernotes.CurFocal = getreal(type);
          }

        else if (tag == 0x2001)
          {
            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()+34, SEEK_SET);
            imgdata.lens.makernotes.LensID = getc(ifp) - '0';
            switch(imgdata.lens.makernotes.LensID) 
              {
            	case 1:
            	case 2:
            	case 3:
            	case 5:
            	case 6:
            		imgdata.lens.makernotes.CameraMount = FixedLens;
                imgdata.lens.makernotes.LensMount = RicohModule;
                break;
              case 8:
                imgdata.lens.makernotes.CameraMount = Leica_M;
                imgdata.lens.makernotes.CameraFormat = APSC;
                imgdata.lens.makernotes.LensID = -1;
                break;
              default:
              	imgdata.lens.makernotes.LensID = -1;
              }
          }
      }

    else if (!strncmp(make, "PENTAX", 6) ||
             !strncmp(model, "PENTAX", 6) ||
             (!strncmp(make, "SAMSUNG", 7) && dng_version) &&
             strncmp(model, "GR", 2))
      {
        if (tag == 0x0005)
          {
            uidPentax = unique_id = get4();
            setPentaxBodyFeatures(unique_id);
          }
        else if (tag == 0x0013)
          {
            imgdata.lens.makernotes.CurAp = (float)get2()/10.0f;
          }
        else if (tag == 0x001d)
          {
            imgdata.lens.makernotes.CurFocal = (float)get4()/100.0f;
          }
        else if (tag == 0x003f)
          {
            imgdata.lens.makernotes.LensID = fgetc(ifp) << 8 | fgetc(ifp);
          }
        else if (tag == 0x0207)
          {
            ushort iLensData = 0;
            table_buf = (uchar*)malloc(len);
            fread(table_buf, len, 1, ifp);
            if ((uidPentax < 0x12b9c) ||
                ((uidPentax == 0x12b9c) ||	// K100D
                 (uidPentax == 0x12b9d) ||	// K110D
                 (uidPentax == 0x12ba2)	&&	// K100D Super
                 (!table_buf[20] || (table_buf[20] == 0xff))))
              {
                iLensData = 3;
                if (imgdata.lens.makernotes.LensID == -1)
                  imgdata.lens.makernotes.LensID =
                    (((unsigned)table_buf[0]) << 8) + table_buf[1];
              }
            else switch (len)
              {
              case 90:							// LensInfo3
                iLensData = 13;
                if (imgdata.lens.makernotes.LensID == -1)
                  imgdata.lens.makernotes.LensID =
                    ((unsigned)((table_buf[1] & 0x0f) + table_buf[3]) <<8) + table_buf[4];
                break;
              case 91:							// LensInfo4
                iLensData = 12;
                if (imgdata.lens.makernotes.LensID == -1)
                  imgdata.lens.makernotes.LensID =
                    ((unsigned)((table_buf[1] & 0x0f) + table_buf[3]) <<8) + table_buf[4];
                break;
              case 80:							// LensInfo5
              case 128:
                iLensData = 15;
                if (imgdata.lens.makernotes.LensID == -1)
                  imgdata.lens.makernotes.LensID =
                    ((unsigned)((table_buf[1] & 0x0f) + table_buf[4]) <<8) + table_buf[5];
                break;
              default:
                if (uidPentax >= 0x12b9c)		// LensInfo2
                  {
                    iLensData = 4;
                    if (imgdata.lens.makernotes.LensID == -1)
                      imgdata.lens.makernotes.LensID =
                        ((unsigned)((table_buf[0] & 0x0f) + table_buf[2]) <<8) + table_buf[3];
                  }
              }
            if (iLensData)
              {
                if (table_buf[iLensData+9] && (fabs(imgdata.lens.makernotes.CurFocal) < 0.1f))
                  imgdata.lens.makernotes.CurFocal =
                    10*(table_buf[iLensData+9]>>2) * powf64(4, (table_buf[iLensData+9] & 0x03)-2);
                if (table_buf[iLensData+10] & 0xf0)
                  imgdata.lens.makernotes.MaxAp4CurFocal =
                    powf64(2.0f, (float)((table_buf[iLensData+10] & 0xf0) >>4)/4.0f);
                if (table_buf[iLensData+10] & 0x0f)
                  imgdata.lens.makernotes.MinAp4CurFocal =
                    powf64(2.0f, (float)((table_buf[iLensData+10] & 0x0f) + 10)/4.0f);
                if (
                    (uidPentax != 0x12e6c) &&	// K-r
                    (uidPentax != 0x12e76) &&	// K-5
                    (uidPentax != 0x12f70)		// K-5 II
                    //        	  		(uidPentax != 0x12f71)		// K-5 II s
                    )
                  {
                    switch (table_buf[iLensData] & 0x06)
                      {
                      case 0: imgdata.lens.makernotes.MinAp4MinFocal = 22.0f; break;
                      case 2: imgdata.lens.makernotes.MinAp4MinFocal = 32.0f; break;
                      case 4: imgdata.lens.makernotes.MinAp4MinFocal = 45.0f; break;
                      case 6: imgdata.lens.makernotes.MinAp4MinFocal = 16.0f; break;
                      }
                    if (table_buf[iLensData] & 0x70)
                      imgdata.lens.makernotes.LensFStops =
                        ((float)(((table_buf[iLensData] & 0x70) >> 4) ^ 0x07)) / 2.0f + 5.0f;
                    if ((table_buf[iLensData+14] > 1) &&
                        (fabs(imgdata.lens.makernotes.MaxAp4CurFocal) < 0.7f))
                      imgdata.lens.makernotes.MaxAp4CurFocal =
                        powf64(2.0f, (float)((table_buf[iLensData+14] & 0x7f) -1)/32.0f);
                  }
                else if ((uidPentax != 0x12e76) &&	// K-5
                         (table_buf[iLensData+15] > 1) &&
                         (fabs(imgdata.lens.makernotes.MaxAp4CurFocal) < 0.7f))
                  {
                    imgdata.lens.makernotes.MaxAp4CurFocal =
                      powf64(2.0f, (float)((table_buf[iLensData+15] & 0x7f) -1)/32.0f);
                  }
              }
            free(table_buf);
          }
        else if (tag == 0x0239)		// Q-series lens info (LensInfoQ)
          {
            char LensInfo [20];
            fseek (ifp, 2, SEEK_CUR);
            fread(imgdata.lens.makernotes.Lens, 30, 1, ifp);
            strcat(imgdata.lens.makernotes.Lens, " ");
            fread(LensInfo, 20, 1, ifp);
            strcat(imgdata.lens.makernotes.Lens, LensInfo);
          }
      }

    else if (!strncmp(make, "SAMSUNG", 7))
      {
        if (tag == 0x0002)
          {
            if(get4() == 0x2000)
              {
                imgdata.lens.makernotes.CameraMount = Samsung_NX;
              }
            else
              {
                imgdata.lens.makernotes.CameraMount = FixedLens;
                imgdata.lens.makernotes.LensMount = FixedLens;
              }
          }
        else if (tag == 0x0003)
          {
            unique_id = get4();
          }
        else if (tag == 0xa003)
          {
            imgdata.lens.makernotes.LensID = get2();
            if (imgdata.lens.makernotes.LensID)
              imgdata.lens.makernotes.LensMount = Samsung_NX;
          }
        else if (tag == 0xa019)
          {
            imgdata.lens.makernotes.CurAp = getreal(type);
          }
        else if (tag == 0xa01a)
          {
            imgdata.lens.samsung.FocalLengthIn35mmFormat = get4() / 10.0f;
            if (imgdata.lens.samsung.FocalLengthIn35mmFormat < 10.0f)
              imgdata.lens.samsung.FocalLengthIn35mmFormat *= 10.0f;
          }
      }

    else if (!strncasecmp(make, "SONY", 4) ||
             !strncasecmp(make, "Konica", 6) ||
             !strncasecmp(make, "Minolta", 7))
      {
        ushort lid;

        if (tag == 0xb001)			// Sony ModelID
        {
          unique_id = imgdata.lens.makernotes.CamID = get2();
          setSonyBodyFeatures(unique_id);
          if (table_buf_0x9050_present)
            {
              process_Sony_0x9050(table_buf_0x9050, unique_id);
              free (table_buf_0x9050);
              table_buf_0x9050_present = 0;
            }
          if (table_buf_0x940c_present)
            {
              if (imgdata.lens.makernotes.CameraMount == Sony_E)
                {
                  process_Sony_0x940c(table_buf_0x940c);
                }
              free (table_buf_0x940c);
              table_buf_0x940c_present = 0;
            }
        }

        else if ((tag == 0x0010) &&					// CameraInfo
                 strncasecmp(model, "DSLR-A100", 9) &&
                 strncasecmp(model, "NEX-5C", 6) &&
                 !strncasecmp(make, "SONY", 4) &&
                 ((len == 368) ||			// a700
                  (len == 5478) ||		// a850, a900
                  (len == 5506) ||		// a200, a300, a350
                  (len == 6118) ||		// a230, a290, a330, a380, a390

                  // a450, a500, a550, a560, a580
                  // a33, a35, a55
                  // NEX3, NEX5, NEX5C, NEXC3, VG10E
                  (len == 15360))
                 )
          {
            table_buf = (uchar*)malloc(len);
            fread(table_buf, len, 1, ifp);
            if (memcmp(table_buf, "\xff\xff\xff\xff\xff\xff\xff\xff", 8) &&
                memcmp(table_buf, "\x00\x00\x00\x00\x00\x00\x00\x00", 8))
              {
                switch (len) 
                  {
                  case 368:
                  case 5478:
                    // a700, a850, a900: CameraInfo
                    if (table_buf[0] | table_buf[3])
                      imgdata.lens.makernotes.MinFocal =
                        bcd2dec(table_buf[0]) * 100 + bcd2dec(table_buf[3]);
                    if (table_buf[2] | table_buf[5])
                      imgdata.lens.makernotes.MaxFocal =
                        bcd2dec(table_buf[2]) * 100 + bcd2dec(table_buf[5]);
                    if (table_buf[4])
                      imgdata.lens.makernotes.MaxAp4MinFocal = bcd2dec(table_buf[4]) / 10.0f;
                    if (table_buf[4])
                      imgdata.lens.makernotes.MaxAp4MaxFocal = bcd2dec(table_buf[7]) / 10.0f;
                    parseSonyLensFeatures(table_buf[1], table_buf[6]);
                    break;
                  default:
                    // CameraInfo2 & 3
                    if (table_buf[1] | table_buf[2])
                      imgdata.lens.makernotes.MinFocal =
                        bcd2dec(table_buf[1]) * 100 + bcd2dec(table_buf[2]);
                    if (table_buf[3] | table_buf[4])
                      imgdata.lens.makernotes.MaxFocal =
                        bcd2dec(table_buf[3]) * 100 + bcd2dec(table_buf[4]);
                    if (table_buf[5])
                      imgdata.lens.makernotes.MaxAp4MinFocal = bcd2dec(table_buf[5]) / 10.0f;
                    if (table_buf[6])
                      imgdata.lens.makernotes.MaxAp4MaxFocal = bcd2dec(table_buf[6]) / 10.0f;
                    parseSonyLensFeatures(table_buf[0], table_buf[7]);
                }
              }
            free(table_buf);
          }

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

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

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

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

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

        else if (((tag == 0xb027) || (tag == 0x010c)) && (imgdata.lens.makernotes.LensID == -1))
          {
            imgdata.lens.makernotes.LensID = get4();
            if ((imgdata.lens.makernotes.LensID > 61184) &&
                (imgdata.lens.makernotes.LensID < 65535))
              {
                imgdata.lens.makernotes.LensID -= 61184;
                imgdata.lens.makernotes.LensMount = Canon_EF;
              }
            if (tag == 0x010c) imgdata.lens.makernotes.CameraMount = Minolta_A;
          }

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

    if (tag == 2 && strstr(make,"NIKON") && !iso_speed)
      iso_speed = (get2(),get2());
    if (tag == 37 && strstr(make,"NIKON") && (!iso_speed || iso_speed == 65535))
      {
        unsigned char cc;
        fread(&cc,1,1,ifp);
        iso_speed = int(100.0 * powf64(2.0f,float(cc)/12.0-5.0));
      }
    if (tag == 4 && len > 26 && len < 35) {
      if ((i=(get4(),get2())) != 0x7fff && (!iso_speed || iso_speed == 65535))
	iso_speed = 50 * powf64(2.0, i/32.0 - 4);
      if ((i=(get2(),get2())) != 0x7fff && !aperture)
	aperture = powf64(2.0, i/64.0);
      if ((i=get2()) != 0xffff && !shutter)
	shutter = powf64(2.0, (short) i/-32.0);
      wbi = (get2(),get2());
      shot_order = (get2(),get2());
    }
    if ((tag == 4 || tag == 0x114) && !strncmp(make,"KONICA",6)) {
      fseek (ifp, tag == 4 ? 140:160, SEEK_CUR);
      switch (get2()) {
	case 72:  flip = 0;  break;
	case 76:  flip = 6;  break;
	case 82:  flip = 5;  break;
      }
    }
    if (tag == 7 && type == 2 && len > 20)
      fgets (model2, 64, ifp);
    if (tag == 8 && type == 4)
      shot_order = get4();
    if (tag == 9 && !strcmp(make,"Canon"))
      fread (artist, 64, 1, ifp);
    if (tag == 0xc && len == 4)
      FORC3 cam_mul[(c << 1 | c >> 1) & 3] = getreal(type);
    if (tag == 0xd && type == 7 && get2() == 0xaaaa) {
      for (c=i=2; (ushort) c != 0xbbbb && i < len; i++)
	c = c << 8 | fgetc(ifp);
      while ((i+=4) < len-5)
	if (get4() == 257 && (i=len) && (c = (get4(),fgetc(ifp))) < 3)
	  flip = "065"[c]-'0';
    }

    if (tag == 0x10 && type == 4)
      {
        unique_id = get4();

#ifdef LIBRAW_LIBRARY_BUILD
        setCanonBodyFeatures(unique_id);
        if (lenCanonCameraInfo) processCanonCameraInfo(unique_id, CanonCameraInfo);
#endif
      }

#ifdef LIBRAW_LIBRARY_BUILD
    if(tag == 0x20400805 && len == 2 && !strncasecmp(make,"Olympus",7))
      {
        imgdata.color.OlympusSensorCalibration[0]=getreal(type);
        imgdata.color.OlympusSensorCalibration[1]=getreal(type);
      }
    if (tag == 0x4001 && len > 500 && !strcasecmp(make,"Canon"))
      {
        long int save1 = ftell(ifp);
        switch (len) 
          {
          case 582:
            imgdata.color.canon_makernotes.CanonColorDataVer = 1;	// 20D / 350D
            break;
          case 653:
            imgdata.color.canon_makernotes.CanonColorDataVer = 2;	// 1Dmk2 / 1DsMK2
            break;
          case 796:
            imgdata.color.canon_makernotes.CanonColorDataVer = 3;	// 1DmkIIN / 5D / 30D / 400D

            // 1DmkIII / 1DSmkIII / 1DmkIV / 5DmkII
            // 7D / 40D / 50D / 60D / 450D / 500D
            // 550D / 1000D / 1100D
          case 674: case 692: case 702: case 1227: case 1250:
          case 1251: case 1337: case 1338: case 1346:
            imgdata.color.canon_makernotes.CanonColorDataVer = 4;
            imgdata.color.canon_makernotes.CanonColorDataSubVer = get2();
            {
              fseek (ifp, save1+(0x0e7<<1), SEEK_SET); // offset 231 short
              int bls=0;
              FORC4 bls+=get2();
              imgdata.color.canon_makernotes.AverageBlackLevel = bls/4;
            }
            if ((imgdata.color.canon_makernotes.CanonColorDataSubVer == 4)
                || (imgdata.color.canon_makernotes.CanonColorDataSubVer == 5))
              {
                fseek (ifp, save1+(0x2b9<<1), SEEK_SET);		// offset 697 shorts
                imgdata.color.canon_makernotes.SpecularWhiteLevel = get2();
              }
            else if ((imgdata.color.canon_makernotes.CanonColorDataSubVer == 6) ||
                     (imgdata.color.canon_makernotes.CanonColorDataSubVer == 7))
              {
                fseek (ifp, save1+(0x2d0<<1), SEEK_SET);		// offset 720 shorts
                imgdata.color.canon_makernotes.SpecularWhiteLevel = get2();
              }
            else if (imgdata.color.canon_makernotes.CanonColorDataSubVer == 9)
              {
                fseek (ifp, save1+(0x2d4<<1), SEEK_SET);		// offset 724 shorts
                imgdata.color.canon_makernotes.SpecularWhiteLevel = get2();
              }
            break;

          case 5120:
            imgdata.color.canon_makernotes.CanonColorDataVer = 5;	// PowerSot G10
            break;

          case 1273: case 1275:
            imgdata.color.canon_makernotes.CanonColorDataVer = 6;	// 600D / 1200D
            imgdata.color.canon_makernotes.CanonColorDataSubVer = get2();
            {
              fseek (ifp, save1+(0x0fb<<1), SEEK_SET);			// offset 251 short
              int bls=0;
              FORC4 bls+=get2();
              imgdata.color.canon_makernotes.AverageBlackLevel = bls/4;
            }
            fseek (ifp, save1+(0x1e4<<1), SEEK_SET);			// offset 484 shorts
            imgdata.color.canon_makernotes.SpecularWhiteLevel = get2();
            break;

            // 1DX / 5DmkIII / 6D / 100D / 650D / 700D / M / 7DmkII / 750D / 760D
          case 1312: case 1313: case 1316: case 1506:
            imgdata.color.canon_makernotes.CanonColorDataVer = 7;
            imgdata.color.canon_makernotes.CanonColorDataSubVer = get2();
            {
              fseek (ifp, save1+(0x114<<1), SEEK_SET);			// offset 276 shorts
              int bls=0;
              FORC4 bls+=get2();
              imgdata.color.canon_makernotes.AverageBlackLevel = bls/4;
            }
            if (imgdata.color.canon_makernotes.CanonColorDataSubVer == 10)
              {
                fseek (ifp, save1+(0x1fd<<1), SEEK_SET);		// offset 509 shorts
                imgdata.color.canon_makernotes.SpecularWhiteLevel = get2();
              } else if (imgdata.color.canon_makernotes.CanonColorDataSubVer == 11)
              {
                fseek (ifp, save1+(0x2dd<<1), SEEK_SET);		// offset 733 shorts
                imgdata.color.canon_makernotes.SpecularWhiteLevel = get2();
              }
            break;
          }
        fseek (ifp, save1, SEEK_SET);
      }
#endif
    if (tag == 0x11 && is_raw && !strncmp(make,"NIKON",5)) {
      fseek (ifp, get4()+base, SEEK_SET);
      parse_tiff_ifd (base);
    }
    if (tag == 0x14 && type == 7) {
      if (len == 2560) {
	fseek (ifp, 1248, SEEK_CUR);
	goto get2_256;
      }
      fread (buf, 1, 10, ifp);
      if (!strncmp(buf,"NRW ",4)) {
	fseek (ifp, strcmp(buf+4,"0100") ? 46:1546, SEEK_CUR);
	cam_mul[0] = get4() << 2;
	cam_mul[1] = get4() + get4();
	cam_mul[2] = get4() << 2;
      }
    }
    if (tag == 0x15 && type == 2 && is_raw)
      fread (model, 64, 1, ifp);
    if (strstr(make,"PENTAX")) {
      if (tag == 0x1b) tag = 0x1018;
      if (tag == 0x1c) tag = 0x1017;
    }
    if (tag == 0x1d)
      while ((c = fgetc(ifp)) && c != EOF)
	serial = serial*10 + (isdigit(c) ? c - '0' : c % 10);
    if (tag == 0x81 && type == 4) {
      data_offset = get4();
      fseek (ifp, data_offset + 41, SEEK_SET);
      raw_height = get2() * 2;
      raw_width  = get2();
      filters = 0x61616161;
    }
    if (tag == 0x29 && type == 1) {
      c = wbi < 18 ? "012347800000005896"[wbi]-'0' : 0;
      fseek (ifp, 8 + c*32, SEEK_CUR);
      FORC4 cam_mul[c ^ (c >> 1) ^ 1] = get4();
    }
    if ((tag == 0x81  && type == 7) ||
	(tag == 0x100 && type == 7) ||
	(tag == 0x280 && type == 1)) {
      thumb_offset = ftell(ifp);
      thumb_length = len;
    }
    if (tag == 0x88 && type == 4 && (thumb_offset = get4()))
      thumb_offset += base;
    if (tag == 0x89 && type == 4)
      thumb_length = get4();
    if (tag == 0x8c || tag == 0x96)
      meta_offset = ftell(ifp);
    if (tag == 0x97) {
      for (i=0; i < 4; i++)
	ver97 = ver97 * 10 + fgetc(ifp)-'0';
      switch (ver97) {
	case 100:
	  fseek (ifp, 68, SEEK_CUR);
	  FORC4 cam_mul[(c >> 1) | ((c & 1) << 1)] = get2();
	  break;
	case 102:
	  fseek (ifp, 6, SEEK_CUR);
	  goto get2_rggb;
	case 103:
	  fseek (ifp, 16, SEEK_CUR);
	  FORC4 cam_mul[c] = get2();
      }
      if (ver97 >= 200) {
	if (ver97 != 205) fseek (ifp, 280, SEEK_CUR);
	fread (buf97, 324, 1, ifp);
      }
    }
    if (tag == 0xa1 && type == 7) {
      order = 0x4949;
      fseek (ifp, 140, SEEK_CUR);
      FORC3 cam_mul[c] = get4();
    }
    if (tag == 0xa4 && type == 3) {
      fseek (ifp, wbi*48, SEEK_CUR);
      FORC3 cam_mul[c] = get2();
    }

    if (tag == 0xa7) {	// shutter count
      NikonKey = fgetc(ifp)^fgetc(ifp)^fgetc(ifp)^fgetc(ifp);
      if ( (unsigned) (ver97-200) < 17) {
        ci = xlat[0][serial & 0xff];
        cj = xlat[1][NikonKey];
        ck = 0x60;
        for (i=0; i < 324; i++)
          buf97[i] ^= (cj += ci * ck++);
        i = "66666>666;6A;:;55"[ver97-200] - '0';
        FORC4 cam_mul[c ^ (c >> 1) ^ (i & 1)] =
          sget2 (buf97 + (i & -2) + c*2);
      }
#ifdef LIBRAW_LIBRARY_BUILD
      if ((NikonLensDataVersion > 200) && lenNikonLensData)
      {
        ci = xlat[0][serial & 0xff];
        cj = xlat[1][NikonKey];
        ck = 0x60;
        for (i = 0; i < lenNikonLensData; i++)
          table_buf[i] ^= (cj += ci * ck++);
        processNikonLensData(table_buf, lenNikonLensData);
        lenNikonLensData = 0;
    	}
#endif
    }

    if(tag == 0xb001 && type == 3)	// Sony ModelID
      {
        unique_id = get2();
      }
    if (tag == 0x200 && len == 3)
      shot_order = (get4(),get4());
    if (tag == 0x200 && len == 4)
      FORC4 cblack[c ^ c >> 1] = get2();
    if (tag == 0x201 && len == 4)
      goto get2_rggb;
    if (tag == 0x220 && type == 7)
      meta_offset = ftell(ifp);
    if (tag == 0x401 && type == 4 && len == 4)
      FORC4 cblack[c ^ c >> 1] = get4();
    if (tag == 0x03d && strstr(make,"NIKON") && len == 4)
      {
        FORC4 cblack[c ^ c >> 1] = get2();
        i = cblack[3];
        FORC3 if(i>cblack[c]) i = cblack[c];
        FORC4 cblack[c]-=i;
        black += i;
      }
    if (tag == 0xe01) {		/* Nikon Capture Note */
      order = 0x4949;
      fseek (ifp, 22, SEEK_CUR);
      for (offset=22; offset+22 < len; offset += 22+i) {
	tag = get4();
	fseek (ifp, 14, SEEK_CUR);
	i = get4()-4;
	if (tag == 0x76a43207) flip = get2();
	else fseek (ifp, i, SEEK_CUR);
      }
    }
    if (tag == 0xe80 && len == 256 && type == 7) {
      fseek (ifp, 48, SEEK_CUR);
      cam_mul[0] = get2() * 508 * 1.078 / 0x10000;
      cam_mul[2] = get2() * 382 * 1.173 / 0x10000;
    }
    if (tag == 0xf00 && type == 7) {
      if (len == 614)
	fseek (ifp, 176, SEEK_CUR);
      else if (len == 734 || len == 1502)
	fseek (ifp, 148, SEEK_CUR);
      else goto next;
      goto get2_256;
    }
    if ((tag == 0x1011 && len == 9) || tag == 0x20400200)
      {
        if(!strncasecmp(make,"Olympus", 7))
          {
            int j,k;
            for (i=0; i < 3; i++)
              FORC3 adobe_cam[i][c] = ((short) get2()) / 256.0;
            for (i=0; i < 3; i++)
              for (j=0; j < 3; j++)
                for (cmatrix[i][j] = k=0; k < 3; k++)
                  cmatrix[i][j] += rgb_adobe[i][k] * adobe_cam[k][j];
          }
        else
          for (i=0; i < 3; i++)
            FORC3 cmatrix[i][c] = ((short) get2()) / 256.0;
      }
    if ((tag == 0x1012 || tag == 0x20400600) && len == 4)
      FORC4 cblack[c ^ c >> 1] = get2();
    if (tag == 0x1017 || tag == 0x20400100)
      cam_mul[0] = get2() / 256.0;
    if (tag == 0x1018 || tag == 0x20400100)
      cam_mul[2] = get2() / 256.0;
    if (tag == 0x2011 && len == 2) {
get2_256:
      order = 0x4d4d;
      cam_mul[0] = get2() / 256.0;
      cam_mul[2] = get2() / 256.0;
    }
    if ((tag | 0x70) == 0x2070 && (type == 4 || type == 13))
      fseek (ifp, get4()+base, SEEK_SET);
    if (tag == 0x2020)
      parse_thumb_note (base, 257, 258);
    if (tag == 0x2040)
      parse_makernote (base, 0x2040);
#ifdef LIBRAW_LIBRARY_BUILD
	// IB start
	if (tag == 0x2010)
	  {
		parse_makernote(base, 0x2010);
	  }
	// IB end
#endif
    if (tag == 0xb028) {
      fseek (ifp, get4()+base, SEEK_SET);
      parse_thumb_note (base, 136, 137);
    }
    if (tag == 0x4001 && len > 500) {
      i = len == 582 ? 50 : len == 653 ? 68 : len == 5120 ? 142 : 126;
      fseek (ifp, i, SEEK_CUR);
get2_rggb:
      FORC4 cam_mul[c ^ (c >> 1)] = get2();
      i = len >> 3 == 164 || len == 1506 ? 112:22;
      fseek (ifp, i, SEEK_CUR);
      FORC4 sraw_mul[c ^ (c >> 1)] = get2();
    }
    if(!strcasecmp(make,"Samsung"))
      {
        if (tag == 0xa020) // get the full Samsung encryption key
            for (i=0; i<11; i++) SamsungKey[i] = get4();
        if (tag == 0xa021) // get and decode Samsung cam_mul array
            FORC4 cam_mul[c ^ (c >> 1)] = get4() - SamsungKey[c];
        if (tag == 0xa030 && len == 9)	// get and decode Samsung color matrix
            for (i=0; i < 3; i++)
              FORC3 cmatrix[i][c] = (short)((get4() + SamsungKey[i*3+c]))/256.0;
        if (tag == 0xa028)
          FORC4 cblack[c ^ (c >> 1)] = get4() - SamsungKey[c];
      }
    else
      {
        // Somebody else use 0xa021 and 0xa028?
        if (tag == 0xa021)
          FORC4 cam_mul[c ^ (c >> 1)] = get4();
        if (tag == 0xa028)
          FORC4 cam_mul[c ^ (c >> 1)] -= get4();
      }
next:
    fseek (ifp, save, SEEK_SET);
  }
quit:
  order = sorder;
}

Project: LibRaw
File: libraw_cxx.cpp

void LibRaw::free_image(void)
{
  if(imgdata.image)
    {
      free(imgdata.image);
      imgdata.image = 0;
      imgdata.progress_flags 
        = LIBRAW_PROGRESS_START|LIBRAW_PROGRESS_OPEN
        |LIBRAW_PROGRESS_IDENTIFY|LIBRAW_PROGRESS_SIZE_ADJUST|LIBRAW_PROGRESS_LOAD_RAW;
    }
}

Project: LibRaw
File: dcraw.c

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

  if (half_size || !meta_length) return 0;
#ifdef DCRAW_VERBOSE
  if (verbose) fprintf (stderr,_("Phase One correction...\n"));
#endif
  fseek (ifp, meta_offset, SEEK_SET);
  order = get2();
  fseek (ifp, 6, SEEK_CUR);
  fseek (ifp, meta_offset+get4(), SEEK_SET);
  entries = get4();  get4();

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

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

Project: LibRaw
File: dcraw.c

void CLASS processCanonCameraInfo (unsigned id, uchar *CameraInfo)
{
  ushort iCanonLensID = 0, iCanonMaxFocal = 0, iCanonMinFocal = 0, iCanonLens = 0, iCanonCurFocal = 0, iCanonFocalType = 0;
  CameraInfo[0] = 0;
  CameraInfo[1] = 0;
  switch (id) {
  case 0x80000001: // 1D
  case 0x80000167: // 1DS
    iCanonCurFocal = 10;
    iCanonLensID = 13;
    iCanonMinFocal = 14;
    iCanonMaxFocal = 16;
    if (!imgdata.lens.makernotes.CurFocal)
      imgdata.lens.makernotes.CurFocal = sget2(CameraInfo + iCanonCurFocal);
    if (!imgdata.lens.makernotes.MinFocal)
      imgdata.lens.makernotes.MinFocal  = sget2(CameraInfo + iCanonMinFocal);
    if (!imgdata.lens.makernotes.MaxFocal)
      imgdata.lens.makernotes.MaxFocal = sget2(CameraInfo + iCanonMaxFocal);
    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)
    {
      imgdata.lens.makernotes.FocalType = CameraInfo[iCanonFocalType];
      if (!imgdata.lens.makernotes.FocalType)	// zero means 'fixed' here, replacing with standard '1'
        imgdata.lens.makernotes.FocalType = 1;
    }
  if (!imgdata.lens.makernotes.CurFocal)
    imgdata.lens.makernotes.CurFocal = sget2Rev(CameraInfo + iCanonCurFocal);
  if (!imgdata.lens.makernotes.LensID)
    imgdata.lens.makernotes.LensID = sget2Rev(CameraInfo + iCanonLensID);
  if (!imgdata.lens.makernotes.MinFocal)
    imgdata.lens.makernotes.MinFocal = sget2Rev(CameraInfo + iCanonMinFocal);
  if (!imgdata.lens.makernotes.MaxFocal)
    imgdata.lens.makernotes.MaxFocal = sget2Rev(CameraInfo + iCanonMaxFocal);
  if (!imgdata.lens.makernotes.Lens[0] && iCanonLens) {
    if (CameraInfo[iCanonLens] < 65)								// non-Canon lens
      memcpy(imgdata.lens.makernotes.Lens, CameraInfo + iCanonLens, 64);
    else if (!strncmp((char *)CameraInfo + iCanonLens, "EF-S", 4)) {
      memcpy(imgdata.lens.makernotes.Lens, "EF-S ", 5);
      memcpy(imgdata.lens.makernotes.LensFeatures_pre, "EF-E", 4);
      imgdata.lens.makernotes.LensMount = Canon_EF_S;
      memcpy(imgdata.lens.makernotes.Lens + 5, CameraInfo + iCanonLens + 4, 60);
    }
    else if (!strncmp((char *)CameraInfo + iCanonLens, "TS-E", 4)) {
      memcpy(imgdata.lens.makernotes.Lens, "TS-E ", 5);
      memcpy(imgdata.lens.makernotes.LensFeatures_pre, "TS-E", 4);
      imgdata.lens.makernotes.LensMount = Canon_EF;
      memcpy(imgdata.lens.makernotes.Lens + 5, CameraInfo + iCanonLens + 4, 60);
    }
    else if (!strncmp((char *)CameraInfo + iCanonLens, "MP-E", 4)) {
      memcpy(imgdata.lens.makernotes.Lens, "MP-E ", 5);
      memcpy(imgdata.lens.makernotes.LensFeatures_pre, "MP-E", 4);
      imgdata.lens.makernotes.LensMount = Canon_EF;
      memcpy(imgdata.lens.makernotes.Lens + 5, CameraInfo + iCanonLens + 4, 60);
    }
    else if (!strncmp((char *)CameraInfo + iCanonLens, "EF-M", 4)) {
      memcpy(imgdata.lens.makernotes.Lens, "EF-M ", 5);
      memcpy(imgdata.lens.makernotes.LensFeatures_pre, "EF-M", 4);
      imgdata.lens.makernotes.LensMount = Canon_EF_M;
      memcpy(imgdata.lens.makernotes.Lens + 5, CameraInfo + iCanonLens + 4, 60);
    }
    else {
      memcpy(imgdata.lens.makernotes.Lens, CameraInfo + iCanonLens, 2);
      memcpy(imgdata.lens.makernotes.LensFeatures_pre, "EF", 2);
      imgdata.lens.makernotes.LensMount = Canon_EF;
      imgdata.lens.makernotes.Lens[2] = 32;
      memcpy(imgdata.lens.makernotes.Lens + 3, CameraInfo + iCanonLens + 2, 62);
    }
  }
  free(CameraInfo);
  return;
}

Project: LibRaw
File: libraw_cxx.cpp

int LibRaw::dcraw_thumb_writer(const char *fname)
{
//    CHECK_ORDER_LOW(LIBRAW_PROGRESS_THUMB_LOAD);

  if(!fname) 
    return ENOENT;
        
  FILE *tfp = fopen(fname,"wb");
    
  if(!tfp) 
    return errno;

  if(!T.thumb)
    {
      fclose(tfp);
      return LIBRAW_OUT_OF_ORDER_CALL;
    }

  try {
    switch (T.tformat)
      {
      case LIBRAW_THUMBNAIL_JPEG:
        jpeg_thumb_writer (tfp,T.thumb,T.tlength);
        break;
      case LIBRAW_THUMBNAIL_BITMAP:
        fprintf (tfp, "P6\n%d %d\n255\n", T.twidth, T.theight);
        fwrite (T.thumb, 1, T.tlength, tfp);
        break;
      default:
        fclose(tfp);
        return LIBRAW_UNSUPPORTED_THUMBNAIL;
      }
    fclose(tfp);
    return 0;
  }
  catch ( LibRaw_exceptions err) {
    fclose(tfp);
    EXCEPTION_HANDLER(err);
  }
}

Project: LibRaw
File: libraw_cxx.cpp

int LibRaw::is_nikon_sraw(){ return load_raw == &LibRaw::nikon_load_sraw;}

Project: LibRaw
File: libraw_cxx.cpp

void LibRaw::x3f_dpq_interpolate_rg()
{
	int w = imgdata.sizes.raw_width/2;
	int h = imgdata.sizes.raw_height/2;
	unsigned short *image = (ushort*)imgdata.rawdata.color3_image;

	for (int color = 0; color < 2;  color++) 
	{
		for (int y = 2; y < (h-2); y++) 
		{
			uint16_t* row0 = &image[imgdata.sizes.raw_width*3*(y*2)+color]; // dst[1]
			uint16_t  row0_3 = row0[3];
			uint16_t* row1 = &image[imgdata.sizes.raw_width*3*(y*2+1)+color]; //dst1[1]
			uint16_t  row1_3 = row1[3];
			for (int x = 2; x < (w-2); x++) 
			{
				row1[0]=row1[3]=row0[3]=row0[0];
				row0 += 6;
				row1 += 6;
			}
		}
	}
}

Project: LibRaw
File: libraw_cxx.cpp

void LibRaw::nikon_load_sraw()
{
  // We're already seeked to data!
  unsigned char *rd = (unsigned char *)malloc(3*(imgdata.sizes.raw_width+2));
  if(!rd) throw LIBRAW_EXCEPTION_ALLOC;
  try {
    int row,col;
    for(row = 0; row < imgdata.sizes.raw_height; row++)
      {
        checkCancel();
        libraw_internal_data.internal_data.input->read(rd,3,imgdata.sizes.raw_width);
        for(col = 0; col < imgdata.sizes.raw_width-1;col+=2)
          {
            int bi = col*3;	
            ushort bits1 = (rd[bi+1] &0xf)<<8| rd[bi]; // 3,0,1
            ushort bits2 = rd[bi+2] << 4 | ((rd[bi+1]>>4)& 0xf); //452
            ushort bits3 =  ((rd[bi+4] & 0xf)<<8) | rd[bi+3]; // 967
            ushort bits4 = rd[bi+5] << 4 | ((rd[bi+4]>>4)& 0xf); // ab8
            imgdata.image[row*imgdata.sizes.raw_width+col][0]=bits1;
            imgdata.image[row*imgdata.sizes.raw_width+col][1]=bits3;
            imgdata.image[row*imgdata.sizes.raw_width+col][2]=bits4;
            imgdata.image[row*imgdata.sizes.raw_width+col+1][0]=bits2;
            imgdata.image[row*imgdata.sizes.raw_width+col+1][1]=2048;
            imgdata.image[row*imgdata.sizes.raw_width+col+1][2]=2048;
          }
      }
  }catch (...) {
    free(rd);
    throw ;
  }
  free(rd);
  C.maximum = 0xfff; // 12 bit?
  if(imgdata.params.sraw_ycc>=2)
    {
      return; // no CbCr interpolation
    }
  // Interpolate CC channels
  int row,col;
  for(row = 0; row < imgdata.sizes.raw_height; row++)
    {
      checkCancel(); // will throw out
      for(col = 0; col < imgdata.sizes.raw_width;col+=2)
        {
          int col2 = col<imgdata.sizes.raw_width-2?col+2:col;
          imgdata.image[row*imgdata.sizes.raw_width+col+1][1]
            =(unsigned short)(int(imgdata.image[row*imgdata.sizes.raw_width+col][1]
                                  +imgdata.image[row*imgdata.sizes.raw_width+col2][1])/2);
          imgdata.image[row*imgdata.sizes.raw_width+col+1][2]
            =(unsigned short)(int(imgdata.image[row*imgdata.sizes.raw_width+col][2]
                                  +imgdata.image[row*imgdata.sizes.raw_width+col2][2])/2);
        }
    }
  if(imgdata.params.sraw_ycc>0)
    return;
  
  for(row = 0; row < imgdata.sizes.raw_height; row++)
    {
      checkCancel(); // will throw out
      for(col = 0; col < imgdata.sizes.raw_width;col++)
        {
          float Y = float(imgdata.image[row*imgdata.sizes.raw_width+col][0])/2549.f;
          float Ch2 = float(imgdata.image[row*imgdata.sizes.raw_width+col][1]-1280)/1536.f;
          float Ch3 = float(imgdata.image[row*imgdata.sizes.raw_width+col][2]-1280)/1536.f;
          if(Y>1.f) Y = 1.f;
		  if(Y>0.803f) Ch2 = Ch3 = 0.5f;
          float r = Y + 1.40200f*(Ch3 - 0.5f);
		  if(r<0.f) r=0.f;
		  if(r>1.f) r=1.f;
          float g = Y - 0.34414f*(Ch2-0.5f) - 0.71414*(Ch3 - 0.5f) ;
		  if(g>1.f) g = 1.f;
		  if(g<0.f) g = 0.f;
          float b = Y + 1.77200*(Ch2-0.5f);
		  if(b>1.f) b = 1.f;
		  if(b<0.f) b = 0.f;
          imgdata.image[row*imgdata.sizes.raw_width+col][0]=imgdata.color.curve[int(r*3072.f)];
          imgdata.image[row*imgdata.sizes.raw_width+col][1]=imgdata.color.curve[int(g*3072.f)];
          imgdata.image[row*imgdata.sizes.raw_width+col][2]=imgdata.color.curve[int(b*3072.f)];
        }
    }
  C.maximum=16383;
}

Project: LibRaw
File: libraw_cxx.cpp

void LibRaw::raw2image_start()
{
  // restore color,sizes and internal data into raw_image fields
  memmove(&imgdata.color,&imgdata.rawdata.color,sizeof(imgdata.color));
  memmove(&imgdata.sizes,&imgdata.rawdata.sizes,sizeof(imgdata.sizes));
  memmove(&imgdata.idata,&imgdata.rawdata.iparams,sizeof(imgdata.idata));
  memmove(&libraw_internal_data.internal_output_params,&imgdata.rawdata.ioparams,sizeof(libraw_internal_data.internal_output_params));

  if (O.user_flip >= 0)
    S.flip = O.user_flip;
        
  switch ((S.flip+3600) % 360) 
    {
    case 270:  S.flip = 5;  break;
    case 180:  S.flip = 3;  break;
    case  90:  S.flip = 6;  break;
    }

  // adjust for half mode!
  IO.shrink = P1.filters && (O.half_size ||
                             ((O.threshold || O.aber[0] != 1 || O.aber[2] != 1) ));
        
  S.iheight = (S.height + IO.shrink) >> IO.shrink;
  S.iwidth  = (S.width  + IO.shrink) >> IO.shrink;

}

Project: LibRaw
File: libraw_cxx.cpp

libraw_processed_image_t *LibRaw::dcraw_make_mem_image(int *errcode)

{
    int width, height, colors, bps;
    get_mem_image_format(&width, &height, &colors, &bps);
    int stride = width * (bps/8) * colors;
    unsigned ds = height * stride;
    libraw_processed_image_t *ret = (libraw_processed_image_t*)::malloc(sizeof(libraw_processed_image_t)+ds);
    if(!ret)
        {
                if(errcode) *errcode= ENOMEM;
                return NULL;
        }
    memset(ret,0,sizeof(libraw_processed_image_t));

    // metadata init
    ret->type   = LIBRAW_IMAGE_BITMAP;
    ret->height = height;
    ret->width  = width;
    ret->colors = colors;
    ret->bits   = bps;
    ret->data_size = ds;
    copy_mem_image(ret->data, stride, 0); 

    return ret;
}

Project: LibRaw
File: unprocessed_raw.cpp

void write_tiff(int width, int height, unsigned short *bitmap, const char *fn)
{
  struct tiff_hdr th;

  FILE *ofp = fopen(fn,"wb");
  if(!ofp) return;
  tiff_head (width,height,&th);
  fwrite (&th, sizeof th, 1, ofp);
  fwrite (bitmap, 2, width*height, ofp);
  fclose(ofp);
}

Project: LibRaw
File: libraw_cxx.cpp

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

  int iterations=-1, dcb_enhance=1, noiserd=0;
  int eeci_refine_fl=0, es_med_passes_fl=0;
  float cared=0,cablue=0;
  float linenoise=0; 
  float lclean=0,cclean=0;
  float thresh=0;
  float preser=0;
  float expos=1.0;


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

  try {

    int no_crop = 1;

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

    libraw_decoder_info_t di;
    get_decoder_info(&di);

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

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

    // Adjust sizes

    int save_4color = O.four_color_rgb;

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

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

    if (O.dark_frame && no_crop)
      {
        subtract (O.dark_frame);
        SET_PROC_FLAG(LIBRAW_PROGRESS_DARK_FRAME);
      }

    if (O.wf_debanding)
      {
        wf_remove_banding();
      }

    quality = 2 + !IO.fuji_width;

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

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

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

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

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

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

    if (
#ifdef LIBRAW_DEMOSAIC_PACK_GPL2
        (!P1.is_foveon || O.force_foveon_x3f) &&
#endif
        !O.no_auto_scale)
      {
        scale_colors();
        SET_PROC_FLAG(LIBRAW_PROGRESS_SCALE_COLORS);
      }

    pre_interpolate();

    SET_PROC_FLAG(LIBRAW_PROGRESS_PRE_INTERPOLATE);

    if (O.dcb_iterations >= 0) iterations = O.dcb_iterations;
    if (O.dcb_enhance_fl >=0 ) dcb_enhance = O.dcb_enhance_fl;
    if (O.fbdd_noiserd >=0 ) noiserd = O.fbdd_noiserd;
    if (O.eeci_refine >=0 ) eeci_refine_fl = O.eeci_refine;
    if (O.es_med_passes >0 ) es_med_passes_fl = O.es_med_passes;

    // LIBRAW_DEMOSAIC_PACK_GPL3

    if (!O.half_size && O.cfa_green >0) {thresh=O.green_thresh ;green_equilibrate(thresh);} 
    if (O.exp_correc >0) {expos=O.exp_shift ; preser=O.exp_preser; exp_bef(expos,preser);} 
    if (O.ca_correc >0 ) {cablue=O.cablue; cared=O.cared; CA_correct_RT(cablue, cared);}
    if (O.cfaline >0 ) {linenoise=O.linenoise; cfa_linedn(linenoise);}
    if (O.cfa_clean >0 ) {lclean=O.lclean; cclean=O.cclean; cfa_impulse_gauss(lclean,cclean);}

    if (P1.filters  && !O.no_interpolation) 
      {
        if (noiserd>0 && P1.colors==3 && P1.filters) fbdd(noiserd);
        if (quality == 0)
          lin_interpolate();
        else if (quality == 1 || P1.colors > 3)
          vng_interpolate();
        else if (quality == 2 && P1.filters > 1000)
          ppg_interpolate();
        else if (P1.filters == LIBRAW_XTRANS)
          {
            // Fuji X-Trans
            xtrans_interpolate(quality>2?3:1);
          }
        else if (quality == 3) 
          ahd_interpolate(); // really don't need it here due to fallback op
        else if (quality == 4)
          dcb(iterations, dcb_enhance);
        //  LIBRAW_DEMOSAIC_PACK_GPL2                
        else if (quality == 5)
          ahd_interpolate_mod();
        else if (quality == 6)
          afd_interpolate_pl(2,1);
        else if (quality == 7)
          vcd_interpolate(0);
        else if (quality == 8)
          vcd_interpolate(12);
        else if (quality == 9)
          lmmse_interpolate(1);
                
        // LIBRAW_DEMOSAIC_PACK_GPL3
        else if (quality == 10)
          amaze_demosaic_RT();
        // LGPL2
        else if (quality == 11)
          dht_interpolate();
        else if (quality == 12)
          aahd_interpolate();
        // fallback to AHD
        else
          ahd_interpolate();

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

    if(!P1.is_foveon)
      {
        if (P1.colors == 3) 
          {
                        
            if (quality == 8) 
              {
                if (eeci_refine_fl == 1) refinement();
                if (O.med_passes > 0)    median_filter_new();
                if (es_med_passes_fl > 0) es_median_filter();
              } 
            else {
              median_filter();
            }
            SET_PROC_FLAG(LIBRAW_PROGRESS_MEDIAN_FILTER);
          }
      }
        
    if (O.highlight == 2) 
      {
        blend_highlights();
        SET_PROC_FLAG(LIBRAW_PROGRESS_HIGHLIGHTS);
      }
        
    if (O.highlight > 2) 
      {
        recover_highlights();
        SET_PROC_FLAG(LIBRAW_PROGRESS_HIGHLIGHTS);
      }
        
    if (O.use_fuji_rotate) 
      {
        fuji_rotate();
        SET_PROC_FLAG(LIBRAW_PROGRESS_FUJI_ROTATE);
      }
    
    if(!libraw_internal_data.output_data.histogram)
      {
        libraw_internal_data.output_data.histogram = (int (*)[LIBRAW_HISTOGRAM_SIZE]) malloc(sizeof(*libraw_internal_data.output_data.histogram)*4);
        merror(libraw_internal_data.output_data.histogram,"LibRaw::dcraw_process()");
      }
#ifndef NO_LCMS
    if(O.camera_profile)
      {
        apply_profile(O.camera_profile,O.output_profile);
        SET_PROC_FLAG(LIBRAW_PROGRESS_APPLY_PROFILE);
      }
#endif

    convert_to_rgb();
    SET_PROC_FLAG(LIBRAW_PROGRESS_CONVERT_RGB);

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

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

Project: LibRaw
File: libraw_cxx.cpp

int LibRaw::sraw_midpoint() {if (load_raw == &LibRaw::canon_sraw_load_raw) return 8192; else if (load_raw == &LibRaw::nikon_load_sraw) return 2048; else return 0;}

Project: LibRaw
File: libraw_cxx.cpp

LibRaw::~LibRaw()
{
  recycle(); 
  delete tls; 
#ifdef USE_RAWSPEED
  if(_rawspeed_camerameta)
    {
      CameraMetaDataLR *cmeta = static_cast<CameraMetaDataLR*>(_rawspeed_camerameta);
      delete cmeta;
      _rawspeed_camerameta = NULL;
    }
#endif
}

Project: LibRaw
File: dcraw.c

void CLASS packed_load_raw()
{
  int vbits=0, bwide, rbits, bite, half, irow, row, col, val, i;
  UINT64 bitbuf=0;
  int save_load_flags = load_flags;
  int ignore_derror = load_flags & 1024;
  load_flags &= 1023;

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

Project: LibRaw
File: dcraw.c

void CLASS parseSonyLensFeatures (uchar a, uchar b) {

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

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

  imgdata.lens.makernotes.LensFormat = FF;
  imgdata.lens.makernotes.LensMount = Minolta_A;
  imgdata.lens.makernotes.LensFeatures_pre[0] = 0;
  imgdata.lens.makernotes.LensFeatures_suf[0] = 0;

  if ((features & 0x0200) && (features & 0x0100)) {
    strcpy(imgdata.lens.makernotes.LensFeatures_pre, "E");
    imgdata.lens.makernotes.LensFormat = APSC;
    imgdata.lens.makernotes.LensMount = Sony_E;
  } else if (features & 0x0200) {
    strcpy(imgdata.lens.makernotes.LensFeatures_pre, "FE");
    imgdata.lens.makernotes.LensMount = Sony_E;
  } else if (features & 0x0100) {
    strcpy(imgdata.lens.makernotes.LensFeatures_pre, "DT");
    imgdata.lens.makernotes.LensFormat = APSC;
  }

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

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

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

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

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

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

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

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

  return;
}

Project: LibRaw
File: dcraw.c

void CLASS parseSonyLensType2 (uchar a, uchar b) {
  ushort lid2;
  lid2 = (((ushort)a)<<8) | ((ushort)b);
  if (!lid2) return;
  if (lid2 < 0x100)
    {
      imgdata.lens.makernotes.AdapterID = lid2;
      switch (lid2) {
      case 1:
      case 2:
      case 3:
      case 6:
        imgdata.lens.makernotes.LensMount = Minolta_A;
        break;
      case 44:
      case 78:
      case 239:
        imgdata.lens.makernotes.LensMount = Canon_EF;
        break;
      }
    }
  else
    imgdata.lens.makernotes.LensID = lid2;
  return;
}

Project: LibRaw
File: libraw_cxx.cpp

void LibRaw::x3f_load_raw()
{
  int raise_error=0;
  x3f_t *x3f = (x3f_t*)_x3f_data;
  if(!x3f) return; // No data pointer set
  if(X3F_OK == x3f_load_data(x3f, x3f_get_raw(x3f)))
    {
      x3f_directory_entry_t *DE = x3f_get_raw(x3f);
      x3f_directory_entry_header_t *DEH = &DE->header;
      x3f_image_data_t *ID = &DEH->data_subsection.image_data;
      x3f_huffman_t *HUF = ID->huffman;
      x3f_true_t *TRU = ID->tru;
      uint16_t *data = NULL;
      if(ID->rows != S.raw_height || ID->columns != S.raw_width)
        {
          raise_error = 1;
          goto end;
        }
      if (HUF != NULL)
        data = HUF->x3rgb16.element;
      if (TRU != NULL)
        data = TRU->x3rgb16.element;
      if (data == NULL) 
        {
          raise_error = 1;
          goto end;
        }
      imgdata.rawdata.color3_image = (ushort (*)[3])data;

	  if(!strcasecmp(imgdata.idata.make,"Sigma") 
		  && (!strcasecmp(imgdata.idata.model,"dp2 Quattro")  || !strcasecmp(imgdata.idata.model,"dp1 Quattro"))
		  && (imgdata.params.x3f_flags & LIBRAW_DP2Q_INTERPOLATEAF)
		  )
	  {
		  if(imgdata.sizes.raw_width == 5888)
		  {
			  x3f_dpq_interpolate_af(32,8,2);
		  }
		  if(imgdata.sizes.raw_width == 2944)
		  {
			  x3f_dpq_interpolate_af(16,4,1);
		  }
	  }

	  if(!strcasecmp(imgdata.idata.make,"Sigma") 
		  && (!strcasecmp(imgdata.idata.model,"dp2 Quattro") || !strcasecmp(imgdata.idata.model,"dp1 Quattro"))
		  && (imgdata.params.x3f_flags & LIBRAW_DP2Q_INTERPOLATERG) 
		  && (imgdata.sizes.raw_width== 5888)
		  )
			x3f_dpq_interpolate_rg();

  
  }
  else
    raise_error = 1;
end:
  if(raise_error)
    throw LIBRAW_EXCEPTION_IO_CORRUPT;
}

Project: LibRaw
File: libraw_cxx.cpp

LibRaw:: LibRaw(unsigned int flags)
{
  double aber[4] = {1,1,1,1};
  double gamm[6] = { 0.45,4.5,0,0,0,0 };
  unsigned greybox[4] =  { 0, 0, UINT_MAX, UINT_MAX };
  unsigned cropbox[4] =  { 0, 0, UINT_MAX, UINT_MAX };
#ifdef DCRAW_VERBOSE
  verbose = 1;
#else
  verbose = 0;
#endif
  ZERO(imgdata);
  imgdata.lens.canon.CanonFocalUnits = 1;
  imgdata.lens.makernotes.LensID = 0xffffffffffffffffULL;

  cleargps(&imgdata.other.parsed_gps);
  ZERO(libraw_internal_data);
  ZERO(callbacks);
  
  _rawspeed_camerameta = _rawspeed_decoder = NULL;
  _x3f_data = NULL;

#ifdef USE_RAWSPEED
  CameraMetaDataLR *camerameta = make_camera_metadata(); // May be NULL in case of exception in make_camera_metadata()
  _rawspeed_camerameta = static_cast<void*>(camerameta);
#endif
  callbacks.mem_cb = (flags & LIBRAW_OPIONS_NO_MEMERR_CALLBACK) ? NULL:  &default_memory_callback;
  callbacks.data_cb = (flags & LIBRAW_OPIONS_NO_DATAERR_CALLBACK)? NULL : &default_data_callback;
  callbacks.exif_cb = NULL; // no default callback
  memmove(&imgdata.params.aber,&aber,sizeof(aber));
  memmove(&imgdata.params.gamm,&gamm,sizeof(gamm));
  memmove(&imgdata.params.greybox,&greybox,sizeof(greybox));
  memmove(&imgdata.params.cropbox,&cropbox,sizeof(cropbox));
  
  imgdata.params.bright=1;
  imgdata.params.use_camera_matrix=1;
  imgdata.params.user_flip=-1;
  imgdata.params.user_black=-1;
  imgdata.params.user_cblack[0]=imgdata.params.user_cblack[1]=imgdata.params.user_cblack[2]=imgdata.params.user_cblack[3]=-1000001;
  imgdata.params.user_sat=-1;
  imgdata.params.user_qual=-1;
  imgdata.params.output_color=1;
  imgdata.params.output_bps=8;
  imgdata.params.use_fuji_rotate=1;
  imgdata.params.exp_shift = 1.0;
  imgdata.params.auto_bright_thr = LIBRAW_DEFAULT_AUTO_BRIGHTNESS_THRESHOLD;
  imgdata.params.adjust_maximum_thr= LIBRAW_DEFAULT_ADJUST_MAXIMUM_THRESHOLD;
  imgdata.params.use_rawspeed = 1;
  imgdata.params.no_auto_scale = 0;
  imgdata.params.no_interpolation = 0;
  imgdata.params.sraw_ycc = 0;
  imgdata.params.force_foveon_x3f = 0;
  imgdata.params.x3f_flags = LIBRAW_DP2Q_INTERPOLATERG|LIBRAW_DP2Q_INTERPOLATEAF;
  imgdata.params.sony_arw2_options = 0;
  imgdata.params.sony_arw2_posterization_thr = 0;
  imgdata.params.green_matching = 0;
  imgdata.params.coolscan_nef_gamma = 1.0f;
  imgdata.parent_class = this;
  imgdata.progress_flags = 0;
  imgdata.color.baseline_exposure = -999.f;
  _exitflag = 0;
  tls = new LibRaw_TLS;
  tls->init();
}

Project: LibRaw
File: dcraw.c

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

  for (i=0; i < 3; i++)
    for (j=0; j < 3; j++)
      for (cmatrix[i][j] = k=0; k < 3; k++)
	cmatrix[i][j] += rgb_romm[i][k] * romm_cam[k][j];
#ifdef LIBRAW_LIBRARY_BUILD
   imgdata.color.digitalBack_color=1;
#endif
}

Project: LibRaw
File: dcraw.c

void CLASS setCanonBodyFeatures (unsigned id)
      {
	if (
            (id == 0x80000001) ||	// 1D
            (id == 0x80000174) ||	// 1D2
            (id == 0x80000232) ||	// 1D2N
            (id == 0x80000169) ||	// 1D3
            (id == 0x80000281)		// 1D4
            )
          {
            imgdata.lens.makernotes.CameraFormat = APSH;
            imgdata.lens.makernotes.CameraMount = Canon_EF;
          }
        else
          if (
              (id == 0x80000167) ||	// 1Ds
              (id == 0x80000188) ||	// 1Ds2
              (id == 0x80000215) ||	// 1Ds3
              (id == 0x80000213) ||	// 5D
              (id == 0x80000218) ||	// 5D2
              (id == 0x80000285) ||	// 5D3
              (id == 0x80000302) ||	// 6D
              (id == 0x80000269) ||	// 1DX
              (id == 0x80000324) ||	// 1DC
              (id == 0x80000382) ||	// 5DS
              (id == 0x80000401)		// 5DS R
              )
            {
              imgdata.lens.makernotes.CameraFormat = FF;
              imgdata.lens.makernotes.CameraMount = Canon_EF;
            }
          else
            if (
                (id == 0x80000331) ||	// M
                (id == 0x80000355)		// M2
                )
              {
                imgdata.lens.makernotes.CameraFormat = APSC;
                imgdata.lens.makernotes.CameraMount = Canon_EF_M;
              }
            else
              if (
                  (id == 0x01140000) ||	// D30
                  (id == 0x01668000) ||	// D60
                  (id > 0x80000000)
                  )
                {
                  imgdata.lens.makernotes.CameraFormat = APSC;
                  imgdata.lens.makernotes.CameraMount = Canon_EF;
                }
              else
                {
                  imgdata.lens.makernotes.CameraMount = FixedLens;
                  imgdata.lens.makernotes.LensMount = FixedLens;
                }

	return;
      }

Project: LibRaw
File: dcraw.c

void CLASS sony_arw2_load_raw()
{
  uchar *data, *dp;
  ushort pix[16];
  int row, col, val, max, min, imax, imin, sh, bit, i;

  data = (uchar *) malloc (raw_width+1);
  merror (data, "sony_arw2_load_raw()");
#ifdef LIBRAW_LIBRARY_BUILD
  try {
#endif
  for (row=0; row < height; row++) {
#ifdef LIBRAW_LIBRARY_BUILD
    checkCancel();
#endif
    fread (data, 1, raw_width, ifp);
    for (dp=data, col=0; col < raw_width-30; dp+=16) {
      max = 0x7ff & (val = sget4(dp));
      min = 0x7ff & val >> 11;
      imax = 0x0f & val >> 22;
      imin = 0x0f & val >> 26;
      for (sh=0; sh < 4 && 0x80 << sh <= max-min; sh++);
#ifdef LIBRAW_LIBRARY_BUILD
      /* flag checks if outside of loop */
      if(imgdata.params.sony_arw2_options == LIBRAW_SONYARW2_NONE
         || imgdata.params.sony_arw2_options == LIBRAW_SONYARW2_DELTATOVALUE
         )
        {
          for (bit=30, i=0; i < 16; i++)
            if      (i == imax) pix[i] = max;
            else if (i == imin) pix[i] = min;
            else {
              pix[i] = ((sget2(dp+(bit >> 3)) >> (bit & 7) & 0x7f) << sh) + min;
              if (pix[i] > 0x7ff) pix[i] = 0x7ff;
              bit += 7;
            }
        }
      else if(imgdata.params.sony_arw2_options == LIBRAW_SONYARW2_BASEONLY)
        {
          for (bit=30, i=0; i < 16; i++)
            if      (i == imax) pix[i] = max;
            else if (i == imin) pix[i] = min;
            else pix[i]=0;
        }
      else if(imgdata.params.sony_arw2_options == LIBRAW_SONYARW2_DELTAONLY)
        {
          for (bit=30, i=0; i < 16; i++)
            if      (i == imax) pix[i] = 0;
            else if (i == imin) pix[i] = 0;
            else {
              pix[i] = ((sget2(dp+(bit >> 3)) >> (bit & 7) & 0x7f) << sh) + min;
              if (pix[i] > 0x7ff) pix[i] = 0x7ff;
              bit += 7;
            }
        }
      else if(imgdata.params.sony_arw2_options == LIBRAW_SONYARW2_DELTAZEROBASE)
        {
          for (bit=30, i=0; i < 16; i++)
            if      (i == imax) pix[i] = 0;
            else if (i == imin) pix[i] = 0;
            else {
              pix[i] = ((sget2(dp+(bit >> 3)) >> (bit & 7) & 0x7f) << sh);
              if (pix[i] > 0x7ff) pix[i] = 0x7ff;
              bit += 7;
            }
        }
#else
      /* unaltered dcraw processing */
      for (bit=30, i=0; i < 16; i++)
	if      (i == imax) pix[i] = max;
	else if (i == imin) pix[i] = min;
	else {
	  pix[i] = ((sget2(dp+(bit >> 3)) >> (bit & 7) & 0x7f) << sh) + min;
	  if (pix[i] > 0x7ff) pix[i] = 0x7ff;
	  bit += 7;
	}
#endif

#ifdef LIBRAW_LIBRARY_BUILD
      if(imgdata.params.sony_arw2_options == LIBRAW_SONYARW2_DELTATOVALUE)
        {
          for (i=0; i < 16; i++, col+=2)
            {
              unsigned slope = pix[i] < 1001? 2 : curve[pix[i]<<1]-curve[(pix[i]<<1)-2];
              unsigned step = 1 << sh;
              RAW(row,col)=curve[pix[i]<<1]>black+imgdata.params.sony_arw2_posterization_thr?
                LIM(((slope*step*1000)/(curve[pix[i]<<1]-black)),0,10000):0;
            }
        }
      else
        {
          for (i=0; i < 16; i++, col+=2)
            RAW(row,col) = curve[pix[i] << 1];
        }
#else
      for (i=0; i < 16; i++, col+=2)
	RAW(row,col) = curve[pix[i] << 1] >> 2;
#endif
      col -= col & 1 ? 1:31;
    }
  }
#ifdef LIBRAW_LIBRARY_BUILD
  } catch(...) {
    free (data);
    throw;
  }
  if(imgdata.params.sony_arw2_options == LIBRAW_SONYARW2_DELTATOVALUE)
    maximum=10000;
#endif
  free (data);
}

Project: LibRaw
File: dcraw.c

void CLASS convert_to_rgb()
{
#ifndef LIBRAW_LIBRARY_BUILD
  int row, col, c;
#endif
  int  i, j, k;
#ifndef LIBRAW_LIBRARY_BUILD
  ushort *img;
  float out[3];
#endif
  float out_cam[3][4];
  double num, inverse[3][3];
  static const double xyzd50_srgb[3][3] =
  { { 0.436083, 0.385083, 0.143055 },
    { 0.222507, 0.716888, 0.060608 },
    { 0.013930, 0.097097, 0.714022 } };
  static const double rgb_rgb[3][3] =
  { { 1,0,0 }, { 0,1,0 }, { 0,0,1 } };
  static const double adobe_rgb[3][3] =
  { { 0.715146, 0.284856, 0.000000 },
    { 0.000000, 1.000000, 0.000000 },
    { 0.000000, 0.041166, 0.958839 } };
  static const double wide_rgb[3][3] =
  { { 0.593087, 0.404710, 0.002206 },
    { 0.095413, 0.843149, 0.061439 },
    { 0.011621, 0.069091, 0.919288 } };
  static const double prophoto_rgb[3][3] =
  { { 0.529317, 0.330092, 0.140588 },
    { 0.098368, 0.873465, 0.028169 },
    { 0.016879, 0.117663, 0.865457 } };
  static const double (*out_rgb[])[3] =
  { rgb_rgb, adobe_rgb, wide_rgb, prophoto_rgb, xyz_rgb };
  static const char *name[] =
  { "sRGB", "Adobe RGB (1998)", "WideGamut D65", "ProPhoto D65", "XYZ" };
  static const unsigned phead[] =
  { 1024, 0, 0x2100000, 0x6d6e7472, 0x52474220, 0x58595a20, 0, 0, 0,
    0x61637370, 0, 0, 0x6e6f6e65, 0, 0, 0, 0, 0xf6d6, 0x10000, 0xd32d };
  unsigned pbody[] =
  { 10, 0x63707274, 0, 36,	/* cprt */
	0x64657363, 0, 40,	/* desc */
	0x77747074, 0, 20,	/* wtpt */
	0x626b7074, 0, 20,	/* bkpt */
	0x72545243, 0, 14,	/* rTRC */
	0x67545243, 0, 14,	/* gTRC */
	0x62545243, 0, 14,	/* bTRC */
	0x7258595a, 0, 20,	/* rXYZ */
	0x6758595a, 0, 20,	/* gXYZ */
	0x6258595a, 0, 20 };	/* bXYZ */
  static const unsigned pwhite[] = { 0xf351, 0x10000, 0x116cc };
  unsigned pcurve[] = { 0x63757276, 0, 1, 0x1000000 };

#ifdef LIBRAW_LIBRARY_BUILD
  RUN_CALLBACK(LIBRAW_PROGRESS_CONVERT_RGB,0,2);
#endif
  gamma_curve (gamm[0], gamm[1], 0, 0);
  memcpy (out_cam, rgb_cam, sizeof out_cam);
#ifndef LIBRAW_LIBRARY_BUILD
  raw_color |= colors == 1 || document_mode ||
		output_color < 1 || output_color > 5;
#else
  raw_color |= colors == 1 ||
		output_color < 1 || output_color > 5;
#endif
  if (!raw_color) {
    oprof = (unsigned *) calloc (phead[0], 1);
    merror (oprof, "convert_to_rgb()");
    memcpy (oprof, phead, sizeof phead);
    if (output_color == 5) oprof[4] = oprof[5];
    oprof[0] = 132 + 12*pbody[0];
    for (i=0; i < pbody[0]; i++) {
      oprof[oprof[0]/4] = i ? (i > 1 ? 0x58595a20 : 0x64657363) : 0x74657874;
      pbody[i*3+2] = oprof[0];
      oprof[0] += (pbody[i*3+3] + 3) & -4;
    }
    memcpy (oprof+32, pbody, sizeof pbody);
    oprof[pbody[5]/4+2] = strlen(name[output_color-1]) + 1;
    memcpy ((char *)oprof+pbody[8]+8, pwhite, sizeof pwhite);
    pcurve[3] = (short)(256/gamm[5]+0.5) << 16;
    for (i=4; i < 7; i++)
      memcpy ((char *)oprof+pbody[i*3+2], pcurve, sizeof pcurve);
    pseudoinverse ((double (*)[3]) out_rgb[output_color-1], inverse, 3);
    for (i=0; i < 3; i++)
      for (j=0; j < 3; j++) {
	for (num = k=0; k < 3; k++)
	  num += xyzd50_srgb[i][k] * inverse[j][k];
	oprof[pbody[j*3+23]/4+i+2] = num * 0x10000 + 0.5;
      }
    for (i=0; i < phead[0]/4; i++)
      oprof[i] = htonl(oprof[i]);
    strcpy ((char *)oprof+pbody[2]+8, "auto-generated by dcraw");
    strcpy ((char *)oprof+pbody[5]+12, name[output_color-1]);
    for (i=0; i < 3; i++)
      for (j=0; j < colors; j++)
	for (out_cam[i][j] = k=0; k < 3; k++)
	  out_cam[i][j] += out_rgb[output_color-1][i][k] * rgb_cam[k][j];
  }
#ifdef DCRAW_VERBOSE
  if (verbose)
    fprintf (stderr, raw_color ? _("Building histograms...\n") :
	_("Converting to %s colorspace...\n"), name[output_color-1]);
#endif
#ifdef LIBRAW_LIBRARY_BUILD
  convert_to_rgb_loop(out_cam);
#else
  memset (histogram, 0, sizeof histogram);
  for (img=image[0], row=0; row < height; row++)
    for (col=0; col < width; col++, img+=4) {
      if (!raw_color) {
	out[0] = out[1] = out[2] = 0;
	FORCC {
	  out[0] += out_cam[0][c] * img[c];
	  out[1] += out_cam[1][c] * img[c];
	  out[2] += out_cam[2][c] * img[c];
	}
	FORC3 img[c] = CLIP((int) out[c]);
      }
      else if (document_mode)
	img[0] = img[fcol(row,col)];
      FORCC histogram[c][img[c] >> 3]++;
    }
#endif
  if (colors == 4 && output_color) colors = 3;
#ifndef LIBRAW_LIBRARY_BUILD
  if (document_mode && filters) colors = 1;
#endif
#ifdef LIBRAW_LIBRARY_BUILD
  RUN_CALLBACK(LIBRAW_PROGRESS_CONVERT_RGB,1,2);
#endif
}