⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dcraw.c

📁 相片处理程序,纯C语言,从数码相机RAW格式图像转换到任何系统的计算机图像
💻 C
📖 第 1 页 / 共 5 页
字号:
	case 5: pred = pred + ((row[1][0] - row[1][-jh->clrs]) >> 1);	break;	case 6: pred = row[1][0] + ((pred - row[1][-jh->clrs]) >> 1);	break;	case 7: pred = (pred + row[1][0]) >> 1;				break;	default: pred = 0;      }      if ((**row = pred + diff) >> jh->bits) derror();      row[0]++; row[1]++;    }  return row[2];}void CLASS lossless_jpeg_load_raw(){  int jwide, jrow, jcol, val, jidx, i, j, row=0, col=0;  struct jhead jh;  int min=INT_MAX;  ushort *rp;  if (!ljpeg_start (&jh, 0)) return;  jwide = jh.wide * jh.clrs;  for (jrow=0; jrow < jh.high; jrow++) {    rp = ljpeg_row (jrow, &jh);    for (jcol=0; jcol < jwide; jcol++) {      val = *rp++;      if (jh.bits <= 12)	val = curve[val];      if (cr2_slice[0]) {	jidx = jrow*jwide + jcol;	i = jidx / (cr2_slice[1]*jh.high);	if ((j = i >= cr2_slice[0]))		 i  = cr2_slice[0];	jidx -= i * (cr2_slice[1]*jh.high);	row = jidx / cr2_slice[1+j];	col = jidx % cr2_slice[1+j] + i*cr2_slice[1];      }      if (raw_width == 3984 && (col -= 2) < 0)	col += (row--,raw_width);      if ((unsigned) (row-top_margin) < height) {	if ((unsigned) (col-left_margin) < width) {	  BAYER(row-top_margin,col-left_margin) = val;	  if (min > val) min = val;	} else black += val;      }      if (++col >= raw_width)	col = (row++,0);    }  }  free (jh.row);  if (raw_width > width)    black /= (raw_width - width) * height;  if (!strcasecmp(make,"KODAK"))    black = min;}void CLASS canon_sraw_load_raw(){  struct jhead jh;  short *rp=0, *ip;  int jwide, slice, scol, ecol, row, col, jrow=0, jcol=0, pix[3], c;  if (!ljpeg_start (&jh, 0)) return;  jwide = (jh.wide >>= 1) * 4;  for (ecol=slice=0; slice <= cr2_slice[0]; slice++) {    scol = ecol;    ecol += cr2_slice[1] >> 1;    if (!cr2_slice[0] || ecol > width-1) ecol = width & -2;    for (row=0; row < height; row++) {      ip = (short *) image[row*width+scol];      for (col=scol; col < ecol; col+=2, jcol+=4, ip+=8) {	if ((jcol %= jwide) == 0)	  rp = (short *) ljpeg_row (jrow++, &jh);	ip[0] = rp[jcol];	ip[4] = rp[jcol+1];	ip[1] = (short) (rp[jcol+2] << 2) >> 2;	ip[2] = (short) (rp[jcol+3] << 2) >> 2;      }    }  }  for (row=0; row < height; row++) {    ip = (short *) image[row*width+1];    for (col=1; col < width-1; col+=2, ip+=8) {      ip[1] = (ip[-3] + ip[5] + 1) >> 1;      ip[2] = (ip[-2] + ip[6] + 1) >> 1;    }    if (col < width) { ip[1] = ip[-3]; ip[2] = ip[-2]; }    ip = (short *) image[row*width];    for (col=0; col < width; col++, ip+=4) {      pix[0] = ip[2] + ip[0];      pix[2] = ip[1] + ip[0];      pix[1] = ((ip[0] << 12) - ip[1]*778 - (ip[2] << 11)) >> 12;      FORC3 ip[c] = CLIP((pix[c] - 512) * sraw_mul[c] >> 10);    }  }  free (jh.row);  maximum = 0x3fff;}void CLASS adobe_copy_pixel (int row, int col, ushort **rp){  unsigned r, c;  r = row -= top_margin;  c = col -= left_margin;  if (is_raw == 2 && shot_select) (*rp)++;  if (filters) {    if (fuji_width) {      r = row + fuji_width - 1 - (col >> 1);      c = row + ((col+1) >> 1);    }    if (r < height && c < width)      BAYER(r,c) = **rp < 0x1000 ? curve[**rp] : **rp;    *rp += is_raw;  } else {    if (r < height && c < width)      FORC(tiff_samples)	image[row*width+col][c] = (*rp)[c] < 0x1000 ? curve[(*rp)[c]]:(*rp)[c];    *rp += tiff_samples;  }  if (is_raw == 2 && shot_select) (*rp)--;}void CLASS adobe_dng_load_raw_lj(){  unsigned save, trow=0, tcol=0, jwide, jrow, jcol, row, col;  struct jhead jh;  ushort *rp;  while (trow < raw_height) {    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;    for (row=col=jrow=0; jrow < jh.high; jrow++) {      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);      }    }    fseek (ifp, save+4, SEEK_SET);    if ((tcol += tile_width) >= raw_width)      trow += tile_length + (tcol = 0);    free (jh.row);  }}void CLASS adobe_dng_load_raw_nc(){  ushort *pixel, *rp;  int row, col;  pixel = (ushort *) calloc (raw_width * tiff_samples, sizeof *pixel);  merror (pixel, "adobe_dng_load_raw_nc()");  for (row=0; row < raw_height; row++) {    if (tiff_bps == 16)      read_shorts (pixel, raw_width * tiff_samples);    else {      getbits(-1);      for (col=0; col < raw_width * tiff_samples; col++)	pixel[col] = getbits(tiff_bps);    }    for (rp=pixel, col=0; col < raw_width; col++)      adobe_copy_pixel (row, col, &rp);  }  free (pixel);}void CLASS pentax_k10_load_raw(){  static const uchar pentax_tree[] =  { 0,2,3,1,1,1,1,1,1,2,0,0,0,0,0,0,    3,4,2,5,1,6,0,7,8,9,10,11,12 };  int row, col, diff;  ushort vpred[2][2] = {{0,0},{0,0}}, hpred[2];  init_decoder();  make_decoder (pentax_tree, 0);  getbits(-1);  for (row=0; row < height; row++)    for (col=0; col < raw_width; col++) {      diff = ljpeg_diff (first_decode);      if (col < 2) hpred[col] = vpred[row & 1][col] += diff;      else	   hpred[col & 1] += diff;      if (col < width)	BAYER(row,col) = hpred[col & 1];      if (hpred[col & 1] >> 12) derror();    }}void CLASS nikon_compressed_load_raw(){  static const uchar nikon_tree[][32] = {    { 0,1,5,1,1,1,1,1,1,2,0,0,0,0,0,0,	/* 12-bit lossy */      5,4,3,6,2,7,1,0,8,9,11,10,12 },    { 0,1,5,1,1,1,1,1,1,2,0,0,0,0,0,0,	/* 12-bit lossy after split */      0x39,0x5a,0x38,0x27,0x16,5,4,3,2,1,0,11,12,12 },    { 0,1,4,2,3,1,2,0,0,0,0,0,0,0,0,0,  /* 12-bit lossless */      5,4,6,3,7,2,8,1,9,0,10,11,12 },    { 0,1,4,3,1,1,1,1,1,2,0,0,0,0,0,0,	/* 14-bit lossy */      5,6,4,7,8,3,9,2,1,0,10,11,12,13,14 },    { 0,1,5,1,1,1,1,1,1,1,2,0,0,0,0,0,	/* 14-bit lossy after split */      8,0x5c,0x4b,0x3a,0x29,7,6,5,4,3,2,1,0,13,14 },    { 0,1,4,2,2,3,1,2,0,0,0,0,0,0,0,0,	/* 14-bit lossless */      7,6,8,5,9,4,10,3,11,12,2,0,1,13,14 } };  struct decode *dindex;  ushort ver0, ver1, vpred[2][2], hpred[2], csize;  int i, max, step=0, huff=0, split=0, row, col, len, shl, diff;  fseek (ifp, meta_offset, SEEK_SET);  ver0 = fgetc(ifp);  ver1 = fgetc(ifp);  if (ver0 == 0x49 || ver1 == 0x58)    fseek (ifp, 2110, SEEK_CUR);  if (ver0 == 0x46) huff = 2;  if (tiff_bps == 14) huff += 3;  read_shorts (vpred[0], 4);  max = 1 << tiff_bps & 0x7fff;  if ((csize = get2()) > 1)    step = max / (csize-1);  if (ver0 == 0x44 && ver1 == 0x20 && step > 0) {    for (i=0; i < csize; i++)      curve[i*step] = get2();    for (i=0; i < max; i++)      curve[i] = ( curve[i-i%step]*(step-i%step) +		   curve[i-i%step+step]*(i%step) ) / step;    fseek (ifp, meta_offset+562, SEEK_SET);    split = get2();  } else if (ver0 != 0x46 && csize <= 0x4001)    read_shorts (curve, max=csize);  init_decoder();  make_decoder (nikon_tree[huff], 0);  fseek (ifp, data_offset, SEEK_SET);  getbits(-1);  for (row=0; row < height; row++) {    if (split && row == split) {      init_decoder();      make_decoder (nikon_tree[huff+1], 0);    }    for (col=0; col < raw_width; col++) {      for (dindex=first_decode; dindex->branch[0]; )	dindex = dindex->branch[getbits(1)];      len = dindex->leaf & 15;      shl = dindex->leaf >> 4;      diff = ((getbits(len-shl) << 1) + 1) << shl >> 1;      if ((diff & (1 << (len-1))) == 0)	diff -= (1 << len) - !shl;      if (col < 2) hpred[col] = vpred[row & 1][col] += diff;      else	   hpred[col & 1] += diff;      if (hpred[col & 1] >= max) derror();      if ((unsigned) (col-left_margin) < width)	BAYER(row,col-left_margin) = curve[hpred[col & 1] & 0x3fff];    }  }}void CLASS nikon_load_raw(){  int irow, row, col, i;  getbits(-1);  for (irow=0; irow < height; irow++) {    row = irow;    if (make[0] == 'O' || model[0] == 'E') {      row = irow * 2 % height + irow / (height/2);      if (row == 1 && data_offset == 0) {	fseek (ifp, 0, SEEK_END);	fseek (ifp, ftell(ifp)/2, SEEK_SET);	getbits(-1);      }    }    for (col=0; col < raw_width; col++) {      i = getbits(12);      if ((unsigned) (col-left_margin) < width)	BAYER(row,col-left_margin) = i;      if (tiff_compress > 32768 && (col % 10) == 9)	if (getbits(8)) derror();    }  }}/*   Figure out if a NEF file is compressed.  These fancy heuristics   are only needed for the D100, thanks to a bug in some cameras   that tags all images as "compressed". */int CLASS nikon_is_compressed(){  uchar test[256];  int i;  fseek (ifp, data_offset, SEEK_SET);  fread (test, 1, 256, ifp);  for (i=15; i < 256; i+=16)    if (test[i]) return 1;  return 0;}/*   Returns 1 for a Coolpix 995, 0 for anything else. */int CLASS nikon_e995(){  int i, histo[256];  const uchar often[] = { 0x00, 0x55, 0xaa, 0xff };  memset (histo, 0, sizeof histo);  fseek (ifp, -2000, SEEK_END);  for (i=0; i < 2000; i++)    histo[fgetc(ifp)]++;  for (i=0; i < 4; i++)    if (histo[often[i]] < 200)      return 0;  return 1;}/*   Returns 1 for a Coolpix 2100, 0 for anything else. */int CLASS nikon_e2100(){  uchar t[12];  int i;  fseek (ifp, 0, SEEK_SET);  for (i=0; i < 1024; i++) {    fread (t, 1, 12, ifp);    if (((t[2] & t[4] & t[7] & t[9]) >> 4	& t[1] & t[6] & t[8] & t[11] & 3) != 3)      return 0;  }  return 1;}void CLASS nikon_3700(){  int bits, i;  uchar dp[24];  static const struct {    int bits;    char make[12], model[15];  } table[] = {    { 0x00, "PENTAX",  "Optio 33WR" },    { 0x03, "NIKON",   "E3200" },    { 0x32, "NIKON",   "E3700" },    { 0x33, "OLYMPUS", "C740UZ" } };  fseek (ifp, 3072, SEEK_SET);  fread (dp, 1, 24, ifp);  bits = (dp[8] & 3) << 4 | (dp[20] & 3);  for (i=0; i < sizeof table / sizeof *table; i++)    if (bits == table[i].bits) {      strcpy (make,  table[i].make );      strcpy (model, table[i].model);    }}/*   Separates a Minolta DiMAGE Z2 from a Nikon E4300. */int CLASS minolta_z2(){  int i;  char tail[424];  fseek (ifp, -sizeof tail, SEEK_END);  fread (tail, 1, sizeof tail, ifp);  for (i=0; i < sizeof tail; i++)    if (tail[i]) return 1;  return 0;}/* Here raw_width is in bytes, not pixels. */void CLASS nikon_e900_load_raw(){  int offset=0, irow, row, col;  for (irow=0; irow < height; irow++) {    row = irow * 2 % height;    if (row == 1)      offset = - (-offset & -4096);    fseek (ifp, offset, SEEK_SET);    offset += raw_width;    getbits(-1);    for (col=0; col < width; col++)      BAYER(row,col) = getbits(10);  }}void CLASS nikon_e2100_load_raw(){  uchar   data[4608], *dp;  ushort pixel[3072], *pix;  int row, col;  for (row=0; row <= height; row+=2) {    if (row == height) {      fseek (ifp, 0, SEEK_END);      fseek (ifp, ftell(ifp)/2, SEEK_SET);      row = 1;    }    fread (data, 1, width*3/2, ifp);    for (dp=data, pix=pixel; pix < pixel+width; dp+=12, pix+=8) {      pix[0] = (dp[2] >> 4) + (dp[ 3] << 4);      pix[1] = (dp[2] << 8) +  dp[ 1];      pix[2] = (dp[7] >> 4) + (dp[ 0] << 4);      pix[3] = (dp[7] << 8) +  dp[ 6];      pix[4] = (dp[4] >> 4) + (dp[ 5] << 4);      pix[5] = (dp[4] << 8) +  dp[11];      pix[6] = (dp[9] >> 4) + (dp[10] << 4);      pix[7] = (dp[9] << 8) +  dp[ 8];    }    for (col=0; col < width; col++)      BAYER(row,col) = (pixel[col] & 0xfff);  }}/*   The Fuji Super CCD is just a Bayer grid rotated 45 degrees. */void CLASS fuji_load_raw(){  ushort *pixel;  int wide, row, col, r, c;  fseek (ifp, (top_margin*raw_width + left_margin) * 2, SEEK_CUR);  wide = fuji_width << !fuji_layout;  pixel = (ushort *) calloc (wide, sizeof *pixel);  merror (pixel, "fuji_load_raw()");  for (row=0; row < raw_height; row++) {    read_shorts (pixel, wide);    fseek (ifp, 2*(raw_width - wide), SEEK_CUR);    for (col=0; col < wide; col++) {      if (fuji_layout) {	r = fuji_width - 1 - col + (row >> 1);	c = col + ((row+1) >> 1);      } else {	r = fuji_width - 1 + row - (col >> 1);	c = row + ((col+1) >> 1);      }      BAYER(r,c) = pixel[col];    }  }  free (pixel);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -