source: trunk/core/dng_hdr.c @ 645

Revision 645, 14.0 KB checked in by EWAVR, 5 years ago (diff)
  • supress some warnings in autobuild process (maybe)
  • fixed "dng via usb" for s5is
Line 
1#include "camera.h"
2
3#if DNG_SUPPORT
4
5#include "stdlib.h"
6#include "string.h"
7#include "platform.h"
8#include "math.h"
9#include "dng.h"
10
11const int cam_DefaultCropSize[]={CAM_JPEG_WIDTH, CAM_JPEG_HEIGHT};    // jpeg size
12const int cam_ActiveArea[]={CAM_ACTIVE_AREA_Y1, CAM_ACTIVE_AREA_X1, CAM_ACTIVE_AREA_Y2, CAM_ACTIVE_AREA_X2};
13const int cam_DefaultCropOrigin[]={CAM_DEFAULT_CROP_ORIGIN_W,CAM_DEFAULT_CROP_ORIGIN_H};
14const int cam_BaselineExposure[]={-1,2};
15const int cam_BaselineNoise[]={1,1};
16const int cam_BaselineSharpness[]={4,3};
17const int cam_LinearResponseLimit[]={1,1};
18const int cam_AnalogBalance[]={1,1,1,1,1,1};
19const int cam_ColorMatrix1[9*2]={CAM_COLORMATRIX1};
20const char cam_name[32];
21const short cam_PreviewBitsPerSample[]={8,8,8};
22const char cam_chdk_ver[]=HDK_VERSION" ver. "BUILD_NUMBER;
23const int cam_Resolution[]={180,1};
24
25// warning: according to TIFF format specification, elements must be sorted by tag value in ascending order!
26
27struct dir_entry IFD0[]={
28 {0xFE,   T_LONG,      1,  1},       // NewSubFileType: Preview Image
29 {0x100,  T_LONG,      1,  DNG_TH_WIDTH},   // ImageWidth
30 {0x101,  T_LONG,      1,  DNG_TH_HEIGHT},   // ImageLength
31 {0x102,  T_SHORT,     3,  (int)cam_PreviewBitsPerSample},   // BitsPerSample: 8,8,8
32 {0x103,  T_SHORT,     1,  1},   // Compression: Uncompressed
33 {0x106,  T_SHORT,     1,  2}, //PhotometricInterpretation: RGB
34 {0x10E,  T_ASCII,     1,  0}, // ImageDescription
35 {0x10F,  T_ASCII,     sizeof(CAM_MAKE),  (int)CAM_MAKE}, // Make
36 {0x110,  T_ASCII,     32, (int)cam_name}, //Model: Filled at header generation.
37 {0x111,  T_LONG,      1,  0}, //StripOffsets: Offset
38 {0x112,  T_SHORT,     1,  1}, //Orientation: 1 - 0th row is top, 0th column is left
39 {0x115,  T_SHORT,     1,  3}, // SamplesPerPixel: 3
40 {0x116,  T_SHORT,     1,  DNG_TH_HEIGHT}, //RowsPerStrip
41 {0x117,  T_LONG,      1,  DNG_TH_WIDTH*DNG_TH_HEIGHT*3}, // StripByteCounts = preview size
42 {0x11C,  T_SHORT,     1,  1}, // PlanarConfiguration: 1
43 {0x131,  T_ASCII,     sizeof(cam_chdk_ver),  (int)cam_chdk_ver}, //Software
44 {0x132,  T_ASCII,     20, 0}, // DateTime
45 {0x14A,  T_LONG,      1,  0}, //SubIFDs offset
46 {0x8298, T_ASCII,     1,  0}, // Copyright
47 {0x8769, T_LONG,      1,  0}, //EXIF_IFD offset
48 {0x9216, T_BYTE,      4,  0x00000001},  // TIFF/EPStandardID: 1.0.0.0
49 {0xC612, T_BYTE,      4,  0x00000101}, //DNGVersion: 1.1.0.0
50 {0xC614, T_ASCII,     32, (int)cam_name}, //UniqueCameraModel. Filled at header generation.
51 {0xC621, T_SRATIONAL, 9,  (int)cam_ColorMatrix1},
52 {0xC627, T_RATIONAL,  3,  (int)cam_AnalogBalance},
53 {0xC62A, T_SRATIONAL, 1,  (int)cam_BaselineExposure},
54 {0xC62B, T_RATIONAL,  1,  (int)cam_BaselineNoise},
55 {0xC62C, T_RATIONAL,  1,  (int)cam_BaselineSharpness},
56 {0xC62E, T_RATIONAL,  1,  (int)cam_LinearResponseLimit},
57 {0xC65A, T_SHORT,     1,  cam_CalibrationIlluminant1},
58 {0}
59};
60
61                                                                                     
62struct dir_entry IFD1[]={
63 {0xFE,   T_LONG,      1,  0},       // NewSubFileType: Main Image
64 {0x100,  T_LONG,      1,  CAM_RAW_ROWPIX},   // ImageWidth
65 {0x101,  T_LONG,      1,  CAM_RAW_ROWS},   // ImageLength
66 {0x102,  T_SHORT,     1,  CAM_SENSOR_BITS_PER_PIXEL},   // BitsPerSample
67 {0x103,  T_SHORT,     1,  1},   // Compression: Uncompressed
68 {0x106,  T_SHORT,     1,  0x8023}, //PhotometricInterpretation: CFA
69 {0x111,  T_LONG,      1,  0}, //StripOffsets: Offset
70 {0x115,  T_SHORT,     1,  1}, // SamplesPerPixel: 1
71 {0x116,  T_SHORT,     1,  CAM_RAW_ROWS}, //RowsPerStrip
72 {0x117,  T_LONG,      1,  CAM_RAW_ROWPIX*CAM_RAW_ROWS*CAM_SENSOR_BITS_PER_PIXEL/8}, // StripByteCounts = CHDK RAW size
73 {0x11A,  T_RATIONAL,  1,  (int)cam_Resolution}, // XResolution
74 {0x11B,  T_RATIONAL,  1,  (int)cam_Resolution}, // YResolution
75 {0x11C,  T_SHORT,     1,  1}, // PlanarConfiguration: 1
76 {0x128,  T_SHORT,     1,  2}, // ResolutionUnit: inch
77 {0x828D, T_SHORT,     2,  0x00020002}, // CFARepeatPatternDim: Rows = 2, Cols = 2
78 {0x828E, T_BYTE,      4,  cam_CFAPattern},
79 {0xC61A, T_LONG,      1,  CAM_BLACK_LEVEL}, // BlackLevel
80 {0xC61D, T_LONG,      1,  CAM_WHITE_LEVEL}, // WhiteLevel
81 {0xC61F, T_LONG,      2,  (int)cam_DefaultCropOrigin},
82 {0xC620, T_LONG,      2,  (int)cam_DefaultCropSize},
83 {0xC68D, T_LONG,      4,  (int)cam_ActiveArea},
84 {0}
85};
86
87
88struct dir_entry EXIF_IFD[]={
89 {0x829A, T_RATIONAL,  1,  0}, //ExposureTime
90 {0x829D, T_RATIONAL,  1,  0}, //FNumber
91 {0x8822, T_SHORT,     1,  0}, //ExposureProgram
92 {0x8827, T_SHORT,     1,  0}, //ISOSpeedRatings
93 {0x9000, T_UNDEFINED, 4,  0x31323230}, // ExifVersion: 2.21
94 {0x9003, T_ASCII,     20, 0}, // DateTimeOriginal
95 {0x9201, T_SRATIONAL, 1,  0}, // ShutterSpeedValue
96 {0x9202, T_RATIONAL,  1,  0}, // ApertureValue
97 {0x9204, T_SRATIONAL, 1,  0}, // ExposureBias
98 {0x9205, T_RATIONAL,  1,  0}, //MaxApertureValue
99 {0x9207, T_SHORT,     1,  0}, // Metering mode
100 {0x9209, T_SHORT,     1,  0}, // Flash mode
101 {0x920A, T_RATIONAL,  1,  0}, //FocalLength
102 {0xA405, T_SHORT,     1,  0}, //FocalLengthIn35mmFilm
103 {0}
104};
105
106
107int get_type_size(int type){
108 switch(type){
109  case T_BYTE:      return 1;
110  case T_ASCII:     return 1;
111  case T_SHORT:     return 2;
112  case T_LONG:      return 4;
113  case T_RATIONAL:  return 8;
114  case T_SBYTE:     return 1;
115  case T_UNDEFINED: return 1;
116  case T_SSHORT:    return 2;
117  case T_SLONG:     return 4;
118  case T_SRATIONAL: return 8;
119  case T_FLOAT:     return 4;
120  case T_DOUBLE:    return 8;
121  default: return 0;
122 }
123}
124
125struct {struct dir_entry* entry; int count;} IFD_LIST[]={{IFD0,0}, {IFD1,0}, {EXIF_IFD,0}};
126
127#define IFDs (sizeof(IFD_LIST)/sizeof(IFD_LIST[0]))
128
129#define TIFF_HDR_SIZE (8)
130
131char* tmp_buf;
132int tmp_buf_size;
133int tmp_buf_offset;
134void add_to_buf(void* var, int size){
135 memcpy(tmp_buf+tmp_buf_offset,var,size);
136 tmp_buf_offset+=size;
137}
138 
139void create_dng_header(struct t_data_for_exif* exif_data){
140 int var;
141 int i,j;
142 int extra_offset;
143 int raw_offset;
144
145 // filling EXIF fields
146
147 for (j=0;j<IFDs;j++) {
148  for(i=0; IFD_LIST[j].entry[i].tag; i++) {
149    switch (IFD_LIST[j].entry[i].tag) {
150     case 0x132 :
151     case 0x9003: IFD_LIST[j].entry[i].offset=(int)get_date_for_exif(exif_data->time); break; //DateTimeOriginal
152     case 0x8827: IFD_LIST[j].entry[i].offset=exif_data->iso; break;//ISOSpeedRatings
153     case 0x829D: IFD_LIST[j].entry[i].offset=(int)get_av_for_exif(exif_data->av); break; //FNumber
154     case 0x829A: IFD_LIST[j].entry[i].offset=(int)get_tv_for_exif(exif_data->tv); break; //ExposureTime
155     case 0x9205: IFD_LIST[j].entry[i].offset=(int)get_max_av_for_exif(exif_data->max_av); break; //MaxApertureValue
156     case 0x9204: IFD_LIST[j].entry[i].offset=(int)get_exp_bias_for_exif(exif_data->exp_bias); break; //ExposureBias
157     case 0x8822: IFD_LIST[j].entry[i].offset=get_exp_program_for_exif(exif_data->exp_program); break;//ExposureProgram
158     case 0x920A: IFD_LIST[j].entry[i].offset=(int)get_focal_length_for_exif(exif_data->focal_length); break; //FocalLength
159     case 0xA405: IFD_LIST[j].entry[i].offset=exif_data->effective_focal_length/1000; break; ////FocalLengthIn35mmFilm
160     case 0x0112: IFD_LIST[j].entry[i].offset=get_orientation_for_exif(exif_data->orientation); break; //Orientation
161     case 0x9209: IFD_LIST[j].entry[i].offset=get_flash_mode_for_exif(exif_data->flash_mode, exif_data->flash_fired); break; //Flash mode
162     case 0x9207: IFD_LIST[j].entry[i].offset=get_metering_mode_for_exif(exif_data->metering_mode); break; // Metering mode
163     case 0x9201: IFD_LIST[j].entry[i].offset=(int)get_shutter_speed_for_exif(exif_data->tv); break; // ShutterSpeedValue
164     case 0x9202: IFD_LIST[j].entry[i].offset=(int)get_aperture_for_exif(exif_data->av); break; // ApertureValue
165    }
166  }
167 }
168 
169 // calculating offset of RAW data and count of directories for each IFD
170
171 raw_offset=TIFF_HDR_SIZE;
172
173 for (j=0;j<IFDs;j++) {
174  IFD_LIST[j].count=0;
175  raw_offset+=6; // IFD header+footer
176  for(i=0; IFD_LIST[j].entry[i].tag; i++) {
177   int size_ext;
178   IFD_LIST[j].count++;
179   raw_offset+=12; // IFD directory size
180   size_ext=get_type_size(IFD_LIST[j].entry[i].type)*IFD_LIST[j].entry[i].count;
181   if (size_ext>4) raw_offset+=size_ext+(size_ext&1);
182  }
183 }
184
185 // creating buffer for writing data
186 raw_offset=(raw_offset/512+1)*512; // exlusively for CHDK fast file writing
187 tmp_buf_size=raw_offset;
188 tmp_buf=umalloc(raw_offset);
189 tmp_buf_offset=0;
190 if (!tmp_buf) return;
191
192 //  writing  offsets for EXIF IFD and RAW data and calculating offset for extra data
193
194 extra_offset=TIFF_HDR_SIZE;
195
196 for (j=0;j<IFDs;j++) {
197  extra_offset+=6+IFD_LIST[j].count*12; // IFD header+footer
198  for(i=0; IFD_LIST[j].entry[i].tag; i++) {
199   if (IFD_LIST[j].entry[i].tag==0x8769) IFD_LIST[j].entry[i].offset=TIFF_HDR_SIZE+(IFD_LIST[0].count+IFD_LIST[1].count)*12+6+6;  // EXIF IFD offset
200   if (IFD_LIST[j].entry[i].tag==0x14A)  IFD_LIST[j].entry[i].offset=TIFF_HDR_SIZE+IFD_LIST[0].count*12+6; // SubIFDs offset
201   if (IFD_LIST[j].entry[i].tag==0x111)  {
202    if (j==1) IFD_LIST[j].entry[i].offset=raw_offset+DNG_TH_WIDTH*DNG_TH_HEIGHT*3;  //StripOffsets for main image
203    if (j==0) IFD_LIST[j].entry[i].offset=raw_offset;  //StripOffsets for thumbnail
204   }
205  }
206 }
207
208 // TIFF file header
209
210 var=0x4949; // little endian
211 add_to_buf(&var, sizeof(short));
212 var=42; //An arbitrary but carefully chosen number that further identifies the file as a TIFF file.
213 add_to_buf(&var, sizeof(short));
214 var=0x8; // offset of first IFD
215 add_to_buf(&var, sizeof(int));
216
217
218 // writing IFDs
219
220 for (j=0;j<IFDs;j++) {
221  int size_ext;
222  var=IFD_LIST[j].count;
223  add_to_buf(&var, sizeof(short));
224  for(i=0; IFD_LIST[j].entry[i].tag; i++) {
225   add_to_buf(&IFD_LIST[j].entry[i].tag, sizeof(short));
226   add_to_buf(&IFD_LIST[j].entry[i].type, sizeof(short));
227   add_to_buf(&IFD_LIST[j].entry[i].count, sizeof(int));
228   size_ext=get_type_size(IFD_LIST[j].entry[i].type)*IFD_LIST[j].entry[i].count;
229   if (size_ext<=4) add_to_buf(&IFD_LIST[j].entry[i].offset, sizeof(int));
230   else {
231    add_to_buf(&extra_offset, sizeof(int));
232    extra_offset+=size_ext+(size_ext&1);   
233   }
234  }
235 var=0;
236 add_to_buf(&var, sizeof(int));
237 }
238
239
240 // writing extra data
241
242 for (j=0;j<IFDs;j++) {
243  int size_ext;
244  char zero=0;
245  for(i=0; IFD_LIST[j].entry[i].tag; i++) {
246   size_ext=get_type_size(IFD_LIST[j].entry[i].type)*IFD_LIST[j].entry[i].count;
247   if (size_ext>4){
248    add_to_buf((void*)IFD_LIST[j].entry[i].offset, size_ext);
249    if (size_ext&1) add_to_buf(&zero, 1);
250   }
251  }
252 }
253
254
255 // writing zeros to tail of dng header (just for fun)
256 for (i=tmp_buf_offset; i<tmp_buf_size; i++) tmp_buf[i]=0;
257
258}
259
260void free_dng_header(void){
261 ufree(tmp_buf);
262 tmp_buf=NULL;
263}
264
265char* get_dng_header(void){
266 return tmp_buf;
267}
268
269int get_dng_header_size(void){
270 return tmp_buf_size;
271}
272
273char *get_date_for_exif(unsigned long time){
274 static char buf[20];
275 struct tm *ttm;
276 ttm = localtime(&time);
277 sprintf(buf, "%04d:%02d:%02d %02d:%02d:%02d", ttm->tm_year+1900, ttm->tm_mon+1, ttm->tm_mday, ttm->tm_hour, ttm->tm_min, ttm->tm_sec);
278 return buf;
279}
280
281unsigned int* get_av_for_exif(short av){
282 static unsigned int fnumber[2]={0,10};
283 fnumber[0]=10*pow(2,av/192.0);
284 return fnumber;
285}
286
287int* get_tv_for_exif(short tv){
288 static int exp_time[2]={0,1000000};
289 exp_time[0]=1000000*pow(2,-tv/96.0);
290 return exp_time;
291}
292
293unsigned int* get_max_av_for_exif(short max_av){
294 static unsigned int mav[2]={0,96};
295 mav[0]=max_av;
296 return mav;
297}
298
299int* get_exp_bias_for_exif(short exp_bias){
300 static int bias[2]={0,96};
301 bias[0]=exp_bias;
302 return bias;
303}
304
305int* get_shutter_speed_for_exif(short tv){
306 static int speed[2]={0,96};
307 speed[0]=tv;
308 return speed;
309}
310
311int* get_aperture_for_exif(short av){
312 static int aperture[2]={0,96};
313 aperture[0]=av;
314 return aperture;
315}
316
317
318unsigned short get_exp_program_for_exif(int exp_program){
319 switch(exp_program){
320  case MODE_M: return 1;
321  case MODE_P: return 2;
322  case MODE_AV: return 3;
323  case MODE_TV: return 4;
324  default: return 0;
325 }
326}
327
328unsigned int* get_focal_length_for_exif(int focal_length){
329 static unsigned int fl[2]={0,1000};
330 fl[0]=focal_length;
331 return fl;
332}
333
334unsigned short get_orientation_for_exif(short orientation){
335 switch(orientation){
336  case 90:  return 6;
337  case 270: return 8;
338  default: return 1;
339 }
340}
341
342unsigned short get_flash_mode_for_exif(short mode, short fired){
343 fired&=1;
344 switch(mode){
345  case 0: return (3<<3)|fired; // auto
346  case 1: return (1<<3)|fired; // on
347  case 2: return (2<<3)|fired; // off
348  default: return fired;
349 };
350}
351
352unsigned short get_metering_mode_for_exif(short metering_mode){
353 switch (metering_mode){
354  case 0: return 5; // Evaluative
355  case 1: return 3; // Spot
356  case 2: return 2; // CenterWeightedAverage
357  default: return 255; // other
358 }
359}
360
361struct t_data_for_exif* capture_data_for_exif(void){
362 static struct t_data_for_exif data;
363 extern volatile long shutter_open_time; // defined in platform/generic/capt_seq.c
364 data.iso=shooting_get_iso_market();
365 get_property_case(PROPCASE_TV, &data.tv, sizeof(data.tv));
366 if (shutter_open_time) { data.time=shutter_open_time+pow(2,-data.tv/96.0); shutter_open_time=0;} // shutter closing time
367 else  data.time=time(NULL);
368 get_property_case(PROPCASE_AV, &data.av, sizeof(data.av));
369 get_property_case(PROPCASE_MIN_AV, &data.max_av, sizeof(data.max_av));
370 get_property_case(PROPCASE_EV_CORRECTION_2, &data.exp_bias, sizeof(data.exp_bias));
371 data.exp_program=mode_get() & MODE_SHOOTING_MASK;
372 data.focal_length=get_focal_length(shooting_get_zoom());
373 data.effective_focal_length=get_effective_focal_length(shooting_get_zoom());
374 get_property_case(PROPCASE_ORIENTATION_SENSOR, &data.orientation, sizeof(data.orientation));
375 get_parameter_data(PARAM_CAMERA_NAME, &cam_name, sizeof(cam_name));
376 get_property_case(PROPCASE_FLASH_MODE, &data.flash_mode, sizeof(data.flash_mode));
377 get_property_case(PROPCASE_FLASH_FIRE, &data.flash_fired, sizeof(data.flash_fired));
378 get_property_case(PROPCASE_METERING_MODE, &data.metering_mode, sizeof(data.metering_mode));
379 return &data;
380}
381
382#endif //DNG_SUPPORT
Note: See TracBrowser for help on using the repository browser.