Commit message: fixed two more problems found by fuzzer
CVE: CVE-2015-8366
CWE: CWE-129
Vulnerability description: Array index error in smal_decode_segment function in LibRaw before 0.17.1 allows context-dependent attackers to cause memory errors and possibly execute arbitrary code via vectors related to indexes.

Project: LibRaw
File: dcraw.c

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

  if (tiff_nifds >= sizeof tiff_ifd / sizeof tiff_ifd[0])
    return 1;
  ifd = tiff_nifds++;
  for (j=0; j < 4; j++)
    for (i=0; i < 4; i++)
      cc[j][i] = i == j;
  entries = get2();
  if (entries > 512) return 1;
  while (entries--) {
    tiff_get (base, &tag, &type, &len, &save);

#ifdef LIBRAW_LIBRARY_BUILD
    if(callbacks.exif_cb)
      {
        int savepos = ftell(ifp);
        callbacks.exif_cb(callbacks.exifparser_data,tag|(pana_raw?0x30000:0),type,len,order,ifp);
        fseek(ifp,savepos,SEEK_SET);
      }
#endif
    switch (tag) {
      case 1:   if(len==4) pana_raw = get4(); break;
      case 5:   width  = get2();  break;
      case 6:   height = get2();  break;
      case 7:   width += get2();  break;
      case 9:   if ((i = get2())) filters = i;
#ifdef LIBRAW_LIBRARY_BUILD
        if(pana_raw && len == 1 && type ==3)
          pana_black[3]+=i;
#endif
        break;
      case 8:
      case 10:
#ifdef LIBRAW_LIBRARY_BUILD
        if(pana_raw && len == 1 && type ==3)
          pana_black[3]+=get2();
#endif
        break;
      case 17: case 18:
	if (type == 3 && len == 1)
	  cam_mul[(tag-17)*2] = get2() / 256.0;
	break;
      case 23:
	if (type == 3) iso_speed = get2();
	break;
      case 28: case 29: case 30:
#ifdef LIBRAW_LIBRARY_BUILD
        if(pana_raw && len == 1 && type ==3)
          {
            pana_black[tag-28] = get2();
          }
        else
#endif
          {
            cblack[tag-28] = get2();
            cblack[3] = cblack[1];
          }
	break;
      case 36: case 37: case 38:
	cam_mul[tag-36] = get2();
	break;
      case 39:
	if (len < 50 || cam_mul[0]) break;
	fseek (ifp, 12, SEEK_CUR);
	FORC3 cam_mul[c] = get2();
	break;
      case 46:
	if (type != 7 || fgetc(ifp) != 0xff || fgetc(ifp) != 0xd8) break;
	thumb_offset = ftell(ifp) - 2;
	thumb_length = len;
	break;
      case 61440:			/* Fuji HS10 table */
	fseek (ifp, get4()+base, SEEK_SET);
	parse_tiff_ifd (base);
	break;
      case 2: case 256: case 61441:	/* ImageWidth */
	tiff_ifd[ifd].t_width = getint(type);
	break;
      case 3: case 257: case 61442:	/* ImageHeight */
	tiff_ifd[ifd].t_height = getint(type);
	break;
      case 258:				/* BitsPerSample */
      case 61443:
	tiff_ifd[ifd].samples = len & 7;
	tiff_ifd[ifd].bps = getint(type);
	break;
      case 61446:
	raw_height = 0;
	if (tiff_ifd[ifd].bps > 12) break;
	load_raw = &CLASS packed_load_raw;
	load_flags = get4() ? 24:80;
	break;
      case 259:				/* Compression */
	tiff_ifd[ifd].comp = getint(type);
	break;
      case 262:				/* PhotometricInterpretation */
	tiff_ifd[ifd].phint = get2();
	break;
      case 270:				/* ImageDescription */
	fread (desc, 512, 1, ifp);
	break;
      case 271:				/* Make */
	fgets (make, 64, ifp);
	break;
      case 272:				/* Model */
	fgets (model, 64, ifp);
	break;
      case 280:				/* Panasonic RW2 offset */
	if (type != 4) break;
	load_raw = &CLASS panasonic_load_raw;
	load_flags = 0x2008;
      case 273:				/* StripOffset */
      case 513:				/* JpegIFOffset */
      case 61447:
	tiff_ifd[ifd].offset = get4()+base;
	if (!tiff_ifd[ifd].bps && tiff_ifd[ifd].offset > 0) {
	  fseek (ifp, tiff_ifd[ifd].offset, SEEK_SET);
	  if (ljpeg_start (&jh, 1)) {
	    tiff_ifd[ifd].comp    = 6;
	    tiff_ifd[ifd].t_width   = jh.wide;
	    tiff_ifd[ifd].t_height  = jh.high;
	    tiff_ifd[ifd].bps     = jh.bits;
	    tiff_ifd[ifd].samples = jh.clrs;
	    if (!(jh.sraw || (jh.clrs & 1)))
	      tiff_ifd[ifd].t_width *= jh.clrs;
	    if ((tiff_ifd[ifd].t_width > 4*tiff_ifd[ifd].t_height) & ~jh.clrs) {
	      tiff_ifd[ifd].t_width  /= 2;
	      tiff_ifd[ifd].t_height *= 2;
	    }
	    i = order;
	    parse_tiff (tiff_ifd[ifd].offset + 12);
	    order = i;
	  }
	}
	break;
      case 274:				/* Orientation */
	tiff_ifd[ifd].t_flip = "50132467"[get2() & 7]-'0';
	break;
      case 277:				/* SamplesPerPixel */
	tiff_ifd[ifd].samples = getint(type) & 7;
	break;
      case 279:				/* StripByteCounts */
      case 514:
      case 61448:
	tiff_ifd[ifd].bytes = get4();
	break;
      case 61454:
	FORC3 cam_mul[(4-c) % 3] = getint(type);
	break;
      case 305:  case 11:		/* Software */
	fgets (software, 64, ifp);
	if (!strncmp(software,"Adobe",5) ||
	    !strncmp(software,"dcraw",5) ||
	    !strncmp(software,"UFRaw",5) ||
	    !strncmp(software,"Bibble",6) ||
	    !strcmp (software,"Digital Photo Professional"))
	  is_raw = 0;
	break;
      case 306:				/* DateTime */
	get_timestamp(0);
	break;
      case 315:				/* Artist */
	fread (artist, 64, 1, ifp);
	break;
      case 322:				/* TileWidth */
	tiff_ifd[ifd].t_tile_width = getint(type);
	break;
      case 323:				/* TileLength */
	tiff_ifd[ifd].t_tile_length = getint(type);
	break;
      case 324:				/* TileOffsets */
	tiff_ifd[ifd].offset = len > 1 ? ftell(ifp) : get4();
	if (len == 1)
	  tiff_ifd[ifd].t_tile_width = tiff_ifd[ifd].t_tile_length = 0;
	if (len == 4) {
	  load_raw = &CLASS sinar_4shot_load_raw;
	  is_raw = 5;
	}
	break;
      case 330:				/* SubIFDs */
	if (!strcmp(model,"DSLR-A100") && tiff_ifd[ifd].t_width == 3872) {
	  load_raw = &CLASS sony_arw_load_raw;
	  data_offset = get4()+base;
	  ifd++;  break;
	}
#ifdef LIBRAW_LIBRARY_BUILD
	if (!strncmp(make,"Hasselblad",10) && libraw_internal_data.unpacker_data.hasselblad_parser_flag) {
          fseek (ifp, ftell(ifp)+4, SEEK_SET);
          fseek (ifp, get4()+base, SEEK_SET);
          parse_tiff_ifd (base);
          break;
	}
#endif
        if(len > 1000) len=1000; /* 1000 SubIFDs is enough */
	while (len--) {
	  i = ftell(ifp);
	  fseek (ifp, get4()+base, SEEK_SET);
	  if (parse_tiff_ifd (base)) break;
	  fseek (ifp, i+4, SEEK_SET);
	}
	break;
      case 400:
	strcpy (make, "Sarnoff");
	maximum = 0xfff;
	break;
#ifdef LIBRAW_LIBRARY_BUILD
      case 700:
        if((type == 1 || type == 2 || type == 6 || type == 7) && len > 1 && len < 5100000)
          {
            xmpdata = (char*)malloc(xmplen = len+1);
            fread(xmpdata,len,1,ifp);
            xmpdata[len]=0;
          }
        break;
#endif
      case 28688:
	FORC4 sony_curve[c+1] = get2() >> 2 & 0xfff;
	for (i=0; i < 5; i++)
	  for (j = sony_curve[i]+1; j <= sony_curve[i+1]; j++)
	    curve[j] = curve[j-1] + (1 << i);
	break;
      case 29184: sony_offset = get4();  break;
      case 29185: sony_length = get4();  break;
      case 29217: sony_key    = get4();  break;
      case 29264:
	parse_minolta (ftell(ifp));
	raw_width = 0;
	break;
      case 29443:
	FORC4 cam_mul[c ^ (c < 2)] = get2();
	break;
      case 29459:
	FORC4 cam_mul[c] = get2();
	i = (cam_mul[1] == 1024 && cam_mul[2] == 1024) << 1;
	SWAP (cam_mul[i],cam_mul[i+1])
	break;
    case 30720: // Sony matrix, Sony_SR2SubIFD_0x7800
      for (i=0; i < 3; i++)
        FORC3 cmatrix[i][c] = ((short) get2()) / 1024.0;
#ifdef DCRAW_VERBOSE
	if (verbose) fprintf (stderr, _(" Sony matrix:\n%f %f %f\n%f %f %f\n%f %f %f\n"), cmatrix[0][0],  cmatrix[0][1], cmatrix[0][2], cmatrix[1][0], cmatrix[1][1], cmatrix[1][2], cmatrix[2][0], cmatrix[2][1], cmatrix[2][2]);
#endif
	break;
    case 29456: // Sony black level, Sony_SR2SubIFD_0x7310, no more needs to be divided by 4
      FORC4 cblack[c ^ c >> 1] = get2();
      i = cblack[3];
      FORC3 if(i>cblack[c]) i = cblack[c];
      FORC4 cblack[c]-=i;
      black = i;
#ifdef DCRAW_VERBOSE
      if (verbose) fprintf (stderr, _("...Sony black: %u cblack: %u %u %u %u\n"),black, cblack[0],cblack[1],cblack[2], cblack[3]);
#endif
      break;
      case 33405:			/* Model2 */
	fgets (model2, 64, ifp);
	break;
      case 33421:			/* CFARepeatPatternDim */
	if (get2() == 6 && get2() == 6)
	  filters = 9;
	break;
      case 33422:			/* CFAPattern */
	if (filters == 9) {
	  FORC(36) ((char *)xtrans)[c] = fgetc(ifp) & 3;
	  break;
	}
      case 64777:			/* Kodak P-series */
        if(len == 36)
          {
            filters = 9;
            colors = 3;
            FORC(36) xtrans[0][c] = fgetc(ifp) & 3;
          }
        else if(len > 0)
          {
            if ((plen=len) > 16) plen = 16;
            fread (cfa_pat, 1, plen, ifp);
            for (colors=cfa=i=0; i < plen && colors < 4; i++) {
              colors += !(cfa & (1 << cfa_pat[i]));
              cfa |= 1 << cfa_pat[i];
            }
            if (cfa == 070) memcpy (cfa_pc,"\003\004\005",3);	/* CMY */
            if (cfa == 072) memcpy (cfa_pc,"\005\003\004\001",4);	/* GMCY */
            goto guess_cfa_pc;
          }
        break;
      case 33424:
      case 65024:
	fseek (ifp, get4()+base, SEEK_SET);
	parse_kodak_ifd (base);
	break;
      case 33434:			/* ExposureTime */
	shutter = getreal(type);
	break;
      case 33437:			/* FNumber */
	aperture = getreal(type);
	break;
#ifdef LIBRAW_LIBRARY_BUILD
// IB start
    case 0xa405:		// FocalLengthIn35mmFormat
      imgdata.lens.FocalLengthIn35mmFormat = get2();
      break;
    case 0xa432:		// LensInfo, 42034dec, Lens Specification per EXIF standard
      imgdata.lens.MinFocal = getreal(type);
      imgdata.lens.MaxFocal = getreal(type);
      imgdata.lens.MaxAp4MinFocal = getreal(type);
      imgdata.lens.MaxAp4MaxFocal = getreal(type);
      break;
    case 0xc630:		// DNG LensInfo, Lens Specification per EXIF standard
      imgdata.lens.MinFocal = getreal(type);
      imgdata.lens.MaxFocal = getreal(type);
      imgdata.lens.MaxAp4MinFocal = getreal(type);
      imgdata.lens.MaxAp4MaxFocal = getreal(type);
      break;
    case 0xa433:		// LensMake
      fread(imgdata.lens.LensMake, MIN(len, sizeof(imgdata.lens.LensMake)), 1, ifp);
      break;
    case 0xa434:		// LensModel
      fread(imgdata.lens.Lens, MIN(len, sizeof(imgdata.lens.Lens)), 1, ifp);
      if (!strncmp(imgdata.lens.Lens, "----", 4))
        imgdata.lens.Lens[0] = 0;
      break;
    case 0x9205:
				imgdata.lens.EXIF_MaxAp = powf64(2.0f, (getreal(type) / 2.0f));
      break;
// IB end
#endif
      case 34306:			/* Leaf white balance */
	FORC4 cam_mul[c ^ 1] = 4096.0 / get2();
	break;
      case 34307:			/* Leaf CatchLight color matrix */
	fread (software, 1, 7, ifp);
	if (strncmp(software,"MATRIX",6)) break;
	colors = 4;
	for (raw_color = i=0; i < 3; i++) {
	  FORC4 fscanf (ifp, "%f", &rgb_cam[i][c^1]);
	  if (!use_camera_wb) continue;
	  num = 0;
	  FORC4 num += rgb_cam[i][c];
	  FORC4 rgb_cam[i][c] /= num;
	}
	break;
      case 34310:			/* Leaf metadata */
	parse_mos (ftell(ifp));
      case 34303:
	strcpy (make, "Leaf");
	break;
      case 34665:			/* EXIF tag */
	fseek (ifp, get4()+base, SEEK_SET);
	parse_exif (base);
	break;
      case 34853:			/* GPSInfo tag */
        {
          unsigned pos;
          fseek(ifp, pos = (get4() + base), SEEK_SET);
          parse_gps(base);
#ifdef LIBRAW_LIBRARY_BUILD
          fseek(ifp, pos, SEEK_SET);
          parse_gps_libraw(base);
#endif
        }
	break;
      case 34675:			/* InterColorProfile */
      case 50831:			/* AsShotICCProfile */
	profile_offset = ftell(ifp);
	profile_length = len;
	break;
      case 37122:			/* CompressedBitsPerPixel */
	kodak_cbpp = get4();
	break;
      case 37386:			/* FocalLength */
	focal_len = getreal(type);
	break;
      case 37393:			/* ImageNumber */
	shot_order = getint(type);
	break;
      case 37400:			/* old Kodak KDC tag */
	for (raw_color = i=0; i < 3; i++) {
	  getreal(type);
	  FORC3 rgb_cam[i][c] = getreal(type);
	}
	break;
      case 40976:
	strip_offset = get4();
	switch (tiff_ifd[ifd].comp) {
	  case 32770: load_raw = &CLASS samsung_load_raw;   break;
	  case 32772: load_raw = &CLASS samsung2_load_raw;  break;
	  case 32773: load_raw = &CLASS samsung3_load_raw;  break;
	}
	break;
      case 46275:			/* Imacon tags */
	strcpy (make, "Imacon");
	data_offset = ftell(ifp);
	ima_len = len;
	break;
      case 46279:
	if (!ima_len) break;
	fseek (ifp, 38, SEEK_CUR);
      case 46274:
	fseek (ifp, 40, SEEK_CUR);
	raw_width  = get4();
	raw_height = get4();
	left_margin = get4() & 7;
	width = raw_width - left_margin - (get4() & 7);
	top_margin = get4() & 7;
	height = raw_height - top_margin - (get4() & 7);
	if (raw_width == 7262 && ima_len == 234317952 ) {
	  height = 5412;
	  width  = 7216;
	  left_margin = 7;
          filters=0;
	} else 	if (raw_width == 7262) {
	  height = 5444;
	  width  = 7244;
	  left_margin = 7;
	}
	fseek (ifp, 52, SEEK_CUR);
	FORC3 cam_mul[c] = getreal(11);
	fseek (ifp, 114, SEEK_CUR);
	flip = (get2() >> 7) * 90;
	if (width * height * 6 == ima_len) {
	  if (flip % 180 == 90) SWAP(width,height);
	  raw_width = width;
	  raw_height = height;
	  left_margin = top_margin = filters = flip = 0;
	}
	sprintf (model, "Ixpress %d-Mp", height*width/1000000);
	load_raw = &CLASS imacon_full_load_raw;
	if (filters) {
	  if (left_margin & 1) filters = 0x61616161;
	  load_raw = &CLASS unpacked_load_raw;
	}
	maximum = 0xffff;
	break;
      case 50454:			/* Sinar tag */
      case 50455:
	if (!(cbuf = (char *) malloc(len))) break;
#ifndef LIBRAW_LIBRARY_BUILD
	fread (cbuf, 1, len, ifp);
#else
	if(fread (cbuf, 1, len, ifp) != len)
		throw LIBRAW_EXCEPTION_IO_CORRUPT; // cbuf to be free'ed in recycle
#endif
	for (cp = cbuf-1; cp && cp < cbuf+len; cp = strchr(cp,'\n'))
	  if (!strncmp (++cp,"Neutral ",8))
	    sscanf (cp+8, "%f %f %f", cam_mul, cam_mul+1, cam_mul+2);
	free (cbuf);
	break;
      case 50458:
	if (!make[0]) strcpy (make, "Hasselblad");
	break;
      case 50459:			/* Hasselblad tag */
#ifdef LIBRAW_LIBRARY_BUILD
        libraw_internal_data.unpacker_data.hasselblad_parser_flag=1;
#endif
	i = order;
	j = ftell(ifp);
	c = tiff_nifds;
	order = get2();
	fseek (ifp, j+(get2(),get4()), SEEK_SET);
	parse_tiff_ifd (j);
	maximum = 0xffff;
	tiff_nifds = c;
	order = i;
	break;
      case 50706:			/* DNGVersion */
	FORC4 dng_version = (dng_version << 8) + fgetc(ifp);
	if (!make[0]) strcpy (make, "DNG");
	is_raw = 1;
	break;
      case 50708:			/* UniqueCameraModel */
	if (model[0]) break;
	fgets (make, 64, ifp);
	if ((cp = strchr(make,' '))) {
	  strcpy(model,cp+1);
	  *cp = 0;
	}
	break;
      case 50710:			/* CFAPlaneColor */
	if (filters == 9) break;
	if (len > 4) len = 4;
	colors = len;
	fread (cfa_pc, 1, colors, ifp);
guess_cfa_pc:
        FORCC tab[cfa_pc[c]] = c;
        cdesc[c] = 0;
        for (i=16; i--; )
          filters = filters << 2 | tab[cfa_pat[i % plen]];
        filters -= !filters;
	break;
      case 50711:			/* CFALayout */
	if (get2() == 2) fuji_width = 1;
	break;
      case 291:
      case 50712:			/* LinearizationTable */
	linear_table (len);
	break;
      case 50713:			/* BlackLevelRepeatDim */
	cblack[4] = get2();
	cblack[5] = get2();
	if (cblack[4] * cblack[5] > (sizeof(cblack) / sizeof (cblack[0]) - 6))
	    cblack[4] = cblack[5] = 1;
	break;
      case 61450:
	cblack[4] = cblack[5] = MIN(sqrt((double)len),64);
      case 50714:			/* BlackLevel */
        if((cblack[4] * cblack[5] < 2) && len == 1)
          {
            black = getreal(type);
          }
        else if(cblack[4] * cblack[5] <= len)
          {
            FORC (cblack[4] * cblack[5])
              cblack[6+c] = getreal(type);
            black = 0;
          }
	break;
      case 50715:			/* BlackLevelDeltaH */
      case 50716:			/* BlackLevelDeltaV */
	for (num=i=0; i < len && i < 65536; i++)
	  num += getreal(type);
	black += num/len + 0.5;
	break;
      case 50717:			/* WhiteLevel */
	maximum = getint(type);
	break;
      case 50718:			/* DefaultScale */
	pixel_aspect  = getreal(type);
	pixel_aspect /= getreal(type);
	if(pixel_aspect > 0.995 && pixel_aspect < 1.005)
          pixel_aspect = 1.0;
	break;
#ifdef LIBRAW_LIBRARY_BUILD
      case 50778:
        imgdata.color.dng_color[0].illuminant = get2();
        break;
      case 50779:
        imgdata.color.dng_color[1].illuminant = get2();
        break;
#endif
      case 50721:			/* ColorMatrix1 */
      case 50722:			/* ColorMatrix2 */
#ifdef LIBRAW_LIBRARY_BUILD
        i = tag == 50721?0:1;
#endif
	FORCC for (j=0; j < 3; j++)
          {
#ifdef LIBRAW_LIBRARY_BUILD
          imgdata.color.dng_color[i].colormatrix[c][j]=
#endif
	  cm[c][j] = getreal(type);
          }
	use_cm = 1;
	break;
      case 50723:			/* CameraCalibration1 */
      case 50724:			/* CameraCalibration2 */
#ifdef LIBRAW_LIBRARY_BUILD
        j = tag == 50723?0:1;
#endif
	for (i=0; i < colors; i++)
	  FORCC
            {
#ifdef LIBRAW_LIBRARY_BUILD
              imgdata.color.dng_color[j].calibration[i][c]=
#endif
              cc[i][c] = getreal(type);
            }
	break;
      case 50727:			/* AnalogBalance */
	FORCC ab[c] = getreal(type);
	break;
      case 50728:			/* AsShotNeutral */
	FORCC asn[c] = getreal(type);
	break;
      case 50729:			/* AsShotWhiteXY */
	xyz[0] = getreal(type);
	xyz[1] = getreal(type);
	xyz[2] = 1 - xyz[0] - xyz[1];
	FORC3 xyz[c] /= d65_white[c];
	break;
#ifdef LIBRAW_LIBRARY_BUILD
      case 50730:			/* DNG: Baseline Exposure */
        baseline_exposure = getreal(type);
        break;
#endif
		  // IB start
    case 50740:			/* tag 0xc634 : DNG Adobe, DNG Pentax, Sony SR2, DNG Private */
#ifdef LIBRAW_LIBRARY_BUILD
      {
        char mbuf[64];
        unsigned short makernote_found = 0;
        INT64 curr_pos, start_pos = ftell(ifp);
        unsigned MakN_order, m_sorder = order;
        unsigned MakN_length;
        unsigned pos_in_original_raw;
        fread(mbuf, 1, 6, ifp);

        if (!strcmp(mbuf, "Adobe"))
          {
            order = 0x4d4d;				// Adobe header is always in "MM" / big endian
            curr_pos = start_pos + 6;
            while (curr_pos + 8 - start_pos <= len)
              {
                fread(mbuf, 1, 4, ifp);
                curr_pos += 8;
                if (!strncmp(mbuf, "MakN", 4)) {
                  makernote_found = 1;
                MakN_length = get4();
                MakN_order = get2();
                pos_in_original_raw = get4();
                order = MakN_order;
                parse_makernote_0xc634(curr_pos + 6 - pos_in_original_raw, 0, AdobeDNG);
                break;
                }
              }
          }
        else
          {
            fread(mbuf + 6, 1, 2, ifp);
            if (!strcmp(mbuf, "PENTAX ") ||
                !strcmp(mbuf, "SAMSUNG"))
              {
                makernote_found = 1;
                fseek(ifp, start_pos, SEEK_SET);
                parse_makernote_0xc634(base, 0, CameraDNG);
              }
          }

        fseek(ifp, start_pos, SEEK_SET);
        order = m_sorder;
      }
      // IB end
#endif
      if (dng_version) break;
      parse_minolta (j = get4()+base);
      fseek (ifp, j, SEEK_SET);
      parse_tiff_ifd (base);
      break;
    case 50752:
      read_shorts (cr2_slice, 3);
      break;
    case 50829:			/* ActiveArea */
      top_margin = getint(type);
      left_margin = getint(type);
      height = getint(type) - top_margin;
      width = getint(type) - left_margin;
      break;
    case 50830:			/* MaskedAreas */
      for (i=0; i < len && i < 32; i++)
        ((int*)mask)[i] = getint(type);
      black = 0;
      break;
    case 51009:			/* OpcodeList2 */
      meta_offset = ftell(ifp);
      break;
    case 64772:			/* Kodak P-series */
      if (len < 13) break;
      fseek (ifp, 16, SEEK_CUR);
      data_offset = get4();
      fseek (ifp, 28, SEEK_CUR);
      data_offset += get4();
      load_raw = &CLASS packed_load_raw;
      break;
    case 65026:
      if (type == 2) fgets (model2, 64, ifp);
    }
    fseek (ifp, save, SEEK_SET);
  }
  if (sony_length && (buf = (unsigned *) malloc(sony_length))) {
    fseek (ifp, sony_offset, SEEK_SET);
    fread (buf, sony_length, 1, ifp);
    sony_decrypt (buf, sony_length/4, 1, sony_key);
#ifndef LIBRAW_LIBRARY_BUILD
    sfp = ifp;
    if ((ifp = tmpfile())) {
      fwrite (buf, sony_length, 1, ifp);
      fseek (ifp, 0, SEEK_SET);
      parse_tiff_ifd (-sony_offset);
      fclose (ifp);
    }
    ifp = sfp;
#else
    if( !ifp->tempbuffer_open(buf,sony_length))
        {
            parse_tiff_ifd(-sony_offset);
            ifp->tempbuffer_close();
        }
#endif
    free (buf);
  }
  for (i=0; i < colors; i++)
    FORCC cc[i][c] *= ab[i];
  if (use_cm) {
    FORCC for (i=0; i < 3; i++)
      for (cam_xyz[c][i]=j=0; j < colors; j++)
	cam_xyz[c][i] += cc[c][j] * cm[j][i] * xyz[i];
    cam_xyz_coeff (cmatrix, cam_xyz);
  }
  if (asn[0]) {
    cam_mul[3] = 0;
    FORCC cam_mul[c] = 1 / asn[c];
  }
  if (!use_cm)
    FORCC pre_mul[c] /= cc[c][c];
  return 0;
}

Project: LibRaw
File: dcraw.c

void CLASS processNikonLensData (uchar *LensData, unsigned len)
{
  ushort i;
  if (!(imgdata.lens.nikon.NikonLensType & 0x01))
    {
      imgdata.lens.makernotes.LensFeatures_pre[0] = 'A';
      imgdata.lens.makernotes.LensFeatures_pre[1] = 'F';
    }
  else
    {
      imgdata.lens.makernotes.LensFeatures_pre[0] = 'M';
      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 = LIBRAW_MOUNT_Nikon_CX;
  else
    imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_Nikon_F;

  if (imgdata.lens.nikon.NikonLensType & 0x20)
  {
    strcpy(imgdata.lens.makernotes.Adapter, "FT-1");
    imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_Nikon_F;
  }

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

  if (len < 20) {
    switch (len) {
    case 9:
      i = 2;
      break;
    case 15:
      i = 7;
      break;
    case 16:
      i = 8;
      break;
    }
    imgdata.lens.nikon.NikonLensIDNumber = LensData[i];
    imgdata.lens.nikon.NikonLensFStops = LensData[i + 1];
    imgdata.lens.makernotes.LensFStops = (float)imgdata.lens.nikon.NikonLensFStops /12.0f;
    if (fabsf(imgdata.lens.makernotes.MinFocal) < 1.1f)
    {
      if ((imgdata.lens.nikon.NikonLensType ^ (uchar)0x01) || LensData[i + 2])
        imgdata.lens.makernotes.MinFocal = 5.0f * powf64(2.0f, (float)LensData[i + 2] / 24.0f);
      if ((imgdata.lens.nikon.NikonLensType ^ (uchar)0x01) || LensData[i + 3])
        imgdata.lens.makernotes.MaxFocal = 5.0f * powf64(2.0f, (float)LensData[i + 3] / 24.0f);
      if ((imgdata.lens.nikon.NikonLensType ^ (uchar)0x01) || LensData[i + 4])
        imgdata.lens.makernotes.MaxAp4MinFocal = powf64(2.0f, (float)LensData[i + 4] / 24.0f);
      if ((imgdata.lens.nikon.NikonLensType ^ (uchar)0x01) || LensData[i + 5])
        imgdata.lens.makernotes.MaxAp4MaxFocal = powf64(2.0f, (float)LensData[i + 5] / 24.0f);
    }
    imgdata.lens.nikon.NikonMCUVersion = LensData[i + 6];
    if (i != 2)
      {
        if ((LensData[i - 1]) &&
            (fabsf(imgdata.lens.makernotes.CurFocal) < 1.1f))
          imgdata.lens.makernotes.CurFocal = 5.0f * powf64(2.0f, (float)LensData[i - 1] / 24.0f);
        if (LensData[i + 7]) imgdata.lens.nikon.NikonEffectiveMaxAp = powf64(2.0f, (float)LensData[i + 7] / 24.0f);
      }
    imgdata.lens.makernotes.LensID =
      (unsigned long long) LensData[i] << 56 |
      (unsigned long long) LensData[i + 1] << 48 |
      (unsigned long long) LensData[i + 2] << 40 |
      (unsigned long long) LensData[i + 3] << 32 |
      (unsigned long long) LensData[i + 4] << 24 |
      (unsigned long long) LensData[i + 5] << 16 |
      (unsigned long long) LensData[i + 6] << 8 |
      (unsigned long long) imgdata.lens.nikon.NikonLensType;

  }
  else if ((len == 459) || (len == 590))
    {
      memcpy(imgdata.lens.makernotes.Lens, LensData + 390, 64);
    }
  else if (len == 509)
    {
      memcpy(imgdata.lens.makernotes.Lens, LensData + 391, 64);
    }
  else if (len == 879)
    {
      memcpy(imgdata.lens.makernotes.Lens, LensData + 680, 64);
    }
  return;
}

Project: LibRaw
File: dcraw.c

int CLASS ljpeg_start (struct jhead *jh, int info_only)
{
  int c, tag;
  ushort len;
  int cnt = 0;
  uchar data[0x10000];
  const uchar *dp;

  memset (jh, 0, sizeof *jh);
  jh->restart = INT_MAX;
  fread (data, 2, 1, ifp);
  if (data[1] != 0xd8) return 0;
  do {
    if(feof(ifp)) return 0;
    if(cnt++ > 1024) return 0; // 1024 tags limit
    fread (data, 2, 2, ifp);
    tag =  data[0] << 8 | data[1];
    len = (data[2] << 8 | data[3]) - 2;
    if (tag <= 0xff00) return 0;
    fread (data, 1, len, ifp);
    switch (tag) {
      case 0xffc3:        // start of frame; lossless, Huffman
	jh->sraw = ((data[7] >> 4) * (data[7] & 15) - 1) & 3;
      case 0xffc0:        // start of frame; baseline jpeg
	jh->bits = data[0];
	jh->high = data[1] << 8 | data[2];
	jh->wide = data[3] << 8 | data[4];
	jh->clrs = data[5] + jh->sraw;

	if (len == 9 && !dng_version) getc(ifp);
	break;
      case 0xffc4:          // define Huffman tables
	if (info_only) break;
	for (dp = data; dp < data+len && (c = *dp++) < 4; )
	  jh->free[c] = jh->huff[c] = make_decoder_ref (&dp);
	break;
      case 0xffda:          // start of scan
	jh->psv = data[1+data[0]*2];
	jh->bits -= data[3+data[0]*2] & 15;
	break;
      case 0xffdd:          // define restart interval
	jh->restart = data[0] << 8 | data[1];
    }
  } while (tag != 0xffda);
  if (info_only) return 1;
  if (jh->clrs > 6 || !jh->huff[0]) return 0;
  FORC(5) if (!jh->huff[c+1]) jh->huff[c+1] = jh->huff[c];
  if (jh->sraw) {
    FORC(4)        jh->huff[2+c] = jh->huff[1];
    FORC(jh->sraw) jh->huff[1+c] = jh->huff[0];
  }
  jh->row = (ushort *) calloc (jh->wide*jh->clrs, 4);
  merror (jh->row, "ljpeg_start()");
  return zero_after_ff = 1;
}

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();
            imgdata.process_warnings |= LIBRAW_WARN_FALLBACK_TO_AHD;
          }


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

    if(!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: dcraw.c

void CLASS setSonyBodyFeatures (unsigned id) {

  imgdata.lens.makernotes.CamID = id;
  if (	// FF cameras
      (id == 257) ||		// a900
      (id == 269) ||		// a850
      (id == 340) ||		// ILCE-7M2
      (id == 318) ||		// ILCE-7S
      (id == 311) ||		// ILCE-7R
      (id == 347) ||		// ILCE-7RM2
      (id == 306) ||		// ILCE-7
      (id == 298) ||		// DSC-RX1
      (id == 299) ||		// NEX-VG900
      (id == 310) ||		// DSC-RX1R
      (id == 294)			// SLT-99, Hasselblad HV
      )
    {
      imgdata.lens.makernotes.CameraFormat = LIBRAW_FORMAT_FF;
    }
  else
    {
      if ((id != 002) &&  // DSC-R1
          (id != 297) &&  // DSC-RX100
          (id != 308) &&  // DSC-RX100M2
          (id != 309) &&  // DSC-RX10
          (id != 317) &&  // DSC-RX100M3
          (id != 341) &&  // DSC-RX100M4
          (id != 342)     // DSC-RX10M2
         )
      imgdata.lens.makernotes.CameraFormat = LIBRAW_FORMAT_APSC;
    }

  if (	// E-mount cameras
      // ILCE:
      (id == 302) ||
      (id == 306) ||
      (id == 311) ||
      (id == 312) ||
      (id == 313) ||
      (id == 318) ||
      (id == 339) ||
      (id == 340) ||
      (id == 346) ||
      (id == 347) ||
      // NEX:
      (id == 278) ||
      (id == 279) ||
      (id == 284) ||
      (id == 288) ||
      (id == 289) ||
      (id == 290) ||
      (id == 293) ||
      (id == 295) ||
      (id == 296) ||
      (id == 299) ||
      (id == 300) ||
      (id == 305) ||
      (id == 307)
      )
    {
      imgdata.lens.makernotes.CameraMount = LIBRAW_MOUNT_Sony_E;
    }

  else if (	// A-mount cameras
           // DSLR:
           (id == 256) ||
           (id == 257) ||
           (id == 258) ||
           (id == 259) ||
           (id == 260) ||
           (id == 261) ||
           (id == 262) ||
           (id == 263) ||
           (id == 264) ||
           (id == 265) ||
           (id == 266) ||
           (id == 269) ||
           (id == 270) ||
           (id == 273) ||
           (id == 274) ||
           (id == 275) ||
           (id == 282) ||
           (id == 283) ||
           // SLT:
           (id == 280) ||
           (id == 281) ||
           (id == 285) ||
           (id == 286) ||
           (id == 287) ||
           (id == 291) ||
           (id == 292) ||
           (id == 294) ||
           (id == 303) ||
           // ILCA:
           (id == 319)
           )
    {
      imgdata.lens.makernotes.CameraMount = LIBRAW_MOUNT_Minolta_A;
    }

  else if (	// DSC
           (id == 002) ||  // DSC-R1
           (id == 297) ||  // DSC-RX100
           (id == 298) ||  // DSC-RX1
           (id == 308) ||  // DSC-RX100M2
           (id == 309) ||  // DSC-RX10
           (id == 310) ||  // DSC-RX1R
           (id == 317) ||  // DSC-RX100M3
           (id == 341) ||  // DSC-RX100M4
           (id == 342)     // DSC-RX10M2
           )
    {
      imgdata.lens.makernotes.CameraMount = LIBRAW_MOUNT_FixedLens;
      imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_FixedLens;
    }
  return;
}

Project: LibRaw
File: dcraw.c

void CLASS identify()
{
  static const short pana[][6] = {
    { 3130, 1743,  4,  0, -6,  0 },
    { 3130, 2055,  4,  0, -6,  0 },
    { 3130, 2319,  4,  0, -6,  0 },
    { 3170, 2103, 18,  0,-42, 20 },
    { 3170, 2367, 18, 13,-42,-21 },
    { 3177, 2367,  0,  0, -1,  0 },
    { 3304, 2458,  0,  0, -1,  0 },
    { 3330, 2463,  9,  0, -5,  0 },
    { 3330, 2479,  9,  0,-17,  4 },
    { 3370, 1899, 15,  0,-44, 20 },
    { 3370, 2235, 15,  0,-44, 20 },
    { 3370, 2511, 15, 10,-44,-21 },
    { 3690, 2751,  3,  0, -8, -3 },
    { 3710, 2751,  0,  0, -3,  0 },
    { 3724, 2450,  0,  0,  0, -2 },
    { 3770, 2487, 17,  0,-44, 19 },
    { 3770, 2799, 17, 15,-44,-19 },
    { 3880, 2170,  6,  0, -6,  0 },
    { 4060, 3018,  0,  0,  0, -2 },
    { 4290, 2391,  3,  0, -8, -1 },
    { 4330, 2439, 17, 15,-44,-19 },
    { 4508, 2962,  0,  0, -3, -4 },
    { 4508, 3330,  0,  0, -3, -6 },
  };
  static const ushort canon[][11] = {
    { 1944, 1416,   0,  0, 48,  0 },
    { 2144, 1560,   4,  8, 52,  2, 0, 0, 0, 25 },
    { 2224, 1456,  48,  6,  0,  2 },
    { 2376, 1728,  12,  6, 52,  2 },
    { 2672, 1968,  12,  6, 44,  2 },
    { 3152, 2068,  64, 12,  0,  0, 16 },
    { 3160, 2344,  44, 12,  4,  4 },
    { 3344, 2484,   4,  6, 52,  6 },
    { 3516, 2328,  42, 14,  0,  0 },
    { 3596, 2360,  74, 12,  0,  0 },
    { 3744, 2784,  52, 12,  8, 12 },
    { 3944, 2622,  30, 18,  6,  2 },
    { 3948, 2622,  42, 18,  0,  2 },
    { 3984, 2622,  76, 20,  0,  2, 14 },
    { 4104, 3048,  48, 12, 24, 12 },
    { 4116, 2178,   4,  2,  0,  0 },
    { 4152, 2772, 192, 12,  0,  0 },
    { 4160, 3124, 104, 11,  8, 65 },
    { 4176, 3062,  96, 17,  8,  0, 0, 16, 0, 7, 0x49 },
    { 4192, 3062,  96, 17, 24,  0, 0, 16, 0, 0, 0x49 },
    { 4312, 2876,  22, 18,  0,  2 },
    { 4352, 2874,  62, 18,  0,  0 },
    { 4476, 2954,  90, 34,  0,  0 },
    { 4480, 3348,  12, 10, 36, 12, 0, 0, 0, 18, 0x49 },
    { 4480, 3366,  80, 50,  0,  0 },
    { 4496, 3366,  80, 50, 12,  0 },
    { 4768, 3516,  96, 16,  0,  0, 0, 16 },
    { 4832, 3204,  62, 26,  0,  0 },
    { 4832, 3228,  62, 51,  0,  0 },
    { 5108, 3349,  98, 13,  0,  0 },
    { 5120, 3318, 142, 45, 62,  0 },
    { 5280, 3528,  72, 52,  0,  0 },  /* EOS M */
    { 5344, 3516, 142, 51,  0,  0 },
    { 5344, 3584, 126,100,  0,  2 },
    { 5360, 3516, 158, 51,  0,  0 },
    { 5568, 3708,  72, 38,  0,  0 },
    { 5632, 3710,  96, 17,  0,  0, 0, 16, 0, 0, 0x49 },
    { 5712, 3774,  62, 20, 10,  2 },
    { 5792, 3804, 158, 51,  0,  0 },
    { 5920, 3950, 122, 80,  2,  0 },
    { 6096, 4056, 72, 34,  0,  0 },     /* EOS M3 */
    { 8896, 5920, 160, 64,  0,  0 },
  };
  static const struct {
    ushort id;
    char t_model[20];
  } unique[] = {
    { 0x001, "EOS-1D" },
    { 0x167, "EOS-1DS" },
    { 0x168, "EOS 10D" },
    { 0x169, "EOS-1D Mark III" },
    { 0x170, "EOS 300D" },
    { 0x174, "EOS-1D Mark II" },
    { 0x175, "EOS 20D" },
    { 0x176, "EOS 450D" },
    { 0x188, "EOS-1Ds Mark II" },
    { 0x189, "EOS 350D" },
    { 0x190, "EOS 40D" },
    { 0x213, "EOS 5D" },
    { 0x215, "EOS-1Ds Mark III" },
    { 0x218, "EOS 5D Mark II" },
    { 0x232, "EOS-1D Mark II N" },
    { 0x234, "EOS 30D" },
    { 0x236, "EOS 400D" },
    { 0x250, "EOS 7D" },
    { 0x252, "EOS 500D" },
    { 0x254, "EOS 1000D" },
    { 0x261, "EOS 50D" },
    { 0x269, "EOS-1D X" },
    { 0x270, "EOS 550D" },
    { 0x281, "EOS-1D Mark IV" },
    { 0x285, "EOS 5D Mark III" },
    { 0x286, "EOS 600D" },
    { 0x287, "EOS 60D" },
    { 0x288, "EOS 1100D" },
    { 0x289, "EOS 7D Mark II" },
    { 0x301, "EOS 650D" },
    { 0x302, "EOS 6D" },
    { 0x324, "EOS-1D C" },
    { 0x325, "EOS 70D" },
    { 0x326, "EOS 700D" },
    { 0x327, "EOS 1200D" },
    { 0x331, "EOS M" },
    { 0x335, "EOS M2" },
    { 0x374, "EOS M3"},  /* temp */
    { 0x346, "EOS 100D" },
    { 0x347, "EOS 760D" },
    { 0x382, "EOS 5DS" },
    { 0x393, "EOS 750D" },
    { 0x401, "EOS 5DS R" },
  }, sonique[] = {
    { 0x002, "DSC-R1" },
    { 0x100, "DSLR-A100" },
    { 0x101, "DSLR-A900" },
    { 0x102, "DSLR-A700" },
    { 0x103, "DSLR-A200" },
    { 0x104, "DSLR-A350" },
    { 0x105, "DSLR-A300" },
    { 0x106, "DSLR-A900" },
    { 0x107, "DSLR-A380" },
    { 0x108, "DSLR-A330" },
    { 0x109, "DSLR-A230" },
    { 0x10a, "DSLR-A290" },
    { 0x10d, "DSLR-A850" },
    { 0x10e, "DSLR-A850" },
    { 0x111, "DSLR-A550" },
    { 0x112, "DSLR-A500" },
    { 0x113, "DSLR-A450" },
    { 0x116, "NEX-5" },
    { 0x117, "NEX-3" },
    { 0x118, "SLT-A33" },
    { 0x119, "SLT-A55V" },
    { 0x11a, "DSLR-A560" },
    { 0x11b, "DSLR-A580" },
    { 0x11c, "NEX-C3" },
    { 0x11d, "SLT-A35" },
    { 0x11e, "SLT-A65V" },
    { 0x11f, "SLT-A77V" },
    { 0x120, "NEX-5N" },
    { 0x121, "NEX-7" },
    { 0x122, "NEX-VG20E"},
    { 0x123, "SLT-A37" },
    { 0x124, "SLT-A57" },
    { 0x125, "NEX-F3" },
    { 0x126, "SLT-A99V" },
    { 0x127, "NEX-6" },
    { 0x128, "NEX-5R" },
    { 0x129, "DSC-RX100" },
    { 0x12a, "DSC-RX1" },
    { 0x12b, "NEX-VG900" },
    { 0x12c, "NEX-VG30E" },
    { 0x12e, "ILCE-3000" },
    { 0x12f, "SLT-A58" },
    { 0x131, "NEX-3N" },
    { 0x132, "ILCE-7" },
    { 0x133, "NEX-5T" },
    { 0x134, "DSC-RX100M2" },
    { 0x135, "DSC-RX10" },
    { 0x136, "DSC-RX1R" },
    { 0x137, "ILCE-7R" },
    { 0x138, "ILCE-6000" },
    { 0x139, "ILCE-5000" },
    { 0x13d, "DSC-RX100M3" },
    { 0x13e, "ILCE-7S" },
    { 0x13f, "ILCA-77M2" },
    { 0x153, "ILCE-5100" },
    { 0x154, "ILCE-7M2" },
    { 0x155, "DSC-RX100M4" },
    { 0x156, "DSC-RX10M2" },
    { 0x15a, "ILCE-QX1" },
    { 0x15b, "ILCE-7RM2" },
  };

  static const struct {
    unsigned fsize;
    ushort rw, rh;
    uchar lm, tm, rm, bm, lf, cf, max, flags;
    char t_make[10], t_model[20];
    ushort offset;
  } table[] = {
    {   786432,1024, 768, 0, 0, 0, 0, 0,0x94,0,0,"AVT","F-080C" },
    {  1447680,1392,1040, 0, 0, 0, 0, 0,0x94,0,0,"AVT","F-145C" },
    {  1920000,1600,1200, 0, 0, 0, 0, 0,0x94,0,0,"AVT","F-201C" },
    {  5067304,2588,1958, 0, 0, 0, 0, 0,0x94,0,0,"AVT","F-510C" },
    {  5067316,2588,1958, 0, 0, 0, 0, 0,0x94,0,0,"AVT","F-510C",12 },
    { 10134608,2588,1958, 0, 0, 0, 0, 9,0x94,0,0,"AVT","F-510C" },
    { 10134620,2588,1958, 0, 0, 0, 0, 9,0x94,0,0,"AVT","F-510C",12 },
    { 16157136,3272,2469, 0, 0, 0, 0, 9,0x94,0,0,"AVT","F-810C" },
    { 15980544,3264,2448, 0, 0, 0, 0, 8,0x61,0,1,"AgfaPhoto","DC-833m" },
    {  9631728,2532,1902, 0, 0, 0, 0,96,0x61,0,0,"Alcatel","5035D" },

//   Android Raw dumps id start
//   File Size in bytes Horizontal Res Vertical Flag then bayer order eg 0x16 bbgr 0x94 rggb
    { 16424960,4208,3120, 0, 0, 0, 0, 1,0x16,0,0,"Sony","IMX135-mipi 13mp" },
    { 17522688,4212,3120, 0, 0, 0, 0, 0,0x16,0,0,"Sony","IMX135-QCOM" },
    { 10223360,2608,1960, 0, 0, 0, 0, 1,0x94,0,0,"Sony","IMX072-mipi" },
    { 5107712,2688,1520, 0, 0, 0, 0, 1,0x61,0,0,"HTC","UltraPixel" },
    { 1540857,2688,1520, 0, 0, 0, 0, 1,0x61,0,0,"Samsung","S3" },
    { 10223363,2688,1520, 0, 0, 0, 0, 1,0x61,0,0,"Samsung","GalaxyNexus" },
    //   Android Raw dumps id end

    {  2868726,1384,1036, 0, 0, 0, 0,64,0x49,0,8,"Baumer","TXG14",1078 },
    {  5298000,2400,1766,12,12,44, 2,40,0x94,0,2,"Canon","PowerShot SD300" },
    {  6553440,2664,1968, 4, 4,44, 4,40,0x94,0,2,"Canon","PowerShot A460" },
    {  6573120,2672,1968,12, 8,44, 0,40,0x94,0,2,"Canon","PowerShot A610" },
    {  6653280,2672,1992,10, 6,42, 2,40,0x94,0,2,"Canon","PowerShot A530" },
    {  7710960,2888,2136,44, 8, 4, 0,40,0x94,0,2,"Canon","PowerShot S3 IS" },
    {  9219600,3152,2340,36,12, 4, 0,40,0x94,0,2,"Canon","PowerShot A620" },
    {  9243240,3152,2346,12, 7,44,13,40,0x49,0,2,"Canon","PowerShot A470" },
    { 10341600,3336,2480, 6, 5,32, 3,40,0x94,0,2,"Canon","PowerShot A720 IS" },
    { 10383120,3344,2484,12, 6,44, 6,40,0x94,0,2,"Canon","PowerShot A630" },
    { 12945240,3736,2772,12, 6,52, 6,40,0x94,0,2,"Canon","PowerShot A640" },
    { 15636240,4104,3048,48,12,24,12,40,0x94,0,2,"Canon","PowerShot A650" },
    { 15467760,3720,2772, 6,12,30, 0,40,0x94,0,2,"Canon","PowerShot SX110 IS" },
    { 15534576,3728,2778,12, 9,44, 9,40,0x94,0,2,"Canon","PowerShot SX120 IS" },
    { 18653760,4080,3048,24,12,24,12,40,0x94,0,2,"Canon","PowerShot SX20 IS" },
    { 19131120,4168,3060,92,16, 4, 1,40,0x94,0,2,"Canon","PowerShot SX220 HS" },
    { 21936096,4464,3276,25,10,73,12,40,0x16,0,2,"Canon","PowerShot SX30 IS" },
    { 24724224,4704,3504, 8,16,56, 8,40,0x49,0,2,"Canon","PowerShot A3300 IS" },
    {  1976352,1632,1211, 0, 2, 0, 1, 0,0x94,0,1,"Casio","QV-2000UX" },
    {  3217760,2080,1547, 0, 0,10, 1, 0,0x94,0,1,"Casio","QV-3*00EX" },
    {  6218368,2585,1924, 0, 0, 9, 0, 0,0x94,0,1,"Casio","QV-5700" },
    {  7816704,2867,2181, 0, 0,34,36, 0,0x16,0,1,"Casio","EX-Z60" },
    {  2937856,1621,1208, 0, 0, 1, 0, 0,0x94,7,13,"Casio","EX-S20" },
    {  4948608,2090,1578, 0, 0,32,34, 0,0x94,7,1,"Casio","EX-S100" },
    {  6054400,2346,1720, 2, 0,32, 0, 0,0x94,7,1,"Casio","QV-R41" },
    {  7426656,2568,1928, 0, 0, 0, 0, 0,0x94,0,1,"Casio","EX-P505" },
    {  7530816,2602,1929, 0, 0,22, 0, 0,0x94,7,1,"Casio","QV-R51" },
    {  7542528,2602,1932, 0, 0,32, 0, 0,0x94,7,1,"Casio","EX-Z50" },
    {  7562048,2602,1937, 0, 0,25, 0, 0,0x16,7,1,"Casio","EX-Z500" },
    {  7753344,2602,1986, 0, 0,32,26, 0,0x94,7,1,"Casio","EX-Z55" },
    {  9313536,2858,2172, 0, 0,14,30, 0,0x94,7,1,"Casio","EX-P600" },
    { 10834368,3114,2319, 0, 0,27, 0, 0,0x94,0,1,"Casio","EX-Z750" },
    { 10843712,3114,2321, 0, 0,25, 0, 0,0x94,0,1,"Casio","EX-Z75" },
    { 10979200,3114,2350, 0, 0,32,32, 0,0x94,7,1,"Casio","EX-P700" },
    { 12310144,3285,2498, 0, 0, 6,30, 0,0x94,0,1,"Casio","EX-Z850" },
    { 12489984,3328,2502, 0, 0,47,35, 0,0x94,0,1,"Casio","EX-Z8" },
    { 15499264,3754,2752, 0, 0,82, 0, 0,0x94,0,1,"Casio","EX-Z1050" },
    { 18702336,4096,3044, 0, 0,24, 0,80,0x94,7,1,"Casio","EX-ZR100" },
    {  7684000,2260,1700, 0, 0, 0, 0,13,0x94,0,1,"Casio","QV-4000" },
    {   787456,1024, 769, 0, 1, 0, 0, 0,0x49,0,0,"Creative","PC-CAM 600" },
    { 28829184,4384,3288, 0, 0, 0, 0,36,0x61,0,0,"DJI" },
    { 15151104,4608,3288, 0, 0, 0, 0, 0,0x94,0,0,"Matrix" },
    {  3840000,1600,1200, 0, 0, 0, 0,65,0x49,0,0,"Foculus","531C" },
    {   307200, 640, 480, 0, 0, 0, 0, 0,0x94,0,0,"Generic" },
    {    62464, 256, 244, 1, 1, 6, 1, 0,0x8d,0,0,"Kodak","DC20" },
    {   124928, 512, 244, 1, 1,10, 1, 0,0x8d,0,0,"Kodak","DC20" },
    {  1652736,1536,1076, 0,52, 0, 0, 0,0x61,0,0,"Kodak","DCS200" },
    {  4159302,2338,1779, 1,33, 1, 2, 0,0x94,0,0,"Kodak","C330" },
    {  4162462,2338,1779, 1,33, 1, 2, 0,0x94,0,0,"Kodak","C330",3160 },
    {  2247168,1232, 912, 0, 0,16, 0, 0,0x00,0,0,"Kodak","C330" },
    {  3370752,1232, 912, 0, 0,16, 0, 0,0x00,0,0,"Kodak","C330" },
    {  6163328,2864,2152, 0, 0, 0, 0, 0,0x94,0,0,"Kodak","C603" },
    {  6166488,2864,2152, 0, 0, 0, 0, 0,0x94,0,0,"Kodak","C603",3160 },
    {   460800, 640, 480, 0, 0, 0, 0, 0,0x00,0,0,"Kodak","C603" },
    {  9116448,2848,2134, 0, 0, 0, 0, 0,0x00,0,0,"Kodak","C603" },
    { 12241200,4040,3030, 2, 0, 0,13, 0,0x49,0,0,"Kodak","12MP" },
    { 12272756,4040,3030, 2, 0, 0,13, 0,0x49,0,0,"Kodak","12MP",31556 },
    { 18000000,4000,3000, 0, 0, 0, 0, 0,0x00,0,0,"Kodak","12MP" },
    {   614400, 640, 480, 0, 3, 0, 0,64,0x94,0,0,"Kodak","KAI-0340" },
    { 15360000,3200,2400, 0, 0, 0, 0,96,0x16,0,0,"Lenovo","A820" },
    {  3884928,1608,1207, 0, 0, 0, 0,96,0x16,0,0,"Micron","2010",3212 },
    {  1138688,1534, 986, 0, 0, 0, 0, 0,0x61,0,0,"Minolta","RD175",513 },
    {  1581060,1305, 969, 0, 0,18, 6, 6,0x1e,4,1,"Nikon","E900" },
    {  2465792,1638,1204, 0, 0,22, 1, 6,0x4b,5,1,"Nikon","E950" },
    {  2940928,1616,1213, 0, 0, 0, 7,30,0x94,0,1,"Nikon","E2100" },
    {  4771840,2064,1541, 0, 0, 0, 1, 6,0xe1,0,1,"Nikon","E990" },
    {  4775936,2064,1542, 0, 0, 0, 0,30,0x94,0,1,"Nikon","E3700" },
    {  5865472,2288,1709, 0, 0, 0, 1, 6,0xb4,0,1,"Nikon","E4500" },
    {  5869568,2288,1710, 0, 0, 0, 0, 6,0x16,0,1,"Nikon","E4300" },
    {  7438336,2576,1925, 0, 0, 0, 1, 6,0xb4,0,1,"Nikon","E5000" },
    {  8998912,2832,2118, 0, 0, 0, 0,30,0x94,7,1,"Nikon","COOLPIX S6" },
    {  5939200,2304,1718, 0, 0, 0, 0,30,0x16,0,0,"Olympus","C770UZ" },
    {  3178560,2064,1540, 0, 0, 0, 0, 0,0x94,0,1,"Pentax","Optio S" },
    {  4841984,2090,1544, 0, 0,22, 0, 0,0x94,7,1,"Pentax","Optio S" },
    {  6114240,2346,1737, 0, 0,22, 0, 0,0x94,7,1,"Pentax","Optio S4" },
    { 10702848,3072,2322, 0, 0, 0,21,30,0x94,0,1,"Pentax","Optio 750Z" },
    {  4147200,1920,1080, 0, 0, 0, 0, 0,0x49,0,0,"Photron","BC2-HD" },
    {  4151666,1920,1080, 0, 0, 0, 0, 0,0x49,0,0,"Photron","BC2-HD",8 },
    { 13248000,2208,3000, 0, 0, 0, 0,13,0x61,0,0,"Pixelink","A782" },
    {  6291456,2048,1536, 0, 0, 0, 0,96,0x61,0,0,"RoverShot","3320AF" },
    {   311696, 644, 484, 0, 0, 0, 0, 0,0x16,0,8,"ST Micro","STV680 VGA" },
    { 16098048,3288,2448, 0, 0,24, 0, 9,0x94,0,1,"Samsung","S85" },
    { 16215552,3312,2448, 0, 0,48, 0, 9,0x94,0,1,"Samsung","S85" },
    { 20487168,3648,2808, 0, 0, 0, 0,13,0x94,5,1,"Samsung","WB550" },
    { 24000000,4000,3000, 0, 0, 0, 0,13,0x94,5,1,"Samsung","WB550" },
    { 12582980,3072,2048, 0, 0, 0, 0,33,0x61,0,0,"Sinar","",68 },
    { 33292868,4080,4080, 0, 0, 0, 0,33,0x61,0,0,"Sinar","",68 },
    { 44390468,4080,5440, 0, 0, 0, 0,33,0x61,0,0,"Sinar","",68 },
    {  1409024,1376,1024, 0, 0, 1, 0, 0,0x49,0,0,"Sony","XCD-SX910CR" },
    {  2818048,1376,1024, 0, 0, 1, 0,97,0x49,0,0,"Sony","XCD-SX910CR" },
  };
  static const char *corp[] =
    { "AgfaPhoto", "Canon", "Casio", "Epson", "Fujifilm",
      "Mamiya", "Minolta", "Motorola", "Kodak", "Konica", "Leica",
      "Nikon", "Nokia", "Olympus", "Pentax", "Phase One", "Ricoh",
      "Samsung", "Sigma", "Sinar", "Sony" };
  char head[32], *cp;
  int hlen, flen, fsize, zero_fsize=1, i, c;
  struct jhead jh;

  tiff_flip = flip = filters = UINT_MAX;	/* unknown */
  raw_height = raw_width = fuji_width = fuji_layout = cr2_slice[0] = 0;
  maximum = height = width = top_margin = left_margin = 0;
  cdesc[0] = desc[0] = artist[0] = make[0] = model[0] = model2[0] = 0;
  iso_speed = shutter = aperture = focal_len = unique_id = 0;
  tiff_nifds = 0;
  memset (tiff_ifd, 0, sizeof tiff_ifd);
  memset (gpsdata, 0, sizeof gpsdata);
  memset (cblack, 0, sizeof cblack);
  memset (white, 0, sizeof white);
  memset (mask, 0, sizeof mask);
  thumb_offset = thumb_length = thumb_width = thumb_height = 0;
  load_raw = thumb_load_raw = 0;
  write_thumb = &CLASS jpeg_thumb;
  data_offset = meta_offset = meta_length = tiff_bps = tiff_compress = 0;
  kodak_cbpp = zero_after_ff = dng_version = load_flags = 0;
  timestamp = shot_order = tiff_samples = black = is_foveon = 0;
  mix_green = profile_length = data_error = zero_is_bad = 0;
  pixel_aspect = is_raw = raw_color = 1;
  tile_width = tile_length = 0;


  for (i=0; i < 4; i++) {
    cam_mul[i] = i == 1;
    pre_mul[i] = i < 3;
    FORC3 cmatrix[c][i] = 0;
    FORC3 rgb_cam[c][i] = c == i;
  }
  colors = 3;
  for (i=0; i < 0x10000; i++) curve[i] = i;

  order = get2();
  hlen = get4();
  fseek (ifp, 0, SEEK_SET);
  fread (head, 1, 32, ifp);
  fseek (ifp, 0, SEEK_END);
  flen = fsize = ftell(ifp);
  if ((cp = (char *) memmem (head, 32, (char*)"MMMM", 4)) ||
      (cp = (char *) memmem (head, 32, (char*)"IIII", 4))) {
    parse_phase_one (cp-head);
    if (cp-head && parse_tiff(0)) apply_tiff();
  } else if (order == 0x4949 || order == 0x4d4d) {
    if (!memcmp (head+6,"HEAPCCDR",8)) {
      data_offset = hlen;
#ifdef LIBRAW_LIBRARY_BUILD
      imgdata.lens.makernotes.CameraMount = LIBRAW_MOUNT_FixedLens;
      imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_FixedLens;
#endif
      parse_ciff (hlen, flen-hlen, 0);
      load_raw = &CLASS canon_load_raw;
    } else if (parse_tiff(0)) apply_tiff();
  } else if (!memcmp (head,"\xff\xd8\xff\xe1",4) &&
	     !memcmp (head+6,"Exif",4)) {
    fseek (ifp, 4, SEEK_SET);
    data_offset = 4 + get2();
    fseek (ifp, data_offset, SEEK_SET);
    if (fgetc(ifp) != 0xff)
      parse_tiff(12);
    thumb_offset = 0;
  } else if (!memcmp (head+25,"ARECOYK",7)) {
    strcpy (make, "Contax");
    strcpy (model,"N Digital");
    fseek (ifp, 33, SEEK_SET);
    get_timestamp(1);
    fseek (ifp, 52, SEEK_SET);
    switch (get4()) {
      case  7: iso_speed = 25;  break;
      case  8: iso_speed = 32;  break;
      case  9: iso_speed = 40;  break;
      case 10: iso_speed = 50;  break;
      case 11: iso_speed = 64;  break;
      case 12: iso_speed = 80;  break;
      case 13: iso_speed = 100; break;
      case 14: iso_speed = 125; break;
      case 15: iso_speed = 160; break;
      case 16: iso_speed = 200; break;
      case 17: iso_speed = 250; break;
      case 18: iso_speed = 320; break;
      case 19: iso_speed = 400; break;
    }
    shutter = powf64(2.0f, (((float)get4())/8.0f)) / 16000.0f;
    FORC4 cam_mul[c ^ (c >> 1)] = get4();
    fseek (ifp, 88, SEEK_SET);
    aperture = powf64(2.0f, ((float)get4())/16.0f);
    fseek (ifp, 112, SEEK_SET);
    focal_len = get4();
#ifdef LIBRAW_LIBRARY_BUILD
    fseek (ifp, 104, SEEK_SET);
    imgdata.lens.makernotes.MaxAp4CurFocal = powf64(2.0f, ((float)get4())/16.0f);
    fseek (ifp, 124, SEEK_SET);
    fread(imgdata.lens.makernotes.Lens, 32, 1, ifp);
    imgdata.lens.makernotes.CameraMount = LIBRAW_MOUNT_Contax_N;
    if (imgdata.lens.makernotes.Lens[0])
      imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_Contax_N;
#endif
  } else if (!strcmp (head, "PXN")) {
    strcpy (make, "Logitech");
    strcpy (model,"Fotoman Pixtura");
  } else if (!strcmp (head, "qktk")) {
    strcpy (make, "Apple");
    strcpy (model,"QuickTake 100");
    load_raw = &CLASS quicktake_100_load_raw;
  } else if (!strcmp (head, "qktn")) {
    strcpy (make, "Apple");
    strcpy (model,"QuickTake 150");
    load_raw = &CLASS kodak_radc_load_raw;
  } else if (!memcmp (head,"FUJIFILM",8)) {
    fseek (ifp, 84, SEEK_SET);
    thumb_offset = get4();
    thumb_length = get4();
    fseek (ifp, 92, SEEK_SET);
    parse_fuji (get4());
    if (thumb_offset > 120) {
      fseek (ifp, 120, SEEK_SET);
      is_raw += (i = get4()) && 1;
      if (is_raw == 2 && shot_select)
	parse_fuji (i);
    }
    load_raw = &CLASS unpacked_load_raw;
    fseek (ifp, 100+28*(shot_select > 0), SEEK_SET);
    parse_tiff (data_offset = get4());
    parse_tiff (thumb_offset+12);
    apply_tiff();
  } else if (!memcmp (head,"RIFF",4)) {
    fseek (ifp, 0, SEEK_SET);
    parse_riff();
  } else if (!memcmp (head+4,"ftypqt   ",9)) {
    fseek (ifp, 0, SEEK_SET);
    parse_qt (fsize);
    is_raw = 0;
  } else if (!memcmp (head,"\0\001\0\001\0@",6)) {
    fseek (ifp, 6, SEEK_SET);
    fread (make, 1, 8, ifp);
    fread (model, 1, 8, ifp);
    fread (model2, 1, 16, ifp);
    data_offset = get2();
    get2();
    raw_width = get2();
    raw_height = get2();
    load_raw = &CLASS nokia_load_raw;
    filters = 0x61616161;
  } else if (!memcmp (head,"NOKIARAW",8)) {
    strcpy (make, "NOKIA");
    order = 0x4949;
    fseek (ifp, 300, SEEK_SET);
    data_offset = get4();
    i = get4();
    width = get2();
    height = get2();
    switch (tiff_bps = i*8 / (width * height)) {
      case  8: load_raw = &CLASS eight_bit_load_raw;  break;
      case 10: load_raw = &CLASS nokia_load_raw;
    }
    raw_height = height + (top_margin = i / (width * tiff_bps/8) - height);
    mask[0][3] = 1;
    filters = 0x61616161;
  } else if (!memcmp (head,"ARRI",4)) {
    order = 0x4949;
    fseek (ifp, 20, SEEK_SET);
    width = get4();
    height = get4();
    strcpy (make, "ARRI");
    fseek (ifp, 668, SEEK_SET);
    fread (model, 1, 64, ifp);
    data_offset = 4096;
    load_raw = &CLASS packed_load_raw;
    load_flags = 88;
    filters = 0x61616161;
  } else if (!memcmp (head,"XPDS",4)) {
    order = 0x4949;
    fseek (ifp, 0x800, SEEK_SET);
    fread (make, 1, 41, ifp);
    raw_height = get2();
    raw_width  = get2();
    fseek (ifp, 56, SEEK_CUR);
    fread (model, 1, 30, ifp);
    data_offset = 0x10000;
    load_raw = &CLASS canon_rmf_load_raw;
    gamma_curve (0, 12.25, 1, 1023);
  } else if (!memcmp (head+4,"RED1",4)) {
    strcpy (make, "Red");
    strcpy (model,"One");
    parse_redcine();
    load_raw = &CLASS redcine_load_raw;
    gamma_curve (1/2.4, 12.92, 1, 4095);
    filters = 0x49494949;
  } else if (!memcmp (head,"DSC-Image",9))
    parse_rollei();
  else if (!memcmp (head,"PWAD",4))
    parse_sinar_ia();
  else if (!memcmp (head,"\0MRM",4))
    parse_minolta(0);
  else if (!memcmp (head,"FOVb",4))
    {
#ifdef LIBRAW_LIBRARY_BUILD
#ifdef  LIBRAW_DEMOSAIC_PACK_GPL2
      if(!imgdata.params.force_foveon_x3f)
        parse_foveon();
      else
#endif
        parse_x3f();
#else
#ifdef  LIBRAW_DEMOSAIC_PACK_GPL2
      parse_foveon();
#endif
#endif
    }
  else if (!memcmp (head,"CI",2))
    parse_cine();
  if(make[0] == 0)
    for (zero_fsize=i=0; i < sizeof table / sizeof *table; i++)
      if (fsize == table[i].fsize) {
	strcpy (make,  table[i].t_make );
#ifdef LIBRAW_LIBRARY_BUILD
        if (!strncmp(make, "Canon",5))
          {
            imgdata.lens.makernotes.CameraMount = LIBRAW_MOUNT_FixedLens;
            imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_FixedLens;
          }
#endif
	strcpy (model, table[i].t_model);
	flip = table[i].flags >> 2;
	zero_is_bad = table[i].flags & 2;
	if (table[i].flags & 1)
	  parse_external_jpeg();
	data_offset = table[i].offset;
	raw_width   = table[i].rw;
	raw_height  = table[i].rh;
	left_margin = table[i].lm;
	 top_margin = table[i].tm;
	width  = raw_width - left_margin - table[i].rm;
	height = raw_height - top_margin - table[i].bm;
	filters = 0x1010101 * table[i].cf;
	colors = 4 - !((filters & filters >> 1) & 0x5555);
	load_flags = table[i].lf;
	switch (tiff_bps = (fsize-data_offset)*8 / (raw_width*raw_height)) {
	  case 6:
	    load_raw = &CLASS minolta_rd175_load_raw;  break;
	  case 8:
	    load_raw = &CLASS eight_bit_load_raw;  break;
	  case 10:
           if ((fsize-data_offset)/raw_height*3 >= raw_width*4) {
             load_raw = &CLASS android_loose_load_raw;  break;
           } else if (load_flags & 1) {
             load_raw = &CLASS android_tight_load_raw;  break;
           }
	  case 12:
	    load_flags |= 128;
	    load_raw = &CLASS packed_load_raw;     break;
	  case 16:
	    order = 0x4949 | 0x404 * (load_flags & 1);
	    tiff_bps -= load_flags >> 4;
	    tiff_bps -= load_flags = load_flags >> 1 & 7;
	    load_raw = &CLASS unpacked_load_raw;
	}
	maximum = (1 << tiff_bps) - (1 << table[i].max);
      }
  if (zero_fsize) fsize = 0;
  if (make[0] == 0) parse_smal (0, flen);
  if (make[0] == 0) {
    parse_jpeg(0);
    fseek(ifp,0,SEEK_END);
    int sz = ftell(ifp);
    if (!(strncmp(model,"ov",2) && strncmp(model,"RP_OV",5)) && sz>=6404096 &&
        !fseek (ifp, -6404096, SEEK_END) &&
	fread (head, 1, 32, ifp) && !strcmp(head,"BRCMn")) {
      strcpy (make, "OmniVision");
      data_offset = ftell(ifp) + 0x8000-32;
      width = raw_width;
      raw_width = 2611;
      load_raw = &CLASS nokia_load_raw;
      filters = 0x16161616;
    } else is_raw = 0;
  }

  for (i=0; i < sizeof corp / sizeof *corp; i++)
    if (strcasestr (make, corp[i]))	/* Simplify company names */
	    strcpy (make, corp[i]);
  if ((!strncmp(make,"Kodak",5) || !strncmp(make,"Leica",5)) &&
	((cp = strcasestr(model," DIGITAL CAMERA")) ||
	 (cp = strstr(model,"FILE VERSION"))))
     *cp = 0;
  if (!strncasecmp(model,"PENTAX",6))
    strcpy (make, "Pentax");
  cp = make + strlen(make);		/* Remove trailing spaces */
  while (*--cp == ' ') *cp = 0;
  cp = model + strlen(model);
  while (*--cp == ' ') *cp = 0;
  i = strlen(make);			/* Remove make from model */
  if (!strncasecmp (model, make, i) && model[i++] == ' ')
    memmove (model, model+i, 64-i);
  if (!strncmp (model,"FinePix ",8))
    strcpy (model, model+8);
  if (!strncmp (model,"Digital Camera ",15))
    strcpy (model, model+15);
  desc[511] = artist[63] = make[63] = model[63] = model2[63] = 0;
  if (!is_raw) goto notraw;

  if (!height) height = raw_height;
  if (!width)  width  = raw_width;
  if (height == 2624 && width == 3936)	/* Pentax K10D and Samsung GX10 */
    { height  = 2616;   width  = 3896; }
  if (height == 3136 && width == 4864)  /* Pentax K20D and Samsung GX20 */
    { height  = 3124;   width  = 4688; filters = 0x16161616; }
  if (width == 4352 && (!strcmp(model,"K-r") || !strcmp(model,"K-x")))
    {			width  = 4309; filters = 0x16161616; }
  if (width >= 4960 && !strncmp(model,"K-5",3))
    { left_margin = 10; width  = 4950; filters = 0x16161616; }
  if (width == 4736 && !strcmp(model,"K-7"))
    { height  = 3122;   width  = 4684; filters = 0x16161616; top_margin = 2; }
  if (width == 6080 && !strcmp(model,"K-3 II"))
    { left_margin = 4;  width  = 6040; }
  if (width == 6080 && !strcmp(model,"K-3"))
    { left_margin = 4;  width  = 6040; }
  if (width == 7424 && !strcmp(model,"645D"))
    { height  = 5502;   width  = 7328; filters = 0x61616161; top_margin = 29;
      left_margin = 48; }
  if (height == 3014 && width == 4096)	/* Ricoh GX200 */
			width  = 4014;
  if (dng_version) {
    if (filters == UINT_MAX) filters = 0;
    if (filters) is_raw = tiff_samples;
    else	 colors = tiff_samples;
    switch (tiff_compress) {
    case 0:  /* Compression not set, assuming uncompressed */
      case 1:     load_raw = &CLASS   packed_dng_load_raw;  break;
      case 7:     load_raw = &CLASS lossless_dng_load_raw;  break;
      case 34892: load_raw = &CLASS    lossy_dng_load_raw;  break;
      default:    load_raw = 0;
    }
    if (!strncmp(make, "Canon",5) && unique_id)
      {
        for (i = 0; i < sizeof unique / sizeof *unique; i++)
          if (unique_id == 0x80000000 + unique[i].id)
            {
              strcpy(model, unique[i].t_model);
              break;
            }
      }
    if (!strncasecmp(make, "Sony",4) && unique_id)
      {
        for (i = 0; i < sizeof sonique / sizeof *sonique; i++)
          if (unique_id == sonique[i].id)
            {
              strcpy(model, sonique[i].t_model);
              break;
            }
      }
    goto dng_skip;
  }
  if (!strncmp(make,"Canon",5) && !fsize && tiff_bps != 15) {
    if (!load_raw)
      load_raw = &CLASS lossless_jpeg_load_raw;
    for (i=0; i < sizeof canon / sizeof *canon; i++)
      if (raw_width == canon[i][0] && raw_height == canon[i][1]) {
	width  = raw_width - (left_margin = canon[i][2]);
	height = raw_height - (top_margin = canon[i][3]);
	width  -= canon[i][4];
	height -= canon[i][5];
	mask[0][1] =  canon[i][6];
	mask[0][3] = -canon[i][7];
	mask[1][1] =  canon[i][8];
	mask[1][3] = -canon[i][9];
	if (canon[i][10]) filters = canon[i][10] * 0x01010101;
      }
    if ((unique_id | 0x20000) == 0x2720000) {
      left_margin = 8;
      top_margin = 16;
    }
  }
  if (!strncmp(make,"Canon",5) && unique_id)
    {
      for (i=0; i < sizeof unique / sizeof *unique; i++)
        if (unique_id == 0x80000000 + unique[i].id)
          {
            adobe_coeff ("Canon", unique[i].t_model);
            strcpy(model,unique[i].t_model);
          }
    }

  if (!strncasecmp(make,"Sony",4) && unique_id)
    {
      for (i=0; i < sizeof sonique / sizeof *sonique; i++)
        if (unique_id == sonique[i].id)
          {
            adobe_coeff ("Sony", sonique[i].t_model);
            strcpy(model,sonique[i].t_model);
          }
    }

  if (!strncmp(make,"Nikon",5)) {
    if (!load_raw)
      load_raw = &CLASS packed_load_raw;
    if (model[0] == 'E')
      load_flags |= !data_offset << 2 | 2;
  }

/* Set parameters based on camera name (for non-DNG files). */

  if (!strcmp(model,"KAI-0340")
	&& find_green (16, 16, 3840, 5120) < 25) {
    height = 480;
    top_margin = filters = 0;
    strcpy (model,"C603");
  }
  if (is_foveon) {
    if (height*2 < width) pixel_aspect = 0.5;
    if (height   > width) pixel_aspect = 2;
    filters = 0;
#ifdef LIBRAW_DEMOSAIC_PACK_GPL2
    if(!imgdata.params.force_foveon_x3f)
      simple_coeff(0);
#endif
  } else if (!strncmp(make,"Canon",5) && tiff_bps == 15) {
    switch (width) {
      case 3344: width -= 66;
      case 3872: width -= 6;
    }
    if (height > width) {
      SWAP(height,width);
      SWAP(raw_height,raw_width);
    }
    if (width == 7200 && height == 3888) {
          raw_width  = width  = 6480;
          raw_height = height = 4320;
    }
    filters = 0;
    tiff_samples = colors = 3;
    load_raw = &CLASS canon_sraw_load_raw;
  } else if (!strcmp(model,"PowerShot 600")) {
    height = 613;
    width  = 854;
    raw_width = 896;
    colors = 4;
    filters = 0xe1e4e1e4;
    load_raw = &CLASS canon_600_load_raw;
  } else if (!strcmp(model,"PowerShot A5") ||
	     !strcmp(model,"PowerShot A5 Zoom")) {
    height = 773;
    width  = 960;
    raw_width = 992;
    pixel_aspect = 256/235.0;
    filters = 0x1e4e1e4e;
    goto canon_a5;
  } else if (!strcmp(model,"PowerShot A50")) {
    height =  968;
    width  = 1290;
    raw_width = 1320;
    filters = 0x1b4e4b1e;
    goto canon_a5;
  } else if (!strcmp(model,"PowerShot Pro70")) {
    height = 1024;
    width  = 1552;
    filters = 0x1e4b4e1b;
canon_a5:
    colors = 4;
    tiff_bps = 10;
    load_raw = &CLASS packed_load_raw;
    load_flags = 40;
  } else if (!strcmp(model,"PowerShot Pro90 IS") ||
	     !strcmp(model,"PowerShot G1")) {
    colors = 4;
    filters = 0xb4b4b4b4;
  } else if (!strcmp(model,"PowerShot A610")) {
    if (canon_s2is()) strcpy (model+10, "S2 IS");
  } else if (!strcmp(model,"PowerShot SX220 HS")) {
    mask[1][3] = -4;
    top_margin=16;
    left_margin = 92;
  } else if (!strcmp(model,"PowerShot S120")) {
        raw_width = 4192;
        raw_height = 3062;
        width = 4022;
        height = 3016;
        mask[0][0] = top_margin = 31;
        mask[0][2] = top_margin + height;
        left_margin = 120;
        mask[0][1] = 23;
        mask[0][3] = 72;
  } else if (!strcmp(model,"PowerShot G16")) {
      mask[0][0] = 0;
      mask[0][2] = 80;
      mask[0][1] = 0;
      mask[0][3] = 16;
      top_margin = 29;
      left_margin = 120;
      width = raw_width-left_margin-48;
      height = raw_height-top_margin-14;
  } else if (!strcmp(model,"PowerShot SX50 HS")) {
    top_margin = 17;
  } else if (!strcmp(model,"EOS D2000C")) {
    filters = 0x61616161;
    black = curve[200];
  } else if (!strcmp(model,"D1")) {
    cam_mul[0] *= 256/527.0;
    cam_mul[2] *= 256/317.0;
  } else if (!strcmp(model,"D1X")) {
    width -= 4;
    pixel_aspect = 0.5;
  } else if (!strcmp(model,"D40X") ||
	     !strcmp(model,"D60")  ||
	     !strcmp(model,"D80")  ||
	     !strcmp(model,"D3000")) {
    height -= 3;
    width  -= 4;
  } else if (!strcmp(model,"D3")   ||
	     !strcmp(model,"D3S")  ||
	     !strcmp(model,"D700")) {
    width -= 4;
    left_margin = 2;
  } else if (!strcmp(model,"D3100")) {
    width -= 28;
    left_margin = 6;
  } else if (!strcmp(model,"D5000") ||
	     !strcmp(model,"D90")) {
    width -= 42;
  } else if (!strcmp(model,"D5100") ||
	     !strcmp(model,"D7000") ||
	     !strcmp(model,"COOLPIX A")) {
    width -= 44;
  } else if (!strcmp(model,"D3200") ||
	    !strncmp(model,"D6",2)  ||
	    !strncmp(model,"D800",4)) {
    width -= 46;
  } else if (!strcmp(model,"D4") ||
	     !strcmp(model,"Df")) {
    width -= 52;
    left_margin = 2;
  } else if (!strncmp(model,"D40",3) ||
	     !strncmp(model,"D50",3) ||
	     !strncmp(model,"D70",3)) {
    width--;
  } else if (!strcmp(model,"D100")) {
    if (load_flags)
      raw_width = (width += 3) + 3;
  } else if (!strcmp(model,"D200")) {
    left_margin = 1;
    width -= 4;
    filters = 0x94949494;
  } else if (!strncmp(model,"D2H",3)) {
    left_margin = 6;
    width -= 14;
  } else if (!strncmp(model,"D2X",3)) {
    if (width == 3264) width -= 32;
    else width -= 8;
  } else if (!strncmp(model,"D300",4)) {
    width -= 32;
  } else if (!strncmp(make,"Nikon",5) && raw_width == 4032) {
    if(!strcmp(model,"COOLPIX P7700"))
      {
        adobe_coeff ("Nikon","COOLPIX P7700");
        maximum = 65504;
        load_flags = 0;
      }
    else if(!strcmp(model,"COOLPIX P7800"))
      {
        adobe_coeff ("Nikon","COOLPIX P7800");
        maximum = 65504;
        load_flags = 0;
      }
    else  if(!strcmp(model,"COOLPIX P340"))
      load_flags=0;
  } else if (!strncmp(model,"COOLPIX P",9) && raw_width != 4032) {
    load_flags = 24;
    filters = 0x94949494;
    if (model[9] == '7' && iso_speed >= 400)
      black = 255;
  } else if (!strncmp(model,"1 ",2)) {
    height -= 2;
  } else if (fsize == 1581060) {
    simple_coeff(3);
    pre_mul[0] = 1.2085;
    pre_mul[1] = 1.0943;
    pre_mul[3] = 1.1103;
  } else if (fsize == 3178560) {
    cam_mul[0] *= 4;
    cam_mul[2] *= 4;
  } else if (fsize == 4771840) {
    if (!timestamp && nikon_e995())
      strcpy (model, "E995");
    if (strcmp(model,"E995")) {
      filters = 0xb4b4b4b4;
      simple_coeff(3);
      pre_mul[0] = 1.196;
      pre_mul[1] = 1.246;
      pre_mul[2] = 1.018;
    }
  } else if (fsize == 2940928) {
    if (!timestamp && !nikon_e2100())
      strcpy (model,"E2500");
    if (!strcmp(model,"E2500")) {
      height -= 2;
      load_flags = 6;
      colors = 4;
      filters = 0x4b4b4b4b;
    }
  } else if (fsize == 4775936) {
    if (!timestamp) nikon_3700();
    if (model[0] == 'E' && atoi(model+1) < 3700)
      filters = 0x49494949;
    if (!strcmp(model,"Optio 33WR")) {
      flip = 1;
      filters = 0x16161616;
    }
    if (make[0] == 'O') {
      i = find_green (12, 32, 1188864, 3576832);
      c = find_green (12, 32, 2383920, 2387016);
      if (abs(i) < abs(c)) {
	SWAP(i,c);
	load_flags = 24;
      }
      if (i < 0) filters = 0x61616161;
    }
  } else if (fsize == 5869568) {
    if (!timestamp && minolta_z2()) {
      strcpy (make, "Minolta");
      strcpy (model,"DiMAGE Z2");
    }
    load_flags = 6 + 24*(make[0] == 'M');
  } else if (fsize == 6291456) {
    fseek (ifp, 0x300000, SEEK_SET);
    if ((order = guess_byte_order(0x10000)) == 0x4d4d) {
      height -= (top_margin = 16);
      width -= (left_margin = 28);
      maximum = 0xf5c0;
      strcpy (make, "ISG");
      model[0] = 0;
    }
  } else if (!strncmp(make,"Fujifilm",8)) {
    if (!strcmp(model+7,"S2Pro")) {
      strcpy (model,"S2Pro");
      height = 2144;
      width  = 2880;
      flip = 6;
    } else if (load_raw != &CLASS packed_load_raw)
      maximum = (is_raw == 2 && shot_select) ? 0x2f00 : 0x3e00;
    top_margin = (raw_height - height) >> 2 << 1;
    left_margin = (raw_width - width ) >> 2 << 1;
    if (width == 2848 || width == 3664) filters = 0x16161616;
    if (width == 4032 || width == 4952) left_margin = 0;
    if (width == 3328 && (width -= 66)) left_margin = 34;
    if (width == 4936) left_margin = 4;
    if (!strcmp(model,"HS50EXR") ||
	!strcmp(model,"F900EXR")) {
      width += 2;
      left_margin = 0;
      filters = 0x16161616;
    }
    if(!strcmp(model,"S5500"))
      {
        height -= (top_margin=6);
      }
    if (fuji_layout) raw_width *= is_raw;
    if (filters == 9)
      FORC(36) ((char *)xtrans)[c] =
	xtrans_abs[(c/6+top_margin) % 6][(c+left_margin) % 6];
  } else if (!strcmp(model,"KD-400Z")) {
    height = 1712;
    width  = 2312;
    raw_width = 2336;
    goto konica_400z;
  } else if (!strcmp(model,"KD-510Z")) {
    goto konica_510z;
  } else if (!strncasecmp(make,"Minolta",7)) {
    if (!load_raw && (maximum = 0xfff))
      load_raw = &CLASS unpacked_load_raw;
    if (!strncmp(model,"DiMAGE A",8)) {
      if (!strcmp(model,"DiMAGE A200"))
	filters = 0x49494949;
      tiff_bps = 12;
      load_raw = &CLASS packed_load_raw;
    } else if (!strncmp(model,"ALPHA",5) ||
	       !strncmp(model,"DYNAX",5) ||
	       !strncmp(model,"MAXXUM",6)) {
      sprintf (model+20, "DYNAX %-10s", model+6+(model[0]=='M'));
      adobe_coeff (make, model+20);
      load_raw = &CLASS packed_load_raw;
    } else if (!strncmp(model,"DiMAGE G",8)) {
      if (model[8] == '4') {
	height = 1716;
	width  = 2304;
      } else if (model[8] == '5') {
konica_510z:
	height = 1956;
	width  = 2607;
	raw_width = 2624;
      } else if (model[8] == '6') {
	height = 2136;
	width  = 2848;
      }
      data_offset += 14;
      filters = 0x61616161;
konica_400z:
      load_raw = &CLASS unpacked_load_raw;
      maximum = 0x3df;
      order = 0x4d4d;
    }
  } else if (!strcmp(model,"*ist D")) {
    load_raw = &CLASS unpacked_load_raw;
    data_error = -1;
  } else if (!strcmp(model,"*ist DS")) {
    height -= 2;
  } else if (!strncmp(make,"Samsung",7) && raw_width == 4704) {
    height -= top_margin = 8;
    width -= 2 * (left_margin = 8);
    load_flags = 32;
  } else if (!strncmp(make,"Samsung",7) && !strcmp(model,"NX3000")) {
    top_margin = 24;
    left_margin = 64;
    width = 5472;
    height = 3648;
    filters = 0x61616161;
    colors = 3;
  } else if (!strncmp(make,"Samsung",7) && raw_height == 3714) {
    height -= top_margin = 18;
    left_margin = raw_width - (width = 5536);
    if (raw_width != 5600)
      left_margin = top_margin = 0;
    filters = 0x61616161;
    colors = 3;
  } else if (!strncmp(make,"Samsung",7) && raw_width == 5632) {
    order = 0x4949;
    height = 3694;
    top_margin = 2;
    width  = 5574 - (left_margin = 32 + tiff_bps);
    if (tiff_bps == 12) load_flags = 80;
  } else if (!strncmp(make,"Samsung",7) && raw_width == 5664) {
    height -= top_margin = 17;
    left_margin = 96;
    width = 5544;
    filters = 0x49494949;
  } else if (!strncmp(make,"Samsung",7) && raw_width == 6496) {
    filters = 0x61616161;
#ifdef LIBRAW_LIBRARY_BUILD
    if(!black && !cblack[0] && !cblack[1] && !cblack[2] && !cblack[3])
#endif
    black = 1 << (tiff_bps - 7);
  } else if (!strcmp(model,"EX1")) {
    order = 0x4949;
    height -= 20;
    top_margin = 2;
    if ((width -= 6) > 3682) {
      height -= 10;
      width  -= 46;
      top_margin = 8;
    }
  } else if (!strcmp(model,"WB2000")) {
    order = 0x4949;
    height -= 3;
    top_margin = 2;
    if ((width -= 10) > 3718) {
      height -= 28;
      width  -= 56;
      top_margin = 8;
    }
  } else if (strstr(model,"WB550")) {
    strcpy (model, "WB550");
  } else if (!strcmp(model,"EX2F")) {
    height = 3045;
    width  = 4070;
    top_margin = 3;
    order = 0x4949;
    filters = 0x49494949;
    load_raw = &CLASS unpacked_load_raw;
  } else if (!strcmp(model,"STV680 VGA")) {
    black = 16;
  } else if (!strcmp(model,"N95")) {
    height = raw_height - (top_margin = 2);
  } else if (!strcmp(model,"640x480")) {
    gamma_curve (0.45, 4.5, 1, 255);
  } else if (!strncmp(make,"Hasselblad",10)) {
    if (load_raw == &CLASS lossless_jpeg_load_raw)
      load_raw = &CLASS hasselblad_load_raw;
    if (raw_width == 7262) {
      height = 5444;
      width  = 7248;
      top_margin  = 4;
      left_margin = 7;
      filters = 0x61616161;
      if(!strncasecmp(model,"H3D",3))
        {
          adobe_coeff("Hasselblad","H3DII-39");
          strcpy(model,"H3DII-39");
        }
    } else if (raw_width == 7410 || raw_width == 8282) {
      height -= 84;
      width  -= 82;
      top_margin  = 4;
      left_margin = 41;
      filters = 0x61616161;
      adobe_coeff("Hasselblad","H4D-40");
      strcpy(model,"H4D-40");
    } else if (raw_width == 9044) {
      if(black > 500)
        {
          top_margin = 12;
          left_margin = 44;
          width = 8956;
          height = 6708;
          memset(cblack,0,sizeof(cblack));
          adobe_coeff("Hasselblad","H4D-60");
          strcpy(model,"H4D-60");
          black = 512;
        }
      else
        {
          height = 6716;
          width  = 8964;
          top_margin  = 8;
          left_margin = 40;
          black += load_flags = 256;
          maximum = 0x8101;
          strcpy(model,"H3DII-60");
        }
    } else if (raw_width == 4090) {
      strcpy (model, "V96C");
      height -= (top_margin = 6);
      width -= (left_margin = 3) + 7;
      filters = 0x61616161;
    } else if (raw_width == 8282 && raw_height == 6240) {
      if(!strncasecmp(model,"H5D",3))
        {
          /* H5D 50*/
          left_margin = 54;
          top_margin = 16;
          width = 8176;
          height = 6132;
          black = 256;
          strcpy(model,"H5D-50");
        }
      else if(!strncasecmp(model,"H3D",3))
        {
          black=0;
          left_margin = 54;
          top_margin = 16;
          width = 8176;
          height = 6132;
          memset(cblack,0,sizeof(cblack));
          adobe_coeff("Hasselblad","H3D-50");
          strcpy(model,"H3D-50");
        }
    } else if (raw_width == 8374 && raw_height == 6304) {
      /* H5D 50c*/
      left_margin = 52;
      top_margin = 100;
      width = 8272;
      height = 6200;
      black = 256;
      strcpy(model,"H5D-50c");
    }
    if (tiff_samples > 1) {
      is_raw = tiff_samples+1;
      if (!shot_select && !half_size) filters = 0;
    }
  } else if (!strncmp(make,"Sinar",5)) {
    if (!load_raw) load_raw = &CLASS unpacked_load_raw;
    if (is_raw > 1 && !shot_select && !half_size) filters = 0;
    maximum = 0x3fff;
  } else if (!strncmp(make,"Leaf",4)) {
    maximum = 0x3fff;
    fseek (ifp, data_offset, SEEK_SET);
    if (ljpeg_start (&jh, 1) && jh.bits == 15)
      maximum = 0x1fff;
    if (tiff_samples > 1) filters = 0;
    if (tiff_samples > 1 || tile_length < raw_height) {
      load_raw = &CLASS leaf_hdr_load_raw;
      raw_width = tile_width;
    }
    if ((width | height) == 2048) {
      if (tiff_samples == 1) {
	filters = 1;
	strcpy (cdesc, "RBTG");
	strcpy (model, "CatchLight");
	top_margin =  8; left_margin = 18; height = 2032; width = 2016;
      } else {
	strcpy (model, "DCB2");
	top_margin = 10; left_margin = 16; height = 2028; width = 2022;
      }
    } else if (width+height == 3144+2060) {
      if (!model[0]) strcpy (model, "Cantare");
      if (width > height) {
	 top_margin = 6; left_margin = 32; height = 2048;  width = 3072;
	filters = 0x61616161;
      } else {
	left_margin = 6;  top_margin = 32;  width = 2048; height = 3072;
	filters = 0x16161616;
      }
      if (!cam_mul[0] || model[0] == 'V') filters = 0;
      else is_raw = tiff_samples;
    } else if (width == 2116) {
      strcpy (model, "Valeo 6");
      height -= 2 * (top_margin = 30);
      width -= 2 * (left_margin = 55);
      filters = 0x49494949;
    } else if (width == 3171) {
      strcpy (model, "Valeo 6");
      height -= 2 * (top_margin = 24);
      width -= 2 * (left_margin = 24);
      filters = 0x16161616;
    }
  } else if (!strncmp(make,"Leica",5) || !strncmp(make,"Panasonic",9)) {
    if (raw_width > 0&& ((flen - data_offset) / (raw_width*8/7) == raw_height) )
      load_raw = &CLASS panasonic_load_raw;
    if (!load_raw) {
      load_raw = &CLASS unpacked_load_raw;
      load_flags = 4;
    }
    zero_is_bad = 1;
    if ((height += 12) > raw_height) height = raw_height;
    for (i=0; i < sizeof pana / sizeof *pana; i++)
      if (raw_width == pana[i][0] && raw_height == pana[i][1]) {
	left_margin = pana[i][2];
	 top_margin = pana[i][3];
	     width += pana[i][4];
	    height += pana[i][5];
      }
    filters = 0x01010101 * (uchar) "\x94\x61\x49\x16"
	[((filters-1) ^ (left_margin & 1) ^ (top_margin << 1)) & 3];
  } else if (!strcmp(model,"C770UZ")) {
    height = 1718;
    width  = 2304;
    filters = 0x16161616;
    load_raw = &CLASS packed_load_raw;
    load_flags = 30;
  } else if (!strncmp(make,"Olympus",7)) {
    height += height & 1;
    if (exif_cfa) filters = exif_cfa;
    if (width == 4100) width -= 4;
    if (width == 4080) width -= 24;
    if (width == 9280) { width -= 6; height -= 6; }
    if (load_raw == &CLASS unpacked_load_raw)
      load_flags = 4;
    tiff_bps = 12;
    if (!strcmp(model,"E-300") ||
	!strcmp(model,"E-500")) {
      width -= 20;
      if (load_raw == &CLASS unpacked_load_raw) {
	maximum = 0xfc3;
	memset (cblack, 0, sizeof cblack);
      }
    } else if (!strcmp(model,"STYLUS1")) {
      width -= 14;
      maximum = 0xfff;
    } else if (!strcmp(model,"E-330")) {
      width -= 30;
      if (load_raw == &CLASS unpacked_load_raw)
	maximum = 0xf79;
    } else if (!strcmp(model,"SP550UZ")) {
      thumb_length = flen - (thumb_offset = 0xa39800);
      thumb_height = 480;
      thumb_width  = 640;
    }
  } else if (!strcmp(model,"N Digital")) {
    height = 2047;
    width  = 3072;
    filters = 0x61616161;
    data_offset = 0x1a00;
    load_raw = &CLASS packed_load_raw;
  } else if (!strcmp(model,"DSC-F828")) {
    width = 3288;
    left_margin = 5;
    mask[1][3] = -17;
    data_offset = 862144;
    load_raw = &CLASS sony_load_raw;
    filters = 0x9c9c9c9c;
    colors = 4;
    strcpy (cdesc, "RGBE");
  } else if (!strcmp(model,"DSC-V3")) {
    width = 3109;
    left_margin = 59;
    mask[0][1] = 9;
    data_offset = 787392;
    load_raw = &CLASS sony_load_raw;
  } else if (!strncmp(make,"Sony",4) && raw_width == 3984) {
    width = 3925;
    order = 0x4d4d;
  } else if (!strncmp(make,"Sony",4) && raw_width == 4288) {
    width -= 32;
  } else if (!strncmp(make,"Sony",4) && raw_width == 4928) {
    if (height < 3280) width -= 8;
  } else if (!strncmp(make,"Sony",4) && raw_width == 5504) { // ILCE-3000//5000
    width -= height > 3664 ? 8 : 32;
  } else if (!strncmp(make,"Sony",4) && raw_width == 6048) {
    width -= 24;
    if (strstr(model,"RX1") || strstr(model,"A99"))
      width -= 6;
  } else if (!strncmp(make,"Sony",4) && raw_width == 7392) {
    width -= 30;
  } else if (!strcmp(model,"DSLR-A100")) {
    if (width == 3880) {
      height--;
      width = ++raw_width;
    } else {
      height -= 4;
      width  -= 4;
      order = 0x4d4d;
      load_flags = 2;
    }
    filters = 0x61616161;
  } else if (!strcmp(model,"DSLR-A350")) {
    height -= 4;
  } else if (!strcmp(model,"PIXL")) {
    height -= top_margin = 4;
    width -= left_margin = 32;
    gamma_curve (0, 7, 1, 255);
  } else if (!strcmp(model,"C603") || !strcmp(model,"C330")
	|| !strcmp(model,"12MP")) {
    order = 0x4949;
    if (filters && data_offset) {
      fseek (ifp, data_offset < 4096 ? 168 : 5252, SEEK_SET);
      read_shorts (curve, 256);
    } else gamma_curve (0, 3.875, 1, 255);
    load_raw  =  filters   ? &CLASS eight_bit_load_raw :
      strcmp(model,"C330") ? &CLASS kodak_c603_load_raw :
			     &CLASS kodak_c330_load_raw;
    load_flags = tiff_bps > 16;
    tiff_bps = 8;
  } else if (!strncasecmp(model,"EasyShare",9)) {
    data_offset = data_offset < 0x15000 ? 0x15000 : 0x17000;
    load_raw = &CLASS packed_load_raw;
  } else if (!strncasecmp(make,"Kodak",5)) {
    if (filters == UINT_MAX) filters = 0x61616161;
    if (!strncmp(model,"NC2000",6) ||
	!strncmp(model,"EOSDCS",6) ||
	!strncmp(model,"DCS4",4)) {
      width -= 4;
      left_margin = 2;
      if (model[6] == ' ') model[6] = 0;
      if (!strcmp(model,"DCS460A")) goto bw;
    } else if (!strcmp(model,"DCS660M")) {
      black = 214;
      goto bw;
    } else if (!strcmp(model,"DCS760M")) {
bw:   colors = 1;
      filters = 0;
    }
    if (!strcmp(model+4,"20X"))
      strcpy (cdesc, "MYCY");
    if (strstr(model,"DC25")) {
      strcpy (model, "DC25");
      data_offset = 15424;
    }
    if (!strncmp(model,"DC2",3)) {
      raw_height = 2 + (height = 242);
      if (!strncmp(model, "DC290", 5))
        iso_speed = 100;
      if (!strncmp(model, "DC280", 5))
        iso_speed = 70;
      if (flen < 100000) {
	raw_width = 256; width = 249;
	pixel_aspect = (4.0*height) / (3.0*width);
      } else {
	raw_width = 512; width = 501;
	pixel_aspect = (493.0*height) / (373.0*width);
      }
      top_margin = left_margin = 1;
      colors = 4;
      filters = 0x8d8d8d8d;
      simple_coeff(1);
      pre_mul[1] = 1.179;
      pre_mul[2] = 1.209;
      pre_mul[3] = 1.036;
      load_raw = &CLASS eight_bit_load_raw;
    } else if (!strcmp(model,"40")) {
      strcpy (model, "DC40");
      height = 512;
      width  = 768;
      data_offset = 1152;
      load_raw = &CLASS kodak_radc_load_raw;
    } else if (strstr(model,"DC50")) {
      strcpy (model, "DC50");
      height = 512;
      width  = 768;
      iso_speed=84;
      data_offset = 19712;
      load_raw = &CLASS kodak_radc_load_raw;
    } else if (strstr(model,"DC120")) {
      strcpy (model, "DC120");
      height = 976;
      width  = 848;
      iso_speed=160;
      pixel_aspect = height/0.75/width;
      load_raw = tiff_compress == 7 ?
	&CLASS kodak_jpeg_load_raw : &CLASS kodak_dc120_load_raw;
    } else if (!strcmp(model,"DCS200")) {
      thumb_height = 128;
      thumb_width  = 192;
      thumb_offset = 6144;
      thumb_misc   = 360;
      iso_speed=140;
      write_thumb = &CLASS layer_thumb;
      black = 17;
    }
  } else if (!strcmp(model,"Fotoman Pixtura")) {
    height = 512;
    width  = 768;
    data_offset = 3632;
    load_raw = &CLASS kodak_radc_load_raw;
    filters = 0x61616161;
    simple_coeff(2);
  } else if (!strncmp(model,"QuickTake",9)) {
    if (head[5]) strcpy (model+10, "200");
    fseek (ifp, 544, SEEK_SET);
    height = get2();
    width  = get2();
    data_offset = (get4(),get2()) == 30 ? 738:736;
    if (height > width) {
      SWAP(height,width);
      fseek (ifp, data_offset-6, SEEK_SET);
      flip = ~get2() & 3 ? 5:6;
    }
    filters = 0x61616161;
  } else if (!strncmp(make,"Rollei",6) && !load_raw) {
    switch (raw_width) {
      case 1316:
	height = 1030;
	width  = 1300;
	top_margin  = 1;
	left_margin = 6;
	break;
      case 2568:
	height = 1960;
	width  = 2560;
	top_margin  = 2;
	left_margin = 8;
    }
    filters = 0x16161616;
    load_raw = &CLASS rollei_load_raw;
  }
  else if (!strcmp(model,"GRAS-50S5C")) {
   height = 2048;
   width = 2440;
   load_raw = &CLASS unpacked_load_raw;
   data_offset = 0;
   filters = 0x49494949;
   order = 0x4949;
   maximum = 0xfffC;
  } else if (!strcmp(model,"BB-500CL")) {
   height = 2058;
   width = 2448;
   load_raw = &CLASS unpacked_load_raw;
   data_offset = 0;
   filters = 0x94949494;
   order = 0x4949;
   maximum = 0x3fff;
  } else if (!strcmp(model,"BB-500GE")) {
   height = 2058;
   width = 2456;
   load_raw = &CLASS unpacked_load_raw;
   data_offset = 0;
   filters = 0x94949494;
   order = 0x4949;
   maximum = 0x3fff;
  } else if (!strcmp(model,"SVS625CL")) {
   height = 2050;
   width = 2448;
   load_raw = &CLASS unpacked_load_raw;
   data_offset = 0;
   filters = 0x94949494;
   order = 0x4949;
   maximum = 0x0fff;
  }
  /* Early reject for damaged images */
  if (!load_raw || height < 22 || width < 22 ||
	tiff_bps > 16 || tiff_samples > 4 || colors > 4 || colors < 1)
    {
      is_raw = 0;
#ifdef LIBRAW_LIBRARY_BUILD
      RUN_CALLBACK(LIBRAW_PROGRESS_IDENTIFY,1,2);
#endif
      return;
    }
  if (!model[0])
    sprintf (model, "%dx%d", width, height);
  if (filters == UINT_MAX) filters = 0x94949494;
  if (thumb_offset && !thumb_height) {
    fseek (ifp, thumb_offset, SEEK_SET);
    if (ljpeg_start (&jh, 1)) {
      thumb_width  = jh.wide;
      thumb_height = jh.high;
    }
  }

dng_skip:
  /* Early reject for damaged images */
  if (!load_raw || height < 22 || width < 22 ||
	tiff_bps > 16 || tiff_samples > 4 || colors > 4 || colors < 1)
    {
      is_raw = 0;
#ifdef LIBRAW_LIBRARY_BUILD
      RUN_CALLBACK(LIBRAW_PROGRESS_IDENTIFY,1,2);
#endif
      return;
    }
  if ((use_camera_matrix & (use_camera_wb || dng_version))
	&& cmatrix[0][0] > 0.125) {
    memcpy (rgb_cam, cmatrix, sizeof cmatrix);
    raw_color = 0;
  }

  if (raw_color) adobe_coeff (make, model);
#ifdef LIBRAW_LIBRARY_BUILD
  else if(imgdata.color.cam_xyz[0][0]<0.01)
	  adobe_coeff (make, model,1);
#endif

  if (load_raw == &CLASS kodak_radc_load_raw)
    if (raw_color) adobe_coeff ("Apple","Quicktake");

  if (fuji_width) {
    fuji_width = width >> !fuji_layout;
    filters = fuji_width & 1 ? 0x94949494 : 0x49494949;
    width = (height >> fuji_layout) + fuji_width;
    height = width - 1;
    pixel_aspect = 1;
  } else {
    if (raw_height < height) raw_height = height;
    if (raw_width  < width ) raw_width  = width;
  }
  if (!tiff_bps) tiff_bps = 12;
  if (!maximum)
    {
      maximum = (1 << tiff_bps) - 1;
      if(maximum < 0x10000 && curve[maximum]>0 &&    load_raw == &CLASS sony_arw2_load_raw)
        maximum = curve[maximum];
    }
  if (!load_raw || height < 22 || width < 22 ||
	tiff_bps > 16 || tiff_samples > 6 || colors > 4)
    is_raw = 0;

  if(raw_width < 22 || raw_width > 64000 || raw_height < 22 || raw_width > 64000)
    is_raw = 0;

#ifdef NO_JASPER
  if (load_raw == &CLASS redcine_load_raw) {
#ifdef DCRAW_VERBOSE
    fprintf (stderr,_("%s: You must link dcraw with %s!!\n"),
	ifname, "libjasper");
#endif
    is_raw = 0;
#ifdef LIBRAW_LIBRARY_BUILD
    imgdata.process_warnings |= LIBRAW_WARN_NO_JASPER;
#endif
  }
#endif
#ifdef NO_JPEG
  if (load_raw == &CLASS kodak_jpeg_load_raw ||
      load_raw == &CLASS lossy_dng_load_raw) {
#ifdef DCRAW_VERBOSE
    fprintf (stderr,_("%s: You must link dcraw with %s!!\n"),
	ifname, "libjpeg");
#endif
    is_raw = 0;
#ifdef LIBRAW_LIBRARY_BUILD
    imgdata.process_warnings |= LIBRAW_WARN_NO_JPEGLIB;
#endif
  }
#endif
  if (!cdesc[0])
    strcpy (cdesc, colors == 3 ? "RGBG":"GMCY");
  if (!raw_height) raw_height = height;
  if (!raw_width ) raw_width  = width;
  if (filters > 999 && colors == 3)
    filters |= ((filters >> 2 & 0x22222222) |
		(filters << 2 & 0x88888888)) & filters << 1;
notraw:
  if (flip == UINT_MAX) flip = tiff_flip;
  if (flip == UINT_MAX) flip = 0;

#ifdef LIBRAW_LIBRARY_BUILD
  RUN_CALLBACK(LIBRAW_PROGRESS_IDENTIFY,1,2);
#endif
}

Project: LibRaw
File: libraw_cxx.cpp

void LibRaw:: recycle()
{
  recycle_datastream();
#define FREE(a) do { if(a) { free(a); a = NULL;} }while(0)

  FREE(imgdata.image);
  FREE(imgdata.thumbnail.thumb);
  FREE(libraw_internal_data.internal_data.meta_data);
  FREE(libraw_internal_data.output_data.histogram);
  FREE(libraw_internal_data.output_data.oprof);
  FREE(imgdata.color.profile);
  FREE(imgdata.rawdata.ph1_cblack);
  FREE(imgdata.rawdata.ph1_rblack);
  FREE(imgdata.rawdata.raw_alloc);
  FREE(imgdata.idata.xmpdata);
#undef FREE
  ZERO(imgdata.rawdata);
  ZERO(imgdata.sizes);
  ZERO(imgdata.color);
  cleargps(&imgdata.other.parsed_gps);
  imgdata.color.baseline_exposure = -999.f;
  imgdata.color.FujiExpoMidPointShift = -999.f;
  ZERO(libraw_internal_data);
  ZERO(imgdata.lens);
  imgdata.lens.makernotes.CanonFocalUnits = 1;
  imgdata.lens.makernotes.LensID = 0xffffffffffffffffULL;

  _exitflag = 0;
#ifdef USE_RAWSPEED
  if(_rawspeed_decoder)
    {
      RawDecoder *d = static_cast<RawDecoder*>(_rawspeed_decoder);
      delete d;
    }
  _rawspeed_decoder = 0;
#endif
  if(_x3f_data)
    {
      x3f_clear(_x3f_data);
      _x3f_data = 0;
    }

  memmgr.cleanup();
  imgdata.thumbnail.tformat = LIBRAW_THUMBNAIL_UNKNOWN;
  imgdata.progress_flags = 0;

  tls->init();
}

Project: LibRaw
File: dcraw.c

void CLASS parse_foveon()
{
  int entries, img=0, off, len, tag, save, i, wide, high, pent, poff[256][2];
  char name[64], value[64];
  order = 0x4949;			/* Little-endian */
  fseek (ifp, 36, SEEK_SET);
  flip = get4();
  fseek (ifp, -4, SEEK_END);
  fseek (ifp, get4(), SEEK_SET);
  if (get4() != 0x64434553) return;	/* SECd */
  entries = (get4(),get4());
  while (entries--) {
    off = get4();
    len = get4();
    tag = get4();
    save = ftell(ifp);
    fseek (ifp, off, SEEK_SET);
    if (get4() != (0x20434553 | (tag << 24))) return;
    switch (tag) {
      case 0x47414d49:			/* IMAG */
      case 0x32414d49:			/* IMA2 */
	fseek (ifp, 8, SEEK_CUR);
	pent = get4();
	wide = get4();
	high = get4();
	if (wide > raw_width && high > raw_height) {
	  switch (pent) {
	    case  5:  load_flags = 1;
	    case  6:  load_raw = &CLASS foveon_sd_load_raw;  break;
	    case 30:  load_raw = &CLASS foveon_dp_load_raw;  break;
	    default:  load_raw = 0;
	  }
	  raw_width  = wide;
	  raw_height = high;
	  data_offset = off+28;
	  is_foveon = 1;
	}
	fseek (ifp, off+28, SEEK_SET);
	if (fgetc(ifp) == 0xff && fgetc(ifp) == 0xd8
		&& thumb_length < len-28) {
	  thumb_offset = off+28;
	  thumb_length = len-28;
	  write_thumb = &CLASS jpeg_thumb;
	}
	if (++img == 2 && !thumb_length) {
	  thumb_offset = off+24;
	  thumb_width = wide;
	  thumb_height = high;
	  write_thumb = &CLASS foveon_thumb;
	}
	break;
      case 0x464d4143:			/* CAMF */
	meta_offset = off+8;
	meta_length = len-28;
	break;
      case 0x504f5250:			/* PROP */
	pent = (get4(),get4());
	fseek (ifp, 12, SEEK_CUR);
	off += pent*8 + 24;
	if ((unsigned) pent > 256) pent=256;
	for (i=0; i < pent*2; i++)
	  ((int *)poff)[i] = off + get4()*2;
	for (i=0; i < pent; i++) {
	  foveon_gets (poff[i][0], name, 64);
	  foveon_gets (poff[i][1], value, 64);
	  if (!strcmp (name, "ISO"))
	    iso_speed = atoi(value);
	  if (!strcmp (name, "CAMMANUF"))
	    strcpy (make, value);
	  if (!strcmp (name, "CAMMODEL"))
	    strcpy (model, value);
	  if (!strcmp (name, "WB_DESC"))
	    strcpy (model2, value);
	  if (!strcmp (name, "TIME"))
	    timestamp = atoi(value);
	  if (!strcmp (name, "EXPTIME"))
	    shutter = atoi(value) / 1000000.0;
	  if (!strcmp (name, "APERTURE"))
	    aperture = atof(value);
	  if (!strcmp (name, "FLENGTH"))
	    focal_len = atof(value);
#ifdef LIBRAW_LIBRARY_BUILD
	  if (!strcmp (name, "FLEQ35MM"))
            imgdata.lens.makernotes.FocalLengthIn35mmFormat = atof(value);
          if (!strcmp (name, "LENSARANGE"))
            {
              char *sp;
              imgdata.lens.makernotes.MaxAp4CurFocal = imgdata.lens.makernotes.MinAp4CurFocal = atof(value);
              sp = strrchr (value, ' ');
              if (sp)
                {
                  imgdata.lens.makernotes.MinAp4CurFocal = atof(sp);
                  if (imgdata.lens.makernotes.MaxAp4CurFocal > imgdata.lens.makernotes.MinAp4CurFocal)
                    my_swap (float, imgdata.lens.makernotes.MaxAp4CurFocal, imgdata.lens.makernotes.MinAp4CurFocal);
                }
            }
          if (!strcmp (name, "LENSFRANGE"))
            {
              char *sp;
              imgdata.lens.makernotes.MinFocal = imgdata.lens.makernotes.MaxFocal = atof(value);
              sp = strrchr (value, ' ');
              if (sp)
                {
                  imgdata.lens.makernotes.MaxFocal = atof(sp);
                  if ((imgdata.lens.makernotes.MaxFocal + 0.17f) < imgdata.lens.makernotes.MinFocal)
                    my_swap (float, imgdata.lens.makernotes.MaxFocal, imgdata.lens.makernotes.MinFocal);
                }
            }
          if (!strcmp (name, "LENSMODEL"))
            {
              imgdata.lens.makernotes.LensID = atoi(value);
              if (imgdata.lens.makernotes.LensID)
                imgdata.lens.makernotes.LensMount = Sigma_X3F;
            }
        }
#endif
    }
#ifdef LOCALTIME
	timestamp = mktime (gmtime (&timestamp));
#endif
    }
    fseek (ifp, save, SEEK_SET);
  }

Project: LibRaw
File: dcraw.c

void CLASS process_Sony_0x9050 (uchar * buf, unsigned id)
{
  ushort lid;

  if ((imgdata.lens.makernotes.CameraMount != LIBRAW_MOUNT_Sony_E) &&
      (imgdata.lens.makernotes.CameraMount != LIBRAW_MOUNT_FixedLens))
    {
      if (buf[0])
        imgdata.lens.makernotes.MaxAp4CurFocal =
          my_roundf(powf64(2.0f, ((float)SonySubstitution[buf[0]] / 8.0 - 1.06f) / 2.0f)*10.0f) / 10.0f;

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

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

  if (imgdata.lens.makernotes.CameraMount == LIBRAW_MOUNT_Sony_E)
    {
      parseSonyLensType2 (SonySubstitution[buf[0x0108]],		// LensType2 - Sony lens ids
                          SonySubstitution[buf[0x0107]]);
    }

  if ((imgdata.lens.makernotes.LensID == -1) &&
      (imgdata.lens.makernotes.CameraMount == LIBRAW_MOUNT_Minolta_A) &&
      (buf[0x010a] | buf[0x0109]))
    {
      imgdata.lens.makernotes.LensID =		 // LensType - Minolta/Sony lens ids
        SonySubstitution[buf[0x010a]] << 8 |
        SonySubstitution[buf[0x0109]];
      if ((imgdata.lens.makernotes.LensID > 61184) &&
          (imgdata.lens.makernotes.LensID < 65535))
        {
          imgdata.lens.makernotes.LensID -= 61184;
          imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_Canon_EF;
        }
    }

  if ((id >= 286) && (id <= 293))
    // "SLT-A65", "SLT-A77", "NEX-7", "NEX-VG20E",
    // "SLT-A37", "SLT-A57", "NEX-F3", "Lunar"
    parseSonyLensFeatures (SonySubstitution[buf[0x115]],
                           SonySubstitution[buf[0x116]]);
  else if (imgdata.lens.makernotes.CameraMount != LIBRAW_MOUNT_FixedLens)
    parseSonyLensFeatures (SonySubstitution[buf[0x116]],
                           SonySubstitution[buf[0x117]]);
  return;
}

Project: LibRaw
File: dcraw.c

void CLASS apply_tiff()
{
  int max_samp=0, raw=-1, thm=-1, i;
  struct jhead jh;

  thumb_misc = 16;
  if (thumb_offset) {
    fseek (ifp, thumb_offset, SEEK_SET);
    if (ljpeg_start (&jh, 1)) {
      if((unsigned)jh.bits<17 && (unsigned)jh.wide < 0x10000 && (unsigned)jh.high < 0x10000)
        {
          thumb_misc   = jh.bits;
          thumb_width  = jh.wide;
          thumb_height = jh.high;
        }
    }
  }
  for (i=0; i < tiff_nifds; i++) {
    if (max_samp < tiff_ifd[i].samples)
	max_samp = tiff_ifd[i].samples;
    if (max_samp > 3) max_samp = 3;
    if ((tiff_ifd[i].comp != 6 || tiff_ifd[i].samples != 3) &&
        unsigned(tiff_ifd[i].t_width | tiff_ifd[i].t_height) < 0x10000 &&
        (unsigned)tiff_ifd[i].bps < 33 && (unsigned)tiff_ifd[i].samples < 13 &&
	tiff_ifd[i].t_width*tiff_ifd[i].t_height > raw_width*raw_height) {
      raw_width     = tiff_ifd[i].t_width;
      raw_height    = tiff_ifd[i].t_height;
      tiff_bps      = tiff_ifd[i].bps;
      tiff_compress = tiff_ifd[i].comp;
      data_offset   = tiff_ifd[i].offset;
      tiff_flip     = tiff_ifd[i].t_flip;
      tiff_samples  = tiff_ifd[i].samples;
      tile_width    = tiff_ifd[i].t_tile_width;
      tile_length   = tiff_ifd[i].t_tile_length;
      raw = i;
    }
  }
  if (!tile_width ) tile_width  = INT_MAX;
  if (!tile_length) tile_length = INT_MAX;
  for (i=tiff_nifds; i--; )
    if (tiff_ifd[i].t_flip) tiff_flip = tiff_ifd[i].t_flip;
  if (raw >= 0 && !load_raw)
    switch (tiff_compress) {
      case 32767:
	if (tiff_ifd[raw].bytes == raw_width*raw_height) {
	  tiff_bps = 12;
	  load_raw = &CLASS sony_arw2_load_raw;			break;
	}
	if (tiff_ifd[raw].bytes*8 != raw_width*raw_height*tiff_bps) {
	  raw_height += 8;
	  load_raw = &CLASS sony_arw_load_raw;			break;
	}
	load_flags = 79;
      case 32769:
	load_flags++;
      case 32770:
      case 32773: goto slr;
      case 0:  case 1:
#ifdef LIBRAW_LIBRARY_BUILD
        if(!strncasecmp(make,"Nikon",5) && !strncmp(software,"Nikon Scan",10))
          {
            load_raw = &CLASS nikon_coolscan_load_raw;
            raw_color = 1;
            filters = 0;
            break;
          }
#endif
	if (!strncmp(make,"OLYMPUS",7) &&
		tiff_ifd[raw].bytes*2 == raw_width*raw_height*3)
	  load_flags = 24;
	if (tiff_ifd[raw].bytes*5 == raw_width*raw_height*8) {
	  load_flags = 81;
	  tiff_bps = 12;
	} slr:
	switch (tiff_bps) {
	  case  8: load_raw = &CLASS eight_bit_load_raw;	break;
	  case 12: if (tiff_ifd[raw].phint == 2)
		     load_flags = 6;
		   load_raw = &CLASS packed_load_raw;		break;
	  case 14: load_flags = 0;
	  case 16: load_raw = &CLASS unpacked_load_raw;
		   if (!strncmp(make,"OLYMPUS",7) &&
			tiff_ifd[raw].bytes*7 > raw_width*raw_height)
		     load_raw = &CLASS olympus_load_raw;
	}
	break;
      case 6:  case 7:  case 99:
	load_raw = &CLASS lossless_jpeg_load_raw;		break;
      case 262:
	load_raw = &CLASS kodak_262_load_raw;			break;
      case 34713:
	if ((raw_width+9)/10*16*raw_height == tiff_ifd[raw].bytes) {
	  load_raw = &CLASS packed_load_raw;
	  load_flags = 1;
	} else if (raw_width*raw_height*3 == tiff_ifd[raw].bytes*2) {
	  load_raw = &CLASS packed_load_raw;
	  if (model[0] == 'N') load_flags = 80;
	} else if (raw_width*raw_height*3 == tiff_ifd[raw].bytes) {
	  load_raw = &CLASS nikon_yuv_load_raw;
	  gamma_curve (1/2.4, 12.92, 1, 4095);
	  memset (cblack, 0, sizeof cblack);
	  filters = 0;
	} else if (raw_width*raw_height*2 == tiff_ifd[raw].bytes) {
	  load_raw = &CLASS unpacked_load_raw;
	  load_flags = 4;
	  order = 0x4d4d;
	} else
#ifdef LIBRAW_LIBRARY_BUILD
          if(raw_width*raw_height*3 == tiff_ifd[raw].bytes*2)
            {
              load_raw = &CLASS packed_load_raw;
              load_flags=80;
            }
          else
#endif
            load_raw = &CLASS nikon_load_raw;			break;
      case 65535:
	load_raw = &CLASS pentax_load_raw;			break;
      case 65000:
	switch (tiff_ifd[raw].phint) {
	  case 2: load_raw = &CLASS kodak_rgb_load_raw;   filters = 0;  break;
	  case 6: load_raw = &CLASS kodak_ycbcr_load_raw; filters = 0;  break;
	  case 32803: load_raw = &CLASS kodak_65000_load_raw;
	}
      case 32867: case 34892: break;
      default: is_raw = 0;
    }
  if (!dng_version)
    if ( ((tiff_samples == 3 && tiff_ifd[raw].bytes && tiff_bps != 14 &&
	  (tiff_compress & -16) != 32768)
          || (tiff_bps == 8 && !strcasestr(make,"Kodak") &&
	  !strstr(model2,"DEBUG RAW")))
         && strncmp(software,"Nikon Scan",10))
      is_raw = 0;
  for (i=0; i < tiff_nifds; i++)
    if (i != raw && tiff_ifd[i].samples == max_samp &&
        tiff_ifd[i].bps>0 && tiff_ifd[i].bps < 33 &&
        unsigned(tiff_ifd[i].t_width | tiff_ifd[i].t_height) < 0x10000 &&
	tiff_ifd[i].t_width * tiff_ifd[i].t_height / (SQR(tiff_ifd[i].bps)+1) >
	      thumb_width *       thumb_height / (SQR(thumb_misc)+1)
	&& tiff_ifd[i].comp != 34892) {
      thumb_width  = tiff_ifd[i].t_width;
      thumb_height = tiff_ifd[i].t_height;
      thumb_offset = tiff_ifd[i].offset;
      thumb_length = tiff_ifd[i].bytes;
      thumb_misc   = tiff_ifd[i].bps;
      thm = i;
    }
  if (thm >= 0) {
    thumb_misc |= tiff_ifd[thm].samples << 5;
    switch (tiff_ifd[thm].comp) {
      case 0:
	write_thumb = &CLASS layer_thumb;
	break;
      case 1:
	if (tiff_ifd[thm].bps <= 8)
	  write_thumb = &CLASS ppm_thumb;
	else if (!strncmp(make,"Imacon",6))
	  write_thumb = &CLASS ppm16_thumb;
	else
	  thumb_load_raw = &CLASS kodak_thumb_load_raw;
	break;
      case 65000:
	thumb_load_raw = tiff_ifd[thm].phint == 6 ?
		&CLASS kodak_ycbcr_load_raw : &CLASS kodak_rgb_load_raw;
    }
  }
}

Project: LibRaw
File: dcraw.c

void CLASS parse_ciff (int offset, int length, int depth)
{
  int tboff, nrecs, c, type, len, save, wbi=-1;
  ushort key[] = { 0x410, 0x45f3 };

  fseek (ifp, offset+length-4, SEEK_SET);
  tboff = get4() + offset;
  fseek (ifp, tboff, SEEK_SET);
  nrecs = get2();
  if ((nrecs | depth) > 127) return;
  while (nrecs--) {
    type = get2();
    len  = get4();
    save = ftell(ifp) + 4;
    fseek (ifp, offset+get4(), SEEK_SET);
    if ((((type >> 8) + 8) | 8) == 0x38) {
      parse_ciff (ftell(ifp), len, depth+1); /* Parse a sub-table */
    }
    if (type == 0x0810)
      fread (artist, 64, 1, ifp);
    if (type == 0x080a) {
      fread (make, 64, 1, ifp);
      fseek (ifp, strlen(make) - 63, SEEK_CUR);
      fread (model, 64, 1, ifp);
    }
    if (type == 0x1810) {
      width = get4();
      height = get4();
      pixel_aspect = int_to_float(get4());
      flip = get4();
    }
    if (type == 0x1835)			/* Get the decoder table */
      tiff_compress = get4();
    if (type == 0x2007) {
      thumb_offset = ftell(ifp);
      thumb_length = len;
    }
    if (type == 0x1818) {
      shutter = powf64(2.0f, -int_to_float((get4(),get4())));
      aperture = powf64(2.0f, int_to_float(get4())/2);
#ifdef LIBRAW_LIBRARY_BUILD
			imgdata.lens.makernotes.CurAp = aperture;
#endif
    }
    if (type == 0x102a) {
			//      iso_speed = pow (2.0, (get4(),get2())/32.0 - 4) * 50;
      iso_speed = powf64(2.0f, ((get2(),get2()) + get2())/32.0f - 5.0f) * 100.0f;
#ifdef LIBRAW_LIBRARY_BUILD
      aperture  = _CanonConvertAperture((get2(),get2()));
      imgdata.lens.makernotes.CurAp = aperture;
#else
      aperture  = powf64(2.0, (get2(),(short)get2())/64.0);
#endif
      shutter   = powf64(2.0,-((short)get2())/32.0);
      wbi = (get2(),get2());
      if (wbi > 17) wbi = 0;
      fseek (ifp, 32, SEEK_CUR);
      if (shutter > 1e6) shutter = get2()/10.0;
    }
    if (type == 0x102c) {
      if (get2() > 512) {		/* Pro90, G1 */
	fseek (ifp, 118, SEEK_CUR);
	FORC4 cam_mul[c ^ 2] = get2();
      } else {				/* G2, S30, S40 */
	fseek (ifp, 98, SEEK_CUR);
	FORC4 cam_mul[c ^ (c >> 1) ^ 1] = get2();
      }
    }
#ifdef LIBRAW_LIBRARY_BUILD
    if (type == 0x102d) {
        fseek(ifp, 44, SEEK_CUR);
        imgdata.lens.makernotes.LensID = get2();
        imgdata.lens.makernotes.MaxFocal = get2();
        imgdata.lens.makernotes.MinFocal = get2();
        imgdata.lens.makernotes.CanonFocalUnits = get2();
        if (imgdata.lens.makernotes.CanonFocalUnits != 1)
          {
            imgdata.lens.makernotes.MaxFocal /= (float)imgdata.lens.makernotes.CanonFocalUnits;
            imgdata.lens.makernotes.MinFocal /= (float)imgdata.lens.makernotes.CanonFocalUnits;
          }
        imgdata.lens.makernotes.MaxAp = _CanonConvertAperture(get2());
        imgdata.lens.makernotes.MinAp = _CanonConvertAperture(get2());
    }
#endif
    if (type == 0x0032) {
      if (len == 768) {			/* EOS D30 */
	fseek (ifp, 72, SEEK_CUR);
	FORC4 cam_mul[c ^ (c >> 1)] = 1024.0 / get2();
	if (!wbi) cam_mul[0] = -1;	/* use my auto white balance */
      } else if (!cam_mul[0]) {
	if (get2() == key[0])		/* Pro1, G6, S60, S70 */
	  c = (strstr(model,"Pro1") ?
	      "012346000000000000":"01345:000000006008")[wbi]-'0'+ 2;
	else {				/* G3, G5, S45, S50 */
	  c = "023457000000006000"[wbi]-'0';
	  key[0] = key[1] = 0;
	}
	fseek (ifp, 78 + c*8, SEEK_CUR);
	FORC4 cam_mul[c ^ (c >> 1) ^ 1] = get2() ^ key[c & 1];
	if (!wbi) cam_mul[0] = -1;
      }
    }
    if (type == 0x10a9) {		/* D60, 10D, 300D, and clones */
      if (len > 66) wbi = "0134567028"[wbi]-'0';
      fseek (ifp, 2 + wbi*8, SEEK_CUR);
      FORC4 cam_mul[c ^ (c >> 1)] = get2();
    }
    if (type == 0x1030 && (0x18040 >> wbi & 1))
      ciff_block_1030();		/* all that don't have 0x10a9 */
    if (type == 0x1031) {
      raw_width = (get2(),get2());
      raw_height = get2();
    }
    if (type == 0x501c) {
      iso_speed = len & 0xffff;
    }
    if (type == 0x5029) {
#ifdef LIBRAW_LIBRARY_BUILD
      imgdata.lens.makernotes.CurFocal  = len >> 16;
      imgdata.lens.makernotes.FocalType = len & 0xffff;
      if (imgdata.lens.makernotes.FocalType == 2) {
        imgdata.lens.makernotes.CanonFocalUnits = 32;
        imgdata.lens.makernotes.CurFocal /= (float)imgdata.lens.makernotes.CanonFocalUnits;
      }
      focal_len = imgdata.lens.makernotes.CurFocal;
#else
      focal_len = len >> 16;
      if ((len & 0xffff) == 2) focal_len /= 32;
#endif
    }
    if (type == 0x5813) flash_used = int_to_float(len);
    if (type == 0x5814) canon_ev   = int_to_float(len);
    if (type == 0x5817) shot_order = len;
    if (type == 0x5834)
		{
			unique_id  = len;
#ifdef LIBRAW_LIBRARY_BUILD
			setCanonBodyFeatures(unique_id);
#endif
		}
    if (type == 0x580e) timestamp  = len;
    if (type == 0x180e) timestamp  = get4();
#ifdef LOCALTIME
    if ((type | 0x4000) == 0x580e)
      timestamp = mktime (gmtime (&timestamp));
#endif
    fseek (ifp, save, SEEK_SET);
  }
}

Project: LibRaw
File: libraw_cxx.cpp

int LibRaw::open_datastream(LibRaw_abstract_datastream *stream)
{

  if(!stream)
    return ENOENT;
  if(!stream->valid())
    return LIBRAW_IO_ERROR;
  recycle();

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

    identify();

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

	// S3Pro DNG patch
	if(imgdata.idata.dng_version && !strcmp(imgdata.idata.make,"Fujifilm") && !strcmp(imgdata.idata.model,"S3Pro") && imgdata.sizes.raw_width == 4288 )
	{
		imgdata.sizes.left_margin++;
		imgdata.sizes.width--;
	}
	if(imgdata.idata.dng_version && !strcmp(imgdata.idata.make,"Fujifilm") && !strcmp(imgdata.idata.model,"S5Pro") && imgdata.sizes.raw_width == 4288 )
	{
		imgdata.sizes.left_margin++;
		imgdata.sizes.width--;
	}
	if(!imgdata.idata.dng_version && !strcmp(imgdata.idata.make,"Fujifilm") 
           && (!strncmp(imgdata.idata.model,"S20Pro",6) || !strncmp(imgdata.idata.model,"F700",4))
           )
	{
          imgdata.sizes.raw_width/=2;
          load_raw= &LibRaw::unpacked_load_raw_fuji_f700s20;
	}
	if(load_raw == &LibRaw::packed_load_raw && !strcasecmp(imgdata.idata.make,"Nikon")
		 && !libraw_internal_data.unpacker_data.load_flags
		 && (!strncasecmp(imgdata.idata.model,"D810",4) || !strcasecmp(imgdata.idata.model,"D4S"))
		 && libraw_internal_data.unpacker_data.data_size*2 == imgdata.sizes.raw_height*imgdata.sizes.raw_width*3)
	{
		libraw_internal_data.unpacker_data.load_flags = 80;
	}
	// Adjust BL for Sony A900/A850
    if(load_raw == &LibRaw::packed_load_raw && !strcasecmp(imgdata.idata.make,"Sony")) // 12 bit sony, but metadata may be for 14-bit range
      {
        if(C.maximum>4095)
          C.maximum = 4095;
        if(C.black > 256 || C.cblack[0] > 256)
          {
            C.black /=4;
            for(int c=0; c< 4; c++)
              C.cblack[c]/=4;
            for(int c=0; c< C.cblack[4]*C.cblack[5];c++)
              C.cblack[6+c]/=4;
          }
      }
    if(  load_raw == &LibRaw::nikon_yuv_load_raw  ) // Is it Nikon sRAW?
      {
           load_raw= &LibRaw::nikon_load_sraw;
           C.black =0;
           memset(C.cblack,0,sizeof(C.cblack));
           imgdata.idata.filters = 0;
           libraw_internal_data.unpacker_data.tiff_samples=3;
           imgdata.idata.colors = 3;
           double beta_1 = -5.79342238397656E-02;
           double beta_2 = 3.28163551282665;
           double beta_3 = -8.43136004842678;
           double beta_4 = 1.03533181861023E+01;
           for(int i=0; i<=3072;i++)
           {
               double x = (double)i/3072.;
               double y = (1.-exp(-beta_1*x-beta_2*x*x-beta_3*x*x*x-beta_4*x*x*x*x));
               if(y<0.)y=0.;
               imgdata.color.curve[i] = (y*16383.);
           }
           for(int i=0;i<3;i++)
             for(int j=0;j<4;j++)
               imgdata.color.rgb_cam[i][j]=float(i==j);
      }
    // Adjust BL for Nikon 12bit
    if((
        load_raw == &LibRaw::nikon_load_raw
        || load_raw == &LibRaw::packed_load_raw)
       && !strcasecmp(imgdata.idata.make,"Nikon")
       && strncmp(imgdata.idata.model,"COOLPIX",7)
//	   && strncmp(imgdata.idata.model,"1 ",2)
       && libraw_internal_data.unpacker_data.tiff_bps == 12)
      {
        C.maximum = 4095;
        C.black /=4;
        for(int c=0; c< 4; c++)
          C.cblack[c]/=4;
        for(int c=0; c< C.cblack[4]*C.cblack[5];c++)
          C.cblack[6+c]/=4;
      }

	// Adjust BL for Panasonic
    if(load_raw == &LibRaw::panasonic_load_raw && (!strcasecmp(imgdata.idata.make,"Panasonic") || !strcasecmp(imgdata.idata.make,"Leica"))
       &&  ID.pana_black[0] && ID.pana_black[1] && ID.pana_black[2])
      {
        C.black=0;
        C.cblack[0] = ID.pana_black[0]+ID.pana_black[3];
        C.cblack[1] = C.cblack[3] = ID.pana_black[1]+ID.pana_black[3];
        C.cblack[2] = ID.pana_black[2]+ID.pana_black[3];
        int i = C.cblack[3];
        for(int c=0; c<3; c++) if(i>C.cblack[c]) i = C.cblack[c];
        for(int c=0; c< 4; c++) C.cblack[c]-=i;
        C.black = i;
      }

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

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

  if(P1.raw_count < 1)
    return LIBRAW_FILE_UNSUPPORTED;


  write_fun = &LibRaw::write_ppm_tiff;

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

  IO.shrink = P1.filters && (O.half_size ||
                             ((O.threshold || O.aber[0] != 1 || O.aber[2] != 1) ));

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

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

  SET_PROC_FLAG(LIBRAW_PROGRESS_SIZE_ADJUST);


  return LIBRAW_SUCCESS;
}