This source file includes following definitions.
- get_type_size
- get_ifd
- get_tag
- add_to_buf
- add_val_to_buf
- process_ifd_list
- process_entries
- inc_ifd_count
- calc_ifd_count
- inc_raw_offset
- calc_raw_offset
- calc_extra_offset
- add_entry_to_buffer
- add_ifd_to_buffer
- add_entry_extra_data_to_buffer
- add_extra_data_to_buffer
- create_dng_header
- free_dng_header
- get_exp_program_for_exif
- get_orientation_for_exif
- get_flash_mode_for_exif
- get_metering_mode_for_exif
- pow_calc_2
- pow_calc
- capture_data_for_exif
- convert_dng_to_chdk_raw
- load_dng_to_rawbuffer
- create_thumbnail
- raw_init_badpixel_bin
- unload_bad_pixels_list_b
- load_bad_pixels_list_b
- patch_bad_pixels_b
- badpixel_list_loaded_b
- action_stack_BADPIX_S3
- action_stack_BADPIX_S2
- action_stack_BADPIX_S1
- action_stack_BADPIX_START
- create_badpixel_bin
- reverse_bytes_task
- write_dng
- create_dng_header_for_ptp
- free_dng_header_for_ptp
- _module_unloader
- _module_can_unload
1 #include "camera_info.h"
2 #include "modes.h"
3 #include "debug_led.h"
4 #include "clock.h"
5 #include "properties.h"
6 #include "shooting.h"
7 #include "conf.h"
8 #include "console.h"
9 #include "raw.h"
10 #include "action_stack.h"
11 #include "gui.h"
12 #include "gui_mbox.h"
13 #include "gui_lang.h"
14 #include "gps.h"
15 #include "math.h"
16 #include "cache.h"
17 #include "task.h"
18 #include "cachebit.h"
19 #include "remotecap.h"
20 #include "time.h"
21
22 #include "dng.h"
23 #include "module_def.h"
24
25
26 static int running = 0;
27
28
29 #define DNG_TH_WIDTH 128
30 #define DNG_TH_HEIGHT 96
31 #define DNG_TH_BYTES (DNG_TH_WIDTH*DNG_TH_HEIGHT*3)
32
33
34
35 void reverse_bytes_order2(char* from, char* to, int count);
36
37
38 typedef struct
39 {
40 unsigned short tag;
41 unsigned short type;
42 unsigned int count;
43 unsigned int offset;
44 } dir_entry;
45
46 #define T_EOL 0
47 #define T_BYTE 1
48 #define T_ASCII 2
49 #define T_SHORT 3
50 #define T_LONG 4
51 #define T_RATIONAL 5
52 #define T_SBYTE 6
53 #define T_UNDEFINED 7
54 #define T_SSHORT 8
55 #define T_SLONG 9
56 #define T_SRATIONAL 10
57 #define T_FLOAT 11
58 #define T_DOUBLE 12
59 #define T_PTR 0x100
60 #define T_SKIP 0x200
61
62 unsigned short get_exp_program_for_exif(int exp_program);
63 unsigned short get_orientation_for_exif(short orientation);
64 unsigned short get_flash_mode_for_exif(short mode, short fired);
65 unsigned short get_metering_mode_for_exif(short metering_mode);
66
67 const int cam_BaselineNoise[] = {1,1};
68 const int cam_BaselineSharpness[] = {4,3};
69 const int cam_LinearResponseLimit[] = {1,1};
70 const int cam_AnalogBalance[] = {1,1,1,1,1,1};
71 static char cam_name[32] = "";
72 static char artist_name[64] = "";
73 static char copyright[64] = "";
74 const short cam_PreviewBitsPerSample[] = {8,8,8};
75 const int cam_Resolution[] = {180,1};
76 static int cam_AsShotNeutral[] = {1000,1000,1000,1000,1000,1000};
77 static char cam_datetime[20] = "";
78 static char cam_subsectime[4] = "";
79 static int cam_shutter[2] = { 0, 1000000 };
80 static int cam_aperture[2] = { 0, 10 };
81 static int cam_apex_shutter[2] = { 0, 96 };
82 static int cam_apex_aperture[2] = { 0, 96 };
83 static int cam_exp_bias[2] = { 0, 96 };
84 static int cam_max_av[2] = { 0, 96 };
85 static int cam_focal_length[2] = { 0, 1000 };
86 static int cam_subject_distance[2] = { 0, 1000 };
87
88 struct t_data_for_exif{
89 short iso;
90 int exp_program;
91 int effective_focal_length;
92 short orientation;
93 short flash_mode;
94 short flash_fired;
95 short metering_mode;
96 };
97
98 static struct t_data_for_exif exif_data;
99
100 #define BE(v) ((v&0x000000FF)<<24)|((v&0x0000FF00)<<8)|((v&0x00FF0000)>>8)|((v&0xFF000000)>>24)
101
102 #define BADPIX_CFA_INDEX 6
103
104 static unsigned int badpixel_opcode[] =
105 {
106
107
108 BE(1),
109
110 BE(4),
111 BE(0x01030000),
112 BE(1),
113 BE(8),
114 BE(0),
115 BE(0),
116 };
117
118
119
120
121 #define CAMERA_NAME_TAG 0x110
122 #define THUMB_DATA_TAG 0x111
123 #define ORIENTATION_TAG 0x112
124 #define CHDK_VER_TAG 0x131
125 #define ARTIST_NAME_TAG 0x13B
126 #define SUBIFDS_TAG 0x14A
127 #define COPYRIGHT_TAG 0x8298
128 #define EXIF_IFD_TAG 0x8769
129 #define GPS_IFD_TAG 0x8825
130 #define DNG_VERSION_TAG 0xC612
131 #define UNIQUE_CAMERA_MODEL_TAG 0xC614
132 #define COLOR_MATRIX2_TAG 0xc622
133 #define CALIBRATION1_TAG 0xc623
134 #define CALIBRATION2_TAG 0xc624
135 #define ILLUMINANT2_TAG 0xc65b
136 #define FORWARD_MATRIX1_TAG 0xc714
137 #define FORWARD_MATRIX2_TAG 0xc715
138
139 #define CAM_MAKE "Canon"
140
141 dir_entry ifd0[]={
142 {0xFE, T_LONG, 1, 1},
143 {0x100, T_LONG, 1, DNG_TH_WIDTH},
144 {0x101, T_LONG, 1, DNG_TH_HEIGHT},
145 {0x102, T_SHORT, 3, (int)cam_PreviewBitsPerSample},
146 {0x103, T_SHORT, 1, 1},
147 {0x106, T_SHORT, 1, 2},
148 {0x10E, T_ASCII, 1, 0},
149 {0x10F, T_ASCII, sizeof(CAM_MAKE), (int)CAM_MAKE},
150 {0x110, T_ASCII, 32, (int)cam_name},
151 {0x111, T_LONG, 1, 0},
152 {0x112, T_SHORT, 1, 1},
153 {0x115, T_SHORT, 1, 3},
154 {0x116, T_SHORT, 1, DNG_TH_HEIGHT},
155 {0x117, T_LONG, 1, DNG_TH_BYTES},
156 {0x11C, T_SHORT, 1, 1},
157 {0x131, T_ASCII|T_PTR,32, 0},
158 {0x132, T_ASCII, 20, (int)cam_datetime},
159 {0x13B, T_ASCII|T_PTR,64, (int)artist_name},
160 {0x14A, T_LONG, 1, 0},
161 {0x8298, T_ASCII|T_PTR,64, (int)copyright},
162 {0x8769, T_LONG, 1, 0},
163 {0x8825, T_LONG, 1, 0},
164 {0x9216, T_BYTE, 4, 0x00000001},
165 {0xC612, T_BYTE, 4, 0x00000301},
166 {0xC613, T_BYTE, 4, 0x00000101},
167 {0xC614, T_ASCII, 32, (int)cam_name},
168 {0xC621, T_SRATIONAL, 9, (int)&camera_sensor.color_matrix1},
169 {0xC622, T_SRATIONAL, 9, (int)&camera_sensor.color_matrix2},
170 {0xC623, T_SRATIONAL, 9, (int)&camera_sensor.camera_calibration1},
171 {0xC624, T_SRATIONAL, 9, (int)&camera_sensor.camera_calibration2},
172 {0xC627, T_RATIONAL, 3, (int)cam_AnalogBalance},
173 {0xC628, T_RATIONAL, 3, (int)cam_AsShotNeutral},
174 {0xC62A, T_SRATIONAL, 1, (int)&camera_sensor.exposure_bias},
175 {0xC62B, T_RATIONAL, 1, (int)cam_BaselineNoise},
176 {0xC62C, T_RATIONAL, 1, (int)cam_BaselineSharpness},
177 {0xC62E, T_RATIONAL, 1, (int)cam_LinearResponseLimit},
178 {0xC630, T_RATIONAL, 4, (int)&camera_sensor.lens_info},
179 {0xC65A, T_SHORT|T_PTR,1, (int)&camera_sensor.calibration_illuminant1},
180 {0xC65B, T_SHORT|T_PTR,1, (int)&camera_sensor.calibration_illuminant2},
181 {0xC714, T_SRATIONAL, 9, (int)&camera_sensor.forward_matrix1},
182 {0xC715, T_SRATIONAL, 9, (int)&camera_sensor.forward_matrix2},
183 {0, T_EOL, 0, 0},
184 };
185
186
187 #define RAW_DATA_TAG 0x111
188 #define BADPIXEL_OPCODE_TAG 0xC740
189
190
191 static int crop_origin[2];
192 static int crop_size[2];
193 static int active_area[4];
194
195 dir_entry ifd1[]={
196 {0xFE, T_LONG, 1, 0},
197 {0x100, T_LONG|T_PTR, 1, (int)&camera_sensor.raw_rowpix},
198 {0x101, T_LONG|T_PTR, 1, (int)&camera_sensor.raw_rows},
199 {0x102, T_SHORT|T_PTR,1, (int)&camera_sensor.bits_per_pixel},
200 {0x103, T_SHORT, 1, 1},
201 {0x106, T_SHORT, 1, 0x8023},
202 {0x111, T_LONG, 1, 0},
203 {0x115, T_SHORT, 1, 1},
204 {0x116, T_SHORT|T_PTR,1, (int)&camera_sensor.raw_rows},
205 {0x117, T_LONG|T_PTR, 1, (int)&camera_sensor.raw_size},
206 {0x11A, T_RATIONAL, 1, (int)cam_Resolution},
207 {0x11B, T_RATIONAL, 1, (int)cam_Resolution},
208 {0x11C, T_SHORT, 1, 1},
209 {0x128, T_SHORT, 1, 2},
210 {0x828D, T_SHORT, 2, 0x00020002},
211 {0x828E, T_BYTE|T_PTR, 4, (int)&camera_sensor.cfa_pattern},
212 {0xC61A, T_LONG|T_PTR, 1, (int)&camera_sensor.black_level},
213 {0xC61D, T_LONG|T_PTR, 1, (int)&camera_sensor.white_level},
214 {0xC61F, T_LONG, 2, (int)&crop_origin},
215 {0xC620, T_LONG, 2, (int)&crop_size},
216 {0xC68D, T_LONG, 4, (int)&active_area},
217 {0xC740, T_UNDEFINED|T_PTR, sizeof(badpixel_opcode), (int)&badpixel_opcode},
218 {0, T_EOL, 0, 0},
219 };
220
221
222 #define EXPOSURE_PROGRAM_TAG 0x8822
223 #define METERING_MODE_TAG 0x9207
224 #define FLASH_MODE_TAG 0x9209
225 #define SSTIME_TAG 0x9290
226 #define SSTIME_ORIG_TAG 0x9291
227
228 dir_entry exif_ifd[]={
229 {0x829A, T_RATIONAL, 1, (int)cam_shutter},
230 {0x829D, T_RATIONAL, 1, (int)cam_aperture},
231 {0x8822, T_SHORT, 1, 0},
232 {0x8827, T_SHORT|T_PTR,1, (int)&exif_data.iso},
233 {0x9000, T_UNDEFINED, 4, 0x31323230},
234 {0x9003, T_ASCII, 20, (int)cam_datetime},
235 {0x9201, T_SRATIONAL, 1, (int)cam_apex_shutter},
236 {0x9202, T_RATIONAL, 1, (int)cam_apex_aperture},
237 {0x9204, T_SRATIONAL, 1, (int)cam_exp_bias},
238 {0x9205, T_RATIONAL, 1, (int)cam_max_av},
239 {0x9206, T_RATIONAL, 1, (int)cam_subject_distance},
240 {0x9207, T_SHORT, 1, 0},
241 {0x9209, T_SHORT, 1, 0},
242 {0x920A, T_RATIONAL, 1, (int)cam_focal_length},
243 {0x9290, T_ASCII|T_PTR,4, (int)cam_subsectime},
244 {0x9291, T_ASCII|T_PTR,4, (int)cam_subsectime},
245 {0xA405, T_SHORT|T_PTR,1, (int)&exif_data.effective_focal_length},
246 {0, T_EOL, 0, 0},
247 };
248
249 tGPS gps_data;
250
251 dir_entry gpd_ifd[]={
252 {0x0000, T_BYTE, 4, 0x00000302},
253 {0x0001, T_ASCII|T_PTR, 2, (int)gps_data.latitudeRef},
254 {0x0002, T_RATIONAL, 3, (int)gps_data.latitude},
255 {0x0003, T_ASCII|T_PTR, 2, (int)gps_data.longitudeRef},
256 {0x0004, T_RATIONAL, 3, (int)gps_data.longitude},
257 {0x0005, T_BYTE|T_PTR, 1, (int)&gps_data.heightRef},
258 {0x0006, T_RATIONAL, 1, (int)gps_data.height},
259 {0x0007, T_RATIONAL, 3, (int)gps_data.timeStamp},
260 {0x0009, T_ASCII|T_PTR, 2, (int)gps_data.status},
261
262 {0x0012, T_ASCII, 7, (int)gps_data.mapDatum},
263 {0x001D, T_ASCII, 11, (int)gps_data.dateStamp},
264 {0, T_EOL, 0, 0},
265 };
266
267 int get_type_size(int type)
268 {
269 switch(type & 0xFF)
270 {
271 case T_BYTE:
272 case T_SBYTE:
273 case T_UNDEFINED:
274 case T_ASCII: return 1;
275 case T_SHORT:
276 case T_SSHORT: return 2;
277 case T_LONG:
278 case T_SLONG:
279 case T_FLOAT: return 4;
280 case T_RATIONAL:
281 case T_SRATIONAL:
282 case T_DOUBLE: return 8;
283 default: return 0;
284 }
285 }
286
287
288 #define IFD_0 1
289 #define IFD_1 2
290 #define IFD_EXIF 3
291 #define IFD_GPS 4
292 #define IFD_SKIP 0x200
293 #define IFD_TYPE_MASK 0xF
294
295 typedef struct
296 {
297 dir_entry* entry;
298 short count;
299 short type;
300 } ifd_entry;
301
302 ifd_entry ifd_list[] =
303 {
304 {ifd0, 0, IFD_0},
305 {ifd1, 0, IFD_1},
306 {exif_ifd, 0, IFD_EXIF},
307 {gpd_ifd, 0, IFD_GPS},
308 {0,0,0},
309 };
310
311
312 static ifd_entry* get_ifd(int type)
313 {
314 int i;
315 for (i = 0; ifd_list[i].entry != 0; i++)
316 {
317 if ((ifd_list[i].type & IFD_TYPE_MASK) == type)
318 return &ifd_list[i];
319 }
320 return 0;
321 }
322
323
324 static dir_entry* get_tag(int ifd, int tag)
325 {
326 ifd_entry* p = get_ifd(ifd);
327 if (p)
328 {
329 int i;
330 for (i=0; p->entry[i].type != T_EOL; i++)
331 {
332 if (p->entry[i].tag == tag)
333 return &p->entry[i];
334 }
335 }
336 return 0;
337 }
338
339 #define TIFF_HDR_SIZE (8)
340
341 char* dng_header_buf = 0;
342 int dng_header_buf_size;
343 int dng_header_buf_offset;
344 char *thumbnail_buf = 0;
345
346
347
348
349 void add_to_buf(void* var, int size)
350 {
351 memcpy(dng_header_buf+dng_header_buf_offset,var,size);
352 dng_header_buf_offset += size;
353 }
354
355
356 void add_val_to_buf(int val, int size)
357 {
358 add_to_buf(&val,size);
359 }
360
361
362 static void process_ifd_list(void (*f)(ifd_entry*))
363 {
364 int i;
365 for (i=0; ifd_list[i].type!=0; i++)
366 {
367 if ((ifd_list[i].type & IFD_SKIP) == 0)
368 {
369 f(&ifd_list[i]);
370 }
371 }
372 }
373
374
375 static void process_entries(ifd_entry* ifd, void (*f)(ifd_entry*, dir_entry*))
376 {
377 int i;
378 for (i=0; ifd->entry[i].type != T_EOL; i++)
379 {
380 if ((ifd->entry[i].type & T_SKIP) == 0)
381 {
382 f(ifd, &ifd->entry[i]);
383 }
384 }
385 }
386
387
388
389 static void inc_ifd_count(ifd_entry* ifd, __attribute__ ((unused))dir_entry* e)
390 {
391 ifd->count++;
392 }
393
394 static void calc_ifd_count(ifd_entry* ifd)
395 {
396 ifd->count = 0;
397 process_entries(ifd, inc_ifd_count);
398 }
399
400
401
402 static int raw_offset;
403
404 static void inc_raw_offset(__attribute__ ((unused))ifd_entry* ifd, dir_entry* e)
405 {
406 raw_offset += 12;
407 int size_ext = get_type_size(e->type) * e->count;
408 if (size_ext > 4) raw_offset += size_ext + (size_ext&1);
409 }
410
411 static void calc_raw_offset(ifd_entry* ifd)
412 {
413 raw_offset+=6;
414 process_entries(ifd, inc_raw_offset);
415 }
416
417
418
419 static int extra_offset;
420
421 static void calc_extra_offset(ifd_entry* ifd)
422 {
423 extra_offset += 6 + ifd->count * 12;
424 }
425
426
427
428 static void add_entry_to_buffer(__attribute__ ((unused))ifd_entry* ifd, dir_entry* e)
429 {
430 add_val_to_buf(e->tag, sizeof(short));
431 add_val_to_buf(e->type & 0xFF, sizeof(short));
432 add_val_to_buf(e->count, sizeof(int));
433 int size_ext = get_type_size(e->type) * e->count;
434 if (size_ext <= 4)
435 {
436 if (e->type & T_PTR)
437 {
438 add_to_buf((void*)e->offset, sizeof(int));
439 }
440 else
441 {
442 add_val_to_buf(e->offset, sizeof(int));
443 }
444 }
445 else
446 {
447 add_val_to_buf(extra_offset, sizeof(int));
448 extra_offset += size_ext + (size_ext&1);
449 }
450 }
451
452 static void add_ifd_to_buffer(ifd_entry* ifd)
453 {
454 add_val_to_buf(ifd->count, sizeof(short));
455 process_entries(ifd, add_entry_to_buffer);
456 add_val_to_buf(0, sizeof(int));
457 }
458
459
460
461 static void add_entry_extra_data_to_buffer(__attribute__ ((unused))ifd_entry* ifd, dir_entry* e)
462 {
463 int size_ext = get_type_size(e->type) * e->count;
464 if (size_ext > 4)
465 {
466 add_to_buf((void*)e->offset, size_ext);
467 if (size_ext&1) add_val_to_buf(0, 1);
468 }
469 }
470
471 static void add_extra_data_to_buffer(ifd_entry* ifd)
472 {
473 process_entries(ifd, add_entry_extra_data_to_buffer);
474 }
475
476
477
478
479
480
481
482 void create_dng_header(int ver1_1, int minimal)
483 {
484 int i;
485
486
487 if (ver1_1)
488 {
489
490 get_tag(IFD_0, DNG_VERSION_TAG)->offset = BE(0x01010000);
491 get_tag(IFD_1, BADPIXEL_OPCODE_TAG)->type |= T_SKIP;
492 }
493 else
494 {
495
496 get_tag(IFD_0, DNG_VERSION_TAG)->offset = BE(0x01030000);
497 get_tag(IFD_1, BADPIXEL_OPCODE_TAG)->type &= ~T_SKIP;
498
499 switch (camera_sensor.cfa_pattern)
500 {
501 case 0x02010100:
502 badpixel_opcode[BADPIX_CFA_INDEX] = BE(0);
503 break;
504 case 0x01020001:
505 badpixel_opcode[BADPIX_CFA_INDEX] = BE(1);
506 break;
507 case 0x01000201:
508 badpixel_opcode[BADPIX_CFA_INDEX] = BE(2);
509 break;
510 case 0x00010102:
511 badpixel_opcode[BADPIX_CFA_INDEX] = BE(3);
512 break;
513 }
514 }
515
516
517 switch (conf.dng_crop_size)
518 {
519 case 0:
520 default:
521
522 crop_origin[0] = camera_sensor.jpeg.x;
523 crop_origin[1] = camera_sensor.jpeg.y;
524 crop_size[0] = camera_sensor.jpeg.width;
525 crop_size[1] = camera_sensor.jpeg.height;
526
527 memcpy(active_area, camera_sensor.dng_active_area, sizeof(active_area));
528 break;
529 case 1:
530
531 crop_origin[0] = 0;
532 crop_origin[1] = 0;
533 crop_size[0] = camera_sensor.active_area.x2 - camera_sensor.active_area.x1;
534 crop_size[1] = camera_sensor.active_area.y2 - camera_sensor.active_area.y1;
535
536 memcpy(active_area, camera_sensor.dng_active_area, sizeof(active_area));
537 break;
538 case 2:
539
540 crop_origin[0] = 0;
541 crop_origin[1] = 0;
542 crop_size[0] = camera_sensor.raw_rowpix;
543 crop_size[1] = camera_sensor.raw_rows;
544
545 active_area[0] = (camera_sensor.active_area.y1 & 1);
546 active_area[1] = 0;
547 active_area[2] = camera_sensor.raw_rows;
548 active_area[3] = camera_sensor.raw_rowpix;
549 break;
550 }
551
552
553
554 if (camera_info.props.gps)
555 {
556
557 get_property_case(camera_info.props.gps, &gps_data, sizeof(gps_data));
558 }
559 else
560 {
561
562 get_ifd(IFD_GPS)->type |= IFD_SKIP;
563 get_tag(IFD_0, GPS_IFD_TAG)->type |= T_SKIP;
564 }
565
566
567
568 get_tag(IFD_0, CAMERA_NAME_TAG)->count = get_tag(IFD_0, UNIQUE_CAMERA_MODEL_TAG)->count = strlen(cam_name) + 1;
569 get_tag(IFD_0, CHDK_VER_TAG)->offset = (int)camera_info.chdk_dng_ver;
570 get_tag(IFD_0, CHDK_VER_TAG)->count = strlen(camera_info.chdk_dng_ver) + 1;
571 get_tag(IFD_0, ARTIST_NAME_TAG)->count = strlen(artist_name) + 1;
572 get_tag(IFD_0, COPYRIGHT_TAG)->count = strlen(copyright) + 1;
573 get_tag(IFD_0, ORIENTATION_TAG)->offset = get_orientation_for_exif(exif_data.orientation);
574
575 get_tag(IFD_EXIF, EXPOSURE_PROGRAM_TAG)->offset = get_exp_program_for_exif(exif_data.exp_program);
576 get_tag(IFD_EXIF, METERING_MODE_TAG)->offset = get_metering_mode_for_exif(exif_data.metering_mode);
577 get_tag(IFD_EXIF, FLASH_MODE_TAG)->offset = get_flash_mode_for_exif(exif_data.flash_mode, exif_data.flash_fired);
578 get_tag(IFD_EXIF, SSTIME_TAG)->count = get_tag(IFD_EXIF, SSTIME_ORIG_TAG)->count = strlen(cam_subsectime)+1;
579
580
581 if (camera_sensor.calibration_illuminant2 == 0)
582 {
583 get_tag(IFD_0, ILLUMINANT2_TAG)->type |= T_SKIP;
584 get_tag(IFD_0, COLOR_MATRIX2_TAG)->type |= T_SKIP;
585 }
586 if (camera_sensor.has_calibration1 == 0) get_tag(IFD_0, CALIBRATION1_TAG)->type |= T_SKIP;
587 if (camera_sensor.has_calibration2 == 0) get_tag(IFD_0, CALIBRATION2_TAG)->type |= T_SKIP;
588 if (camera_sensor.has_forwardmatrix1 == 0) get_tag(IFD_0, FORWARD_MATRIX1_TAG)->type |= T_SKIP;
589 if (camera_sensor.has_forwardmatrix2 == 0) get_tag(IFD_0, FORWARD_MATRIX2_TAG)->type |= T_SKIP;
590
591
592 process_ifd_list(calc_ifd_count);
593
594
595 raw_offset = TIFF_HDR_SIZE;
596 process_ifd_list(calc_raw_offset);
597
598
599 if (minimal)
600 {
601 raw_offset = (raw_offset/4+1)*4;
602 dng_header_buf = malloc(raw_offset);
603 thumbnail_buf = NULL;
604 }
605 else
606 {
607 raw_offset = (raw_offset/512+1)*512;
608 dng_header_buf = malloc(raw_offset + DNG_TH_BYTES);
609 thumbnail_buf = dng_header_buf + raw_offset;
610 }
611 dng_header_buf_size = raw_offset;
612 if (!dng_header_buf)
613 {
614 thumbnail_buf = NULL;
615 return;
616 }
617 dng_header_buf_offset = 0;
618
619
620
621 get_tag(IFD_0, SUBIFDS_TAG)->offset = TIFF_HDR_SIZE + ifd_list[0].count * 12 + 6;
622 get_tag(IFD_0, EXIF_IFD_TAG)->offset = TIFF_HDR_SIZE + (ifd_list[0].count + ifd_list[1].count) * 12 + 6 + 6;
623 if (camera_info.props.gps)
624 get_tag(IFD_0, GPS_IFD_TAG)->offset = TIFF_HDR_SIZE + (ifd_list[0].count + ifd_list[1].count + ifd_list[2].count) * 12 + 6 + 6 + 6;
625
626 get_tag(IFD_0, THUMB_DATA_TAG)->offset = raw_offset;
627 get_tag(IFD_1, RAW_DATA_TAG)->offset = raw_offset + DNG_TH_BYTES;
628
629 extra_offset=TIFF_HDR_SIZE;
630 process_ifd_list(calc_extra_offset);
631
632
633 add_val_to_buf(0x4949, sizeof(short));
634 add_val_to_buf(42, sizeof(short));
635 add_val_to_buf(TIFF_HDR_SIZE, sizeof(int));
636
637
638 process_ifd_list(add_ifd_to_buffer);
639
640
641 process_ifd_list(add_extra_data_to_buffer);
642
643
644 for (i=dng_header_buf_offset; i<dng_header_buf_size; i++) dng_header_buf[i]=0;
645 }
646
647 void free_dng_header(void)
648 {
649 if (dng_header_buf)
650 {
651 free(dng_header_buf);
652 dng_header_buf = NULL;
653 }
654 }
655
656
657 unsigned short get_exp_program_for_exif(int exp_program)
658 {
659 switch(exp_program)
660 {
661 case MODE_M: return 1;
662 case MODE_P: return 2;
663 case MODE_AV: return 3;
664 case MODE_TV: return 4;
665 default: return 0;
666 }
667 }
668
669 unsigned short get_orientation_for_exif(short orientation)
670 {
671 switch(orientation)
672 {
673 case 90: return 6;
674 case 180: return 3;
675 case 270: return 8;
676 case 0:
677 default : return 1;
678 }
679 }
680
681 unsigned short get_flash_mode_for_exif(short mode, short fired){
682 fired&=1;
683 switch(mode)
684 {
685 case 0: return (3<<3)|fired;
686 case 1: return (1<<3)|fired;
687 case 2: return (2<<3)|fired;
688 default: return fired;
689 }
690 }
691
692 unsigned short get_metering_mode_for_exif(short metering_mode)
693 {
694 switch (metering_mode)
695 {
696 case 0: return 5;
697 case 1: return 3;
698 case 2: return 2;
699 default: return 255;
700 }
701 }
702
703 int pow_calc_2( int mult, int x, int x_div, double y, int y_div)
704 {
705 double x1 = x;
706 if ( x_div != 1 ) { x1=x1/x_div;}
707 if ( y_div != 1 ) { y=y/y_div;}
708
709 if ( mult==1 )
710 return pow( x1, y );
711 else
712 return mult * pow( x1, y );
713 }
714
715 int pow_calc( int mult, int x, int x_div, int y, int y_div)
716 {
717 return pow_calc_2( mult, x, x_div, y, y_div);
718 }
719
720
721 void capture_data_for_exif(void)
722 {
723 short short_prop_val;
724 time_t datetime;
725 long subsectime;
726 struct tm *ttm;
727 int wb[3];
728
729 exif_data.iso=shooting_get_iso_market();
730
731
732 get_property_case(camera_info.props.tv, &short_prop_val, sizeof(short_prop_val));
733 cam_shutter[0] = pow_calc( 1000000, 2, 1, -short_prop_val, 96);
734 cam_apex_shutter[0] = short_prop_val;
735
736
737 if (camera_info.state.shutter_open_time)
738 {
739
740 subsectime = (camera_info.state.shutter_open_tick_count - camera_info.tick_count_offset) % 1000;
741
742 datetime = camera_info.state.shutter_open_time + ((cam_shutter[0] + (subsectime * 1000)) / 1000000);
743 camera_info.state.shutter_open_time = 0;
744 }
745 else
746 {
747 datetime = time(NULL);
748
749 subsectime = (get_tick_count() - camera_info.tick_count_offset) % 1000;
750 }
751 ttm = localtime(&datetime);
752 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);
753 sprintf(cam_subsectime, "%02d", subsectime/10);
754
755 get_property_case(camera_info.props.av, &short_prop_val, sizeof(short_prop_val));
756 cam_aperture[0] = pow_calc( 10, 2, 1, short_prop_val, 192);
757 cam_apex_aperture[0] = short_prop_val;
758
759 get_property_case(camera_info.props.min_av, &short_prop_val, sizeof(short_prop_val));
760 cam_max_av[0] = short_prop_val;
761
762 get_property_case(camera_info.props.ev_correction_2, &short_prop_val, sizeof(short_prop_val));
763 cam_exp_bias[0] = short_prop_val;
764
765 exif_data.exp_program = camera_info.state.mode_shooting;
766
767 cam_subject_distance[0] = shooting_get_exif_subject_dist();
768
769 cam_focal_length[0] = get_focal_length(shooting_get_zoom());
770 exif_data.effective_focal_length = get_effective_focal_length(shooting_get_zoom()) / 1000;
771
772 get_property_case(camera_info.props.orientation_sensor, &exif_data.orientation, sizeof(exif_data.orientation));
773 get_parameter_data(camera_info.params.camera_name, &cam_name, sizeof(cam_name));
774 if (camera_info.params.artist_name) get_parameter_data(camera_info.params.artist_name, &artist_name, sizeof(artist_name));
775 else if (camera_info.params.owner_name) get_parameter_data(camera_info.params.owner_name, &artist_name, 32);
776 if (camera_info.params.copyright) get_parameter_data(camera_info.params.copyright, ©right, sizeof(copyright));
777 get_property_case(camera_info.props.flash_mode, &exif_data.flash_mode, sizeof(exif_data.flash_mode));
778 get_property_case(camera_info.props.flash_fire, &exif_data.flash_fired, sizeof(exif_data.flash_fired));
779 get_property_case(camera_info.props.metering_mode, &exif_data.metering_mode, sizeof(exif_data.metering_mode));
780
781 get_property_case(camera_info.props.wb_adj, &wb, sizeof(wb));
782 cam_AsShotNeutral[1]=wb[1];
783 cam_AsShotNeutral[3]=wb[0];
784 cam_AsShotNeutral[5]=wb[2];
785 }
786
787
788
789 static int convert_dng_to_chdk_raw(char* fn)
790 {
791 #define BUF_SIZE (32768)
792 FILE *dng, *raw;
793 int *buf;
794 unsigned i;
795 struct stat st;
796 struct utimbuf t;
797
798 if (stat(fn, &st) != 0 || st.st_size<=camera_sensor.raw_size)
799 return 0;
800
801 running = 1;
802
803 buf=malloc(BUF_SIZE);
804 if (buf)
805 {
806 started();
807 dng=fopen(fn,"rb");
808 if (dng)
809 {
810 fread(buf, 1, 8, dng);
811 if (buf[0]==0x2A4949 && buf[1]==8)
812 {
813 i=strlen(fn)-3;
814 if (strncmp(fn+i,"CR",2)==0) strcpy(fn+i,"WAV"); else strcpy(fn+i,"CRW");
815 raw=fopen(fn,"w+b");
816 if (raw){
817 fseek(dng, st.st_size-camera_sensor.raw_size, SEEK_SET);
818 for (i=0; i<camera_sensor.raw_size/BUF_SIZE; i++)
819 {
820 fread(buf, 1, BUF_SIZE, dng);
821 reverse_bytes_order2((char*)buf, (char*)buf, BUF_SIZE);
822 fwrite(buf, 1, BUF_SIZE, raw);
823 }
824 fread(buf, 1, camera_sensor.raw_size%BUF_SIZE, dng);
825 reverse_bytes_order2((char*)buf, (char*)buf, camera_sensor.raw_size%BUF_SIZE);
826 fwrite(buf, 1, camera_sensor.raw_size%BUF_SIZE, raw);
827 fclose(raw);
828 t.actime = t.modtime = time(NULL);
829 utime(fn, &t);
830 }
831 }
832 fclose(dng);
833 }
834 free(buf);
835 finished();
836 }
837
838 running = 0;
839
840 return 1;
841 }
842
843 static void load_dng_to_rawbuffer(char *fn, char *rawadr)
844 {
845 running = 1;
846
847 struct stat st;
848 if ((stat(fn,&st) == 0) && (st.st_size >= camera_sensor.raw_size))
849 {
850 int fd = open(fn, O_RDONLY, 0777);
851 if (fd >= 0)
852 {
853 lseek(fd, st.st_size-camera_sensor.raw_size, SEEK_SET);
854 read(fd, rawadr, camera_sensor.raw_size);
855 close(fd);
856 reverse_bytes_order2(rawadr, rawadr, camera_sensor.raw_size);
857 }
858 }
859
860 running = 0;
861 }
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880 static const unsigned char gamma[256] =
881 {
882 0,15,22,27,31,35,39,42,45,47,50,52,75,77,79,82,
883 84,86,88,90,92,93,95,97,99,100,102,103,105,106,108,109,
884 111,112,113,115,116,117,119,120,121,122,123,125,126,127,128,129,
885 130,131,132,133,134,136,137,138,139,140,141,141,142,143,144,145,
886 180,181,181,182,183,183,184,185,185,186,187,187,188,189,189,190,
887 190,191,192,192,193,193,194,194,195,195,196,197,197,198,198,199,
888 199,200,200,201,201,202,202,203,203,204,204,205,205,206,206,207,
889 207,208,208,208,209,209,210,210,211,211,212,212,212,213,213,214,
890 214,215,215,215,216,216,217,217,217,218,218,219,219,219,220,220,
891 221,221,221,222,222,222,223,223,224,224,224,225,225,225,226,226,
892 226,227,227,228,228,228,229,229,229,230,230,230,231,231,231,232,
893 232,232,233,233,233,234,234,234,235,235,235,235,236,236,236,237,
894 237,237,238,238,238,239,239,239,239,240,240,240,241,241,241,242,
895 242,242,242,243,243,243,244,244,244,244,245,245,245,246,246,246,
896 246,247,247,247,247,248,248,248,249,249,249,249,250,250,250,250,
897 251,251,251,251,252,252,252,252,253,253,253,253,254,254,254,255
898 };
899 void create_thumbnail()
900 {
901 char *buf = thumbnail_buf;
902 int shift = camera_sensor.bits_per_pixel - 8;
903
904 int x_inc = camera_sensor.jpeg.width / DNG_TH_WIDTH;
905 int y_inc = camera_sensor.jpeg.height / DNG_TH_HEIGHT;
906
907 int x_end = camera_sensor.active_area.x1 + camera_sensor.jpeg.x + DNG_TH_WIDTH*x_inc;
908 int y_end = camera_sensor.active_area.y1 + camera_sensor.jpeg.y + DNG_TH_HEIGHT*y_inc;
909
910 int x_off,y_off;
911
912
913
914
915
916
917
918
919 int yadj = (camera_sensor.cfa_pattern == 0x01000201) ? 1 : 0;
920 int xadj = (camera_sensor.cfa_pattern == 0x01020001) ? 1 : 0;
921
922 for (y_off=camera_sensor.active_area.y1 + camera_sensor.jpeg.y; y_off<y_end; y_off += y_inc)
923 for (x_off=camera_sensor.active_area.x1 + camera_sensor.jpeg.x; x_off<x_end; x_off += x_inc)
924 {
925 int x = (x_off & 0xFFFFFFFE) + xadj;
926 int y = (y_off & 0xFFFFFFFE) + yadj;
927
928 *buf++ = gamma[get_raw_pixel(x,y)>>shift];
929
930 int g=get_raw_pixel(x+1,y) >> (shift+1);
931 *buf++ = gamma[g+(g>>2)];
932 *buf++ = gamma[get_raw_pixel(x+1,y+1)>>shift];
933 }
934 }
935
936
937
938
939
940 #define INIT_BADPIXEL_COUNT -1
941 #define INIT_BADPIXEL_FILE -2
942
943 #define PATH_BADPIXEL_BIN "A/CHDK/badpixel.bin"
944 #define PATH_BAD_TMP_BIN "A/CHDK/bad_tmp.bin"
945
946 int init_badpixel_bin_flag;
947
948 int raw_init_badpixel_bin()
949 {
950 int count;
951 int x, y, xlen, ylen;
952 unsigned short c[9];
953
954 FILE*f;
955 if(init_badpixel_bin_flag == INIT_BADPIXEL_FILE)
956 {
957 f=fopen(PATH_BAD_TMP_BIN,"w+b");
958 }
959 else if (init_badpixel_bin_flag == INIT_BADPIXEL_COUNT)
960 {
961 f=NULL;
962 }
963 else
964 {
965 return 0;
966 }
967 count = 0;
968 for (x=camera_sensor.active_area.x1; x<camera_sensor.active_area.x2; x++)
969 {
970 xlen = 0;
971 for (y=camera_sensor.active_area.y1; y<camera_sensor.active_area.y2; y++)
972 {
973 if (get_raw_pixel(x,y) <= camera_sensor.dng_badpixel_value_limit)
974 {
975 for (ylen=1; ylen<8 && (y+ylen)<camera_sensor.active_area.y2; ylen++)
976 if (get_raw_pixel(x,y+ylen) > camera_sensor.dng_badpixel_value_limit)
977 break;
978 if (f)
979 {
980 c[++xlen] = y | ((ylen-1) << 13);
981 if (xlen == 8)
982 {
983 c[0] = x | ((xlen-1) << 13);
984 fwrite(c, 2, xlen+1, f);
985 xlen = 0;
986 }
987 }
988 count = count + ylen;
989 y += ylen - 1;
990 }
991 }
992 if (f && (xlen > 0))
993 {
994 c[0] = x | ((xlen-1) << 13);
995 fwrite(c, 2, xlen+1, f);
996 }
997 }
998 if (f) fclose(f);
999 init_badpixel_bin_flag = count;
1000 camera_info.state.state_shooting_progress = SHOOTING_PROGRESS_PROCESSING;
1001 return 1;
1002 }
1003
1004 short* binary_list=NULL;
1005 int binary_count=-1;
1006
1007 void unload_bad_pixels_list_b(void)
1008 {
1009 if (binary_list) free(binary_list);
1010 binary_list=NULL;
1011 binary_count=-1;
1012 }
1013
1014 void load_bad_pixels_list_b(char* filename)
1015 {
1016 struct stat st;
1017 long filesize;
1018 void* ptr;
1019 FILE *fd;
1020
1021 if ( filename==0 )
1022 {
1023 unload_bad_pixels_list_b();
1024 return;
1025 }
1026
1027 binary_count=-1;
1028 if (stat(filename,&st)!=0) return;
1029 filesize=st.st_size;
1030 if (filesize%sizeof(short) != 0) return;
1031 if (filesize == 0) { binary_count = 0; return; }
1032 ptr=malloc(filesize);
1033 if (!ptr) return;
1034 fd=fopen(filename, "rb");
1035 if (fd)
1036 {
1037 fread(ptr,1, filesize,fd);
1038 fclose(fd);
1039 binary_list=ptr;
1040 binary_count=filesize/sizeof(short);
1041 }
1042 else free(ptr);
1043 }
1044
1045 void patch_bad_pixels_b(void)
1046 {
1047 int i;
1048 short* ptr=binary_list;
1049 short x, y, xcnt, ycnt;
1050 for (i=0; i<binary_count;)
1051 {
1052 x = ptr[i] & 0x1FFF;
1053 xcnt = (ptr[i] >> 13) & 7;
1054 i++;
1055 for (; xcnt>=0; xcnt--)
1056 {
1057 y = ptr[i] & 0x1FFF;
1058 ycnt = (ptr[i] >> 13) & 7;
1059 i++;
1060 for (; ycnt>=0; ycnt--, y++)
1061 if (get_raw_pixel(x, y) <= camera_sensor.dng_badpixel_value_limit)
1062 patch_bad_pixel(x, y);
1063 }
1064 }
1065 }
1066
1067 int badpixel_list_loaded_b(void)
1068 {
1069 return (binary_count >= 0) ? 1 : 0;
1070 }
1071
1072
1073
1074 static int badpix_cnt1;
1075
1076 static int action_stack_BADPIX_S3()
1077 {
1078 action_pop_func(0);
1079 running = 0;
1080 return 1;
1081 }
1082
1083 static int action_stack_BADPIX_S2()
1084 {
1085
1086
1087 action_pop_func(0);
1088
1089 console_clear();
1090 if (badpix_cnt1 == init_badpixel_bin_flag)
1091 {
1092
1093
1094
1095 char msg[32];
1096 console_add_line("badpixel.bin created.");
1097 sprintf(msg, "Bad pixel count: %d", badpix_cnt1);
1098 console_add_line(msg);
1099 remove(PATH_BADPIXEL_BIN);
1100 rename(PATH_BAD_TMP_BIN,PATH_BADPIXEL_BIN);
1101 }
1102 else
1103 {
1104 console_add_line("badpixel.bin failed.");
1105 console_add_line("Please try again.");
1106 }
1107 init_badpixel_bin_flag = 0;
1108 remove(PATH_BAD_TMP_BIN);
1109
1110
1111 action_push_func(action_stack_BADPIX_S3);
1112 action_push_delay(3000);
1113
1114 return 1;
1115 }
1116
1117 static int action_stack_BADPIX_S1()
1118 {
1119
1120
1121 action_pop_func(0);
1122
1123
1124 badpix_cnt1 = init_badpixel_bin_flag;
1125 init_badpixel_bin_flag = INIT_BADPIXEL_FILE;
1126 shooting_set_tv96_direct(96, SET_LATER);
1127
1128
1129 action_push_func(action_stack_BADPIX_S2);
1130 action_push_shoot(1);
1131
1132 return 1;
1133 }
1134
1135 static int action_stack_BADPIX_START()
1136 {
1137
1138
1139 action_pop_func(0);
1140
1141
1142 console_clear();
1143 console_add_line("Wait please... ");
1144 console_add_line("This takes a few seconds,");
1145 console_add_line("don't panic!");
1146
1147 init_badpixel_bin_flag = INIT_BADPIXEL_COUNT;
1148
1149 shooting_set_tv96_direct(96, SET_LATER);
1150
1151
1152 action_push_func(action_stack_BADPIX_S1);
1153 action_push_shoot(1);
1154 action_push_delay(3000);
1155
1156 return 1;
1157 }
1158
1159 void create_badpixel_bin()
1160 {
1161 if (!camera_info.state.mode_rec)
1162 {
1163 gui_mbox_init(LANG_ERROR, LANG_MSG_RECMODE_REQUIRED, MBOX_BTN_OK|MBOX_TEXT_CENTER, NULL);
1164 return;
1165 }
1166
1167 running = 1;
1168
1169 gui_set_mode(&altGuiHandler);
1170
1171 action_stack_create(&action_stack_BADPIX_START);
1172 }
1173
1174
1175 #define RB_STAGE_DONE 0
1176 #define RB_STAGE_INIT 1
1177 #define RB_STAGE_REVERSING 2
1178 #define RB_STAGE_DEREVERSING 3
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188 #define DNG_REV_CHUNK_SIZE (512*1024)
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198 #define DNG_END_CHUNK_SIZE (512*1024)
1199
1200
1201
1202
1203 #define DNG_END_NUM_CHUNKS (3)
1204
1205 static struct {
1206
1207
1208 char *src;
1209 char *dst;
1210 char *end;
1211
1212 char *reversed;
1213 char *written;
1214 int stage;
1215 } rb_state;
1216
1217 void reverse_bytes_task() {
1218 char *src = rb_state.src;
1219 rb_state.stage = RB_STAGE_REVERSING;
1220 rb_state.reversed = rb_state.dst;
1221
1222 while(rb_state.reversed < rb_state.end) {
1223 int chunk_size;
1224 if(rb_state.reversed + DNG_REV_CHUNK_SIZE > rb_state.end) {
1225 chunk_size = rb_state.end - rb_state.reversed;
1226 } else {
1227 chunk_size = DNG_REV_CHUNK_SIZE;
1228 }
1229 reverse_bytes_order2(src, rb_state.reversed, chunk_size);
1230 src += chunk_size;
1231 rb_state.reversed += chunk_size;
1232
1233
1234
1235
1236 msleep(10);
1237 }
1238 rb_state.stage = RB_STAGE_DEREVERSING;
1239
1240
1241 if(rb_state.src == rb_state.dst) {
1242 src = rb_state.src;
1243 while(src < rb_state.end) {
1244 int chunk_size = rb_state.written - src;
1245 if(!chunk_size) {
1246 msleep(10);
1247 continue;
1248 }
1249 reverse_bytes_order2(src, src, chunk_size);
1250 src += chunk_size;
1251 }
1252
1253
1254 if(ADR_IS_CACHED(rb_state.dst)) {
1255 dcache_clean_all();
1256 }
1257 }
1258
1259
1260 rb_state.stage = RB_STAGE_DONE;
1261 ExitTask();
1262 }
1263
1264
1265
1266
1267
1268 int write_dng(char* rawadr, char* altrawadr)
1269 {
1270 int fd;
1271
1272 create_dng_header(conf.dng_version,0);
1273
1274 if (!dng_header_buf) {
1275 return 0;
1276 }
1277
1278 if (conf.dng_version)
1279 patch_bad_pixels_b();
1280
1281 create_thumbnail();
1282
1283
1284 if(rb_state.stage != RB_STAGE_DONE) {
1285 int i;
1286 for(i=0;i<50;i++) {
1287 debug_led(1);
1288 msleep(200);
1289 debug_led(0);
1290 msleep(200);
1291 }
1292 return 0;
1293 }
1294 rb_state.stage = RB_STAGE_INIT;
1295 rb_state.src = rawadr;
1296 rb_state.written = rb_state.reversed = rb_state.dst = altrawadr;
1297 rb_state.end = rb_state.dst + camera_sensor.raw_size;
1298
1299
1300
1301 CreateTask("RevBytes",0x1A,0x400,reverse_bytes_task);
1302
1303 fd = raw_createfile();
1304 if(fd < 0) {
1305
1306 rb_state.written = rb_state.end;
1307 while(rb_state.stage != RB_STAGE_DONE) {
1308 msleep(10);
1309 }
1310 return 0;
1311 }
1312
1313
1314 dcache_clean_all();
1315 write(fd, ADR_TO_UNCACHED(dng_header_buf), dng_header_buf_size + DNG_TH_BYTES);
1316 free_dng_header();
1317
1318 while(rb_state.written < rb_state.end) {
1319 int size = rb_state.reversed - rb_state.written;
1320 if(!size) {
1321 msleep(10);
1322 continue;
1323 }
1324
1325
1326 if(rawadr == altrawadr) {
1327 if(size > DNG_END_CHUNK_SIZE && (rb_state.written + DNG_END_CHUNK_SIZE*DNG_END_NUM_CHUNKS) >= rb_state.end) {
1328 size = DNG_END_CHUNK_SIZE;
1329 }
1330 }
1331
1332 if(conf.raw_cache) {
1333 dcache_clean_all();
1334 }
1335 write(fd,ADR_TO_UNCACHED(rb_state.written),size);
1336 rb_state.written += size;
1337 }
1338
1339 raw_closefile(fd);
1340
1341
1342 while(rb_state.stage != RB_STAGE_DONE) {
1343 msleep(10);
1344 }
1345 return 1;
1346 }
1347
1348 void create_dng_header_for_ptp(ptp_data_chunk *pdc)
1349 {
1350 create_dng_header(0,1);
1351 if (dng_header_buf) {
1352 pdc->address = (unsigned int)dng_header_buf;
1353 pdc->length = (unsigned int)dng_header_buf_size;
1354 } else {
1355 pdc->address = 0;
1356 pdc->length = 0;
1357 }
1358 }
1359 void free_dng_header_for_ptp()
1360 {
1361 free_dng_header();
1362 }
1363
1364
1365
1366
1367
1368
1369
1370 int _module_unloader()
1371 {
1372 unload_bad_pixels_list_b();
1373 free_dng_header();
1374 return 0;
1375 }
1376
1377 int _module_can_unload()
1378 {
1379 return (running == 0) && (remotecap_using_dng_module() == 0) && ((conf.save_raw == 0) || (conf.dng_raw == 0));
1380 }
1381
1382
1383
1384 libdng_sym _libdng =
1385 {
1386 {
1387 0, _module_unloader, _module_can_unload, 0, 0
1388 },
1389
1390 create_badpixel_bin,
1391 raw_init_badpixel_bin,
1392 capture_data_for_exif,
1393 load_bad_pixels_list_b,
1394 badpixel_list_loaded_b,
1395
1396 convert_dng_to_chdk_raw,
1397 write_dng,
1398 load_dng_to_rawbuffer,
1399
1400 create_dng_header_for_ptp,
1401 free_dng_header_for_ptp
1402 };
1403
1404 ModuleInfo _module_info =
1405 {
1406 MODULEINFO_V1_MAGICNUM,
1407 sizeof(ModuleInfo),
1408 DNG_VERSION,
1409
1410 ANY_CHDK_BRANCH, 0, OPT_ARCHITECTURE,
1411 ANY_PLATFORM_ALLOWED,
1412
1413 (int32_t)"DNG (dll)",
1414 MTYPE_EXTENSION,
1415
1416 &_libdng.base,
1417
1418 CONF_VERSION,
1419 ANY_VERSION,
1420 CAM_SENSOR_VERSION,
1421 CAM_INFO_VERSION,
1422
1423 0,
1424 };
1425
1426