用LibRaw dump数码相机raw的参数,并分离出raw图像

libRaw中的unprocessed_raw程序可以将数码相机的raw图像转存为tiff图像。但是如果想知道更多的raw图像信息,并分离出不带tiff头的raw图像数据,则需要改造unprocessed_raw程序。

ispforfun在unprocessed_raw中添加了相应的代码,改写出第一版的代码。分享给大家,如果有好的建议,欢迎大家一起讨论。ispforfun会根据大家的意见将好的建议实现在后续的版本中。

  1 /* -*- C++ -*-
  2  * File: unprocessed_raw.cpp
  3  * Copyright 2009-2013 LibRaw LLC ([email protected])
  4  * Created: Fri Jan 02, 2009
  5  *
  6  * LibRaw sample
  7  * Generates unprocessed raw image: with masked pixels and without black subtraction
  8  *
  9
 10 LibRaw is free software; you can redistribute it and/or modify
 11 it under the terms of the one of three licenses as you choose:
 12
 13 1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1
 14    (See file LICENSE.LGPL provided in LibRaw distribution archive for details).
 15
 16 2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0
 17    (See file LICENSE.CDDL provided in LibRaw distribution archive for details).
 18
 19 3. LibRaw Software License 27032010
 20    (See file LICENSE.LibRaw.pdf provided in LibRaw distribution archive for details).
 21
 22  */
 23
 24 /*
 25    Modified by ispforfun
 26    1. add more dump information for camera raw images.
 27    2. write out naive raw file.
 28 */
 29
 30 #include <stdio.h>
 31 #include <string.h>
 32 #include <math.h>
 33 #include <time.h>
 34 #ifndef WIN32
 35 #include <netinet/in.h>
 36 #else
 37 #include <sys/utime.h>
 38 #include <winsock2.h>
 39 #endif
 40
 41 #include "libraw/libraw.h"
 42
 43 #ifdef WIN32
 44 #define snprintf _snprintf
 45 #endif
 46
 47 #if !(LIBRAW_COMPILE_CHECK_VERSION_NOTLESS(0,14))
 48 #error This code is for LibRaw 0.14+ only
 49 #endif
 50
 51 void  gamma_curve (unsigned short curve[]);
 52 void write_ppm(unsigned width, unsigned height, unsigned short *bitmap, const char *basename);
 53 void write_tiff(int width, int height, unsigned short *bitmap, const char *basename);
 54 // added by ispforfun
 55 void write_raw(int width, int height, unsigned short *bitmap, const char *fn);
 56
 57
 58 int main(int ac, char *av[])
 59 {
 60     int  i, ret;
 61     int verbose=1,autoscale=0,use_gamma=0,out_tiff=0,out_raw=0;
 62     char outfn[1024];
 63     char outrawfn[1024];
 64
 65     LibRaw RawProcessor;
 66     if(ac<2)
 67         {
 68           usage:
 69             printf(
 70                 "unprocessed_raw - LibRaw %s sample. %d cameras supported\n"
 71                 "Usage: %s [-q] [-A] [-g] [-s N] raw-files....\n"
 72                 "\t-q - be quiet\n"
 73                 "\t-s N - select Nth image in file (default=0)\n"
 74                 "\t-g - use gamma correction with gamma 2.2 (not precise,use for visual inspection only)\n"
 75                 "\t-A - autoscaling (by integer factor)\n"
 76                 "\t-T - write tiff instead of pgm\n"
 77                 "\t-r - write naive raw file\n"
 78                 ,LibRaw::version(),
 79                 LibRaw::cameraCount(),
 80                 av[0]);
 81             return 0;
 82         }
 83
 84 #define S RawProcessor.imgdata.sizes
 85 #define C RawProcessor.imgdata.color
 86 #define INFO RawProcessor.imgdata.idata
 87 #define OUT RawProcessor.imgdata.params
 88
 89     for (i=1;i<ac;i++)
 90         {
 91             if(av[i][0]==‘-‘)
 92                 {
 93                     if(av[i][1]==‘q‘ && av[i][2]==0)
 94                         verbose=0;
 95                     else if(av[i][1]==‘A‘ && av[i][2]==0)
 96                         autoscale=1;
 97                     else if(av[i][1]==‘g‘ && av[i][2]==0)
 98                         use_gamma = 1;
 99                     else if(av[i][1]==‘T‘ && av[i][2]==0)
100                         out_tiff = 1;
101             else if(av[i][1]==‘r‘ && av[i][2]==0)
102                 out_raw = 1;
103                     else if(av[i][1]==‘s‘ && av[i][2]==0)
104                         {
105                             i++;
106                             OUT.shot_select=av[i]?atoi(av[i]):0;
107                         }
108                     else
109                         goto usage;
110                     continue;
111                 }
112
113             if(verbose) printf("Processing file %s\n",av[i]);
114             if( (ret = RawProcessor.open_file(av[i])) != LIBRAW_SUCCESS)
115                 {
116                     fprintf(stderr,"Cannot open %s: %s\n",av[i],libraw_strerror(ret));
117                     continue; // no recycle b/c open file will recycle itself
118                 }
119             if(verbose)
120                 {
121                     printf("Camera Model is %s, and manufactured by %s.\n", INFO.model, INFO.make);
122                     printf("Bayer Format: ");
123                     putchar(INFO.cdesc[RawProcessor.fcol(0,0)]);
124                     putchar(INFO.cdesc[RawProcessor.fcol(0,1)]);
125                     putchar(INFO.cdesc[RawProcessor.fcol(1,0)]);
126                     putchar(INFO.cdesc[RawProcessor.fcol(1,1)]);
127                     printf("\nColor Information\n");
128                     printf("Black level = %d, %d, %d, %d\n", C.cblack[0], C.cblack[1], C.cblack[2], C.cblack[3]);
129                     printf("Black = %d\n", C.black);
130                     printf("data maximum = %d\n", C.data_maximum);
131                     printf("maximum = %d\n", C.maximum);
132                     printf("cam_mul = %f, %f, %f, %f\n", C.cam_mul[0], C.cam_mul[1], C.cam_mul[2], C.cam_mul[3]);
133                     printf("Image size: %dx%d\nRaw size: %dx%d\n",S.width,S.height,S.raw_width,S.raw_height);
134                             printf("Margins: top=%d, left=%d\n",
135                            S.top_margin,S.left_margin);
136                 }
137
138             if( (ret = RawProcessor.unpack() ) != LIBRAW_SUCCESS)
139                 {
140                     fprintf(stderr,"Cannot unpack %s: %s\n",av[i],libraw_strerror(ret));
141                     continue;
142                 }
143
144             if(verbose)
145                 printf("Unpacked....\n");
146
147             libraw_decoder_info_t decoder_info;
148             RawProcessor.get_decoder_info(&decoder_info);
149             if(!(decoder_info.decoder_flags & LIBRAW_DECODER_FLATFIELD))
150                 {
151                     printf("Only Bayer-pattern RAW files supported, sorry....\n");
152                     continue;
153                 }
154
155
156             if(autoscale)
157                 {
158                     unsigned max=0,scale;
159                     for(int j=0; j<S.raw_height*S.raw_width; j++)
160                         if(max < RawProcessor.imgdata.rawdata.raw_image[j])
161                             max = RawProcessor.imgdata.rawdata.raw_image[j];
162                     if (max >0 && max< 1<<15)
163                         {
164                             scale = (1<<16)/max;
165                             if(verbose)
166                                 printf("Scaling with multiplier=%d (max=%d)\n",scale,max);
167
168                             for(int j=0; j<S.raw_height*S.raw_width; j++)
169                                 RawProcessor.imgdata.rawdata.raw_image[j] *= scale;
170                         }
171                 }
172             if(use_gamma)
173                 {
174                     unsigned short curve[0x10000];
175                     gamma_curve(curve);
176                     for(int j=0; j<S.raw_height*S.raw_width; j++)
177                                 RawProcessor.imgdata.rawdata.raw_image[j]
178                                     = curve[RawProcessor.imgdata.rawdata.raw_image[j]];
179                     if(verbose)
180                         printf("Gamma-corrected....\n");
181                 }
182
183
184             if(OUT.shot_select)
185                 snprintf(outfn,sizeof(outfn),"%s-%d.%s",av[i],OUT.shot_select,out_tiff?"tiff":"pgm");
186             else
187                 snprintf(outfn,sizeof(outfn),"%s.%s",av[i],out_tiff?"tiff":"pgm");
188
189          if (out_raw){
190                snprintf(outrawfn,sizeof(outrawfn),"%s.%s",av[i],"raw");
191           write_raw(S.raw_width,S.raw_height,RawProcessor.imgdata.rawdata.raw_image,outrawfn);
192          }
193
194             if(out_tiff)
195                 write_tiff(S.raw_width,S.raw_height,RawProcessor.imgdata.rawdata.raw_image,outfn);
196             else
197                 write_ppm(S.raw_width,S.raw_height,RawProcessor.imgdata.rawdata.raw_image,outfn);
198
199             if(verbose) printf("Stored to file %s\n",outfn);
200         }
201     return 0;
202 }
203
204 void write_ppm(unsigned width, unsigned height, unsigned short *bitmap, const char *fname)
205 {
206     if(!bitmap) return;
207
208     FILE *f = fopen(fname,"wb");
209     if(!f) return;
210     int bits = 16;
211     fprintf (f, "P5\n%d %d\n%d\n", width, height, (1 << bits)-1);
212     unsigned char *data = (unsigned char *)bitmap;
213     unsigned data_size = width*height*2;
214 #define SWAP(a,b) { a ^= b; a ^= (b ^= a); }
215     for(unsigned i=0; i< data_size; i+=2)
216             SWAP(data[i],data[i+1]);
217 #undef SWAP
218     fwrite(data,data_size,1,f);
219     fclose(f);
220 }
221
222 /*  == gamma curve and tiff writer - simplified cut‘n‘paste from dcraw.c */
223
224 #define SQR(x) ((x)*(x))
225
226 void  gamma_curve (unsigned short *curve)
227 {
228
229     double pwr = 1.0/2.2;
230     double ts = 0.0;
231     int imax = 0xffff;
232     int mode = 2;
233   int i;
234   double g[6], bnd[2]={0,0}, r;
235
236   g[0] = pwr;
237   g[1] = ts;
238   g[2] = g[3] = g[4] = 0;
239   bnd[g[1] >= 1] = 1;
240   if (g[1] && (g[1]-1)*(g[0]-1) <= 0) {
241     for (i=0; i < 48; i++) {
242       g[2] = (bnd[0] + bnd[1])/2;
243       if (g[0]) bnd[(pow(g[2]/g[1],-g[0]) - 1)/g[0] - 1/g[2] > -1] = g[2];
244       else    bnd[g[2]/exp(1-1/g[2]) < g[1]] = g[2];
245     }
246     g[3] = g[2] / g[1];
247     if (g[0]) g[4] = g[2] * (1/g[0] - 1);
248   }
249   if (g[0]) g[5] = 1 / (g[1]*SQR(g[3])/2 - g[4]*(1 - g[3]) +
250         (1 - pow(g[3],1+g[0]))*(1 + g[4])/(1 + g[0])) - 1;
251   else      g[5] = 1 / (g[1]*SQR(g[3])/2 + 1
252         - g[2] - g[3] -    g[2]*g[3]*(log(g[3]) - 1)) - 1;
253   for (i=0; i < 0x10000; i++) {
254     curve[i] = 0xffff;
255     if ((r = (double) i / imax) < 1)
256       curve[i] = 0x10000 * ( mode
257     ? (r < g[3] ? r*g[1] : (g[0] ? pow( r,g[0])*(1+g[4])-g[4]    : log(r)*g[2]+1))
258     : (r < g[2] ? r/g[1] : (g[0] ? pow((r+g[4])/(1+g[4]),1/g[0]) : exp((r-1)/g[2]))));
259   }
260 }
261
262
263 void tiff_set (ushort *ntag,
264     ushort tag, ushort type, int count, int val)
265 {
266   struct tiff_tag *tt;
267   int c;
268
269   tt = (struct tiff_tag *)(ntag+1) + (*ntag)++;
270   tt->tag = tag;
271   tt->type = type;
272   tt->count = count;
273   if (type < 3 && count <= 4)
274       for(c=0;c<4;c++) tt->val.c[c] = val >> (c << 3);
275   else if (type == 3 && count <= 2)
276       for(c=0;c<2;c++) tt->val.s[c] = val >> (c << 4);
277   else tt->val.i = val;
278 }
279 #define TOFF(ptr) ((char *)(&(ptr)) - (char *)th)
280
281
282 void tiff_head (int width, int height, struct tiff_hdr *th)
283 {
284   int c;
285   time_t timestamp = time(NULL);
286   struct tm *t;
287
288   memset (th, 0, sizeof *th);
289   th->t_order = htonl(0x4d4d4949) >> 16;
290   th->magic = 42;
291   th->ifd = 10;
292   tiff_set (&th->ntag, 254, 4, 1, 0);
293   tiff_set (&th->ntag, 256, 4, 1, width);
294   tiff_set (&th->ntag, 257, 4, 1, height);
295   tiff_set (&th->ntag, 258, 3, 1, 16);
296   for(c=0;c<4;c++) th->bps[c] = 16;
297   tiff_set (&th->ntag, 259, 3, 1, 1);
298   tiff_set (&th->ntag, 262, 3, 1, 1);
299   tiff_set (&th->ntag, 273, 4, 1, sizeof *th);
300   tiff_set (&th->ntag, 277, 3, 1, 1);
301   tiff_set (&th->ntag, 278, 4, 1, height);
302   tiff_set (&th->ntag, 279, 4, 1, height*width*2);
303   tiff_set (&th->ntag, 282, 5, 1, TOFF(th->rat[0]));
304   tiff_set (&th->ntag, 283, 5, 1, TOFF(th->rat[2]));
305   tiff_set (&th->ntag, 284, 3, 1, 1);
306   tiff_set (&th->ntag, 296, 3, 1, 2);
307   tiff_set (&th->ntag, 306, 2, 20, TOFF(th->date));
308   th->rat[0] = th->rat[2] = 300;
309   th->rat[1] = th->rat[3] = 1;
310   t = localtime (&timestamp);
311   if(t)
312       sprintf (th->date, "%04d:%02d:%02d %02d:%02d:%02d",
313                t->tm_year+1900,t->tm_mon+1,t->tm_mday,t->tm_hour,t->tm_min,t->tm_sec);
314 }
315
316 void write_tiff(int width, int height, unsigned short *bitmap, const char *fn)
317 {
318   struct tiff_hdr th;
319
320   FILE *ofp = fopen(fn,"wb");
321   if(!ofp) return;
322   tiff_head (width,height,&th);
323   fwrite (&th, sizeof th, 1, ofp);
324   fwrite (bitmap, 2, width*height, ofp);
325   fclose(ofp);
326 }
327
328
329 void write_raw(int width, int height, unsigned short *bitmap, const char *fn)
330 {
331   FILE *ofp = fopen(fn,"wb");
332   if(!ofp) return;
333   fwrite (bitmap, 2, width*height, ofp);
334   fclose(ofp);
335 }

编译成功,调用的命令为:

unprocessed_raw -r -T DSC00018.ARW

DSC00018.ARW可以替换成相应的数码相机raw文件。

Processing file DSC00018.ARW
Camera Model is DSC-RX100M3, and manufactured by Sony.
Bayer Format: RGGB
Color Information
Black level = 0, 0, 0, 0
Black = 200
data maximum = 0
maximum = 4095
cam_mul = 2576.000000, 1024.000000, 1784.000000, 1024.000000
Image size: 5496x3672
Raw size: 5504x3672
Margins: top=0, left=0
Unpacked....
Stored to file DSC00018.ARW.tiff

可以发现DSC00018.ARW.tiff和DSC00018.ARW.raw文件。

时间: 2024-10-08 09:58:39

用LibRaw dump数码相机raw的参数,并分离出raw图像的相关文章

函数接收参数并弹出

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-

EBS OAF开发中实现参数式弹出窗口

(版权声明,本人原创或者翻译的文章如需转载,如转载用于个人学习,请注明出处:否则请与本人联系,违者必究) 概览 参数式弹出窗口和嵌入式弹出窗口不一样,它拥有独立的区域,并不嵌入到使用页面中,它里面的内容根据需要来获取和生成,它拥有自己的AM和页面状态,对popup页面事件的处理也不一样.两种弹出式窗口都只在下面四种组件所支持,既不能改变大小也不可移动. 1.        Text(messageStyledText) 2.        Image 3.        Link 4.     

javascript小练习—函数接收参数并弹出

<!DOCTYPE html><html><head lang="en"> <meta charset="UTF-8"> <title>函数接收参数并弹出</title> <style> body{font:12px/1.5 Tahoma;text-align:center;} code,input,button{font-family:inherit;} input{border:

SQL 参数,传入参数和自己申明参数——异常抛出

ALTER PROCEDURE [dbo].[OA_RemoveProject] @Password nvarchar(30), --这是传入的参数 @ProjectNo nvarchar(8) AS DECLARE @ProjectId int --这是声明的参数. DECLARE @Count int BEGIN IF UPPER(@Password)='FEIFEIDEMAO' BEGIN SET @Count=(SELECT COUNT(*) FROM DwProject WHERE [

oracle向in语句传入参数查不出数据

在oracle字符串中使用了in,但是查不出数据 1 string getModel = "select * from TB_YBSH where ID in :ids"; 2 OracleParameter p = new OracleParameter("ids", ids); 3 DataTable dt = DbHelperOra.ExecuteTable(getModel,p); 直接拼接就可以 string getModel = "select

mysql 存储过程执行异常,参数不是出参

执行存储过程时,出现如下错误,一般都是因为调用用户没有对应操作权限导致. Parameter number 1 is not an OUT parameter 检查用户对应权限 show grants for [email protected]%;如果没有对应 execute,alter routine,create routine权限,请root用户登录进行授权操作. 授权: grants execute ,alter routine,create routine to [email prot

find 命令参数大全

Linux中find常见用法示例 ·find   path   -option   [   -print ]   [ -exec   -ok   command ]   {} \; find命令的参数: pathname: find命令所查找的目录路径.例如用.来表示当前目录,用/来表示系统根目录.-print: find命令将匹配的文件输出到标准输出.-exec: find命令对匹配的文件执行该参数所给出的shell命令.相应命令的形式为'command' { } \;,注意{ }和\:之间的

RAW模板开发必备知识

写这个主要是为了让已经熟练掌握PHP的人能够快速的掌握RAW模板开发,从而享受RAW的优越! (注:在实际开发中,最好注意RAW模板开发统一规范,那样可以增强用户体验) 废话不多说,进入正题. 需要记住的有两个要点: 1.模板类型与新建模板 2.RAW标记 3.入口文件 4.多文件模板 5.模板信息 上面几个就是RAW模板开发的关键技术点,掌握了这几项就可以进行RAW模板开发. ***************************模板类型与新建*************************

Redhat 5.4 + ASM + RAW+ Oracle 10g RAC 安装文档

基于Redhat 5 和redhat 4 的RAC 区别在对raw的处理上. 之前做的是redhat 4.7 的 RAC 实验. 准备做一个Redhat 5.4 的环境. RAC 的一些理论东西: http://blog.csdn.net/tianlesoftware/archive/2010/02/27/5331067.aspx RAW+ASM+ REDHAT 4.7 RAC 文档 http://blog.csdn.net/tianlesoftware/archive/2010/02/27/5