source: trunk/core/dng.c @ 1796

Revision 1796, 31.5 KB checked in by philmoz, 14 months ago (diff)

Update for DNG handling:

  • Change DNG version to 1.3.0.0
  • Add opcodes for bad pixel removal instead of generating badpixel.bin and mapping out bad pixels in the camera
  • Comment out badpixel.bin related code.
  • Property svn:eol-style set to native
Line 
1#include "camera.h"
2
3#include "stdlib.h"
4#include "string.h"
5#include "platform.h"
6#include "conf.h"
7#include "console.h"
8#include "dng.h"
9#include "raw.h"
10#include "action_stack.h"
11#include "gui_mbox.h"
12#include "gui_lang.h"
13#include "gps.h"
14
15//thumbnail
16#define DNG_TH_WIDTH 128
17#define DNG_TH_HEIGHT 96
18// higly recommended that DNG_TH_WIDTH*DNG_TH_HEIGHT would be divisible by 512
19
20struct dir_entry{unsigned short tag; unsigned short type; unsigned int count; unsigned int offset;};
21
22#define T_END       0
23#define T_BYTE      1
24#define T_ASCII     2
25#define T_SHORT     3
26#define T_LONG      4
27#define T_RATIONAL  5
28#define T_SBYTE     6
29#define T_UNDEFINED 7
30#define T_SSHORT    8
31#define T_SLONG     9
32#define T_SRATIONAL 10
33#define T_FLOAT     11
34#define T_DOUBLE    12
35#define T_PTR       0x100   // Stored as long/short etc in DNG header, referenced by pointer in IFD (must be pointer to int variable)
36
37unsigned short get_exp_program_for_exif(int exp_program);
38unsigned short get_orientation_for_exif(short orientation);
39unsigned short get_flash_mode_for_exif(short mode, short fired);
40unsigned short get_metering_mode_for_exif(short metering_mode);
41
42const int cam_BaselineNoise[]           = {1,1};
43const int cam_BaselineSharpness[]       = {4,3};
44const int cam_LinearResponseLimit[]     = {1,1};
45const int cam_AnalogBalance[]           = {1,1,1,1,1,1};
46const char cam_name[32];
47const short cam_PreviewBitsPerSample[]  = {8,8,8};
48const char cam_chdk_ver[]               = HDK_VERSION" ver. "BUILD_NUMBER;
49const int cam_Resolution[]              = {180,1};
50int cam_AsShotNeutral[]                 = {1000,1000,1000,1000,1000,1000};
51
52struct t_data_for_exif{
53 short iso;
54 int exp_program;
55 int effective_focal_length;
56 short orientation;
57 short flash_mode;
58 short flash_fired;
59 short metering_mode;
60};
61
62static struct t_data_for_exif exif_data;
63
64#define BE(v)   ((v&0x000000FF)<<24)|((v&0x0000FF00)<<8)|((v&0x00FF0000)>>8)|((v&0xFF000000)>>24)   // Convert to big_endian
65
66static unsigned int badpixel_opcode[] =
67{
68    // *** all values must be in big endian order
69
70    BE(4),              // Count = 4
71
72    BE(4),              // FixBadPixelsConstant = 4
73    BE(0x01030000),     // DNG version = 1.3.0.0
74    BE(1),              // Flags = 1
75    BE(8),              // Opcode length = 8 bytes
76    BE(0),              // Constant = 0
77#if   cam_CFAPattern == 0x02010100
78    BE(0),              // BayerPhase = 0 (top left pixel is red)
79#elif cam_CFAPattern == 0x01020001
80    BE(1),              // BayerPhase = 1 (top left pixel is green in a green/red row)
81#elif cam_CFAPattern == 0x01000201
82    BE(2),              // BayerPhase = 2 (top left pixel is green in a green/blue row)
83#elif cam_CFAPattern == 0x00010102
84    BE(3),              // BayerPhase = 3 (top left pixel is blue)
85#endif
86
87    BE(4),              // FixBadPixelsConstant = 4
88    BE(0x01030000),     // DNG version = 1.3.0.0
89    BE(1),              // Flags = 1
90    BE(8),              // Opcode length = 8 bytes
91    BE(1),              // Constant = 1
92#if   cam_CFAPattern == 0x02010100
93    BE(0),              // BayerPhase = 0 (top left pixel is red)
94#elif cam_CFAPattern == 0x01020001
95    BE(1),              // BayerPhase = 1 (top left pixel is green in a green/red row)
96#elif cam_CFAPattern == 0x01000201
97    BE(2),              // BayerPhase = 2 (top left pixel is green in a green/blue row)
98#elif cam_CFAPattern == 0x00010102
99    BE(3),              // BayerPhase = 3 (top left pixel is blue)
100#endif
101
102    BE(4),              // FixBadPixelsConstant = 4
103    BE(0x01030000),     // DNG version = 1.3.0.0
104    BE(1),              // Flags = 1
105    BE(8),              // Opcode length = 8 bytes
106    BE(2),              // Constant = 2
107#if   cam_CFAPattern == 0x02010100
108    BE(0),              // BayerPhase = 0 (top left pixel is red)
109#elif cam_CFAPattern == 0x01020001
110    BE(1),              // BayerPhase = 1 (top left pixel is green in a green/red row)
111#elif cam_CFAPattern == 0x01000201
112    BE(2),              // BayerPhase = 2 (top left pixel is green in a green/blue row)
113#elif cam_CFAPattern == 0x00010102
114    BE(3),              // BayerPhase = 3 (top left pixel is blue)
115#endif
116
117    BE(4),              // FixBadPixelsConstant = 4
118    BE(0x01030000),     // DNG version = 1.3.0.0
119    BE(1),              // Flags = 1
120    BE(8),              // Opcode length = 8 bytes
121    BE(3),              // Constant = 3
122#if   cam_CFAPattern == 0x02010100
123    BE(0),              // BayerPhase = 0 (top left pixel is red)
124#elif cam_CFAPattern == 0x01020001
125    BE(1),              // BayerPhase = 1 (top left pixel is green in a green/red row)
126#elif cam_CFAPattern == 0x01000201
127    BE(2),              // BayerPhase = 2 (top left pixel is green in a green/blue row)
128#elif cam_CFAPattern == 0x00010102
129    BE(3),              // BayerPhase = 3 (top left pixel is blue)
130#endif
131};
132
133// warning: according to TIFF format specification, elements must be sorted by tag value in ascending order!
134
135struct dir_entry IFD0[]={
136 {0xFE,   T_LONG,       1,  1},                                 // NewSubFileType: Preview Image
137 {0x100,  T_LONG,       1,  DNG_TH_WIDTH},                      // ImageWidth
138 {0x101,  T_LONG,       1,  DNG_TH_HEIGHT},                     // ImageLength
139 {0x102,  T_SHORT,      3,  (int)cam_PreviewBitsPerSample},     // BitsPerSample: 8,8,8
140 {0x103,  T_SHORT,      1,  1},                                 // Compression: Uncompressed
141 {0x106,  T_SHORT,      1,  2},                                 //PhotometricInterpretation: RGB
142 {0x10E,  T_ASCII,      1,  0},                                 // ImageDescription
143 {0x10F,  T_ASCII,      sizeof(CAM_MAKE), (int)CAM_MAKE},       // Make
144 {0x110,  T_ASCII,      32, (int)cam_name},                     //Model: Filled at header generation.
145 {0x111,  T_LONG,       1,  0},                                 //StripOffsets: Offset
146 {0x112,  T_SHORT,      1,  1},                                 //Orientation: 1 - 0th row is top, 0th column is left
147 {0x115,  T_SHORT,      1,  3},                                 // SamplesPerPixel: 3
148 {0x116,  T_SHORT,      1,  DNG_TH_HEIGHT},                     //RowsPerStrip
149 {0x117,  T_LONG,       1,  DNG_TH_WIDTH*DNG_TH_HEIGHT*3},      // StripByteCounts = preview size
150 {0x11C,  T_SHORT,      1,  1},                                 // PlanarConfiguration: 1
151 {0x131,  T_ASCII,      sizeof(cam_chdk_ver), (int)cam_chdk_ver},//Software
152 {0x132,  T_ASCII,      20, 0},                                 // DateTime
153 {0x14A,  T_LONG,       1,  0},                                 //SubIFDs offset
154 {0x8298, T_ASCII,      1,  0},                                 // Copyright
155 {0x8769, T_LONG,       1,  0},                                 //EXIF_IFD offset
156 {0x8825, T_LONG,       1,  0},                                 //GPS_IFD offset
157 {0x9216, T_BYTE,       4,  0x00000001},                        // TIFF/EPStandardID: 1.0.0.0
158 {0xC612, T_BYTE,       4,  0x00000301},                        //DNGVersion: 1.3.0.0
159 {0xC614, T_ASCII,      32, (int)cam_name},                     //UniqueCameraModel. Filled at header generation.
160 {0xC621, T_SRATIONAL,  9,  (int)&camera_sensor.color_matrix1},
161 {0xC627, T_RATIONAL,   3,  (int)cam_AnalogBalance},
162 {0xC628, T_RATIONAL,   3,  (int)cam_AsShotNeutral},
163 {0xC62A, T_SRATIONAL,  1,  (int)&camera_sensor.exposure_bias},
164 {0xC62B, T_RATIONAL,   1,  (int)cam_BaselineNoise},
165 {0xC62C, T_RATIONAL,   1,  (int)cam_BaselineSharpness},
166 {0xC62E, T_RATIONAL,   1,  (int)cam_LinearResponseLimit},
167 {0xC630, T_RATIONAL,   4,  (int)&camera_sensor.lens_info},
168 {0xC65A, T_SHORT|T_PTR,1,  (int)&camera_sensor.calibration_illuminant1},
169 {0, T_END}
170};
171
172                                                                                     
173struct dir_entry IFD1[]={
174 {0xFE,   T_LONG,       1,  0},                                 // NewSubFileType: Main Image
175 {0x100,  T_LONG|T_PTR, 1,  (int)&camera_sensor.raw_rowpix},      // ImageWidth
176 {0x101,  T_LONG|T_PTR, 1,  (int)&camera_sensor.raw_rows},        // ImageLength
177 {0x102,  T_SHORT|T_PTR,1,  (int)&camera_sensor.bits_per_pixel},  // BitsPerSample
178 {0x103,  T_SHORT,      1,  1},                                 // Compression: Uncompressed
179 {0x106,  T_SHORT,      1,  0x8023},                            //PhotometricInterpretation: CFA
180 {0x111,  T_LONG,       1,  0},                                 //StripOffsets: Offset
181 {0x115,  T_SHORT,      1,  1},                                 // SamplesPerPixel: 1
182 {0x116,  T_SHORT|T_PTR,1,  (int)&camera_sensor.raw_rows},        //RowsPerStrip
183 {0x117,  T_LONG|T_PTR, 1,  (int)&camera_sensor.raw_size},        // StripByteCounts = CHDK RAW size
184 {0x11A,  T_RATIONAL,   1,  (int)cam_Resolution},               // XResolution
185 {0x11B,  T_RATIONAL,   1,  (int)cam_Resolution},               // YResolution
186 {0x11C,  T_SHORT,      1,  1},                                 // PlanarConfiguration: 1
187 {0x128,  T_SHORT,      1,  2},                                 // ResolutionUnit: inch
188 {0x828D, T_SHORT,      2,  0x00020002},                        // CFARepeatPatternDim: Rows = 2, Cols = 2
189 {0x828E, T_BYTE|T_PTR, 4,  (int)&camera_sensor.cfa_pattern},
190 {0xC61A, T_LONG|T_PTR, 1,  (int)&camera_sensor.black_level},     // BlackLevel
191 {0xC61D, T_LONG|T_PTR, 1,  (int)&camera_sensor.white_level},     // WhiteLevel
192 {0xC61F, T_LONG,       2,  (int)&camera_sensor.crop.origin},
193 {0xC620, T_LONG,       2,  (int)&camera_sensor.crop.size},
194 {0xC68D, T_LONG,       4,  (int)&camera_sensor.dng_active_area},
195 {0xC740, T_UNDEFINED|T_PTR, sizeof(badpixel_opcode),  (int)&badpixel_opcode},
196 {0, T_END}
197};
198
199
200static int cam_shutter[2]       = { 0, 1000000 };       // Shutter speed
201static int cam_aperture[2]      = { 0, 10 };            // Aperture
202static char cam_datetime[20]    = "";                   // DateTimeOriginal
203static int cam_apex_shutter[2]  = { 0, 96 };            // Shutter speed in APEX units
204static int cam_apex_aperture[2] = { 0, 96 };            // Aperture in APEX units
205static int cam_exp_bias[2]      = { 0, 96 };
206static int cam_max_av[2]        = { 0, 96 };
207static int cam_focal_length[2]  = { 0, 1000 };
208
209struct dir_entry EXIF_IFD[]={
210 {0x829A, T_RATIONAL,   1,  (int)cam_shutter},          // Shutter speed
211 {0x829D, T_RATIONAL,   1,  (int)cam_aperture},         // Aperture
212 {0x8822, T_SHORT,      1,  0},                         // ExposureProgram
213 {0x8827, T_SHORT|T_PTR,1,  (int)&exif_data.iso},       // ISOSpeedRatings
214 {0x9000, T_UNDEFINED,  4,  0x31323230},                // ExifVersion: 2.21
215 {0x9003, T_ASCII,      20, (int)cam_datetime},         // DateTimeOriginal
216 {0x9201, T_SRATIONAL,  1,  (int)cam_apex_shutter},     // ShutterSpeedValue (APEX units)
217 {0x9202, T_RATIONAL,   1,  (int)cam_apex_aperture},    // ApertureValue (APEX units)
218 {0x9204, T_SRATIONAL,  1,  (int)cam_exp_bias},         // ExposureBias
219 {0x9205, T_RATIONAL,   1,  (int)cam_max_av},           // MaxApertureValue
220 {0x9207, T_SHORT,      1,  0},                         // Metering mode
221 {0x9209, T_SHORT,      1,  0},                         // Flash mode
222 {0x920A, T_RATIONAL,   1,  (int)cam_focal_length},     // FocalLength
223 {0xA405, T_SHORT|T_PTR,1,  (int)&exif_data.effective_focal_length},    // FocalLengthIn35mmFilm
224 {0, T_END}
225};
226
227tGPS gps_data;
228
229struct dir_entry GPS_IFD[]={
230  {0x0000, T_BYTE,              4,  0x00000302},                    //GPSVersionID: 2 3 0 0
231  {0x0001, T_ASCII,             2,  (int)gps_data.latitudeRef},     //North or South Latitude "N\0" or "S\0"
232  {0x0002, T_RATIONAL,          3,  (int)gps_data.latitude},        //Latitude
233  {0x0003, T_ASCII,             2,  (int)gps_data.longitudeRef},    //East or West Latitude "E\0" or "W\0"
234  {0x0004, T_RATIONAL,          3,  (int)gps_data.longitude},       //Longitude
235  {0x0005, T_BYTE,              1,  (int)gps_data.heightRef},       //AltitudeRef
236  {0x0006, T_RATIONAL,          1,  (int)gps_data.height},          //Altitude
237  {0x0007, T_RATIONAL,          3,  (int)gps_data.timeStamp},       //TimeStamp
238  {0x0009, T_ASCII,             2,  (int)gps_data.status},          //Status
239//{0x000A, T_ASCII,             1,  0},                             //MeasureMode
240  {0x0012, T_ASCII,             7,  (int)gps_data.mapDatum},        //MapDatum 7 + 1 pad byte
241  {0x001D, T_ASCII,             11, (int)gps_data.dateStamp},       //DateStamp 11 + 1 pad byte
242  {0, T_END}
243};
244
245
246int get_type_size(int type){
247 switch(type & 0xFF){
248  case T_BYTE:
249  case T_SBYTE:
250  case T_UNDEFINED:
251  case T_ASCII:     return 1;
252  case T_SHORT:
253  case T_SSHORT:    return 2;
254  case T_LONG:
255  case T_SLONG:
256  case T_FLOAT:     return 4;
257  case T_RATIONAL:
258  case T_SRATIONAL:
259  case T_DOUBLE:    return 8;
260  default:          return 0;
261 }
262}
263
264struct {struct dir_entry* entry; int count;} IFD_LIST[]={{IFD0,0}, {IFD1,0}, {EXIF_IFD,0}, {GPS_IFD, 0}};
265
266#define IFDs (sizeof(IFD_LIST)/sizeof(IFD_LIST[0]))
267
268#define TIFF_HDR_SIZE (8)
269
270char* dng_header_buf;
271int dng_header_buf_size;
272int dng_header_buf_offset;
273char *thumbnail_buf;
274
275void add_to_buf(void* var, int size)
276{
277 memcpy(dng_header_buf+dng_header_buf_offset,var,size);
278 dng_header_buf_offset+=size;
279}
280
281void create_dng_header(){
282 int var;
283 int i,j;
284 int extra_offset;
285 int raw_offset;
286
287 // filling EXIF fields
288
289 gps_getData(&gps_data);
290
291 for (j=0;j<IFDs;j++) {
292  for(i=0; IFD_LIST[j].entry[i].type; i++) {
293    switch (IFD_LIST[j].entry[i].tag) {
294     // For camera name string make sure the 'count' in the IFD header is correct for the string
295     case 0x110 :                                                                                       // CameraName
296     case 0xC614: IFD_LIST[j].entry[i].count = strlen((char*)IFD_LIST[j].entry[i].offset) + 1; break;   // UniqueCameraModel
297     case 0x132 :
298     case 0x8822: IFD_LIST[j].entry[i].offset=get_exp_program_for_exif(exif_data.exp_program); break;//ExposureProgram
299     case 0x0112: IFD_LIST[j].entry[i].offset=get_orientation_for_exif(exif_data.orientation); break; //Orientation
300     case 0x9209: IFD_LIST[j].entry[i].offset=get_flash_mode_for_exif(exif_data.flash_mode, exif_data.flash_fired); break; //Flash mode
301     case 0x9207: IFD_LIST[j].entry[i].offset=get_metering_mode_for_exif(exif_data.metering_mode); break; // Metering mode
302    }
303  }
304 }
305 
306 // calculating offset of RAW data and count of directories for each IFD
307
308 raw_offset=TIFF_HDR_SIZE;
309
310 for (j=0;j<IFDs;j++) {
311  IFD_LIST[j].count=0;
312  raw_offset+=6; // IFD header+footer
313  for(i=0; IFD_LIST[j].entry[i].type; i++) {
314   int size_ext;
315   IFD_LIST[j].count++;
316   raw_offset+=12; // IFD directory size
317   size_ext=get_type_size(IFD_LIST[j].entry[i].type)*IFD_LIST[j].entry[i].count;
318   if (size_ext>4) raw_offset+=size_ext+(size_ext&1);
319  }
320 }
321
322 // creating buffer for writing data
323 raw_offset=(raw_offset/512+1)*512; // exlusively for CHDK fast file writing
324 dng_header_buf_size=raw_offset;
325 dng_header_buf=umalloc(raw_offset);
326 dng_header_buf_offset=0;
327 if (!dng_header_buf) return;
328
329 // create buffer for thumbnail
330 thumbnail_buf = malloc(DNG_TH_WIDTH*DNG_TH_HEIGHT*3);
331 if (!thumbnail_buf)
332 {
333     ufree(dng_header_buf);
334     dng_header_buf = 0;
335     return;
336 }
337
338 //  writing  offsets for EXIF IFD and RAW data and calculating offset for extra data
339
340 extra_offset=TIFF_HDR_SIZE;
341
342 for (j=0;j<IFDs;j++) {
343  extra_offset+=6+IFD_LIST[j].count*12; // IFD header+footer
344  for(i=0; IFD_LIST[j].entry[i].type; i++) {
345   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
346   if (IFD_LIST[j].entry[i].tag==0x8825) IFD_LIST[j].entry[i].offset=TIFF_HDR_SIZE+(IFD_LIST[0].count+IFD_LIST[1].count+IFD_LIST[2].count)*12+6+6+6;  // GPS IFD offset
347   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
348   if (IFD_LIST[j].entry[i].tag==0x111)  {
349    if (j==1) IFD_LIST[j].entry[i].offset=raw_offset+DNG_TH_WIDTH*DNG_TH_HEIGHT*3;  //StripOffsets for main image
350    if (j==0) IFD_LIST[j].entry[i].offset=raw_offset;  //StripOffsets for thumbnail
351   }
352  }
353 }
354
355 // TIFF file header
356
357 var=0x4949; // little endian
358 add_to_buf(&var, sizeof(short));
359 var=42; //An arbitrary but carefully chosen number that further identifies the file as a TIFF file.
360 add_to_buf(&var, sizeof(short));
361 var=0x8; // offset of first IFD
362 add_to_buf(&var, sizeof(int));
363
364
365 // writing IFDs
366
367 for (j=0;j<IFDs;j++) {
368  int size_ext;
369  var=IFD_LIST[j].count;
370  add_to_buf(&var, sizeof(short));
371  for(i=0; IFD_LIST[j].entry[i].type; i++) {
372    add_to_buf(&IFD_LIST[j].entry[i].tag, sizeof(short));
373    unsigned short t = IFD_LIST[j].entry[i].type & 0xFF;
374    add_to_buf(&t, sizeof(short));
375    add_to_buf(&IFD_LIST[j].entry[i].count, sizeof(int));
376    size_ext=get_type_size(IFD_LIST[j].entry[i].type)*IFD_LIST[j].entry[i].count;
377    if (size_ext<=4)
378    {
379        if (IFD_LIST[j].entry[i].type & T_PTR)
380        {
381            add_to_buf((void*)IFD_LIST[j].entry[i].offset, sizeof(int));
382        }
383        else
384        {
385            add_to_buf(&IFD_LIST[j].entry[i].offset, sizeof(int));
386        }
387    }
388    else
389    {
390        add_to_buf(&extra_offset, sizeof(int));
391        extra_offset+=size_ext+(size_ext&1);   
392    }
393  }
394 var=0;
395 add_to_buf(&var, sizeof(int));
396 }
397
398
399 // writing extra data
400
401 for (j=0;j<IFDs;j++) {
402  int size_ext;
403  char zero=0;
404  for(i=0; IFD_LIST[j].entry[i].type; i++) {
405   size_ext=get_type_size(IFD_LIST[j].entry[i].type)*IFD_LIST[j].entry[i].count;
406   if (size_ext>4){
407    add_to_buf((void*)IFD_LIST[j].entry[i].offset, size_ext);
408    if (size_ext&1) add_to_buf(&zero, 1);
409   }
410  }
411 }
412
413 // writing zeros to tail of dng header (just for fun)
414 for (i=dng_header_buf_offset; i<dng_header_buf_size; i++) dng_header_buf[i]=0;
415}
416
417void free_dng_header(void)
418{
419    if (dng_header_buf)
420    {
421        ufree(dng_header_buf);
422        dng_header_buf=NULL;
423    }
424    if (thumbnail_buf)
425    {
426        free(thumbnail_buf);
427        thumbnail_buf = 0;
428    }
429}
430
431unsigned short get_exp_program_for_exif(int exp_program){
432 switch(exp_program){
433  case MODE_M: return 1;
434  case MODE_P: return 2;
435  case MODE_AV: return 3;
436  case MODE_TV: return 4;
437  default: return 0;
438 }
439}
440
441unsigned short get_orientation_for_exif(short orientation){
442 switch(orientation){
443  case  90: return 6;  // Right  - Top
444  case 180: return 3;  // Bottom - Right
445  case 270: return 8;  // Left   - Bottom
446  case   0:            // Top    - Left
447  default : return 1;
448 }
449}
450
451unsigned short get_flash_mode_for_exif(short mode, short fired){
452 fired&=1;
453 switch(mode){
454  case 0: return (3<<3)|fired; // auto
455  case 1: return (1<<3)|fired; // on
456  case 2: return (2<<3)|fired; // off
457  default: return fired;
458 };
459}
460
461unsigned short get_metering_mode_for_exif(short metering_mode){
462 switch (metering_mode){
463  case 0: return 5; // Evaluative
464  case 1: return 3; // Spot
465  case 2: return 2; // CenterWeightedAverage
466  default: return 255; // other
467 }
468}
469
470void capture_data_for_exif(void)
471{
472 short short_prop_val;
473 time_t datetime;
474 struct tm *ttm;
475 extern volatile long shutter_open_time; // defined in platform/generic/capt_seq.c
476 int wb[3];
477
478 exif_data.iso=shooting_get_iso_market();
479
480 // Shutter speed tags
481 get_property_case(camera_info.props.tv, &short_prop_val, sizeof(short_prop_val));
482 cam_shutter[0]      = pow_calc( 1000000, 2, 1, -short_prop_val, 96);
483 cam_apex_shutter[0] = short_prop_val;
484
485 // Date & time tag (note - uses shutter speed from 'short_prop_val' code above)
486 if (shutter_open_time) { datetime = shutter_open_time + pow_calc(1, 2, 1, -short_prop_val, 96); shutter_open_time=0;} // shutter closing time
487 else  datetime = time(NULL);
488 ttm = localtime(&datetime);
489 sprintf(cam_datetime, "%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);
490
491 get_property_case(camera_info.props.av, &short_prop_val, sizeof(short_prop_val));
492 cam_aperture[0]      = pow_calc( 10, 2, 1, short_prop_val, 192);
493 cam_apex_aperture[0] = short_prop_val;
494
495 get_property_case(camera_info.props.min_av, &short_prop_val, sizeof(short_prop_val));
496 cam_max_av[0] = short_prop_val;
497
498 get_property_case(camera_info.props.ev_correction_2, &short_prop_val, sizeof(short_prop_val));
499 cam_exp_bias[0] = short_prop_val;
500
501 exif_data.exp_program=mode_get() & MODE_SHOOTING_MASK;
502
503 cam_focal_length[0] = get_focal_length(shooting_get_zoom());
504 exif_data.effective_focal_length = get_effective_focal_length(shooting_get_zoom()) / 1000;
505
506 get_property_case(camera_info.props.orientation_sensor, &exif_data.orientation, sizeof(exif_data.orientation));
507 get_parameter_data(camera_info.params.camera_name, &cam_name, sizeof(cam_name));
508 get_property_case(camera_info.props.flash_mode, &exif_data.flash_mode, sizeof(exif_data.flash_mode));
509 get_property_case(camera_info.props.flash_fire, &exif_data.flash_fired, sizeof(exif_data.flash_fired));
510 get_property_case(camera_info.props.metering_mode, &exif_data.metering_mode, sizeof(exif_data.metering_mode));
511
512 get_property_case(camera_info.props.wb_adj, &wb, sizeof(wb)); 
513 cam_AsShotNeutral[1]=wb[1];
514 cam_AsShotNeutral[3]=wb[0];
515 cam_AsShotNeutral[5]=wb[2];
516}
517
518//-------------------------------------------------------------------
519
520void convert_dng_to_chdk_raw(char* fn){
521 #define BUF_SIZE (32768)
522 FILE *dng, *raw;
523 int *buf;
524 int i;
525 struct STD_stat st;
526 struct utimbuf t;
527
528 if (safe_stat(fn, &st) != 0 || st.st_size<=camera_sensor.raw_size)  return;
529 buf=malloc(BUF_SIZE);
530 if (buf){
531  started();
532  dng=fopen(fn,"rb");
533  if (dng){
534   fread(buf, 1, 8, dng);
535   if (buf[0]==0x2A4949 && buf[1]==8) {  // chdk dng header
536    i=strlen(fn)-3;
537    if (strncmp(fn+i,"CR",2)==0) strcpy(fn+i,"WAV"); else strcpy(fn+i,"CRW");
538    raw=fopen(fn,"w+b");
539    if (raw){
540     fseek(dng, st.st_size-camera_sensor.raw_size, SEEK_SET); // SEEK_END is not working?
541     for (i=0; i<camera_sensor.raw_size/BUF_SIZE; i++) {
542      fread(buf, 1, BUF_SIZE, dng);
543      reverse_bytes_order((char*)buf, BUF_SIZE);
544      fwrite(buf, 1, BUF_SIZE, raw);
545     }
546     fread(buf, 1, camera_sensor.raw_size%BUF_SIZE, dng);
547     reverse_bytes_order((char*)buf, camera_sensor.raw_size%BUF_SIZE);
548     fwrite(buf, 1, camera_sensor.raw_size%BUF_SIZE, raw);
549     fclose(raw);
550     t.actime = t.modtime = time(NULL);
551     utime(fn, &t);
552    } // if (raw)
553   } // if chdk dng header
554  fclose(dng);
555  } //if (dng)
556 free(buf);
557 finished();
558 }  //if (buf)
559}
560
561//-------------------------------------------------------------------
562// Functions for creating DNG thumbnail image
563
564static unsigned char gamma[256];
565
566void fill_gamma_buf(void) {
567    int i;
568    if (gamma[255]) return;
569    for (i=0; i<12; i++) gamma[i]=pow_calc_2(255, i, 255, 0.5, 1);
570    for (i=12; i<64; i++) gamma[i]=pow_calc_2(255, i, 255, 0.4, 1);
571    for (i=64; i<=255; i++) gamma[i]=pow_calc_2(255, i, 255, 0.25, 1);
572}
573
574void create_thumbnail() {
575    register int i, j, x, y, yadj, xadj;
576    register char *buf = thumbnail_buf;
577    register int shift = camera_sensor.bits_per_pixel - 8;
578
579    // The sensor bayer patterns are:
580    //  0x02010100  0x01000201  0x01020001
581    //      R G         G B         G R
582    //      G B         R G         B G
583    // for the second pattern yadj shifts the thumbnail row down one line
584    // for the third pattern xadj shifts the thumbnail row accross one pixel
585    // these make the patterns the same
586    yadj = (camera_sensor.cfa_pattern == 0x01000201) ? 1 : 0;
587    xadj = (camera_sensor.cfa_pattern == 0x01020001) ? 1 : 0;
588
589    for (i=0; i<DNG_TH_HEIGHT; i++)
590        for (j=0; j<DNG_TH_WIDTH; j++)
591        {
592            x = ((camera_sensor.jpeg.x + (camera_sensor.jpeg.width  * j) / DNG_TH_WIDTH)  & 0xFFFFFFFE) + xadj;
593            y = ((camera_sensor.jpeg.y + (camera_sensor.jpeg.height * i) / DNG_TH_HEIGHT) & 0xFFFFFFFE) + yadj;
594
595            *buf++ = gamma[get_raw_pixel(x,y)>>shift];           // red pixel
596            *buf++ = gamma[6*(get_raw_pixel(x+1,y)>>shift)/10];  // green pixel
597            *buf++ = gamma[get_raw_pixel(x+1,y+1)>>shift];       // blue pixel
598        }
599}
600
601//-------------------------------------------------------------------
602// Functions for handling DNG bad pixel file creation and bad pixel
603// removal from images.
604
605//#define INIT_BADPIXEL_COUNT -1
606//#define INIT_BADPIXEL_FILE -2
607//
608//#define PATH_BADPIXEL_BIN "A/CHDK/badpixel.bin"
609//#define PATH_BAD_TMP_BIN "A/CHDK/bad_tmp.bin"
610//
611//int init_badpixel_bin_flag; // contants above to count/create file, > 0 num bad pixel
612//
613int raw_init_badpixel_bin() {
614//    int count;
615//    unsigned short c[2];
616//    FILE*f;
617//    if(init_badpixel_bin_flag == INIT_BADPIXEL_FILE) {
618//        f=fopen(PATH_BAD_TMP_BIN,"w+b");
619//    } else if (init_badpixel_bin_flag == INIT_BADPIXEL_COUNT) {
620//        f=NULL;
621//    } else {
622//        return 0;
623//    }
624//    count = 0;
625//    for (c[0]=camera_sensor.active_area.x1; c[0]<camera_sensor.active_area.x2; c[0]++)
626//    {
627//        for (c[1]=camera_sensor.active_area.y1; c[1]<camera_sensor.active_area.y2; c[1]++)
628//        {
629//            if (get_raw_pixel(c[0],c[1]) <= DNG_BADPIXEL_VALUE_LIMIT)
630//            {
631//                unsigned short l;
632//                for (l=0; l<7 && (c[1]+l+1)<camera_sensor.active_area.y2; l++)
633//                    if (get_raw_pixel(c[0],c[1]+l+1) > DNG_BADPIXEL_VALUE_LIMIT)
634//                        break;
635//                c[1] = c[1] | (l << 13);
636//                if (f) fwrite(c, 1, 4, f);
637//                c[1] = (c[1] & 0x1FFF) + l;
638//                count = count + l + 1;
639//            }
640//        }
641//    }
642//    if (f) fclose(f);
643//    init_badpixel_bin_flag = count;
644//    state_shooting_progress = SHOOTING_PROGRESS_PROCESSING;
645    return 1;
646}
647
648//short* binary_list=NULL;
649//int binary_count=-1;
650
651void load_bad_pixels_list_b(char* filename) {
652 //   struct STD_stat st;
653 //   long filesize;
654 //   void* ptr;
655 //   FILE *fd;
656
657        //if ( filename==0 )
658        // { unload_bad_pixels_list_b(); return; }
659
660 //   binary_count=-1;
661 //   if (safe_stat(filename,&st)!=0) return;
662 //   filesize=st.st_size;
663 //   if (filesize%(2*sizeof(short)) != 0) return;
664        //if (filesize == 0) { binary_count = 0; return; }      // Allow empty badpixel.bin file
665 //   ptr=malloc(filesize);
666 //   if (!ptr) return;
667 //   fd=fopen(filename, "rb");
668 //   if (fd) {
669 //       fread(ptr,1, filesize,fd);
670 //       fclose(fd);
671 //       binary_list=ptr;
672 //       binary_count=filesize/(2*sizeof(short));
673 //   }
674 //   else free(ptr);
675}
676
677void unload_bad_pixels_list_b(void) {
678    //if (binary_list) free(binary_list);
679    //binary_list=NULL;
680    //binary_count=-1;
681}
682
683void patch_bad_pixels_b(void) {
684    //int i;
685    //short* ptr=binary_list;
686    //short y, cnt;
687    //for (i=0; i<binary_count; i++, ptr+=2)
688    //{
689    //    y = ptr[1] & 0x1FFF;
690    //    cnt = (ptr[1] >> 13) & 7;
691    //    for (; cnt>=0; cnt--, y++)
692    //        if (get_raw_pixel(ptr[0], y) <= DNG_BADPIXEL_VALUE_LIMIT)
693    //            patch_bad_pixel(ptr[0], y);
694    //}
695}
696
697int badpixel_list_loaded_b(void) {
698//      return (binary_count >= 0) ? 1 : 0;
699    return 1;
700}
701
702// -----------------------------------------------
703
704//enum BadpixelFSM {
705//    BADPIX_START,
706//    BADPIX_S1,
707//    BADPIX_S2
708//};
709//
710//int badpixel_task_stack(long p) {
711//    static unsigned int badpix_cnt1;
712//
713//    switch(p) {
714//        case BADPIX_START:
715//            action_pop();
716//
717//            console_clear();
718//            console_add_line("Wait please... ");
719//            console_add_line("This takes a few seconds,");
720//            console_add_line("don't panic!");
721//
722//            init_badpixel_bin_flag = INIT_BADPIXEL_COUNT;
723//
724//            shooting_set_tv96_direct(96, SET_LATER);
725//            action_push(BADPIX_S1);
726//            action_push(AS_SHOOT);
727//            action_push_delay(3000);
728//            break;
729//        case BADPIX_S1:
730//            action_pop();
731//
732//            badpix_cnt1 = init_badpixel_bin_flag;
733//            init_badpixel_bin_flag = INIT_BADPIXEL_FILE;
734//            shooting_set_tv96_direct(96, SET_LATER);
735//
736//            action_push(BADPIX_S2);
737//            action_push(AS_SHOOT);
738//            break;
739//        case BADPIX_S2:
740//            action_pop();
741//
742//            console_clear();
743//            if (badpix_cnt1 == init_badpixel_bin_flag) {
744//                // TODO script asked confirmation first
745//                // should sanity check bad pixel count at least,
746//                // wrong buffer address could make badpixel bigger than available mem
747//                char msg[32];
748//                console_add_line("badpixel.bin created.");
749//                sprintf(msg, "Bad pixel count: %d", badpix_cnt1);
750//                console_add_line(msg);
751//                remove(PATH_BADPIXEL_BIN);
752//                rename(PATH_BAD_TMP_BIN,PATH_BADPIXEL_BIN);
753//            } else {
754//                console_add_line("badpixel.bin failed.");
755//                console_add_line("Please try again.");
756//            }
757//            init_badpixel_bin_flag = 0;
758//            remove(PATH_BAD_TMP_BIN);
759//
760//            action_push_delay(3000);
761//            break;
762//        default:
763//            action_stack_standard(p);
764//            break;
765//    }
766//
767//    return 1;
768//}
769
770
771void create_badpixel_bin() {
772    //if (!(mode_get() & MODE_REC)) {
773    //    gui_mbox_init(LANG_ERROR, LANG_MSG_RECMODE_REQUIRED, MBOX_BTN_OK|MBOX_TEXT_CENTER, NULL);
774    //    return;
775    //}
776
777    //gui_set_mode(&altGuiHandler);
778    //action_stack_create(&badpixel_task_stack, BADPIX_START);
779}
780
781//-------------------------------------------------------------------
782// Write DNG header, thumbnail and data to file
783
784void write_dng(int fd, char* rawadr, char* altrawadr, unsigned long uncachedbit)
785{
786        create_dng_header();
787
788    if (dng_header_buf)
789    {
790        fill_gamma_buf();
791        //patch_bad_pixels_b();
792        create_thumbnail();
793        write(fd, dng_header_buf, dng_header_buf_size);
794        write(fd, thumbnail_buf, DNG_TH_WIDTH*DNG_TH_HEIGHT*3);
795
796        reverse_bytes_order2(rawadr, altrawadr, camera_sensor.raw_size);
797
798        // Write alternate (inactive) buffer that we reversed the bytes into above (if only one buffer then it will be the active buffer instead)
799        write(fd, (char*)(((unsigned long)altrawadr)|uncachedbit), camera_sensor.raw_size);
800
801        if (rawadr == altrawadr)    // If only one RAW buffer then we have to swap the bytes back
802            reverse_bytes_order2(rawadr, altrawadr, camera_sensor.raw_size);
803
804        free_dng_header();
805    }
806}
807
808/*********** BEGIN OF AUXILARY PART **********************/
809
810#include "module_load.h"
811
812struct libdng_sym libdng = {
813                        MAKE_API_VERSION(1,0),          // apiver: increase major if incompatible changes made in module,
814                                                                                // increase minor if compatible changes made(including extending this struct)
815
816                        create_badpixel_bin,
817                        raw_init_badpixel_bin,
818                        capture_data_for_exif,
819                        load_bad_pixels_list_b,
820                        badpixel_list_loaded_b,
821
822                        convert_dng_to_chdk_raw,
823                        write_dng
824                };
825
826
827//-------------------------------------------
828void* MODULE_EXPORT_LIST[] = {
829        /* 0 */ (void*)EXPORTLIST_MAGIC_NUMBER,
830        /* 1 */ (void*)1,
831
832                        &libdng
833                };
834
835//--------------------------------------------
836int _module_loader( unsigned int* chdk_export_list )
837{
838  if ( chdk_export_list[0] != EXPORTLIST_MAGIC_NUMBER )
839     return 1;
840
841  if ( !API_VERSION_MATCH_REQUIREMENT( camera_sensor.api_version, 1, 0 ) )
842         return 1;
843  if ( !API_VERSION_MATCH_REQUIREMENT( camera_info.api_version, 1, 0 ) )
844         return 1;
845
846  return 0;
847}
848
849
850//---------------------------------------------------------
851// PURPOSE: Finalize module operations (close allocs, etc)
852// RETURN VALUE: 0-ok, 1-fail
853//---------------------------------------------------------
854int _module_unloader()
855{
856
857        unload_bad_pixels_list_b();
858    free_dng_header();
859    return 0;
860}
861
862
863/******************** Module Information structure ******************/
864
865struct ModuleInfo _module_info = {      MODULEINFO_V1_MAGICNUM,
866                                                                        sizeof(struct ModuleInfo),
867
868                                                                        ANY_CHDK_BRANCH, 0,                     // Requirements of CHDK version
869                                                                        PLATFORMID,                                     // Specify platform dependency
870                                                                        MODULEINFO_FLAG_SYSTEM,         // flag
871                                                                        (int32_t)"DNG (dll)",   // Module name
872                                                                        1, 0,                                           // Module version
873                                                                        (int32_t)"Processing of DNG"
874                                                                 };
875
876
877/*************** END OF AUXILARY PART *******************/
Note: See TracBrowser for help on using the repository browser.