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

Project: LibRaw
File: dcraw.c

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

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

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

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

Project: LibRaw
File: libraw_cxx.cpp

void LibRaw::copy_bayer(unsigned short cblack[4],unsigned short *dmaxp)
{
  // Both cropped and uncropped
  int row;

#if defined(LIBRAW_USE_OPENMP)
#pragma omp parallel for default(shared)
#endif
  for (row=0; row < S.height; row++)
    {
      int col;
      unsigned short ldmax = 0;
      for (col=0; col < S.width; col++)
        {
          unsigned short val = imgdata.rawdata.raw_image[(row+S.top_margin)*S.raw_pitch/2+(col+S.left_margin)];
          int cc = fcol(row,col);
          if(val>cblack[cc])
            {
              val-=cblack[cc];
              if(val>ldmax)ldmax = val;
            }
          else
            val = 0;
          imgdata.image[((row) >> IO.shrink)*S.iwidth + ((col) >> IO.shrink)][cc] = val; 
        }
#if defined(LIBRAW_USE_OPENMP)
#pragma omp critical(dataupdate)
#endif
      {
        if(*dmaxp < ldmax)
          *dmaxp = ldmax;
      }
    }
}

Project: LibRaw
File: libraw_cxx.cpp

int LibRaw::raw2image_ex(int do_subtract_black)
{

  CHECK_ORDER_LOW(LIBRAW_PROGRESS_LOAD_RAW);

  try {
    raw2image_start();

    // Compressed P1 files with bl data!
    if (is_phaseone_compressed())
      {
        phase_one_allocate_tempbuffer();
        phase_one_subtract_black((ushort*)imgdata.rawdata.raw_alloc,imgdata.rawdata.raw_image);
        phase_one_correct();
      }

    // process cropping
    int do_crop = 0;
    unsigned save_width = S.width;
    if (~O.cropbox[2] && ~O.cropbox[3] 
#ifdef LIBRAW_DEMOSAIC_PACK_GPL2
        && load_raw != &LibRaw::foveon_sd_load_raw
#endif
        ) // Foveon SD to be cropped later
      {
        int crop[4],c,filt;
        for(int c=0;c<4;c++) 
          {
            crop[c] = O.cropbox[c];
            if(crop[c]<0)
              crop[c]=0;
          }
        
        if(IO.fuji_width && imgdata.idata.filters >= 1000) 
          {
            crop[0] = (crop[0]/4)*4;
            crop[1] = (crop[1]/4)*4;
            if(!libraw_internal_data.unpacker_data.fuji_layout)
              {
                crop[2]*=sqrt(2.0);
                crop[3]/=sqrt(2.0);
              }
            crop[2] = (crop[2]/4+1)*4;
            crop[3] = (crop[3]/4+1)*4;
          }
        else if (imgdata.idata.filters == 1)
          {
            crop[0] = (crop[0]/16)*16;
            crop[1] = (crop[1]/16)*16;
          }
        else if(imgdata.idata.filters == LIBRAW_XTRANS)
          {
            crop[0] = (crop[0]/6)*6;
            crop[1] = (crop[1]/6)*6;
          }
        do_crop = 1;
        
        crop[2] = MIN (crop[2], (signed) S.width-crop[0]);
        crop[3] = MIN (crop[3], (signed) S.height-crop[1]);
        if (crop[2] <= 0 || crop[3] <= 0)
          throw LIBRAW_EXCEPTION_BAD_CROP;
        
        // adjust sizes!
        S.left_margin+=crop[0];
        S.top_margin+=crop[1];
        S.width=crop[2];
        S.height=crop[3];
        
        S.iheight = (S.height + IO.shrink) >> IO.shrink;
        S.iwidth  = (S.width  + IO.shrink) >> IO.shrink;
        if(!IO.fuji_width && imgdata.idata.filters && imgdata.idata.filters >= 1000)
          {
            for (filt=c=0; c < 16; c++)
              filt |= FC((c >> 1)+(crop[1]),
                         (c &  1)+(crop[0])) << c*2;
            imgdata.idata.filters = filt;
          }
      }

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

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

    libraw_decoder_info_t decoder_info;
    get_decoder_info(&decoder_info);

    // Adjust black levels
    unsigned short cblack[4]={0,0,0,0};
    unsigned short dmax = 0;
    if(do_subtract_black)
      {
        adjust_bl();
        for(int i=0; i< 4; i++)
          cblack[i] = (unsigned short)C.cblack[i];
      }
        
    // Move saved bitmap to imgdata.image
    if(imgdata.idata.filters || P1.colors == 1)
      {
        if (IO.fuji_width) 
          {
            if(do_crop)
              {
                IO.fuji_width = S.width >> !libraw_internal_data.unpacker_data.fuji_layout;
                int IO_fwidth = (S.height >> libraw_internal_data.unpacker_data.fuji_layout) + IO.fuji_width;
                int IO_fheight = IO_fwidth - 1;
                
                int row,col;
                for(row=0;row<S.height;row++)
                  {
                    for(col=0;col<S.width;col++)
                      {
                        int r,c;
                        if (libraw_internal_data.unpacker_data.fuji_layout) {
                          r = IO.fuji_width - 1 - col + (row >> 1);
                          c = col + ((row+1) >> 1);
                        } else {
                          r = IO.fuji_width - 1 + row - (col >> 1);
                          c = row + ((col+1) >> 1);
                        }
                        
                        unsigned short val = imgdata.rawdata.raw_image[(row+S.top_margin)*S.raw_pitch/2
                                                            +(col+S.left_margin)];
                        int cc = FCF(row,col);
                        if(val > cblack[cc])
                          {
                            val-=cblack[cc];
                            if(dmax < val) dmax = val;
                          }
                        else
                          val = 0;
                        imgdata.image[((r) >> IO.shrink)*alloc_width + ((c) >> IO.shrink)][cc] = val;
                      }
                  }
                S.height = IO_fheight;
                S.width = IO_fwidth;
                S.iheight = (S.height + IO.shrink) >> IO.shrink;
                S.iwidth  = (S.width  + IO.shrink) >> IO.shrink;
                S.raw_height -= 2*S.top_margin;
              }
            else
              {
                copy_fuji_uncropped(cblack,&dmax);
              }
          } // end Fuji
        else 
          {
            copy_bayer(cblack,&dmax);
          }
      }
    else //if(decoder_info.decoder_flags & LIBRAW_DECODER_LEGACY)
      {
        if(imgdata.rawdata.color4_image)
          {
            if(S.raw_pitch != S.width*8)
              {
                for(int row = 0; row < S.height; row++)
                  memmove(&imgdata.image[row*S.width],
                          &imgdata.rawdata.color4_image[(row+S.top_margin)*S.raw_pitch/8+S.left_margin],
                          S.width*sizeof(*imgdata.image));
              }
            else
              {
                // legacy is always 4channel and not shrinked!
                memmove(imgdata.image,imgdata.rawdata.color4_image,S.width*S.height*sizeof(*imgdata.image));
              }
          }
        else if(imgdata.rawdata.color3_image)
          {
            unsigned char *c3image = (unsigned char*) imgdata.rawdata.color3_image;
            for(int row = 0; row < S.height; row++)
              {
                ushort (*srcrow)[3] = (ushort (*)[3]) &c3image[(row+S.top_margin)*S.raw_pitch];
                ushort (*dstrow)[4] = (ushort (*)[4]) &imgdata.image[row*S.width];
                for(int col=0; col < S.width; col++)
                  {
                    for(int c=0; c< 3; c++)
                      dstrow[col][c] = srcrow[S.left_margin+col][c];
                    dstrow[col][3]=0;
                  }
              }
          }
        else
          {
            // legacy decoder, but no data?
            throw LIBRAW_EXCEPTION_DECODE_RAW;
          }
      }

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

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

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

Project: LibRaw
File: dcraw.c

void CLASS setOlympusBodyFeatures (unsigned long id)
{
  if ((id == 0x4434303430) ||
      (id == 0x4434303431) ||
      ((id >= 0x5330303030) && (id <= 0x5330303939)))
    {
      imgdata.lens.makernotes.CameraFormat = FT;
      imgdata.lens.makernotes.CameraMount = FT;
    }
  else
    {
      imgdata.lens.makernotes.LensMount = FixedLens;
      imgdata.lens.makernotes.CameraMount = FixedLens;
    }

  if ((id == 0x4434303430) ||
      (id == 0x4434303431) ||
      ((id >= 0x5330303033) && (id <= 0x5330303138)) ||
      (id == 0x5330303233) ||
      (id == 0x5330303239) ||
      (id == 0x5330303330) ||
      (id == 0x5330303333))
    {
      imgdata.lens.makernotes.CameraMount = FT;
    }
  else if (imgdata.lens.makernotes.CameraMount != FixedLens)
    {
      imgdata.lens.makernotes.CameraMount = mFT;
    }
  return;
}

Project: LibRaw
File: dcraw.c

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

  kodak = !strncmp(make,"EASTMAN",7) && tiff_nifds < 3;
  entries = get2();
  if(!strcmp(make,"Hasselblad") && (tiff_nifds > 3) && (entries > 512)) return;

//  printf("\n*** in parse_exif, make: =%s= model: =%s=", make, model);

  while (entries--) {
    tiff_get (base, &tag, &type, &len, &save);

		//    printf("\n\ttag: %x", tag);

#ifdef LIBRAW_LIBRARY_BUILD
    if(callbacks.exif_cb)
      {
        int savepos = ftell(ifp);
        callbacks.exif_cb(callbacks.exifparser_data,tag,type,len,order,ifp);
        fseek(ifp,savepos,SEEK_SET);
      }
#endif
    switch (tag) {
#ifdef LIBRAW_LIBRARY_BUILD
    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.dng.MinFocal = getreal(type);
      imgdata.lens.dng.MaxFocal = getreal(type);
      imgdata.lens.dng.MaxAp4MinFocal = getreal(type);
      imgdata.lens.dng.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.LensMake)), 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;
#endif
      case 33434:  shutter = getreal(type);		break;
      case 33437:  aperture = getreal(type);		break;
      case 34855:  iso_speed = get2();			break;
      case 34866:
        if (iso_speed == 0xffff && (!strcasecmp(make, "SONY") || !strcasecmp(make, "CANON")))
          iso_speed = getreal(type);
        break;
      case 36867:
      case 36868:  get_timestamp(0);			break;
      case 37377:  if ((expo = -getreal(type)) < 128 && shutter == 0.)
          shutter = powf64(2.0, expo);		break;
      case 37378:
        if (fabs(ape = getreal(type))<256.0)
          aperture = powf64(2.0, ape/2);
        break;
      case 37385:  flash_used = getreal(type);          break;
      case 37386:  focal_len = getreal(type);		break;
      case 37500:  parse_makernote (base, 0);		break;	// tag 0x927c
      case 40962:  if (kodak) raw_width  = get4();	break;
      case 40963:  if (kodak) raw_height = get4();	break;
      case 41730:
	if (get4() == 0x20002)
	  for (exif_cfa=c=0; c < 8; c+=2)
	    exif_cfa |= fgetc(ifp) * 0x01010101 << c;
    }
    fseek (ifp, save, SEEK_SET);
  }
}

Project: LibRaw
File: unprocessed_raw.cpp

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

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

Project: LibRaw
File: libraw_cxx.cpp

LibRaw_colormatrix_type LibRaw::camera_color_type()
{
  if(C.cmatrix[0][0] <= 0.125) return LIBRAW_CMATRIX_NONE;
  if(P1.dng_version) return LIBRAW_CMATRIX_DNG;
  if(C.digitalBack_color) return LIBRAW_CMATRIX_DIGBACK;
  return LIBRAW_CMATRIX_OTHER;

}

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

//    printf ("\n*** parse_tiff_ifd tag: 0x%04x", tag);

#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;
	    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;
#ifdef LIBRAW_LIBRARY_BUILD
      case 325:				/* TileByteCount */
          tiff_ifd[ifd].tile_maxbytes = 0;
          for(int jj=0;jj<len;jj++)
              {
                  int s = get4();
                  if(s > tiff_ifd[ifd].tile_maxbytes) tiff_ifd[ifd].tile_maxbytes=s;
              }
	break;
#endif
      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 (!strcmp(make,"Hasselblad") && 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) xtrans[0][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 ((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;
	fread (cbuf, 1, len, ifp);
	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 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;
	  filters = 0x49494949;
	}
	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 */
      {
        char mbuf[64];
        unsigned short makernote_found = 0;
        unsigned 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);
            }
        }

        if (!makernote_found) fseek(ifp, start_pos, SEEK_SET);
        order = m_sorder;
      }
      // IB end
	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++)
	  mask[0][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 process_Sony_0x9050 (uchar * buf, unsigned id)
{
  ushort lid;

  if ((imgdata.lens.makernotes.CameraMount != Sony_E) &&
      (imgdata.lens.makernotes.CameraMount != FixedLens))
    {
      if (buf[0])
        imgdata.lens.makernotes.MaxAp =
          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.MinAp =
          my_roundf(powf64(2.0f, ((float)SonySubstitution[buf[1]] / 8.0 - 1.06f) / 2.0f)*10.0f) / 10.0f;
    }

  if (imgdata.lens.makernotes.CameraMount != 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 != Canon_EF))
        imgdata.lens.makernotes.LensMount =
          SonySubstitution[buf[0x105]];
      if (buf[0x106])
        imgdata.lens.makernotes.LensFormat =
          SonySubstitution[buf[0x106]];
    }

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

  if ((imgdata.lens.makernotes.LensID == -1) &&
      (imgdata.lens.makernotes.CameraMount == 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 = 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 != FixedLens)
    parseSonyLensFeatures (SonySubstitution[buf[0x116]],
                           SonySubstitution[buf[0x117]]);
  return;
}

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") && !strcmp(imgdata.idata.model,"S20Pro"))
	{
		if(imgdata.idata.raw_count>1)
			imgdata.idata.raw_count = 1;
	}

	if(load_raw == &LibRaw::packed_load_raw && !strcasecmp(imgdata.idata.make,"Nikon")
		 && !libraw_internal_data.unpacker_data.load_flags 
		 && (!strcasecmp(imgdata.idata.model,"D810") || !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_load_raw 
        || load_raw == &LibRaw::packed_load_raw)  
       && !strcasecmp(imgdata.idata.make,"Nikon")
	   && S.raw_width*S.raw_height*3 == libraw_internal_data.unpacker_data.data_size
       ) // 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;
}

Project: LibRaw
File: dcraw.c

void CLASS lossless_dng_load_raw()
{
  unsigned save, trow=0, tcol=0, jwide, jrow, jcol, row, col;
  struct jhead jh;
  ushort *rp;

  while (trow < raw_height) {
#ifdef LIBRAW_LIBRARY_BUILD
    checkCancel();
#endif
    save = ftell(ifp);
    if (tile_length < INT_MAX)
      fseek (ifp, get4(), SEEK_SET);
    if (!ljpeg_start (&jh, 0)) break;
    jwide = jh.wide;
    if (filters) jwide *= jh.clrs;
    jwide /= is_raw;
#ifdef LIBRAW_LIBRARY_BUILD
  try {
#endif
    for (row=col=jrow=0; jrow < jh.high; jrow++) {
#ifdef LIBRAW_LIBRARY_BUILD
    checkCancel();
#endif
      rp = ljpeg_row (jrow, &jh);
      for (jcol=0; jcol < jwide; jcol++) {
	adobe_copy_pixel (trow+row, tcol+col, &rp);
	if (++col >= tile_width || col >= raw_width)
	  row += 1 + (col = 0);
      }
    }
#ifdef LIBRAW_LIBRARY_BUILD
  } catch (...) {
      ljpeg_end (&jh);
      throw ;
  }
#endif
    fseek (ifp, save+4, SEEK_SET);
    if ((tcol += tile_width) >= raw_width)
      trow += tile_length + (tcol = 0);

    ljpeg_end (&jh);
  }
}

Project: LibRaw
File: dcraw.c

void CLASS scale_colors()
{
  unsigned bottom, right, size, row, col, ur, uc, i, x, y, c, sum[8];
  int val, dark, sat;
  double dsum[8], dmin, dmax;
  float scale_mul[4], fr, fc;
  ushort *img=0, *pix;

#ifdef LIBRAW_LIBRARY_BUILD
  RUN_CALLBACK(LIBRAW_PROGRESS_SCALE_COLORS,0,2);
#endif

  if (user_mul[0])
    memcpy (pre_mul, user_mul, sizeof pre_mul);
  if (use_auto_wb || (use_camera_wb && cam_mul[0] == -1)) {
    memset (dsum, 0, sizeof dsum);
    bottom = MIN (greybox[1]+greybox[3], height);
    right  = MIN (greybox[0]+greybox[2], width);
    for (row=greybox[1]; row < bottom; row += 8)
      for (col=greybox[0]; col < right; col += 8) {
	memset (sum, 0, sizeof sum);
	for (y=row; y < row+8 && y < bottom; y++)
	  for (x=col; x < col+8 && x < right; x++)
	    FORC4 {
	      if (filters) {
		c = fcol(y,x);
		val = BAYER2(y,x);
	      } else
		val = image[y*width+x][c];
	      if (val > maximum-25) goto skip_block;
	      if ((val -= cblack[c]) < 0) val = 0;
	      sum[c] += val;
	      sum[c+4]++;
	      if (filters) break;
	    }
	FORC(8) dsum[c] += sum[c];
skip_block: ;
      }
    FORC4 if (dsum[c]) pre_mul[c] = dsum[c+4] / dsum[c];
  }
  if (use_camera_wb && cam_mul[0] != -1) {
    memset (sum, 0, sizeof sum);
    for (row=0; row < 8; row++)
      for (col=0; col < 8; col++) {
	c = FC(row,col);
	if ((val = white[row][col] - cblack[c]) > 0)
	  sum[c] += val;
	sum[c+4]++;
      }
#ifdef LIBRAW_LIBRARY_BUILD
    if(load_raw == &LibRaw::nikon_load_sraw)
      {
        // Nikon sRAW: camera WB already applied:
        pre_mul[0]=pre_mul[1]=pre_mul[2]=pre_mul[3]=1.0;
			imgdata.color.wb_applied = 1;
      }
    else
#endif
    if (sum[0] && sum[1] && sum[2] && sum[3])
      FORC4 pre_mul[c] = (float) sum[c+4] / sum[c];
    else if (cam_mul[0] && cam_mul[2])
      memcpy (pre_mul, cam_mul, sizeof pre_mul);
    else
      {
#ifdef LIBRAW_LIBRARY_BUILD
            imgdata.process_warnings |= LIBRAW_WARN_BAD_CAMERA_WB;
#endif
#ifdef DCRAW_VERBOSE
            fprintf (stderr,_("%s: Cannot use camera white balance.\n"), ifname);
#endif
      }
  }
#ifdef LIBRAW_LIBRARY_BUILD
  // Nikon sRAW, daylight
  if (load_raw == &LibRaw::nikon_load_sraw
      && !use_camera_wb && !use_auto_wb
      && cam_mul[0] > 0.001f && cam_mul[1] > 0.001f && cam_mul[2] > 0.001f )
    {
      for(c=0;c<3;c++)
        pre_mul[c]/=cam_mul[c];
  }
#endif
  if (pre_mul[1] == 0) pre_mul[1] = 1;
  if (pre_mul[3] == 0) pre_mul[3] = colors < 4 ? pre_mul[1] : 1;
  dark = black;
  sat = maximum;
  if (threshold) wavelet_denoise();
  maximum -= black;
  for (dmin=DBL_MAX, dmax=c=0; c < 4; c++) {
    if (dmin > pre_mul[c])
	dmin = pre_mul[c];
    if (dmax < pre_mul[c])
	dmax = pre_mul[c];
  }
  if (!highlight) dmax = dmin;
  FORC4 scale_mul[c] = (pre_mul[c] /= dmax) * 65535.0 / maximum;
#ifdef DCRAW_VERBOSE
  if (verbose) {
    fprintf (stderr,
      _("Scaling with darkness %d, saturation %d, and\nmultipliers"), dark, sat);
    FORC4 fprintf (stderr, " %f", pre_mul[c]);
    fputc ('\n', stderr);
  }
#endif
  if (filters > 1000 && (cblack[4]+1)/2 == 1 && (cblack[5]+1)/2 == 1) {
    FORC4 cblack[FC(c/2,c%2)] +=
	cblack[6 + c/2 % cblack[4] * cblack[5] + c%2 % cblack[5]];
    cblack[4] = cblack[5] = 0;
  }
  size = iheight*iwidth;
#ifdef LIBRAW_LIBRARY_BUILD
  scale_colors_loop(scale_mul);
#else
  for (i=0; i < size*4; i++) {
    if (!(val = image[0][i])) continue;
    if (cblack[4] && cblack[5])
      val -= cblack[6 + i/4 / iwidth % cblack[4] * cblack[5] +
			i/4 % iwidth % cblack[5]];
    val -= cblack[i & 3];
    val *= scale_mul[i & 3];
    image[0][i] = CLIP(val);
  }
#endif
  if ((aber[0] != 1 || aber[2] != 1) && colors == 3) {
#ifdef DCRAW_VERBOSE
    if (verbose)
      fprintf (stderr,_("Correcting chromatic aberration...\n"));
#endif
    for (c=0; c < 4; c+=2) {
      if (aber[c] == 1) continue;
      img = (ushort *) malloc (size * sizeof *img);
      merror (img, "scale_colors()");
      for (i=0; i < size; i++)
	img[i] = image[i][c];
      for (row=0; row < iheight; row++) {
	ur = fr = (row - iheight*0.5) * aber[c] + iheight*0.5;
	if (ur > iheight-2) continue;
	fr -= ur;
	for (col=0; col < iwidth; col++) {
	  uc = fc = (col - iwidth*0.5) * aber[c] + iwidth*0.5;
	  if (uc > iwidth-2) continue;
	  fc -= uc;
	  pix = img + ur*iwidth + uc;
	  image[row*iwidth+col][c] =
	    (pix[     0]*(1-fc) + pix[       1]*fc) * (1-fr) +
	    (pix[iwidth]*(1-fc) + pix[iwidth+1]*fc) * fr;
	}
      }
      free(img);
    }
  }
#ifdef LIBRAW_LIBRARY_BUILD
  RUN_CALLBACK(LIBRAW_PROGRESS_SCALE_COLORS,1,2);
#endif
}

Project: LibRaw
File: libraw_cxx.cpp

libraw_processed_image_t * LibRaw::dcraw_make_mem_thumb(int *errcode)
{
  if(!T.thumb)
    {
      if ( !ID.toffset) 
        {
          if(errcode) *errcode= LIBRAW_NO_THUMBNAIL;
        }
      else
        {
          if(errcode) *errcode= LIBRAW_OUT_OF_ORDER_CALL;
        }
      return NULL;
    }
    
  if (T.tformat == LIBRAW_THUMBNAIL_BITMAP)
    {
      libraw_processed_image_t * ret = 
        (libraw_processed_image_t *)::malloc(sizeof(libraw_processed_image_t)+T.tlength);

      if(!ret)
        {
          if(errcode) *errcode= ENOMEM;
          return NULL;
        }

      memset(ret,0,sizeof(libraw_processed_image_t));
      ret->type   = LIBRAW_IMAGE_BITMAP;
      ret->height = T.theight;
      ret->width  = T.twidth;
      ret->colors = 3; 
      ret->bits   = 8;
      ret->data_size = T.tlength;
      memmove(ret->data,T.thumb,T.tlength);
      if(errcode) *errcode= 0;
      return ret;
    }
  else if (T.tformat == LIBRAW_THUMBNAIL_JPEG)
    {
      ushort exif[5];
      int mk_exif = 0;
      if(strcmp(T.thumb+6,"Exif")) mk_exif = 1;
            
      int dsize = T.tlength + mk_exif * (sizeof(exif)+sizeof(tiff_hdr));

      libraw_processed_image_t * ret = 
        (libraw_processed_image_t *)::malloc(sizeof(libraw_processed_image_t)+dsize);

      if(!ret)
        {
          if(errcode) *errcode= ENOMEM;
          return NULL;
        }

      memset(ret,0,sizeof(libraw_processed_image_t));

      ret->type = LIBRAW_IMAGE_JPEG;
      ret->data_size = dsize;
            
      ret->data[0] = 0xff;
      ret->data[1] = 0xd8;
      if(mk_exif)
        {
          struct tiff_hdr th;
          memcpy (exif, "\xff\xe1  Exif\0\0", 10);
          exif[1] = htons (8 + sizeof th);
          memmove(ret->data+2,exif,sizeof(exif));
          tiff_head (&th, 0);
          memmove(ret->data+(2+sizeof(exif)),&th,sizeof(th));
          memmove(ret->data+(2+sizeof(exif)+sizeof(th)),T.thumb+2,T.tlength-2);
        }
      else
        {
          memmove(ret->data+2,T.thumb+2,T.tlength-2);
        }
      if(errcode) *errcode= 0;
      return ret;
            
    }
  else
    {
      if(errcode) *errcode= LIBRAW_UNSUPPORTED_THUMBNAIL;
      return NULL;
    }
}

Project: LibRaw
File: dcraw.c

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

#ifdef LIBRAW_LIBRARY_BUILD
	char body_id[3];
	body_id[0] = 0;
#endif

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

#ifdef LIBRAW_LIBRARY_BUILD
    case 0x0102:
      fread(body_id, 1, 3, ifp);
      if ((body_id[0] == 0x4c) && (body_id[1] == 0x49)) {
        body_id[1] = body_id[2];
      }
      unique_id = (((body_id[0] & 0x3f) << 5) | (body_id[1] & 0x3f)) - 0x41;
      setPhaseOneFeatures(unique_id);
      break;
    case 0x0401:
      if (type == 4) imgdata.lens.makernotes.CurAp =  powf64(2.0f, (int_to_float(data)/2.0f));
      else imgdata.lens.makernotes.CurAp = powf64(2.0f, (getreal(type)/2.0f));
      break;
    case 0x0403:
      if (type == 4) imgdata.lens.makernotes.CurFocal =  int_to_float(data);
      else imgdata.lens.makernotes.CurFocal = getreal(type);
      break;
    case 0x0410:
      fread(imgdata.lens.makernotes.body, 1, len, ifp);
      break;
    case 0x0412:
      fread(imgdata.lens.makernotes.Lens, 1, len, ifp);
      break;
    case 0x0414:
      if (type == 4) {
      	imgdata.lens.makernotes.MaxAp4CurFocal = powf64(2.0f, (int_to_float(data)/2.0f));
      } else {
        imgdata.lens.makernotes.MaxAp4CurFocal = powf64(2.0f, (getreal(type) / 2.0f));
      }
      break;
    case 0x0415:
      if (type == 4) {
      	imgdata.lens.makernotes.MinAp4CurFocal = powf64(2.0f, (int_to_float(data)/2.0f));
      } else {
        imgdata.lens.makernotes.MinAp4CurFocal = powf64(2.0f, (getreal(type) / 2.0f));
      }
      break;
    case 0x0416:
      if (type == 4) {
        imgdata.lens.makernotes.MinFocal =  int_to_float(data);
      } else {
        imgdata.lens.makernotes.MinFocal = getreal(type);
      }
      if (imgdata.lens.makernotes.MinFocal > 1000.0f)
        {
          imgdata.lens.makernotes.MinFocal = 0.0f;
        }
      break;
    case 0x0417:
      if (type == 4) {
        imgdata.lens.makernotes.MaxFocal =  int_to_float(data);
      } else {
        imgdata.lens.makernotes.MaxFocal = getreal(type);
      }
      break;
#endif

      case 0x100:  flip = "0653"[data & 3]-'0';  break;
      case 0x106:
	for (i=0; i < 9; i++)
	  romm_cam[0][i] = getreal(11);
	romm_coeff (romm_cam);
	break;
      case 0x107:
	FORC3 cam_mul[c] = getreal(11);
	break;
      case 0x108:  raw_width     = data;	break;
      case 0x109:  raw_height    = data;	break;
      case 0x10a:  left_margin   = data;	break;
      case 0x10b:  top_margin    = data;	break;
      case 0x10c:  width         = data;	break;
      case 0x10d:  height        = data;	break;
      case 0x10e:  ph1.format    = data;	break;
      case 0x10f:  data_offset   = data+base;	break;
      case 0x110:  meta_offset   = data+base;
		   meta_length   = len;			break;
      case 0x112:  ph1.key_off   = save - 4;		break;
      case 0x210:  ph1.tag_210   = int_to_float(data);	break;
      case 0x21a:  ph1.tag_21a   = data;		break;
      case 0x21c:  strip_offset  = data+base;		break;
      case 0x21d:  ph1.t_black     = data;		break;
      case 0x222:  ph1.split_col = data;		break;
      case 0x223:  ph1.black_col = data+base;		break;
      case 0x224:  ph1.split_row = data;		break;
      case 0x225:  ph1.black_row = data+base;		break;
      case 0x301:
	model[63] = 0;
	fread (model, 1, 63, ifp);
	if ((cp = strstr(model," camera"))) *cp = 0;
    }
    fseek (ifp, save, SEEK_SET);
  }

#ifdef LIBRAW_LIBRARY_BUILD
  if (!imgdata.lens.makernotes.body[0] && !body_id[0]) {
    fseek (ifp, meta_offset, SEEK_SET);
    order = get2();
    fseek (ifp, 6, SEEK_CUR);
    fseek (ifp, meta_offset+get4(), SEEK_SET);
    entries = get4();  get4();
    while (entries--) {
      tag  = get4();
      len  = get4();
      data = get4();
      save = ftell(ifp);
      fseek (ifp, meta_offset+data, SEEK_SET);
      if (tag == 0x0407) {
        fread(body_id, 1, 3, ifp);
        if ((body_id[0] == 0x4c) && (body_id[1] == 0x49)) {
          body_id[1] = body_id[2];
        }
        unique_id = (((body_id[0] & 0x3f) << 5) | (body_id[1] & 0x3f)) - 0x41;
        setPhaseOneFeatures(unique_id);
      }
      fseek (ifp, save, SEEK_SET);
    }
  }
#endif

  load_raw = ph1.format < 3 ?
	&CLASS phase_one_load_raw : &CLASS phase_one_load_raw_c;
  maximum = 0xffff;
  strcpy (make, "Phase One");
  if (model[0]) return;
  switch (raw_height) {
    case 2060: strcpy (model,"LightPhase");	break;
    case 2682: strcpy (model,"H 10");		break;
    case 4128: strcpy (model,"H 20");		break;
    case 5488: strcpy (model,"H 25");		break;
  }
}

Project: LibRaw
File: libraw_cxx.cpp

void LibRaw::copy_fuji_uncropped(unsigned short cblack[4],unsigned short *dmaxp)
{
  int row;
#if defined(LIBRAW_USE_OPENMP)
#pragma omp parallel for default(shared)
#endif
  for (row=0; row < S.raw_height-S.top_margin*2; row++) 
    {
      int col;
      unsigned short ldmax = 0;
      for (col=0; col < IO.fuji_width << !libraw_internal_data.unpacker_data.fuji_layout; col++) 
        {
          unsigned r,c;
          if (libraw_internal_data.unpacker_data.fuji_layout) {
            r = IO.fuji_width - 1 - col + (row >> 1);
            c = col + ((row+1) >> 1);
          } else {
            r = IO.fuji_width - 1 + row - (col >> 1);
            c = row + ((col+1) >> 1);
          }
          if (r < S.height && c < S.width)
            {
              unsigned short val = imgdata.rawdata.raw_image[(row+S.top_margin)*S.raw_pitch/2+(col+S.left_margin)];
              int cc = FC(r,c);
              if(val>cblack[cc])
                {
                  val-=cblack[cc];
                  if(val>ldmax)ldmax = val;
                }
              else
                val = 0;
              imgdata.image[((r)>>IO.shrink)*S.iwidth+((c)>>IO.shrink)][cc] = val; 
            }
        }
#if defined(LIBRAW_USE_OPENMP)
#pragma omp critical(dataupdate)
#endif
      {
        if(*dmaxp < ldmax)
          *dmaxp = ldmax;
      }
    }
}

Project: LibRaw
File: libraw_cxx.cpp

void LibRaw::adjust_bl()
{
  int clear_repeat=0;
   if (O.user_black >= 0) 
     {
       C.black = O.user_black;
       clear_repeat = 1;
     }
   for(int i=0; i<4; i++)
     if(O.user_cblack[i]>-1000000)
       {
         C.cblack[i] = O.user_cblack[i];
         clear_repeat  = 1;
       }

   if(clear_repeat)
     C.cblack[4]=C.cblack[5]=0;

 // Add common part to cblack[] early
   if (imgdata.idata.filters > 1000 && (C.cblack[4]+1)/2 == 1 && (C.cblack[5]+1)/2 == 1) 
   {
	   for(int c=0; c<4; c++)
		   C.cblack[c] += C.cblack[6 + c/2 % C.cblack[4] * C.cblack[5] + c%2 % C.cblack[5]];
	   C.cblack[4]=C.cblack[5]=0;
   }
   else if(imgdata.idata.filters <= 1000 && C.cblack[4]==1 && C.cblack[5]==1) // Fuji RAF dng
   {
	   for(int c=0; c<4; c++)
		   C.cblack[c] += C.cblack[6];
	   C.cblack[4]=C.cblack[5]=0;
   }
  // remove common part from C.cblack[]
  int i = C.cblack[3];
  int c;
  for(c=0;c<3;c++) if (i > C.cblack[c]) i = C.cblack[c];

  for(c=0;c<4;c++) C.cblack[c] -= i; // remove common part
  C.black += i;

  // Now calculate common part for cblack[6+] part and move it to C.black

  if(C.cblack[4] && C.cblack[5])
    {
      i = C.cblack[6];
      for(c=1; c<C.cblack[4]*C.cblack[5]; c++)
        if(i>C.cblack[6+c]) i = C.cblack[6+c];
      // Remove i from cblack[6+]
      int nonz=0;
      for(c=0; c<C.cblack[4]*C.cblack[5]; c++)
        {
          C.cblack[6+c]-=i;
          if(C.cblack[6+c])nonz++;
        }
      C.black +=i;
      if(!nonz)
        C.cblack[4] = C.cblack[5] = 0;
    }
  for(c=0;c<4;c++) C.cblack[c] += C.black; 
}

Project: LibRaw
File: dcraw.c

int CLASS main (int argc, const char **argv)
{
  int arg, status=0, quality, i, c;
  int timestamp_only=0, thumbnail_only=0, identify_only=0;
  int user_qual=-1, user_black=-1, user_sat=-1, user_flip=-1;
  int use_fuji_rotate=1, write_to_stdout=0, read_from_stdin=0;
  const char *sp, *bpfile=0, *dark_frame=0, *write_ext;
  char opm, opt, *ofname, *cp;
  struct utimbuf ut;
#ifndef NO_LCMS
  const char *cam_profile=0, *out_profile=0;
#endif

#ifndef LOCALTIME
  putenv ((char *) "TZ=UTC");
#endif
#ifdef LOCALEDIR
  setlocale (LC_CTYPE, "");
  setlocale (LC_MESSAGES, "");
  bindtextdomain ("dcraw", LOCALEDIR);
  textdomain ("dcraw");
#endif

  if (argc == 1) {
    printf(_("\nRaw photo decoder \"dcraw\" v%s"), DCRAW_VERSION);
    printf(_("\nby Dave Coffin, dcoffin a cybercom o net\n"));
    printf(_("\nUsage:  %s [OPTION]... [FILE]...\n\n"), argv[0]);
    puts(_("-v        Print verbose messages"));
    puts(_("-c        Write image data to standard output"));
    puts(_("-e        Extract embedded thumbnail image"));
    puts(_("-i        Identify files without decoding them"));
    puts(_("-i -v     Identify files and show metadata"));
    puts(_("-z        Change file dates to camera timestamp"));
    puts(_("-w        Use camera white balance, if possible"));
    puts(_("-a        Average the whole image for white balance"));
    puts(_("-A <x y w h> Average a grey box for white balance"));
    puts(_("-r <r g b g> Set custom white balance"));
    puts(_("+M/-M     Use/don't use an embedded color matrix"));
    puts(_("-C <r b>  Correct chromatic aberration"));
    puts(_("-P <file> Fix the dead pixels listed in this file"));
    puts(_("-K <file> Subtract dark frame (16-bit raw PGM)"));
    puts(_("-k <num>  Set the darkness level"));
    puts(_("-S <num>  Set the saturation level"));
    puts(_("-n <num>  Set threshold for wavelet denoising"));
    puts(_("-H [0-9]  Highlight mode (0=clip, 1=unclip, 2=blend, 3+=rebuild)"));
    puts(_("-t [0-7]  Flip image (0=none, 3=180, 5=90CCW, 6=90CW)"));
    puts(_("-o [0-5]  Output colorspace (raw,sRGB,Adobe,Wide,ProPhoto,XYZ)"));
#ifndef NO_LCMS
    puts(_("-o <file> Apply output ICC profile from file"));
    puts(_("-p <file> Apply camera ICC profile from file or \"embed\""));
#endif
    puts(_("-d        Document mode (no color, no interpolation)"));
    puts(_("-D        Document mode without scaling (totally raw)"));
    puts(_("-j        Don't stretch or rotate raw pixels"));
    puts(_("-W        Don't automatically brighten the image"));
    puts(_("-b <num>  Adjust brightness (default = 1.0)"));
    puts(_("-g <p ts> Set custom gamma curve (default = 2.222 4.5)"));
    puts(_("-q [0-3]  Set the interpolation quality"));
    puts(_("-h        Half-size color image (twice as fast as \"-q 0\")"));
    puts(_("-f        Interpolate RGGB as four colors"));
    puts(_("-m <num>  Apply a 3x3 median filter to R-G and B-G"));
    puts(_("-s [0..N-1] Select one raw image or \"all\" from each file"));
    puts(_("-6        Write 16-bit instead of 8-bit"));
    puts(_("-4        Linear 16-bit, same as \"-6 -W -g 1 1\""));
    puts(_("-T        Write TIFF instead of PPM"));
    puts("");
    return 1;
  }
  argv[argc] = "";
  for (arg=1; (((opm = argv[arg][0]) - 2) | 2) == '+'; ) {
    opt = argv[arg++][1];
    if ((cp = (char *) strchr (sp="nbrkStqmHACg", opt)))
      for (i=0; i < "114111111422"[cp-sp]-'0'; i++)
	if (!isdigit(argv[arg+i][0])) {
	  fprintf (stderr,_("Non-numeric argument to \"-%c\"\n"), opt);
	  return 1;
	}
    switch (opt) {
      case 'n':  threshold   = atof(argv[arg++]);  break;
      case 'b':  bright      = atof(argv[arg++]);  break;
      case 'r':
	   FORC4 user_mul[c] = atof(argv[arg++]);  break;
      case 'C':  aber[0] = 1 / atof(argv[arg++]);
		 aber[2] = 1 / atof(argv[arg++]);  break;
      case 'g':  gamm[0] =     atof(argv[arg++]);
		 gamm[1] =     atof(argv[arg++]);
		 if (gamm[0]) gamm[0] = 1/gamm[0]; break;
      case 'k':  user_black  = atoi(argv[arg++]);  break;
      case 'S':  user_sat    = atoi(argv[arg++]);  break;
      case 't':  user_flip   = atoi(argv[arg++]);  break;
      case 'q':  user_qual   = atoi(argv[arg++]);  break;
      case 'm':  med_passes  = atoi(argv[arg++]);  break;
      case 'H':  highlight   = atoi(argv[arg++]);  break;
      case 's':
	shot_select = abs(atoi(argv[arg]));
	multi_out = !strcmp(argv[arg++],"all");
	break;
      case 'o':
	if (isdigit(argv[arg][0]) && !argv[arg][1])
	  output_color = atoi(argv[arg++]);
#ifndef NO_LCMS
	else     out_profile = argv[arg++];
	break;
      case 'p':  cam_profile = argv[arg++];
#endif
	break;
      case 'P':  bpfile     = argv[arg++];  break;
      case 'K':  dark_frame = argv[arg++];  break;
      case 'z':  timestamp_only    = 1;  break;
      case 'e':  thumbnail_only    = 1;  break;
      case 'i':  identify_only     = 1;  break;
      case 'c':  write_to_stdout   = 1;  break;
      case 'v':  verbose           = 1;  break;
      case 'h':  half_size         = 1;  break;
      case 'f':  four_color_rgb    = 1;  break;
      case 'A':  FORC4 greybox[c]  = atoi(argv[arg++]);
      case 'a':  use_auto_wb       = 1;  break;
      case 'w':  use_camera_wb     = 1;  break;
      case 'M':  use_camera_matrix = 3 * (opm == '+');  break;
      case 'I':  read_from_stdin   = 1;  break;
      case 'E':  document_mode++;
      case 'D':  document_mode++;
      case 'd':  document_mode++;
      case 'j':  use_fuji_rotate   = 0;  break;
      case 'W':  no_auto_bright    = 1;  break;
      case 'T':  output_tiff       = 1;  break;
      case '4':  gamm[0] = gamm[1] =
		 no_auto_bright    = 1;
      case '6':  output_bps       = 16;  break;
      default:
	fprintf (stderr,_("Unknown option \"-%c\".\n"), opt);
	return 1;
    }
  }
  if (arg == argc) {
    fprintf (stderr,_("No files to process.\n"));
    return 1;
  }
  if (write_to_stdout) {
    if (isatty(1)) {
      fprintf (stderr,_("Will not write an image to the terminal!\n"));
      return 1;
    }
#if defined(WIN32) || defined(DJGPP) || defined(__CYGWIN__)
    if (setmode(1,O_BINARY) < 0) {
      perror ("setmode()");
      return 1;
    }
#endif
  }
  for ( ; arg < argc; arg++) {
    status = 1;
    raw_image = 0;
    image = 0;
    oprof = 0;
    meta_data = ofname = 0;
    ofp = stdout;
    if (setjmp (failure)) {
      if (fileno(ifp) > 2) fclose(ifp);
      if (fileno(ofp) > 2) fclose(ofp);
      status = 1;
      goto cleanup;
    }
    ifname = argv[arg];
    if (!(ifp = fopen (ifname, "rb"))) {
      perror (ifname);
      continue;
    }
    status = (identify(),!is_raw);
    if (user_flip >= 0)
      flip = user_flip;
    switch ((flip+3600) % 360) {
      case 270:  flip = 5;  break;
      case 180:  flip = 3;  break;
      case  90:  flip = 6;
    }
    if (timestamp_only) {
      if ((status = !timestamp))
	fprintf (stderr,_("%s has no timestamp.\n"), ifname);
      else if (identify_only)
	printf ("%10ld%10d %s\n", (long) timestamp, shot_order, ifname);
      else {
	if (verbose)
	  fprintf (stderr,_("%s time set to %d.\n"), ifname, (int) timestamp);
	ut.actime = ut.modtime = timestamp;
	utime (ifname, &ut);
      }
      goto next;
    }
    write_fun = &CLASS write_ppm_tiff;
    if (thumbnail_only) {
      if ((status = !thumb_offset)) {
	fprintf (stderr,_("%s has no thumbnail.\n"), ifname);
	goto next;
      } else if (thumb_load_raw) {
	load_raw = thumb_load_raw;
	data_offset = thumb_offset;
	height = thumb_height;
	width  = thumb_width;
	filters = 0;
	colors = 3;
      } else {
	fseek (ifp, thumb_offset, SEEK_SET);
	write_fun = write_thumb;
	goto thumbnail;
      }
    }
    if (load_raw == &CLASS kodak_ycbcr_load_raw) {
      height += height & 1;
      width  += width  & 1;
    }

    if (identify_only && verbose && make[0]) {
      printf (_("\nFilename: %s\n"), ifname);
      printf (_("Timestamp: %s"), ctime(&timestamp));
      printf (_("Camera: %s %s\n"), make, model);
      if (artist[0])
	printf (_("Owner: %s\n"), artist);
      if (dng_version) {
	printf (_("DNG Version: "));
	for (i=24; i >= 0; i -= 8)
	  printf ("%d%c", dng_version >> i & 255, i ? '.':'\n');
      }
      printf (_("ISO speed: %d\n"), (int) iso_speed);
      printf (_("Shutter: "));
      if (shutter > 0 && shutter < 1)
	shutter = (printf ("1/"), 1 / shutter);
      printf (_("%0.1f sec\n"), shutter);
      printf (_("Aperture: f/%0.1f\n"), aperture);
      printf (_("Focal length: %0.1f mm\n"), focal_len);
      printf (_("Embedded ICC profile: %s\n"), profile_length ? _("yes"):_("no"));
      printf (_("Number of raw images: %d\n"), is_raw);
      if (pixel_aspect != 1)
	printf (_("Pixel Aspect Ratio: %0.6f\n"), pixel_aspect);
      if (thumb_offset)
	printf (_("Thumb size:  %4d x %d\n"), thumb_width, thumb_height);
      printf (_("Full size:   %4d x %d\n"), raw_width, raw_height);
    } else if (!is_raw)
      fprintf (stderr,_("Cannot decode file %s\n"), ifname);
    if (!is_raw) goto next;
    shrink = filters && (half_size || (!identify_only &&
	(threshold || aber[0] != 1 || aber[2] != 1)));
    iheight = (height + shrink) >> shrink;
    iwidth  = (width  + shrink) >> shrink;
    if (identify_only) {
      if (verbose) {
	if (document_mode == 3) {
	  top_margin = left_margin = fuji_width = 0;
	  height = raw_height;
	  width  = raw_width;
	}
	iheight = (height + shrink) >> shrink;
	iwidth  = (width  + shrink) >> shrink;
	if (use_fuji_rotate) {
	  if (fuji_width) {
	    fuji_width = (fuji_width - 1 + shrink) >> shrink;
	    iwidth = fuji_width / sqrt(0.5);
	    iheight = (iheight - fuji_width) / sqrt(0.5);
	  } else {
	    if (pixel_aspect < 1) iheight = iheight / pixel_aspect + 0.5;
	    if (pixel_aspect > 1) iwidth  = iwidth  * pixel_aspect + 0.5;
	  }
	}
	if (flip & 4)
	  SWAP(iheight,iwidth);
	printf (_("Image size:  %4d x %d\n"), width, height);
	printf (_("Output size: %4d x %d\n"), iwidth, iheight);
	printf (_("Raw colors: %d"), colors);
	if (filters) {
	  int fhigh = 2, fwide = 2;
	  if ((filters ^ (filters >>  8)) & 0xff)   fhigh = 4;
	  if ((filters ^ (filters >> 16)) & 0xffff) fhigh = 8;
	  if (filters == 1) fhigh = fwide = 16;
	  if (filters == 9) fhigh = fwide = 6;
	  printf (_("\nFilter pattern: "));
	  for (i=0; i < fhigh; i++)
	    for (c = i && putchar('/') && 0; c < fwide; c++)
	      putchar (cdesc[fcol(i,c)]);
	}
	printf (_("\nDaylight multipliers:"));
	FORCC printf (" %f", pre_mul[c]);
	if (cam_mul[0] > 0) {
	  printf (_("\nCamera multipliers:"));
	  FORC4 printf (" %f", cam_mul[c]);
	}
	putchar ('\n');
      } else
	printf (_("%s is a %s %s image.\n"), ifname, make, model);
next:
      fclose(ifp);
      continue;
    }
    if (meta_length) {
      meta_data = (char *) malloc (meta_length);
      merror (meta_data, "main()");
    }
    if (filters || colors == 1) {
      raw_image = (ushort *) calloc ((raw_height+7), raw_width*2);
      merror (raw_image, "main()");
    } else {
      image = (ushort (*)[4]) calloc (iheight, iwidth*sizeof *image);
      merror (image, "main()");
    }
    if (verbose)
      fprintf (stderr,_("Loading %s %s image from %s ...\n"),
	make, model, ifname);
    if (shot_select >= is_raw)
      fprintf (stderr,_("%s: \"-s %d\" requests a nonexistent image!\n"),
	ifname, shot_select);
    fseeko (ifp, data_offset, SEEK_SET);
    if (raw_image && read_from_stdin)
      fread (raw_image, 2, raw_height*raw_width, stdin);
    else (*load_raw)();
    if (document_mode == 3) {
      top_margin = left_margin = fuji_width = 0;
      height = raw_height;
      width  = raw_width;
    }
    iheight = (height + shrink) >> shrink;
    iwidth  = (width  + shrink) >> shrink;
    if (raw_image) {
      image = (ushort (*)[4]) calloc (iheight, iwidth*sizeof *image);
      merror (image, "main()");
      crop_masked_pixels();
      free (raw_image);
    }
    if (zero_is_bad) remove_zeroes();
    bad_pixels (bpfile);
    if (dark_frame) subtract (dark_frame);
    quality = 2 + !fuji_width;
    if (user_qual >= 0) quality = user_qual;
    i = cblack[3];
    FORC3 if (i > cblack[c]) i = cblack[c];
    FORC4 cblack[c] -= i;
    black += i;
    i = cblack[6];
    FORC (cblack[4] * cblack[5])
      if (i > cblack[6+c]) i = cblack[6+c];
    FORC (cblack[4] * cblack[5])
      cblack[6+c] -= i;
    black += i;
    if (user_black >= 0) black = user_black;
    FORC4 cblack[c] += black;
    if (user_sat > 0) maximum = user_sat;
#ifdef COLORCHECK
    colorcheck();
#endif
    if (is_foveon) {
      if (document_mode || load_raw == &CLASS foveon_dp_load_raw) {
	for (i=0; i < height*width*4; i++)
	  if ((short) image[0][i] < 0) image[0][i] = 0;
      } else foveon_interpolate();
    } else if (document_mode < 2)
      scale_colors();
    pre_interpolate();
    if (filters && !document_mode) {
      if (quality == 0)
	lin_interpolate();
      else if (quality == 1 || colors > 3)
	vng_interpolate();
      else if (quality == 2 && filters > 1000)
	ppg_interpolate();
      else if (filters == 9)
	xtrans_interpolate (quality*2-3);
      else
	ahd_interpolate();
    }
    if (mix_green)
      for (colors=3, i=0; i < height*width; i++)
	image[i][1] = (image[i][1] + image[i][3]) >> 1;
    if (!is_foveon && colors == 3) median_filter();
    if (!is_foveon && highlight == 2) blend_highlights();
    if (!is_foveon && highlight > 2) recover_highlights();
    if (use_fuji_rotate) fuji_rotate();
#ifndef NO_LCMS
    if (cam_profile) apply_profile (cam_profile, out_profile);
#endif
    convert_to_rgb();
    if (use_fuji_rotate) stretch();
thumbnail:
    if (write_fun == &CLASS jpeg_thumb)
      write_ext = ".jpg";
    else if (output_tiff && write_fun == &CLASS write_ppm_tiff)
      write_ext = ".tiff";
    else
      write_ext = ".pgm\0.ppm\0.ppm\0.pam" + colors*5-5;
    ofname = (char *) malloc (strlen(ifname) + 64);
    merror (ofname, "main()");
    if (write_to_stdout)
      strcpy (ofname,_("standard output"));
    else {
      strcpy (ofname, ifname);
      if ((cp = strrchr (ofname, '.'))) *cp = 0;
      if (multi_out)
	sprintf (ofname+strlen(ofname), "_%0*d",
		snprintf(0,0,"%d",is_raw-1), shot_select);
      if (thumbnail_only)
	strcat (ofname, ".thumb");
      strcat (ofname, write_ext);
      ofp = fopen (ofname, "wb");
      if (!ofp) {
	status = 1;
	perror (ofname);
	goto cleanup;
      }
    }
    if (verbose)
      fprintf (stderr,_("Writing data to %s ...\n"), ofname);
    (*write_fun)();
    fclose(ifp);
    if (ofp != stdout) fclose(ofp);
cleanup:
    if (meta_data) free (meta_data);
    if (ofname) free (ofname);
    if (oprof) free (oprof);
    if (image) free (image);
    if (multi_out) {
      if (++shot_select < is_raw) arg--;
      else shot_select = 0;
    }
  }
  return status;
}

Project: LibRaw
File: libraw_cxx.cpp

void LibRaw::derror()
{
  if (!libraw_internal_data.unpacker_data.data_error && libraw_internal_data.internal_data.input) 
    {
      if (libraw_internal_data.internal_data.input->eof())
        {
          if(callbacks.data_cb)(*callbacks.data_cb)(callbacks.datacb_data,
                                                    libraw_internal_data.internal_data.input->fname(),-1);
          throw LIBRAW_EXCEPTION_IO_EOF;
        }
      else
        {
          if(callbacks.data_cb)(*callbacks.data_cb)(callbacks.datacb_data,
                                                    libraw_internal_data.internal_data.input->fname(),
                                                    libraw_internal_data.internal_data.input->tell());
          //throw LIBRAW_EXCEPTION_IO_CORRUPT;
        }
    }
  libraw_internal_data.unpacker_data.data_error++;
}

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;
#ifdef LIBRAW_LIBRARY_BUILD
      data_size     = tile_length < INT_MAX && tile_length>0 ? tiff_ifd[i].tile_maxbytes: tiff_ifd[i].bytes;
#endif
      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(!strcasecmp(make,"Nikon") && !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;
	} 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 (!strcmp(make,"Imacon"))
	  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: libraw_cxx.cpp

void LibRaw::exp_bef(float shift, float smooth)
{
  // params limits
  if(shift>8) shift = 8;
  if(shift<0.25) shift = 0.25;
  if(smooth < 0.0) smooth = 0.0;
  if(smooth > 1.0) smooth = 1.0;
    
  unsigned short *lut = (ushort*)malloc((TBLN+1)*sizeof(unsigned short));

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

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

  if(C.data_maximum <=TBLN)
    C.data_maximum = lut[C.data_maximum];
  if(C.maximum <= TBLN)
    C.maximum = lut[C.maximum];
  // no need to adjust the minumum, black is already subtracted
  free(lut);
}

Project: LibRaw
File: libraw_cxx.cpp

void LibRaw::kodak_thumb_loader()
{
  // some kodak cameras
  ushort s_height = S.height, s_width = S.width,s_iwidth = S.iwidth,s_iheight=S.iheight;
  ushort s_flags = libraw_internal_data.unpacker_data.load_flags;
  libraw_internal_data.unpacker_data.load_flags = 12;
  int s_colors = P1.colors;
  unsigned s_filters = P1.filters;
  ushort (*s_image)[4] = imgdata.image;

    
  S.height = T.theight;
  S.width  = T.twidth;
  P1.filters = 0;

  if (thumb_load_raw == &CLASS kodak_ycbcr_load_raw) 
    {
      S.height += S.height & 1;
      S.width  += S.width  & 1;
    }
    
  imgdata.image = (ushort (*)[4]) calloc (S.iheight*S.iwidth, sizeof (*imgdata.image));
  merror (imgdata.image, "LibRaw::kodak_thumb_loader()");

  ID.input->seek(ID.toffset, SEEK_SET);
  // read kodak thumbnail into T.image[]
  try {
	  (this->*thumb_load_raw)();
  } catch (...)
  {
	  free(imgdata.image);
	  imgdata.image  = s_image;

	  T.twidth = 0;
	  S.width = s_width;

	  S.iwidth = s_iwidth;
	  S.iheight = s_iheight;

	  T.theight = 0;
	  S.height = s_height;

	  T.tcolors = 0;
	  P1.colors = s_colors;

	  P1.filters = s_filters;
	  T.tlength=0;
	  libraw_internal_data.unpacker_data.load_flags = s_flags;
	  return;
  }

  // copy-n-paste from image pipe
#define MIN(a,b) ((a) < (b) ? (a) : (b))
#define MAX(a,b) ((a) > (b) ? (a) : (b))
#define LIM(x,min,max) MAX(min,MIN(x,max))
#define CLIP(x) LIM(x,0,65535)
#define SWAP(a,b) { a ^= b; a ^= (b ^= a); }

  // from scale_colors
  {
    double   dmax;
    float scale_mul[4];
    int c,val;
    for (dmax=DBL_MAX, c=0; c < 3; c++) 
      if (dmax > C.pre_mul[c])
        dmax = C.pre_mul[c];

    for( c=0; c< 3; c++)
      scale_mul[c] = (C.pre_mul[c] / dmax) * 65535.0 / C.maximum;
    scale_mul[3] = scale_mul[1];

    size_t size = S.height * S.width;
    for (unsigned i=0; i < size*4 ; i++) 
      {
        val = imgdata.image[0][i];
        if(!val) continue;
        val *= scale_mul[i & 3];
        imgdata.image[0][i] = CLIP(val);
      }
  }

  // from convert_to_rgb
  ushort *img;
  int row,col;
    
  int  (*t_hist)[LIBRAW_HISTOGRAM_SIZE] =  (int (*)[LIBRAW_HISTOGRAM_SIZE]) calloc(sizeof(*t_hist),4);
  merror (t_hist, "LibRaw::kodak_thumb_loader()");
    
  float out[3], 
    out_cam[3][4] = 
    {
      {2.81761312, -1.98369181, 0.166078627, 0}, 
      {-0.111855984, 1.73688626, -0.625030339, 0}, 
      {-0.0379119813, -0.891268849, 1.92918086, 0}
    };

  for (img=imgdata.image[0], row=0; row < S.height; row++)
    for (col=0; col < S.width; col++, img+=4)
      {
        out[0] = out[1] = out[2] = 0;
        int c;
        for(c=0;c<3;c++) 
          {
            out[0] += out_cam[0][c] * img[c];
            out[1] += out_cam[1][c] * img[c];
            out[2] += out_cam[2][c] * img[c];
          }
        for(c=0; c<3; c++)
          img[c] = CLIP((int) out[c]);
        for(c=0; c<P1.colors;c++)
          t_hist[c][img[c] >> 3]++;
                    
      }

  // from gamma_lut
  int  (*save_hist)[LIBRAW_HISTOGRAM_SIZE] = libraw_internal_data.output_data.histogram;
  libraw_internal_data.output_data.histogram = t_hist;

  // make curve output curve!
  ushort (*t_curve) = (ushort*) calloc(sizeof(C.curve),1);
  merror (t_curve, "LibRaw::kodak_thumb_loader()");
  memmove(t_curve,C.curve,sizeof(C.curve));
  memset(C.curve,0,sizeof(C.curve));
  {
    int perc, val, total, t_white=0x2000,c;

    perc = S.width * S.height * 0.01;		/* 99th percentile white level */
    if (IO.fuji_width) perc /= 2;
    if (!((O.highlight & ~2) || O.no_auto_bright))
      for (t_white=c=0; c < P1.colors; c++) {
        for (val=0x2000, total=0; --val > 32; )
          if ((total += libraw_internal_data.output_data.histogram[c][val]) > perc) break;
        if (t_white < val) t_white = val;
      }
    gamma_curve (O.gamm[0], O.gamm[1], 2, (t_white << 3)/O.bright);
  }
    
  libraw_internal_data.output_data.histogram = save_hist;
  free(t_hist);
    
  // from write_ppm_tiff - copy pixels into bitmap
    
  S.iheight = S.height;
  S.iwidth  = S.width;
  if (S.flip & 4) SWAP(S.height,S.width);

  if(T.thumb) free(T.thumb);
  T.thumb = (char*) calloc (S.width * S.height, P1.colors);
  merror (T.thumb, "LibRaw::kodak_thumb_loader()");
  T.tlength = S.width * S.height * P1.colors;

  // from write_tiff_ppm
  {
    int soff  = flip_index (0, 0);
    int cstep = flip_index (0, 1) - soff;
    int rstep = flip_index (1, 0) - flip_index (0, S.width);
        
    for (int row=0; row < S.height; row++, soff += rstep) 
      {
        char *ppm = T.thumb + row*S.width*P1.colors;
        for (int col=0; col < S.width; col++, soff += cstep)
          for(int c = 0; c < P1.colors; c++)
            ppm [col*P1.colors+c] = imgdata.color.curve[imgdata.image[soff][c]]>>8;
      }
  }

  memmove(C.curve,t_curve,sizeof(C.curve));
  free(t_curve);

  // restore variables
  free(imgdata.image);
  imgdata.image  = s_image;
    
  T.twidth = S.width;
  S.width = s_width;

  S.iwidth = s_iwidth;
  S.iheight = s_iheight;

  T.theight = S.height;
  S.height = s_height;

  T.tcolors = P1.colors;
  P1.colors = s_colors;

  P1.filters = s_filters;
  libraw_internal_data.unpacker_data.load_flags = s_flags;
}

Project: LibRaw
File: libraw_cxx.cpp

int LibRaw::get_decoder_info(libraw_decoder_info_t* d_info)
{
  if(!d_info)   return LIBRAW_UNSPECIFIED_ERROR;
  if(!load_raw) return LIBRAW_OUT_OF_ORDER_CALL;
  
  d_info->decoder_flags = 0;
  int rawdata = (imgdata.idata.filters || P1.colors == 1);
  // dcraw.c names order
  if (load_raw == &LibRaw::android_tight_load_raw)
  {
	  d_info->decoder_name = "android_tight_load_raw()";
  }
  else if (load_raw == &LibRaw::android_loose_load_raw)
  {
	  d_info->decoder_name = "android_loose_load_raw()";
  }
  else if (load_raw == &LibRaw::canon_600_load_raw)
    {
      d_info->decoder_name = "canon_600_load_raw()";   
    }
  else if (load_raw == &LibRaw::canon_load_raw)
    {
      d_info->decoder_name = "canon_load_raw()"; 
    }
  else if (load_raw == &LibRaw::lossless_jpeg_load_raw)
    {
      // Check rbayer
      d_info->decoder_name = "lossless_jpeg_load_raw()"; 
      d_info->decoder_flags = LIBRAW_DECODER_HASCURVE | LIBRAW_DECODER_TRYRAWSPEED;
    }
  else if (load_raw == &LibRaw::canon_sraw_load_raw) 
    {
      d_info->decoder_name = "canon_sraw_load_raw()";
      d_info->decoder_flags = LIBRAW_DECODER_TRYRAWSPEED; 
    }
  else if (load_raw == &LibRaw::lossless_dng_load_raw) 
    {
      // Check rbayer
      d_info->decoder_name = "lossless_dng_load_raw()"; 
      d_info->decoder_flags = LIBRAW_DECODER_HASCURVE | LIBRAW_DECODER_TRYRAWSPEED;
    }
  else if (load_raw == &LibRaw::packed_dng_load_raw)
    {
      // Check rbayer
      d_info->decoder_name = "packed_dng_load_raw()"; 
      d_info->decoder_flags = LIBRAW_DECODER_HASCURVE | LIBRAW_DECODER_TRYRAWSPEED;
    }
  else if (load_raw == &LibRaw::pentax_load_raw )
    {
      d_info->decoder_name = "pentax_load_raw()"; 
      d_info->decoder_flags = LIBRAW_DECODER_TRYRAWSPEED;
    }
  else if (load_raw == &LibRaw::nikon_load_raw)
    {
      // Check rbayer
      d_info->decoder_name = "nikon_load_raw()";
      d_info->decoder_flags = LIBRAW_DECODER_TRYRAWSPEED;
    }
  else if (load_raw == &LibRaw::nikon_coolscan_load_raw )
  {
	  d_info->decoder_name = "nikon_coolscan_load_raw()";
	  d_info->decoder_flags = LIBRAW_DECODER_FIXEDMAXC; 
  }
  else if (load_raw == &LibRaw::nikon_load_sraw )
    {
      d_info->decoder_name = "nikon_load_sraw()";
      d_info->decoder_flags = LIBRAW_DECODER_HASCURVE | LIBRAW_DECODER_FIXEDMAXC; 
    }
  else if (load_raw == &LibRaw::rollei_load_raw )
    {
      // UNTESTED
      d_info->decoder_name = "rollei_load_raw()"; 
    }
  else if (load_raw == &LibRaw::phase_one_load_raw )
    {
      d_info->decoder_name = "phase_one_load_raw()"; 
    }
  else if (load_raw == &LibRaw::phase_one_load_raw_c )
    {
      d_info->decoder_name = "phase_one_load_raw_c()"; 
    }
  else if (load_raw == &LibRaw::hasselblad_load_raw )
    {
      d_info->decoder_name = "hasselblad_load_raw()"; 
    }
  else if (load_raw == &LibRaw::leaf_hdr_load_raw )
    {
      d_info->decoder_name = "leaf_hdr_load_raw()"; 
    }
  else if (load_raw == &LibRaw::unpacked_load_raw )
    {
      d_info->decoder_name = "unpacked_load_raw()"; 
    }
  else if (load_raw == &LibRaw::sinar_4shot_load_raw )
    {
      // UNTESTED
      d_info->decoder_name = "sinar_4shot_load_raw()";
    }
  else if (load_raw == &LibRaw::imacon_full_load_raw )
    {
      d_info->decoder_name = "imacon_full_load_raw()"; 
    }
  else if (load_raw == &LibRaw::hasselblad_full_load_raw )
    {
      d_info->decoder_name = "hasselblad_full_load_raw()"; 
    }
  else if (load_raw == &LibRaw::packed_load_raw )
    {
      d_info->decoder_name = "packed_load_raw()";
      d_info->decoder_flags = LIBRAW_DECODER_TRYRAWSPEED;
    }
  else if (load_raw == &LibRaw::nokia_load_raw )
    {
      // UNTESTED
      d_info->decoder_name = "nokia_load_raw()";
    }
  else if (load_raw == &LibRaw::canon_rmf_load_raw )
    {
      // UNTESTED
      d_info->decoder_name = "canon_rmf_load_raw()";
    }
  else if (load_raw == &LibRaw::panasonic_load_raw )
    {
      d_info->decoder_name = "panasonic_load_raw()";
      d_info->decoder_flags = LIBRAW_DECODER_TRYRAWSPEED;
    }
  else if (load_raw == &LibRaw::olympus_load_raw )
    {
      d_info->decoder_name = "olympus_load_raw()"; 
      d_info->decoder_flags = LIBRAW_DECODER_TRYRAWSPEED;
    }
  else if (load_raw == &LibRaw::minolta_rd175_load_raw ) 
    {  
      // UNTESTED
      d_info->decoder_name = "minolta_rd175_load_raw()"; 
    }
  else if (load_raw == &LibRaw::quicktake_100_load_raw )
    {
      // UNTESTED
      d_info->decoder_name = "quicktake_100_load_raw()";
    }
  else if (load_raw == &LibRaw::kodak_radc_load_raw )
    {
      d_info->decoder_name = "kodak_radc_load_raw()"; 
    }
  else if (load_raw == &LibRaw::kodak_jpeg_load_raw )
    {
      // UNTESTED + RBAYER
      d_info->decoder_name = "kodak_jpeg_load_raw()"; 
    }
  else if (load_raw == &LibRaw::lossy_dng_load_raw)
    {
      // Check rbayer
      d_info->decoder_name = "lossy_dng_load_raw()"; 
      d_info->decoder_flags = LIBRAW_DECODER_TRYRAWSPEED | LIBRAW_DECODER_HASCURVE;
    }
  else if (load_raw == &LibRaw::kodak_dc120_load_raw )
    {
      d_info->decoder_name = "kodak_dc120_load_raw()"; 
    }
  else if (load_raw == &LibRaw::eight_bit_load_raw )
    {
      d_info->decoder_name = "eight_bit_load_raw()";
      d_info->decoder_flags = LIBRAW_DECODER_HASCURVE;
    }
#if 0 // OLD kodak decoder
  else if (load_raw == &LibRaw::kodak_yrgb_load_raw )    
    {
      d_info->decoder_name = "kodak_yrgb_load_raw()"; 
      d_info->decoder_flags = LIBRAW_DECODER_HASCURVE;
    }
#else
  else if (load_raw == &LibRaw::kodak_c330_load_raw )    
    {
      d_info->decoder_name = "kodak_yrgb_load_raw()"; 
      d_info->decoder_flags = LIBRAW_DECODER_HASCURVE;
    }
  else if (load_raw == &LibRaw::kodak_c603_load_raw )    
    {
      d_info->decoder_name = "kodak_yrgb_load_raw()"; 
      d_info->decoder_flags = LIBRAW_DECODER_HASCURVE;
    }
#endif
  else if (load_raw == &LibRaw::kodak_262_load_raw )
    {
      d_info->decoder_name = "kodak_262_load_raw()"; // UNTESTED!
      d_info->decoder_flags = LIBRAW_DECODER_HASCURVE;
    }
  else if (load_raw == &LibRaw::kodak_65000_load_raw )
    {
      d_info->decoder_name = "kodak_65000_load_raw()";
      d_info->decoder_flags = LIBRAW_DECODER_HASCURVE;
    }
  else if (load_raw == &LibRaw::kodak_ycbcr_load_raw )
    {
      // UNTESTED
      d_info->decoder_name = "kodak_ycbcr_load_raw()"; 
      d_info->decoder_flags = LIBRAW_DECODER_HASCURVE;
    }
  else if (load_raw == &LibRaw::kodak_rgb_load_raw ) 
    {
      // UNTESTED
      d_info->decoder_name = "kodak_rgb_load_raw()"; 
    }
  else if (load_raw == &LibRaw::sony_load_raw )
    {
      d_info->decoder_name = "sony_load_raw()"; 
    }
  else if (load_raw == &LibRaw::sony_arw_load_raw )
    {
      d_info->decoder_name = "sony_arw_load_raw()";
      d_info->decoder_flags = LIBRAW_DECODER_TRYRAWSPEED;

    }
  else if (load_raw == &LibRaw::sony_arw2_load_raw )
    {
      d_info->decoder_name = "sony_arw2_load_raw()";
      d_info->decoder_flags = LIBRAW_DECODER_HASCURVE | LIBRAW_DECODER_TRYRAWSPEED | LIBRAW_DECODER_SONYARW2;
    }
  else if (load_raw == &LibRaw::samsung_load_raw )
    {
      d_info->decoder_name = "samsung_load_raw()";
      d_info->decoder_flags = LIBRAW_DECODER_TRYRAWSPEED;
    }
  else if (load_raw == &LibRaw::samsung2_load_raw )
    {
      d_info->decoder_name = "samsung2_load_raw()";
    }
  else if (load_raw == &LibRaw::samsung3_load_raw )
    {
      d_info->decoder_name = "samsung3_load_raw()";
    }
  else if (load_raw == &LibRaw::smal_v6_load_raw )
    {
      // UNTESTED
      d_info->decoder_name = "smal_v6_load_raw()";
    }
  else if (load_raw == &LibRaw::smal_v9_load_raw )
    {
      // UNTESTED
      d_info->decoder_name = "smal_v9_load_raw()";
    }
  else  if (load_raw == &LibRaw::redcine_load_raw)
    {
      d_info->decoder_name = "redcine_load_raw()";
      d_info->decoder_flags = LIBRAW_DECODER_HASCURVE;
    }
  else if (load_raw == &LibRaw::x3f_load_raw )
    {
      d_info->decoder_name = "x3f_load_raw()";
      d_info->decoder_flags = LIBRAW_DECODER_OWNALLOC; 
    }
#ifdef LIBRAW_DEMOSAIC_PACK_GPL2
  else if (load_raw == &LibRaw::foveon_sd_load_raw )
    {
      d_info->decoder_name = "foveon_sd_load_raw()";
    }
  else if (load_raw == &LibRaw::foveon_dp_load_raw )
    {
      d_info->decoder_name = "foveon_dp_load_raw()";
    }
#endif
  else
    {
      d_info->decoder_name = "Unknown unpack function";
      d_info->decoder_flags = LIBRAW_DECODER_NOTSET;
    }
  return LIBRAW_SUCCESS;
}

Project: LibRaw
File: dcraw.c

void CLASS tiff_head (struct tiff_hdr *th, int full)
{
  int c, psize=0;
  struct tm *t;

  memset (th, 0, sizeof *th);
  th->t_order = htonl(0x4d4d4949) >> 16;
  th->magic = 42;
  th->ifd = 10;
  if (full) {
    tiff_set (&th->ntag, 254, 4, 1, 0);
    tiff_set (&th->ntag, 256, 4, 1, width);
    tiff_set (&th->ntag, 257, 4, 1, height);
    tiff_set (&th->ntag, 258, 3, colors, output_bps);
    if (colors > 2)
      th->tag[th->ntag-1].val.i = TOFF(th->bps);
    FORC4 th->bps[c] = output_bps;
    tiff_set (&th->ntag, 259, 3, 1, 1);
    tiff_set (&th->ntag, 262, 3, 1, 1 + (colors > 1));
  }
  tiff_set (&th->ntag, 270, 2, 512, TOFF(th->t_desc));
  tiff_set (&th->ntag, 271, 2, 64, TOFF(th->t_make));
  tiff_set (&th->ntag, 272, 2, 64, TOFF(th->t_model));
  if (full) {
    if (oprof) psize = ntohl(oprof[0]);
    tiff_set (&th->ntag, 273, 4, 1, sizeof *th + psize);
    tiff_set (&th->ntag, 277, 3, 1, colors);
    tiff_set (&th->ntag, 278, 4, 1, height);
    tiff_set (&th->ntag, 279, 4, 1, height*width*colors*output_bps/8);
  } else
    tiff_set (&th->ntag, 274, 3, 1, "12435867"[flip]-'0');
  tiff_set (&th->ntag, 282, 5, 1, TOFF(th->rat[0]));
  tiff_set (&th->ntag, 283, 5, 1, TOFF(th->rat[2]));
  tiff_set (&th->ntag, 284, 3, 1, 1);
  tiff_set (&th->ntag, 296, 3, 1, 2);
  tiff_set (&th->ntag, 305, 2, 32, TOFF(th->soft));
  tiff_set (&th->ntag, 306, 2, 20, TOFF(th->date));
  tiff_set (&th->ntag, 315, 2, 64, TOFF(th->t_artist));
  tiff_set (&th->ntag, 34665, 4, 1, TOFF(th->nexif));
  if (psize) tiff_set (&th->ntag, 34675, 7, psize, sizeof *th);
  tiff_set (&th->nexif, 33434, 5, 1, TOFF(th->rat[4]));
  tiff_set (&th->nexif, 33437, 5, 1, TOFF(th->rat[6]));
  tiff_set (&th->nexif, 34855, 3, 1, iso_speed);
  tiff_set (&th->nexif, 37386, 5, 1, TOFF(th->rat[8]));
  if (gpsdata[1]) {
    tiff_set (&th->ntag, 34853, 4, 1, TOFF(th->ngps));
    tiff_set (&th->ngps,  0, 1,  4, 0x202);
    tiff_set (&th->ngps,  1, 2,  2, gpsdata[29]);
    tiff_set (&th->ngps,  2, 5,  3, TOFF(th->gps[0]));
    tiff_set (&th->ngps,  3, 2,  2, gpsdata[30]);
    tiff_set (&th->ngps,  4, 5,  3, TOFF(th->gps[6]));
    tiff_set (&th->ngps,  5, 1,  1, gpsdata[31]);
    tiff_set (&th->ngps,  6, 5,  1, TOFF(th->gps[18]));
    tiff_set (&th->ngps,  7, 5,  3, TOFF(th->gps[12]));
    tiff_set (&th->ngps, 18, 2, 12, TOFF(th->gps[20]));
    tiff_set (&th->ngps, 29, 2, 12, TOFF(th->gps[23]));
    memcpy (th->gps, gpsdata, sizeof th->gps);
  }
  th->rat[0] = th->rat[2] = 300;
  th->rat[1] = th->rat[3] = 1;
  FORC(6) th->rat[4+c] = 1000000;
  th->rat[4] *= shutter;
  th->rat[6] *= aperture;
  th->rat[8] *= focal_len;
  strncpy (th->t_desc, desc, 512);
  strncpy (th->t_make, make, 64);
  strncpy (th->t_model, model, 64);
  strcpy (th->soft, "dcraw v" DCRAW_VERSION);
  t = localtime (&timestamp);
  sprintf (th->date, "%04d:%02d:%02d %02d:%02d:%02d",
      t->tm_year+1900,t->tm_mon+1,t->tm_mday,t->tm_hour,t->tm_min,t->tm_sec);
  strncpy (th->t_artist, artist, 64);
}

Project: LibRaw
File: dcraw.c

void CLASS setPhaseOneFeatures (unsigned id) {

  ushort i;
  static const struct {
    ushort id;
    char t_model[32];
  } p1_unique[] = {
    // Phase One section:
    {1, "Hasselblad V"},
    {10, "PhaseOne/Mamiya"},
    {12, "Contax 645"},
    {16, "Hasselblad V"},
    {17, "Hasselblad V"},
    {18, "Contax 645"},
    {19, "PhaseOne/Mamiya"},
    {20, "Hasselblad V"},
    {21, "Contax 645"},
    {22, "PhaseOne/Mamiya"},
    {23, "Hasselblad V"},
    {24, "Hasselblad H"},
    {25, "PhaseOne/Mamiya"},
    {32, "Contax 645"},
    {34, "Hasselblad V"},
    {35, "Hasselblad V"},
    {36, "Hasselblad H"},
    {37, "Contax 645"},
    {38, "PhaseOne/Mamiya"},
    {39, "Hasselblad V"},
    {40, "Hasselblad H"},
    {41, "Contax 645"},
    {42, "PhaseOne/Mamiya"},
    {44, "Hasselblad V"},
    {45, "Hasselblad H"},
    {46, "Contax 645"},
    {47, "PhaseOne/Mamiya"},
    {48, "Hasselblad V"},
    {49, "Hasselblad H"},
    {50, "Contax 645"},
    {51, "PhaseOne/Mamiya"},
    {52, "Hasselblad V"},
    {53, "Hasselblad H"},
    {54, "Contax 645"},
    {55, "PhaseOne/Mamiya"},
    {67, "Hasselblad V"},
    {68, "Hasselblad H"},
    {69, "Contax 645"},
    {70, "PhaseOne/Mamiya"},
    {71, "Hasselblad V"},
    {72, "Hasselblad H"},
    {73, "Contax 645"},
    {74, "PhaseOne/Mamiya"},
    {76, "Hasselblad V"},
    {77, "Hasselblad H"},
    {78, "Contax 645"},
    {79, "PhaseOne/Mamiya"},
    {80, "Hasselblad V"},
    {81, "Hasselblad H"},
    {82, "Contax 645"},
    {83, "PhaseOne/Mamiya"},
    {84, "Hasselblad V"},
    {85, "Hasselblad H"},
    {86, "Contax 645"},
    {87, "PhaseOne/Mamiya"},
    {99, "Hasselblad V"},
    {100, "Hasselblad H"},
    {101, "Contax 645"},
    {102, "PhaseOne/Mamiya"},
    {103, "Hasselblad V"},
    {104, "Hasselblad H"},
    {105, "PhaseOne/Mamiya"},
    {106, "Contax 645"},
    {112, "Hasselblad V"},
    {113, "Hasselblad H"},
    {114, "Contax 645"},
    {115, "PhaseOne/Mamiya"},
    {131, "Hasselblad V"},
    {132, "Hasselblad H"},
    {133, "Contax 645"},
    {134, "PhaseOne/Mamiya"},
    {135, "Hasselblad V"},
    {136, "Hasselblad H"},
    {137, "Contax 645"},
    {138, "PhaseOne/Mamiya"},
    {140, "Hasselblad V"},
    {141, "Hasselblad H"},
    {142, "Contax 645"},
    {143, "PhaseOne/Mamiya"},
    {148, "Hasselblad V"},
    {149, "Hasselblad H"},
    {150, "Contax 645"},
    {151, "PhaseOne/Mamiya"},
    {160, "A-250"},
    {161, "A-260"},
    {162, "A-280"},
    {167, "Hasselblad V"},
    {168, "Hasselblad H"},
    {169, "Contax 645"},
    {170, "PhaseOne/Mamiya"},
    {172, "Hasselblad V"},
    {173, "Hasselblad H"},
    {174, "Contax 645"},
    {175, "PhaseOne/Mamiya"},
    {176, "Hasselblad V"},
    {177, "Hasselblad H"},
    {178, "Contax 645"},
    {179, "PhaseOne/Mamiya"},
    {180, "Hasselblad V"},
    {181, "Hasselblad H"},
    {182, "Contax 645"},
    {183, "PhaseOne/Mamiya"},
    {208, "Hasselblad V"},
    {211, "PhaseOne/Mamiya"},
    {448, "Phase One 645AF"},
    {457, "Phase One 645DF"},
    {471, "Phase One 645DF+"},
    {704, "Phase One iXA"},
    {705, "Phase One iXA - R"},
    {706, "Phase One iXU 150"},
    {707, "Phase One iXU 150 - NIR"},
    {708, "Phase One iXU 180"},
    {721, "Phase One iXR"},
    // Leaf section:
    {333,"Mamiya"},
    {329,"Universal"},
    {330,"Hasselblad H1/H2"},
    {332,"Contax"},
    {336,"AFi"},
    {327,"Mamiya"},
    {324,"Universal"},
    {325,"Hasselblad H1/H2"},
    {326,"Contax"},
    {335,"AFi"},
    {340,"Mamiya"},
    {337,"Universal"},
    {338,"Hasselblad H1/H2"},
    {339,"Contax"},
    {323,"Mamiya"},
    {320,"Universal"},
    {322,"Hasselblad H1/H2"},
    {321,"Contax"},
    {334,"AFi"},
    {369,"Universal"},
    {370,"Mamiya"},
    {371,"Hasselblad H1/H2"},
    {372,"Contax"},
    {373,"Afi"},
  };
  if (id && !imgdata.lens.makernotes.body[0]) {
    for (i=0; i < sizeof p1_unique / sizeof *p1_unique; i++)
      if (id == p1_unique[i].id) {
        strcpy(imgdata.lens.makernotes.body,p1_unique[i].t_model);
      }
  }
  return;
}

Project: LibRaw
File: dcraw.c

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

  if (strcmp (input, "embed"))
    hInProfile = cmsOpenProfileFromFile (input, "r");
  else if (profile_length) {
#ifndef LIBRAW_LIBRARY_BUILD
    prof = (char *) malloc (profile_length);
    merror (prof, "apply_profile()");
    fseek (ifp, profile_offset, SEEK_SET);
    fread (prof, 1, profile_length, ifp);
    hInProfile = cmsOpenProfileFromMem (prof, profile_length);
    free (prof);
#else
    hInProfile = cmsOpenProfileFromMem (imgdata.color.profile, profile_length);
#endif
  } else
    {
#ifdef LIBRAW_LIBRARY_BUILD
          imgdata.process_warnings |= LIBRAW_WARN_NO_EMBEDDED_PROFILE;
#endif
#ifdef DCRAW_VERBOSE
          fprintf (stderr,_("%s has no embedded profile.\n"), ifname);
#endif
    }
  if (!hInProfile)
      {
#ifdef LIBRAW_LIBRARY_BUILD
          imgdata.process_warnings |= LIBRAW_WARN_NO_INPUT_PROFILE;
#endif
          return;
      }
  if (!output)
    hOutProfile = cmsCreate_sRGBProfile();
  else if ((fp = fopen (output, "rb"))) {
    fread (&size, 4, 1, fp);
    fseek (fp, 0, SEEK_SET);
    oprof = (unsigned *) malloc (size = ntohl(size));
    merror (oprof, "apply_profile()");
    fread (oprof, 1, size, fp);
    fclose (fp);
    if (!(hOutProfile = cmsOpenProfileFromMem (oprof, size))) {
      free (oprof);
      oprof = 0;
    }
  }
#ifdef DCRAW_VERBOSE
 else
    fprintf (stderr,_("Cannot open file %s!\n"), output);
#endif
  if (!hOutProfile)
      {
#ifdef LIBRAW_LIBRARY_BUILD
          imgdata.process_warnings |= LIBRAW_WARN_BAD_OUTPUT_PROFILE;
#endif
          goto quit;
      }
#ifdef DCRAW_VERBOSE
  if (verbose)
    fprintf (stderr,_("Applying color profile...\n"));
#endif
#ifdef LIBRAW_LIBRARY_BUILD
  RUN_CALLBACK(LIBRAW_PROGRESS_APPLY_PROFILE,0,2);
#endif
  hTransform = cmsCreateTransform (hInProfile, TYPE_RGBA_16,
	hOutProfile, TYPE_RGBA_16, INTENT_PERCEPTUAL, 0);
  cmsDoTransform (hTransform, image, image, width*height);
  raw_color = 1;		/* Don't use rgb_cam with a profile */
  cmsDeleteTransform (hTransform);
  cmsCloseProfile (hOutProfile);
quit:
  cmsCloseProfile (hInProfile);
#ifdef LIBRAW_LIBRARY_BUILD
  RUN_CALLBACK(LIBRAW_PROGRESS_APPLY_PROFILE,1,2);
#endif
}

Project: LibRaw
File: dcraw.c

void CLASS process_Sony_0x940c (uchar * buf)
{
  ushort lid2;
  if (imgdata.lens.makernotes.LensMount != Canon_EF)
    {
      switch (SonySubstitution[buf[0x0008]]) {
      case 1:
      case 5:
        imgdata.lens.makernotes.LensMount = Minolta_A;
        break;
      case 4:
        imgdata.lens.makernotes.LensMount = Sony_E;
        break;
      }
    }
  lid2 = (((ushort)SonySubstitution[buf[0x000a]])<<8) |
    ((ushort)SonySubstitution[buf[0x0009]]);
  if ((lid2 > 0) && (lid2 < 32784))
    parseSonyLensType2 (SonySubstitution[buf[0x000a]],	// LensType2 - Sony lens ids
                        SonySubstitution[buf[0x0009]]);
  return;
}

Project: LibRaw
File: libraw_cxx.cpp

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

  x3f_header_t *H = NULL;
  x3f_directory_section_t *DS = NULL;

  H = &x3f->header;
  // Parse RAW size from RAW section
  x3f_directory_entry_t *DE = x3f_get_raw(x3f);
  if(!DE) return;
  imgdata.sizes.flip = H->rotation;
  x3f_directory_entry_header_t *DEH = &DE->header;
  x3f_image_data_t *ID = &DEH->data_subsection.image_data;
  imgdata.sizes.raw_width = ID->columns;
  imgdata.sizes.raw_height = ID->rows;
  // Parse other params from property section
  DE = x3f_get_prop(x3f);
  if((x3f_load_data(x3f,DE) == X3F_OK))
  {
	  // Parse property list
	  DEH = &DE->header;
	  x3f_property_list_t *PL = &DEH->data_subsection.property_list;
	  if (PL->property_table.size != 0) {
		  int i;
		  x3f_property_t *P = PL->property_table.element;
		  for (i=0; i<PL->num_properties; i++) {
			  char name[100], value[100];
			  utf2char(P[i].name,name);
			  utf2char(P[i].value,value);
			  if (!strcmp (name, "ISO"))
				  imgdata.other.iso_speed = atoi(value);
			  if (!strcmp (name, "CAMMANUF"))
				  strcpy (imgdata.idata.make, value);
			  if (!strcmp (name, "CAMMODEL"))
				  strcpy (imgdata.idata.model, value);
			  if (!strcmp (name, "WB_DESC"))
				  strcpy (imgdata.color.model2, value);
			  if (!strcmp (name, "TIME"))
				  imgdata.other.timestamp = atoi(value);
#if 0
			  if (!strcmp (name, "EXPTIME"))
				  imgdata.other.shutter = atoi(value) / 1000000.0;
#endif
			  if (!strcmp (name, "SHUTTER"))
				  imgdata.other.shutter = atof(value);
			  if (!strcmp (name, "APERTURE"))
				  imgdata.other.aperture = atof(value);
			  if (!strcmp (name, "FLENGTH"))
				  imgdata.other.focal_len = atof(value);
		  }
		  imgdata.idata.raw_count=1;
		  load_raw = &LibRaw::x3f_load_raw;
		  imgdata.sizes.raw_pitch = imgdata.sizes.raw_width*6;
		  imgdata.idata.is_foveon = 1;
		  libraw_internal_data.internal_output_params.raw_color=1; // Force adobe coeff
		  imgdata.color.maximum=0x3fff; // To be reset by color table
		  libraw_internal_data.unpacker_data.order = 0x4949;
	  }
  }
  else
  {
	  // No property list
	  if(imgdata.sizes.raw_width == 5888 ||imgdata.sizes.raw_width == 2944 ) // dp2Q
	  {
		  imgdata.idata.raw_count=1;
		  load_raw = &LibRaw::x3f_load_raw;
		  imgdata.sizes.raw_pitch = imgdata.sizes.raw_width*6;
		  imgdata.idata.is_foveon = 1;
		  libraw_internal_data.internal_output_params.raw_color=1; // Force adobe coeff
		  libraw_internal_data.unpacker_data.order = 0x4949;
		  strcpy (imgdata.idata.make, "SIGMA");
#if 1
		  // Try to find model number in first 2048 bytes;
		  int pos = libraw_internal_data.internal_data.input->tell();
		  libraw_internal_data.internal_data.input->seek(0,SEEK_SET);
		  unsigned char buf[2048];
		  libraw_internal_data.internal_data.input->read(buf,2048,1);
		  libraw_internal_data.internal_data.input->seek(pos,SEEK_SET);
		  unsigned char *fnd=(unsigned char*)lr_memmem(buf,2048,"SIGMA dp",8);
		  if(fnd)
		  {
			  unsigned char *nm = fnd+8;
			  snprintf(imgdata.idata.model,64,"dp%c Quattro",*nm<='9' && *nm >='0' ? *nm: '2');
		  }
		  else
#endif
			strcpy (imgdata.idata.model, "dp2 Quattro");
	  }
  }
  // Try to get thumbnail data
  LibRaw_thumbnail_formats format = LIBRAW_THUMBNAIL_UNKNOWN;
  if(DE = x3f_get_thumb_jpeg(x3f))
    {
      format = LIBRAW_THUMBNAIL_JPEG;
    }
  else if(DE = x3f_get_thumb_plain(x3f))
    {
      format = LIBRAW_THUMBNAIL_BITMAP;
    }
  if(DE)
    {
      x3f_directory_entry_header_t *DEH = &DE->header;
      x3f_image_data_t *ID = &DEH->data_subsection.image_data;
      imgdata.thumbnail.twidth = ID->columns;
      imgdata.thumbnail.theight = ID->rows;
      imgdata.thumbnail.tcolors = 3;
      imgdata.thumbnail.tformat = format;
      libraw_internal_data.internal_data.toffset = DE->input.offset;
      write_thumb = &LibRaw::x3f_thumb_loader;
    }
}

Project: LibRaw
File: dcraw.c

void CLASS setPentaxBodyFeatures (unsigned id)
{
  switch (id) {
  case 0x12994:
  case 0x12aa2:
  case 0x12b1a:
  case 0x12b60:
  case 0x12b7e:
  case 0x12b80:
  case 0x12b9c:
  case 0x12b9d:
  case 0x12ba2:
  case 0x12c1e:
  case 0x12c20:
  case 0x12cd2:
  case 0x12cd4:
  case 0x12cfa:
  case 0x12d72:
  case 0x12d73:
  case 0x12db8:
  case 0x12dfe:
  case 0x12e6c:
  case 0x12e76:
  case 0x12ef8:
  case 0x12f52:
  case 0x12f70:
  case 0x12f71:
  case 0x12fb6:
  case 0x12fc0:
  case 0x12fca:
  case 0x1301a:
    imgdata.lens.makernotes.LensMount = Pentax_K;
    imgdata.lens.makernotes.CameraMount = Pentax_K;
    imgdata.lens.makernotes.CameraFormat = APSC;
    break;
  case 0x12e08:
  case 0x13010:
    imgdata.lens.makernotes.LensMount = Pentax_645;
    imgdata.lens.makernotes.LensFormat = MF;
    imgdata.lens.makernotes.CameraMount = Pentax_645;
    imgdata.lens.makernotes.CameraFormat = MF;
    break;
  case 0x12ee4:
  case 0x12f66:
  case 0x12f7a:
  case 0x1302e:
    imgdata.lens.makernotes.LensMount = Pentax_Q;
    imgdata.lens.makernotes.CameraMount = Pentax_Q;
    break;
  default:
    imgdata.lens.makernotes.LensMount = FixedLens;
    imgdata.lens.makernotes.CameraMount = FixedLens;
  }
  return;
}

Project: LibRaw
File: unprocessed_raw.cpp

void write_ppm(unsigned width, unsigned height, unsigned short *bitmap, const char *fname)
{
    if(!bitmap) return;

    FILE *f = fopen(fname,"wb");
    if(!f) return;
    int bits = 16;
    fprintf (f, "P5\n%d %d\n%d\n", width, height, (1 << bits)-1);
    unsigned char *data = (unsigned char *)bitmap;
    unsigned data_size = width*height*2;
#define SWAP(a,b) { a ^= b; a ^= (b ^= a); }
    for(unsigned i=0; i< data_size; i+=2)
            SWAP(data[i],data[i+1]);
#undef SWAP
    fwrite(data,data_size,1,f);
    fclose(f);
}

Project: LibRaw
File: libraw_cxx.cpp

void LibRaw:: recycle_datastream() 
{
  if(libraw_internal_data.internal_data.input && libraw_internal_data.internal_data.input_internal) 
    { 
      delete libraw_internal_data.internal_data.input; 
      libraw_internal_data.internal_data.input = NULL;
    }
  libraw_internal_data.internal_data.input_internal = 0;
}

Project: LibRaw
File: dcraw.c

void CLASS setSonyBodyFeatures (unsigned id) {

  if (	// FF cameras
      (id == 257) ||		// a900
      (id == 269) ||		// a850
      (id == 340) ||		// ILCE-7M2
      (id == 318) ||		// ILCE-7S
      (id == 311) ||		// ILCE-7R
      (id == 306) ||		// ILCE-7
      (id == 298) ||		// DSC-RX1
      (id == 299) ||		// NEX-VG900
      (id == 310) ||		// DSC-RX1R
      (id == 294)				// SLT-99
      )
    {
      imgdata.lens.makernotes.CameraFormat = FF;
    }
  else
    {
      imgdata.lens.makernotes.CameraFormat = APSC;
    }

  if (	// E-mount cameras
      // ILCE:
      (id == 302) ||
      (id == 306) ||
      (id == 311) ||
      (id == 312) ||
      (id == 313) ||
      (id == 318) ||
      (id == 339) ||
      (id == 340) ||
      (id == 346)	||
      // 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 = 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 = Minolta_A;
    }

  else if (	// DSC
           (id == 002) ||
           (id == 297) ||
           (id == 298) ||
           (id == 308) ||
           (id == 309) ||
           (id == 310) ||
           (id == 317)
           )
    {
      imgdata.lens.makernotes.CameraMount = FixedLens;
      imgdata.lens.makernotes.LensMount = FixedLens;
    }
  return;
}

Project: LibRaw
File: dcraw.c

void CLASS parse_fuji (int offset)
{
  unsigned entries, tag, len, save, c;

  fseek (ifp, offset, SEEK_SET);
  entries = get4();
  if (entries > 255) return;
  while (entries--) {
    tag = get2();
    len = get2();
    save = ftell(ifp);
    if (tag == 0x100) {
      raw_height = get2();
      raw_width  = get2();
    } else if (tag == 0x121) {
      height = get2();
      if ((width = get2()) == 4284) width += 3;
    } else if (tag == 0x130) {
      fuji_layout = fgetc(ifp) >> 7;
      fuji_width = !(fgetc(ifp) & 8);
    } else if (tag == 0x131) {
      filters = 9;
      FORC(36) xtrans_abs[0][35-c] = fgetc(ifp) & 3;
    } else if (tag == 0x2ff0) {
      FORC4 cam_mul[c ^ 1] = get2();
    } else if (tag == 0xc000) {
      c = order;
      order = 0x4949;
      if ((tag = get4()) > 10000) tag = get4();
      width = tag;
      height = get4();
      order = c;
    }
    fseek (ifp, save+len, SEEK_SET);
  }
  height <<= fuji_layout;
  width  >>= fuji_layout;
}

Project: LibRaw
File: libraw_cxx.cpp

int LibRaw::phase_one_subtract_black(ushort *src, ushort *dest)
{
  
  try
    {
      if (O.user_black < 0 && O.user_cblack[0] <= -1000000 && O.user_cblack[1] <= -1000000 && O.user_cblack[2] <= -1000000 && O.user_cblack[3] <= -1000000)
        {
          if (!imgdata.rawdata.ph1_cblack || !imgdata.rawdata.ph1_rblack)
            {
              register int bl = imgdata.color.phase_one_data.t_black;
              for (int row = 0; row < S.raw_height; row++)
                {
                  checkCancel();
                  for (int col = 0; col < S.raw_width; col++)
                    {
                      int idx = row*S.raw_width + col;
                      int val = int(src[idx]) - bl;
                      dest[idx] = val>0 ? val : 0;
                    }
                }
            }
          else
            {
              register int bl = imgdata.color.phase_one_data.t_black;
              for (int row = 0; row < S.raw_height; row++)
                {
                  checkCancel();
                  for (int col = 0; col < S.raw_width; col++)
                    {
                      int idx = row*S.raw_width + col;
                      int val = int(src[idx]) - bl
                      + imgdata.rawdata.ph1_cblack[row][col >= imgdata.rawdata.color.phase_one_data.split_col]
                        + imgdata.rawdata.ph1_rblack[col][row >= imgdata.rawdata.color.phase_one_data.split_row];
                      dest[idx] = val>0 ? val : 0;
                    }
                }
            }
        }
      else // black set by user interaction
        {
          // Black level in cblack!
          for (int row = 0; row < S.raw_height; row++)
            {
              checkCancel();
              unsigned short cblk[16];
              for (int cc = 0; cc < 16; cc++)
                cblk[cc] = C.cblack[fcol(row, cc)];
              for (int col = 0; col < S.raw_width; col++)
                {
                  int idx = row*S.raw_width + col;
                  ushort val = src[idx];
                  ushort bl = cblk[col & 0xf];
                  dest[idx] = val>bl ? val - bl : 0;
                }
            }
        }
      return 0;
    }
  catch (LibRaw_exceptions err) {
    return LIBRAW_CANCELLED_BY_CALLBACK;
  }
}

Project: LibRaw
File: dcraw.c

void CLASS parse_kodak_ifd (int base)
{
  unsigned entries, tag, type, len, save;
  int i, c, wbi=-2, wbtemp=6500;
  float mul[3]={1,1,1}, num;
  static const int wbtag[] = { 64037,64040,64039,64041,-1,-1,64042 };

  entries = get2();
  if (entries > 1024) return;
  while (entries--) {
    tiff_get (base, &tag, &type, &len, &save);
    if (tag == 1020) wbi = getint(type);
    if (tag == 1021 && len == 72) {		/* WB set in software */
      fseek (ifp, 40, SEEK_CUR);
      FORC3 cam_mul[c] = 2048.0 / get2();
      wbi = -2;
    }
    if (tag == 2118) wbtemp = getint(type);
    if (tag == 2120 + wbi && wbi >= 0)
      FORC3 cam_mul[c] = 2048.0 / getreal(type);
    if (tag == 2130 + wbi)
      FORC3 mul[c] = getreal(type);
    if (tag == 2140 + wbi && wbi >= 0)
      FORC3 {
	for (num=i=0; i < 4; i++)
	  num += getreal(type) * pow (wbtemp/100.0, i);
	cam_mul[c] = 2048 / (num * mul[c]);
      }
    if (tag == 2317) linear_table (len);
    if (tag == 6020) iso_speed = getint(type);
    if (tag == 64013) wbi = fgetc(ifp);
    if ((unsigned) wbi < 7 && tag == wbtag[wbi])
      FORC3 cam_mul[c] = get4();
    if (tag == 64019) width = getint(type);
    if (tag == 64020) height = (getint(type)+1) & -2;
    fseek (ifp, save, SEEK_SET);
  }
}

Project: LibRaw
File: libraw_cxx.cpp

  void default_data_callback(void*,const char *file, const int offset)
  {
    if(offset < 0)
      fprintf (stderr,"%s: Unexpected end of file\n", file?file:"unknown file");
    else
      fprintf (stderr,"%s: data corrupted at %d\n",file?file:"unknown file",offset); 
  }

Project: LibRaw
File: dcraw.c

void CLASS write_ppm_tiff()
{
  struct tiff_hdr th;
  uchar *ppm;
  ushort *ppm2;
  int c, row, col, soff, rstep, cstep;
  int perc, val, total, t_white=0x2000;

#ifdef LIBRAW_LIBRARY_BUILD
  perc = width * height * auto_bright_thr;
#else
  perc = width * height * 0.01;		/* 99th percentile white level */
#endif
  if (fuji_width) perc /= 2;
  if (!((highlight & ~2) || no_auto_bright))
    for (t_white=c=0; c < colors; c++) {
      for (val=0x2000, total=0; --val > 32; )
	if ((total += histogram[c][val]) > perc) break;
      if (t_white < val) t_white = val;
    }
  gamma_curve (gamm[0], gamm[1], 2, (t_white << 3)/bright);
  iheight = height;
  iwidth  = width;
  if (flip & 4) SWAP(height,width);
  ppm = (uchar *) calloc (width, colors*output_bps/8);
  ppm2 = (ushort *) ppm;
  merror (ppm, "write_ppm_tiff()");
  if (output_tiff) {
    tiff_head (&th, 1);
    fwrite (&th, sizeof th, 1, ofp);
    if (oprof)
      fwrite (oprof, ntohl(oprof[0]), 1, ofp);
  } else if (colors > 3)
    fprintf (ofp,
      "P7\nWIDTH %d\nHEIGHT %d\nDEPTH %d\nMAXVAL %d\nTUPLTYPE %s\nENDHDR\n",
	width, height, colors, (1 << output_bps)-1, cdesc);
  else
    fprintf (ofp, "P%d\n%d %d\n%d\n",
	colors/2+5, width, height, (1 << output_bps)-1);
  soff  = flip_index (0, 0);
  cstep = flip_index (0, 1) - soff;
  rstep = flip_index (1, 0) - flip_index (0, width);
  for (row=0; row < height; row++, soff += rstep) {
    for (col=0; col < width; col++, soff += cstep)
      if (output_bps == 8)
	   FORCC ppm [col*colors+c] = curve[image[soff][c]] >> 8;
      else FORCC ppm2[col*colors+c] = curve[image[soff][c]];
    if (output_bps == 16 && !output_tiff && htons(0x55aa) != 0x55aa)
      swab ((char*)ppm2, (char*)ppm2, width*colors*2);
    fwrite (ppm, colors*output_bps/8, width, ofp);
  }
  free (ppm);
}

Project: LibRaw
File: dcraw.c

void CLASS parse_makernote_0xc634(int base, int uptag, unsigned dng_writer)
{
  unsigned offset = 0, entries, tag, type, len, save, c;
  unsigned i;

  uchar NikonKey, ci, cj, ck;
  unsigned serial = 0;
  unsigned NikonLensDataVersion = 0;
  unsigned lenNikonLensData = 0;

  uchar *CanonCameraInfo;
  unsigned lenCanonCameraInfo = 0;

  unsigned uidPentax = 0;

  uchar *table_buf;
  uchar *table_buf_0x9050;
  ushort table_buf_0x9050_present = 0;
  uchar *table_buf_0x940c;
  ushort table_buf_0x940c_present = 0;

  short morder, sorder = order;
  char buf[10];

  fread(buf, 1, 10, ifp);
  if (!strcmp(buf, "Nikon")) {
    base = ftell(ifp);
    order = get2();
    if (get2() != 42) goto quit;
    offset = get4();
    fseek(ifp, offset - 8, SEEK_CUR);
  }
  else if (!strcmp(buf, "OLYMPUS") ||
           !strcmp(buf, "PENTAX ") ||
           (!strncmp(make, "SAMSUNG", 7) && (dng_writer == CameraDNG))) {
    base = ftell(ifp) - 10;
    fseek(ifp, -2, SEEK_CUR);
    order = get2();
    if (buf[0] == 'O') get2();
  }
  else if (!strncmp(buf, "SONY", 4) ||
           !strcmp(buf, "Panasonic")) {
    goto nf;
  }
  else if (!strncmp(buf, "FUJIFILM", 8)) {
    base = ftell(ifp) - 10;
  nf: order = 0x4949;
    fseek(ifp, 2, SEEK_CUR);
  }
  else if (!strcmp(buf, "OLYMP") ||
           !strcmp(buf, "LEICA") ||
           !strcmp(buf, "Ricoh") ||
           !strcmp(buf, "EPSON"))
    fseek(ifp, -2, SEEK_CUR);
  else if (!strcmp(buf, "AOC") ||
           !strcmp(buf, "QVC"))
    fseek(ifp, -4, SEEK_CUR);
  else {
    fseek(ifp, -10, SEEK_CUR);
    if ((!strncmp(make, "SAMSUNG", 7) &&
				(dng_writer == AdobeDNG)))
      base = ftell(ifp);
  }

  entries = get2();

// if (dng_writer == AdobeDNG)
//   printf("\n*** parse_makernote_0xc634: AdobeDNG");
// else if (dng_writer == CameraDNG)
//   printf("\n*** parse_makernote_0xc634: CameraDNG");

//   printf ("\n\tbuf  =%s=\n\tmake  =%s=\n\tmodel =%s=\n\tbase: 0x%x\n\tentries: %d\n",
//   		buf, make, model, base, entries);

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

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

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

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

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

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

        else if (tag == 0x10 && type == 4)	// Canon ModelID
          {
            unique_id = get4();
            setCanonBodyFeatures(unique_id);
            if (lenCanonCameraInfo) processCanonCameraInfo(unique_id, CanonCameraInfo);
          }

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

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

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

    else if (!strncmp(make, "NIKON", 5))
      {
        if (tag == 0x1d)							// serial number
          while ((c = fgetc(ifp)) && c != EOF)
            serial = serial * 10 + (isdigit(c) ? c - '0' : c % 10);

        else if (tag == 0x0082)				// lens attachment
          {
            fread(imgdata.lens.makernotes.Attachment, len, 1, ifp);
          }
        else if (tag == 0x0083)				// lens type
          {
            imgdata.lens.nikon.NikonLensType = fgetc(ifp);
            if (!(imgdata.lens.nikon.NikonLensType & 0x01))
              {
                imgdata.lens.makernotes.LensFeatures_pre[0] = 'A';
                imgdata.lens.makernotes.LensFeatures_pre[1] = 'F';
              }
            if (imgdata.lens.nikon.NikonLensType & 0x02)
              {
                if (imgdata.lens.nikon.NikonLensType & 0x04)
                  imgdata.lens.makernotes.LensFeatures_suf[0] = 'G';
                else
                  imgdata.lens.makernotes.LensFeatures_suf[0] = 'D';
                imgdata.lens.makernotes.LensFeatures_suf[1] = ' ';
              }
            if (imgdata.lens.nikon.NikonLensType & 0x08)
              {
                imgdata.lens.makernotes.LensFeatures_suf[2] = 'V';
                imgdata.lens.makernotes.LensFeatures_suf[3] = 'R';
              }
            if (imgdata.lens.nikon.NikonLensType & 0x10)
              {
                imgdata.lens.makernotes.LensMount = Nikon_CX;
              }

            if (imgdata.lens.nikon.NikonLensType & 0x20)
              {
                strcpy(imgdata.lens.makernotes.Adapter, "FT-1");
              }
            imgdata.lens.nikon.NikonLensType = imgdata.lens.nikon.NikonLensType & 0xdf;
          }
        else if (tag == 0x0084)				// lens
          {
            imgdata.lens.makernotes.MinFocal = getreal(type);
            imgdata.lens.makernotes.MaxFocal = getreal(type);
            imgdata.lens.makernotes.MaxAp4MinFocal = getreal(type);
            imgdata.lens.makernotes.MaxAp4MaxFocal = getreal(type);
          }
        else if (tag == 0x008b)				// lens f-stops
          {
            uchar a, b, c;
            a = fgetc(ifp);
            b = fgetc(ifp);
            c = fgetc(ifp);
            if (c)
              {
                imgdata.lens.nikon.NikonLensFStops = a*b*(12/c);
                imgdata.lens.makernotes.LensFStops =
                  (float)imgdata.lens.nikon.NikonLensFStops /12.0f;
              }
          }
        else if ((tag == 0x0093) &&		// compression
                 (get2() == 8))				// sRAW
          {
            imgdata.color.wb_applied = 1;
            imgdata.color.gamma_applied = 1;
          }

        else if (tag == 0x0098)				// contains lens data
          {
            for (i = 0; i < 4; i++)
              {
                NikonLensDataVersion = NikonLensDataVersion * 10 + fgetc(ifp) - '0';
              }
            switch (NikonLensDataVersion)
              {
              case 100: lenNikonLensData = 9; imgdata.lens.makernotes.LensMount = Nikon_F; break;
              case 101:
              case 201:	// encrypted, starting from v.201
              case 202:
              case 203: lenNikonLensData = 15; imgdata.lens.makernotes.LensMount = Nikon_F; break;
              case 204: lenNikonLensData = 16; imgdata.lens.makernotes.LensMount = Nikon_F; break;
              case 400: lenNikonLensData = 459; break;
              case 401: lenNikonLensData = 590; break;
              case 402: lenNikonLensData = 509; break;
              case 403: lenNikonLensData = 879; break;
              }
            table_buf = (uchar*)malloc(lenNikonLensData);
            fread(table_buf, lenNikonLensData, 1, ifp);
            if ((NikonLensDataVersion < 201) && lenNikonLensData)
            {
              processNikonLensData(table_buf, lenNikonLensData);
              lenNikonLensData = 0;
            }
          }

        else if (tag == 0xa7)					// shutter count
          {
            NikonKey = fgetc(ifp) ^ fgetc(ifp) ^ fgetc(ifp) ^ fgetc(ifp);
            if ((NikonLensDataVersion > 200) && lenNikonLensData)
              {
                ci = xlat[0][serial & 0xff];
                cj = xlat[1][NikonKey];
                ck = 0x60;
                for (i = 0; i < lenNikonLensData; i++)
                  table_buf[i] ^= (cj += ci * ck++);
                processNikonLensData(table_buf, lenNikonLensData);
                lenNikonLensData = 0;
              }
          }

        else if (tag == 37 && (!iso_speed || iso_speed == 65535))
          {
            unsigned char cc;
            fread(&cc, 1, 1, ifp);
            iso_speed = (int)(100.0 * powf64(2.0, (double)(cc) / 12.0 - 5.0));
            break;
          }
      }

    else if (!strncmp(make, "OLYMPUS", 7))
      {
        if (tag == 0x2010)
          {
            fseek(ifp, save - 4, SEEK_SET);
            fseek(ifp, base + get4(), SEEK_SET);
            parse_makernote_0xc634(base, 0x2010, dng_writer);
          }

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

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

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

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

        if (tag == 0xb001)			// Sony ModelID
          {
            unique_id = imgdata.lens.makernotes.CamID = get2();
            setSonyBodyFeatures(unique_id);
            if (table_buf_0x9050_present)
              {
                process_Sony_0x9050(table_buf_0x9050, unique_id);
                free (table_buf_0x9050);
                table_buf_0x9050_present = 0;
              }
            if (table_buf_0x940c_present)
              {
                if (imgdata.lens.makernotes.CameraMount == Sony_E)
                  {
                    process_Sony_0x940c(table_buf_0x940c);
                  }
                free (table_buf_0x940c);
                table_buf_0x940c_present = 0;
              }
          }
        else if ((tag == 0x0010) &&					// CameraInfo
                 strncasecmp(model, "DSLR-A100", 9) &&
                 strncasecmp(model, "NEX-5C", 6) &&
                 !strncasecmp(make, "SONY", 4) &&
                 ((len == 368) ||			// a700
                  (len == 5478) ||		// a850, a900
                  (len == 5506) ||		// a200, a300, a350
                  (len == 6118) ||		// a230, a290, a330, a380, a390

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

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

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

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

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

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

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

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

Project: LibRaw
File: libraw_cxx.cpp

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

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

    if ( !ID.toffset) 
      {
        return LIBRAW_NO_THUMBNAIL;
      } 
    else if (thumb_load_raw) 
      {
        kodak_thumb_loader();
        T.tformat = LIBRAW_THUMBNAIL_BITMAP;
        SET_PROC_FLAG(LIBRAW_PROGRESS_THUMB_LOAD);
        return 0;
      } 
    else 
      {
        ID.input->seek(ID.toffset, SEEK_SET);
        if ( write_thumb == &LibRaw::jpeg_thumb)
          {
            if(T.thumb) free(T.thumb);
            T.thumb = (char *) malloc (T.tlength);
            merror (T.thumb, "jpeg_thumb()");
            ID.input->read (T.thumb, 1, T.tlength);
            T.tcolors = 3;
            T.tformat = LIBRAW_THUMBNAIL_JPEG;
            SET_PROC_FLAG(LIBRAW_PROGRESS_THUMB_LOAD);
            return 0;
          }
        else if (write_thumb == &LibRaw::ppm_thumb)
          {
            T.tlength = T.twidth * T.theight*3;
            if(T.thumb) free(T.thumb);

            T.thumb = (char *) malloc (T.tlength);
            merror (T.thumb, "ppm_thumb()");

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

            T.tformat = LIBRAW_THUMBNAIL_BITMAP;
            SET_PROC_FLAG(LIBRAW_PROGRESS_THUMB_LOAD);
            return 0;

          }
        else if (write_thumb == &LibRaw::ppm16_thumb)
          {
            T.tlength = T.twidth * T.theight*3;
            ushort *t_thumb = (ushort*)calloc(T.tlength,2);
            ID.input->read(t_thumb,2,T.tlength);
            if ((libraw_internal_data.unpacker_data.order == 0x4949) == (ntohs(0x1234) == 0x1234))
              swab ((char*)t_thumb, (char*)t_thumb, T.tlength*2);

            if(T.thumb) free(T.thumb);
            T.thumb = (char *) malloc (T.tlength);
            merror (T.thumb, "ppm_thumb()");
            for (int i=0; i < T.tlength; i++)
              T.thumb[i] = t_thumb[i] >> 8;
            free(t_thumb);
            T.tformat = LIBRAW_THUMBNAIL_BITMAP;
            SET_PROC_FLAG(LIBRAW_PROGRESS_THUMB_LOAD);
            return 0;

          }
        else if (write_thumb == &LibRaw::x3f_thumb_loader)
          {
            x3f_thumb_loader();
            SET_PROC_FLAG(LIBRAW_PROGRESS_THUMB_LOAD);
            return 0;
          }
#ifdef LIBRAW_DEMOSAIC_PACK_GPL2
        else if (write_thumb == &LibRaw::foveon_thumb)
          {
            foveon_thumb_loader();
            // may return with error, so format is set in
            // foveon thumb loader itself
            SET_PROC_FLAG(LIBRAW_PROGRESS_THUMB_LOAD);
            return 0;
          }
        // else if -- all other write_thumb cases!
#endif
        else
          {
            return LIBRAW_UNSUPPORTED_THUMBNAIL;
          }
      }
    // last resort
    return LIBRAW_UNSUPPORTED_THUMBNAIL;
  }
  catch ( LibRaw_exceptions err) {
    EXCEPTION_HANDLER(err);
  }

}