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

📄 dcraw.c

📁 相片处理程序,纯C语言,从数码相机RAW格式图像转换到任何系统的计算机图像
💻 C
📖 第 1 页 / 共 5 页
字号:
}void CLASS jpeg_thumb (FILE *tfp);void CLASS ppm_thumb (FILE *tfp){  char *thumb;  thumb_length = thumb_width*thumb_height*3;  thumb = (char *) malloc (thumb_length);  merror (thumb, "ppm_thumb()");  fprintf (tfp, "P6\n%d %d\n255\n", thumb_width, thumb_height);  fread  (thumb, 1, thumb_length, ifp);  fwrite (thumb, 1, thumb_length, tfp);  free (thumb);}void CLASS layer_thumb (FILE *tfp){  int i, c;  char *thumb, map[][4] = { "012","102" };  colors = thumb_misc >> 5 & 7;  thumb_length = thumb_width*thumb_height;  thumb = (char *) calloc (colors, thumb_length);  merror (thumb, "layer_thumb()");  fprintf (tfp, "P%d\n%d %d\n255\n",	5 + (colors >> 1), thumb_width, thumb_height);  fread (thumb, thumb_length, colors, ifp);  for (i=0; i < thumb_length; i++)    FORCC putc (thumb[i+thumb_length*(map[thumb_misc >> 8][c]-'0')], tfp);  free (thumb);}void CLASS rollei_thumb (FILE *tfp){  unsigned i;  ushort *thumb;  thumb_length = thumb_width * thumb_height;  thumb = (ushort *) calloc (thumb_length, 2);  merror (thumb, "rollei_thumb()");  fprintf (tfp, "P6\n%d %d\n255\n", thumb_width, thumb_height);  read_shorts (thumb, thumb_length);  for (i=0; i < thumb_length; i++) {    putc (thumb[i] << 3, tfp);    putc (thumb[i] >> 5  << 2, tfp);    putc (thumb[i] >> 11 << 3, tfp);  }  free (thumb);}void CLASS rollei_load_raw(){  uchar pixel[10];  unsigned iten=0, isix, i, buffer=0, row, col, todo[16];  isix = raw_width * raw_height * 5 / 8;  while (fread (pixel, 1, 10, ifp) == 10) {    for (i=0; i < 10; i+=2) {      todo[i]   = iten++;      todo[i+1] = pixel[i] << 8 | pixel[i+1];      buffer    = pixel[i] >> 2 | buffer << 6;    }    for (   ; i < 16; i+=2) {      todo[i]   = isix++;      todo[i+1] = buffer >> (14-i)*5;    }    for (i=0; i < 16; i+=2) {      row = todo[i] / raw_width - top_margin;      col = todo[i] % raw_width - left_margin;      if (row < height && col < width)	BAYER(row,col) = (todo[i+1] & 0x3ff);    }  }  maximum = 0x3ff;}int CLASS bayer (unsigned row, unsigned col){  return (row < height && col < width) ? BAYER(row,col) : 0;}void CLASS phase_one_flat_field (int is_float, int nc){  ushort head[8];  unsigned wide, y, x, c, rend, cend, row, col;  float *mrow, num, mult[4];  read_shorts (head, 8);  wide = head[2] / head[4];  mrow = (float *) calloc (nc*wide, sizeof *mrow);  merror (mrow, "phase_one_flat_field()");  for (y=0; y < head[3] / head[5]; y++) {    for (x=0; x < wide; x++)      for (c=0; c < nc; c+=2) {	num = is_float ? getreal(11) : get2()/32768.0;	if (y==0) mrow[c*wide+x] = num;	else mrow[(c+1)*wide+x] = (num - mrow[c*wide+x]) / head[5];      }    if (y==0) continue;    rend = head[1]-top_margin + y*head[5];    for (row = rend-head[5]; row < height && row < rend; row++) {      for (x=1; x < wide; x++) {	for (c=0; c < nc; c+=2) {	  mult[c] = mrow[c*wide+x-1];	  mult[c+1] = (mrow[c*wide+x] - mult[c]) / head[4];	}	cend = head[0]-left_margin + x*head[4];	for (col = cend-head[4]; col < width && col < cend; col++) {	  c = nc > 2 ? FC(row,col) : 0;	  if (!(c & 1)) {	    c = BAYER(row,col) * mult[c];	    BAYER(row,col) = LIM(c,0,65535);	  }	  for (c=0; c < nc; c+=2)	    mult[c] += mult[c+1];	}      }      for (x=0; x < wide; x++)	for (c=0; c < nc; c+=2)	  mrow[c*wide+x] += mrow[(c+1)*wide+x];    }  }  free (mrow);}void CLASS phase_one_correct(){  unsigned entries, tag, data, save, col, row, type;  int len, i, j, k, cip, val[4], dev[4], sum, max;  int head[9], diff, mindiff=INT_MAX, off_412=0;  static const signed char dir[12][2] =    { {-1,-1}, {-1,1}, {1,-1}, {1,1}, {-2,0}, {0,-2}, {0,2}, {2,0},      {-2,-2}, {-2,2}, {2,-2}, {2,2} };  float poly[8], num, cfrac, frac, mult[2], *yval[2];  ushort curve[0x10000], *xval[2];  if (half_size || !meta_length) return;  if (verbose) fprintf (stderr,_("Phase One correction...\n"));  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 == 0x419) {				/* Polynomial curve */      for (get4(), i=0; i < 8; i++)	poly[i] = getreal(11);      poly[3] += (ph1.tag_210 - poly[7]) * poly[6] + 1;      for (i=0; i < 0x10000; i++) {	num = (poly[5]*i + poly[3])*i + poly[1];	curve[i] = LIM(num,0,65535);      } goto apply;				/* apply to right half */    } else if (tag == 0x41a) {			/* Polynomial curve */      for (i=0; i < 4; i++)	poly[i] = getreal(11);      for (i=0; i < 0x10000; i++) {	for (num=0, j=4; j--; )	  num = num * i + poly[j];	curve[i] = LIM(num+i,0,65535);      } apply:					/* apply to whole image */      for (row=0; row < height; row++)	for (col = (tag & 1)*ph1.split_col; col < width; col++)	  BAYER(row,col) = curve[BAYER(row,col)];    } else if (tag == 0x400) {			/* Sensor defects */      while ((len -= 8) >= 0) {	col  = get2() - left_margin;	row  = get2() - top_margin;	type = get2(); get2();	if (col >= width) continue;	if (type == 131)			/* Bad column */	  for (row=0; row < height; row++)	    if (FC(row,col) == 1) {	      for (sum=i=0; i < 4; i++)		sum += val[i] = bayer (row+dir[i][0], col+dir[i][1]);	      for (max=i=0; i < 4; i++) {		dev[i] = abs((val[i] << 2) - sum);		if (dev[max] < dev[i]) max = i;	      }	      BAYER(row,col) = (sum - val[max])/3.0 + 0.5;	    } else {	      for (sum=0, i=8; i < 12; i++)		sum += bayer (row+dir[i][0], col+dir[i][1]);	      BAYER(row,col) = 0.5 + sum * 0.0732233 +		(bayer(row,col-2) + bayer(row,col+2)) * 0.3535534;	    }	else if (type == 129) {			/* Bad pixel */	  if (row >= height) continue;	  j = (FC(row,col) != 1) * 4;	  for (sum=0, i=j; i < j+8; i++)	    sum += bayer (row+dir[i][0], col+dir[i][1]);	  BAYER(row,col) = (sum + 4) >> 3;	}      }    } else if (tag == 0x401) {			/* All-color flat fields */      phase_one_flat_field (1, 2);    } else if (tag == 0x416 || tag == 0x410) {      phase_one_flat_field (0, 2);    } else if (tag == 0x40b) {			/* Red+blue flat field */      phase_one_flat_field (0, 4);    } else if (tag == 0x412) {      fseek (ifp, 36, SEEK_CUR);      diff = abs (get2() - ph1.tag_21a);      if (mindiff > diff) {	mindiff = diff;	off_412 = ftell(ifp) - 38;      }    }    fseek (ifp, save, SEEK_SET);  }  if (off_412) {    fseek (ifp, off_412, SEEK_SET);    for (i=0; i < 9; i++) head[i] = get4() & 0x7fff;    yval[0] = (float *) calloc (head[1]*head[3] + head[2]*head[4], 6);    merror (yval[0], "phase_one_correct()");    yval[1] = (float  *) (yval[0] + head[1]*head[3]);    xval[0] = (ushort *) (yval[1] + head[2]*head[4]);    xval[1] = (ushort *) (xval[0] + head[1]*head[3]);    get2();    for (i=0; i < 2; i++)      for (j=0; j < head[i+1]*head[i+3]; j++)	yval[i][j] = getreal(11);    for (i=0; i < 2; i++)      for (j=0; j < head[i+1]*head[i+3]; j++)	xval[i][j] = get2();    for (row=0; row < height; row++)      for (col=0; col < width; col++) {	cfrac = (float) col * head[3] / raw_width;	cfrac -= cip = cfrac;	num = BAYER(row,col) * 0.5;	for (i=cip; i < cip+2; i++) {	  for (k=j=0; j < head[1]; j++)	    if (num < xval[0][k = head[1]*i+j]) break;	  frac = (j == 0 || j == head[1]) ? 0 :		(xval[0][k] - num) / (xval[0][k] - xval[0][k-1]);	  mult[i-cip] = yval[0][k-1] * frac + yval[0][k] * (1-frac);	}	i = ((mult[0] * (1-cfrac) + mult[1] * cfrac)		* (row + top_margin) + num) * 2;	BAYER(row,col) = LIM(i,0,65535);      }    free (yval[0]);  }}void CLASS phase_one_load_raw(){  int row, col, a, b;  ushort *pixel, akey, bkey, mask;  fseek (ifp, ph1.key_off, SEEK_SET);  akey = get2();  bkey = get2();  mask = ph1.format == 1 ? 0x5555:0x1354;  fseek (ifp, data_offset + top_margin*raw_width*2, SEEK_SET);  pixel = (ushort *) calloc (raw_width, sizeof *pixel);  merror (pixel, "phase_one_load_raw()");  for (row=0; row < height; row++) {    read_shorts (pixel, raw_width);    for (col=0; col < raw_width; col+=2) {      a = pixel[col+0] ^ akey;      b = pixel[col+1] ^ bkey;      pixel[col+0] = (a & mask) | (b & ~mask);      pixel[col+1] = (b & mask) | (a & ~mask);    }    for (col=0; col < width; col++)      BAYER(row,col) = pixel[col+left_margin];  }  free (pixel);  phase_one_correct();}unsigned CLASS ph1_bits (int nbits){  static UINT64 bitbuf=0;  static int vbits=0;  if (nbits == -1)    return bitbuf = vbits = 0;  if (nbits == 0) return 0;  if (vbits < nbits) {    bitbuf = bitbuf << 32 | get4();    vbits += 32;  }  vbits -= nbits;  return bitbuf << (64-nbits-vbits) >> (64-nbits);}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 (*black)[2];  pixel = (ushort *) calloc (raw_width + 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();  black = (short (*)[2]) offset + raw_height;  fseek (ifp, ph1.black_off, SEEK_SET);  if (ph1.black_off)    read_shorts ((ushort *) black[0], raw_height*2);  for (i=0; i < 256; i++)    curve[i] = i*i / 3.969 + 0.5;  for (row=0; row < raw_height; row++) {    fseek (ifp, data_offset + offset[row], SEEK_SET);    ph1_bits(-1);    pred[0] = pred[1] = 0;    for (col=0; col < raw_width; col++) {      if (col >= (raw_width & -8))	len[0] = len[1] = 14;      else if ((col & 7) == 0)	for (i=0; i < 2; i++) {	  for (j=0; j < 5 && !ph1_bits(1); j++);	  if (j--) len[i] = length[j*2 + ph1_bits(1)];	}      if ((i = len[col & 1]) == 14)	pixel[col] = pred[col & 1] = ph1_bits(16);      else	pixel[col] = pred[col & 1] += ph1_bits(i) + 1 - (1 << (i - 1));      if (pred[col & 1] >> 16) derror();      if (ph1.format == 5 && pixel[col] < 256)	pixel[col] = curve[pixel[col]];    }    if ((unsigned) (row-top_margin) < height)      for (col=0; col < width; col++) {	i = (pixel[col+left_margin] << 2)		- ph1.black + black[row][col >= ph1.split_col];	if (i > 0) BAYER(row-top_margin,col) = i;      }  }  free (pixel);  phase_one_correct();  maximum = 0xfffc - ph1.black;}void CLASS hasselblad_load_raw(){  struct jhead jh;  struct decode *dindex;  int row, col, pred[2], len[2], diff, i;  if (!ljpeg_start (&jh, 0)) return;  free (jh.row);  ph1_bits(-1);  for (row=-top_margin; row < height; row++) {    pred[0] = pred[1] = 0x8000;    for (col=-left_margin; col < raw_width-left_margin; col+=2) {      for (i=0; i < 2; i++) {	for (dindex=jh.huff[0]; dindex->branch[0]; )	  dindex = dindex->branch[ph1_bits(1)];	len[i] = dindex->leaf;      }      for (i=0; i < 2; i++) {	diff = ph1_bits(len[i]);	if ((diff & (1 << (len[i]-1))) == 0)	  diff -= (1 << len[i]) - 1;	pred[i] += diff;	if (row >= 0 && (unsigned)(col+i) < width)	  BAYER(row,col+i) = pred[i];      }    }  }  maximum = 0xffff;}void CLASS leaf_hdr_load_raw(){  ushort *pixel;  unsigned tile=0, r, c, row, col;  pixel = (ushort *) calloc (raw_width, sizeof *pixel);  merror (pixel, "leaf_hdr_load_raw()");  FORC(tiff_samples)    for (r=0; r < raw_height; r++) {      if (r % tile_length == 0) {	fseek (ifp, data_offset + 4*tile++, SEEK_SET);	fseek (ifp, get4() + 2*left_margin, SEEK_SET);      }      if (filters && c != shot_select) continue;      read_shorts (pixel, raw_width);      if ((row = r - top_margin) >= height) continue;      for (col=0; col < width; col++)	if (filters)  BAYER(row,col) = pixel[col];	else image[row*width+col][c] = pixel[col];    }  free (pixel);  if (!filters) {    maximum = 0xffff;    raw_color = 1;  }}void CLASS unpacked_load_raw();void CLASS sinar_4shot_load_raw(){  ushort *pixel;  unsigned shot, row, col, r, c;  if ((shot = shot_select) || half_size) {    if (shot) shot--;    if (shot > 3) shot = 3;    fseek (ifp, data_offset + shot*4, SEEK_SET);    fseek (ifp, get4(), SEEK_SET);    unpacked_load_raw();    return;  }  free (image);  image = (ushort (*)[4])	calloc ((iheight=height)*(iwidth=width), sizeof *image);  merror (image, "sinar_4shot_load_raw()");  pixel = (ushort *) calloc (raw_width, sizeof *pixel);  merror (pixel, "sinar_4shot_load_raw()");  for (shot=0; shot < 4; shot++) {    fseek (ifp, data_offset + shot*4, SEEK_SET);    fseek (ifp, get4(), SEEK_SET);    for (row=0; row < raw_height; row++) {      read_shorts (pixel, raw_width);      if ((r = row-top_margin - (shot >> 1 & 1)) >= height) continue;      for (col=0; col < raw_width; col++) {	if ((c = col-left_margin - (shot & 1)) >= width) continue;        image[r*width+c][FC(row,col)] = pixel[col];      }    }  }  free (pixel);  shrink = filters = 0;}void CLASS imacon_full_load_raw(){  int row, col;  for (row=0; row < height; row++)    for (col=0; col < width; col++)      read_shorts (image[row*width+col], 3);}void CLASS packed_12_load_raw(){

⌨️ 快捷键说明

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