码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2015-01-25 12:18:39      阅读:558      评论:0      收藏:0      [点我收藏+]

标签:

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 (info@libraw.org)
  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文件。

技术分享

 

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

标签:

原文地址:http://www.cnblogs.com/ispforfun/p/4247974.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!