首页 > 代码库 > 用LibRaw dump数码相机raw的参数,并分离出raw图像

用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 (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                     else109                         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 itself118                 }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             else187                 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             else197                 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 = http://www.mamicode.com/(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 SWAP218     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 + 1252         - 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 * ( mode257     ? (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图像