source: trunk/core/raw.c @ 1701

Revision 1701, 11.2 KB checked in by philmoz, 15 months ago (diff)

Remove incorrect optimisation for RAW/DNG code that breaks bad pixel handling.

  • Property svn:eol-style set to native
Line 
1#include "platform.h"
2#include "conf.h"
3#include "stdlib.h"
4#include "raw.h"
5#include "console.h"
6#include "math.h"
7#include "modules.h"
8#include "shot_histogram.h"
9
10//-------------------------------------------------------------------
11#define RAW_TARGET_DIRECTORY    "A/DCIM/%03dCANON"
12//#define RAW_TMP_FILENAME        "HDK_RAW.TMP"
13#define RAW_TARGET_FILENAME     "%s%04d%s"
14#define RAW_BRACKETING_FILENAME "%s%04d_%02d%s"
15
16//-------------------------------------------------------------------
17static char fn[64];
18static char dir[32];
19static int develop_raw=0;
20
21//-------------------------------------------------------------------
22void raw_prepare_develop(const char* filename) {
23    if (filename) {
24        develop_raw=1;
25        strcpy(fn,filename);
26    } else {
27        develop_raw=0;
28    }
29}
30
31//-------------------------------------------------------------------
32void patch_bad_pixels(void);
33//-------------------------------------------------------------------
34
35char* get_raw_image_addr(void) {
36    if (!conf.raw_cache) return hook_raw_image_addr();
37    else return (char*) ((int)hook_raw_image_addr()&~CAM_UNCACHED_BIT);
38}
39
40char* get_alt_raw_image_addr(void) {    // return inactive buffer for cameras with multiple RAW buffers (otherwise return active buffer)
41    if (!conf.raw_cache) return hook_alt_raw_image_addr();
42    else return (char*) ((int)hook_alt_raw_image_addr()&~CAM_UNCACHED_BIT);
43}
44//-------------------------------------------------------------------
45
46int raw_savefile() {
47    int ret = 0;
48    int fd;
49    static struct utimbuf t;
50    static int br_counter;
51#if DNG_SUPPORT
52    if (conf.save_raw && conf.dng_raw && is_raw_enabled()) {                             
53                if ( module_dng_load(LIBDNG_OWNED_BY_RAW) )
54                        libdng->capture_data_for_exif();
55        }
56#endif   
57    if (state_kbd_script_run && shot_histogram_isenabled()) build_shot_histogram();
58
59    // Get pointers to RAW buffers (will be the same on cameras that don't have two or more buffers)
60    char* rawadr = get_raw_image_addr();
61    char* altrawadr = get_alt_raw_image_addr();
62
63#if DNG_SUPPORT
64    // count/save badpixels if requested
65    if( libdng &&
66                libdng->raw_init_badpixel_bin &&
67                libdng->raw_init_badpixel_bin()) {
68        return 0;
69    }
70#endif   
71
72    if (develop_raw) {
73        started();
74        fd = open(fn, O_RDONLY, 0777);
75        if (fd>=0) {
76            read(fd, rawadr, hook_raw_size());
77            close(fd);
78        }
79#ifdef OPT_CURVES
80        if (conf.curve_enable) {
81                        if (module_curves_load())
82                                libcurves->curve_apply();
83                }
84#endif
85        finished();
86        develop_raw=0;
87        return 0;
88    }
89
90    if (conf.bad_pixel_removal) patch_bad_pixels();
91
92    shooting_bracketing();
93
94    if(conf.tv_bracket_value || conf.av_bracket_value || conf.iso_bracket_value || conf.subj_dist_bracket_value) {
95        if(state_shooting_progress != SHOOTING_PROGRESS_PROCESSING)
96            br_counter = 1;
97        else
98            br_counter++;
99    }
100    else
101        br_counter=0;
102
103    // got here second time in a row. Skip second RAW saving.
104    if (conf.raw_save_first_only && state_shooting_progress == SHOOTING_PROGRESS_PROCESSING) {
105        return 0;
106    }
107
108    state_shooting_progress = SHOOTING_PROGRESS_PROCESSING;
109
110    if (conf.save_raw && is_raw_enabled())
111    {
112        int timer; char txt[30];
113
114        started();
115
116        t.actime = t.modtime = time(NULL);
117
118        mkdir_if_not_exist("A/DCIM");
119#if defined(CAM_DATE_FOLDER_NAMING)
120        if (conf.raw_in_dir)
121            get_target_dir_name(dir);
122        else
123            sprintf(dir, RAW_TARGET_DIRECTORY, 100);
124#else
125        sprintf(dir, RAW_TARGET_DIRECTORY, (conf.raw_in_dir)?get_target_dir_num():100);
126#endif
127        mkdir_if_not_exist(dir);
128
129        sprintf(fn, "%s/", dir);
130        if(br_counter && conf.bracketing_add_raw_suffix && (shooting_get_drive_mode()!=1)) {
131            sprintf(fn+strlen(fn),
132                    RAW_BRACKETING_FILENAME,
133                    img_prefixes[conf.raw_prefix],
134                    get_target_file_num(),
135                    br_counter,
136                    conf.dng_raw&&conf.raw_dng_ext ? ".DNG" : img_exts[conf.raw_ext]);
137        } else {
138            sprintf(fn+strlen(fn),
139                    RAW_TARGET_FILENAME,
140                    img_prefixes[conf.raw_prefix],
141                    get_target_file_num(),
142                    conf.dng_raw&&conf.raw_dng_ext ? ".DNG" : img_exts[conf.raw_ext]);
143        }
144        fd = open(fn, O_WRONLY|O_CREAT, 0777);
145        if (fd>=0) {
146            timer=get_tick_count();
147#if DNG_SUPPORT
148            if (conf.dng_raw)
149            {
150                                if ( module_dng_load(LIBDNG_OWNED_BY_RAW) )
151                                        libdng->write_dng(fd, rawadr, altrawadr, CAM_UNCACHED_BIT );
152            }
153            else
154            {
155                // Write active RAW buffer
156                write(fd, (char*)(((unsigned long)rawadr)|CAM_UNCACHED_BIT), hook_raw_size());
157            }
158            close(fd);
159            utime(fn, &t);
160#else
161            // Write active RAW buffer
162            write(fd, (char*)(((unsigned long)rawadr)|CAM_UNCACHED_BIT), hook_raw_size());
163            close(fd);
164            utime(fn, &t);
165#endif
166            if (conf.raw_timer) {
167                timer=get_tick_count()-timer;
168                sprintf(txt, "saving time=%d", timer);
169                console_add_line(txt);
170            }
171        }
172
173        finished();
174
175        ret = (fd >= 0);
176    }
177
178#ifdef OPT_CURVES
179    if (conf.curve_enable) {
180                if (module_curves_load())
181                        libcurves->curve_apply();
182        }
183#endif
184    return ret;
185}
186
187//-------------------------------------------------------------------
188void raw_postprocess() {
189}
190
191//-------------------------------------------------------------------
192
193void set_raw_pixel(unsigned int x, unsigned int y, unsigned short value) {
194#if CAM_SENSOR_BITS_PER_PIXEL==10
195    unsigned char* addr=(unsigned char*)get_raw_image_addr()+y*camera_sensor.raw_rowlen+(x/8)*10;
196    switch (x%8) {
197        case 0: addr[0]=(addr[0]&0x3F)|(value<<6); addr[1]=value>>2;                  break;
198        case 1: addr[0]=(addr[0]&0xC0)|(value>>4); addr[3]=(addr[3]&0x0F)|(value<<4); break;
199        case 2: addr[2]=(addr[2]&0x03)|(value<<2); addr[3]=(addr[3]&0xF0)|(value>>6); break;
200        case 3: addr[2]=(addr[2]&0xFC)|(value>>8); addr[5]=value;                     break;
201        case 4: addr[4]=value>>2;                  addr[7]=(addr[7]&0x3F)|(value<<6); break;
202        case 5: addr[6]=(addr[6]&0x0F)|(value<<4); addr[7]=(addr[7]&0xC0)|(value>>4); break;
203        case 6: addr[6]=(addr[6]&0xF0)|(value>>6); addr[9]=(addr[9]&0x03)|(value<<2); break;
204        case 7: addr[8]=value;                     addr[9]=(addr[9]&0xFC)|(value>>8); break;
205    }
206#elif CAM_SENSOR_BITS_PER_PIXEL==12
207    unsigned char* addr=(unsigned char*)get_raw_image_addr()+y*camera_sensor.raw_rowlen+(x/4)*6;
208    switch (x%4) {
209        case 0: addr[0] = (addr[0]&0x0F) | (unsigned char)(value << 4);  addr[1] = (unsigned char)(value >> 4);  break;
210        case 1: addr[0] = (addr[0]&0xF0) | (unsigned char)(value >> 8);  addr[3] = (unsigned char)value;         break;
211        case 2: addr[2] = (unsigned char)(value >> 4);  addr[5] = (addr[5]&0x0F) | (unsigned char)(value << 4);  break;
212        case 3: addr[4] = (unsigned char)value; addr[5] = (addr[5]&0xF0) | (unsigned char)(value >> 8);  break;
213    }
214#else
215    #error define set_raw_pixel for sensor bit depth
216#endif
217}
218
219//-------------------------------------------------------------------
220unsigned short get_raw_pixel(unsigned int x,unsigned  int y) {
221#if CAM_SENSOR_BITS_PER_PIXEL==10
222    unsigned char* addr=(unsigned char*)get_raw_image_addr()+y*camera_sensor.raw_rowlen+(x/8)*10;
223    switch (x%8) {
224        case 0: return ((0x3fc&(((unsigned short)addr[1])<<2)) | (addr[0] >> 6));
225        case 1: return ((0x3f0&(((unsigned short)addr[0])<<4)) | (addr[3] >> 4));
226        case 2: return ((0x3c0&(((unsigned short)addr[3])<<6)) | (addr[2] >> 2));
227        case 3: return ((0x300&(((unsigned short)addr[2])<<8)) | (addr[5]));
228        case 4: return ((0x3fc&(((unsigned short)addr[4])<<2)) | (addr[7] >> 6));
229        case 5: return ((0x3f0&(((unsigned short)addr[7])<<4)) | (addr[6] >> 4));
230        case 6: return ((0x3c0&(((unsigned short)addr[6])<<6)) | (addr[9] >> 2));
231        case 7: return ((0x300&(((unsigned short)addr[9])<<8)) | (addr[8]));
232    }
233#elif CAM_SENSOR_BITS_PER_PIXEL==12
234    unsigned char* addr=(unsigned char*)get_raw_image_addr()+y*camera_sensor.raw_rowlen+(x/4)*6;
235    switch (x%4) {
236        case 0: return ((unsigned short)(addr[1]) << 4) | (addr[0] >> 4);
237        case 1: return ((unsigned short)(addr[0] & 0x0F) << 8) | (addr[3]);
238        case 2: return ((unsigned short)(addr[2]) << 4) | (addr[5] >> 4);
239        case 3: return ((unsigned short)(addr[5] & 0x0F) << 8) | (addr[4]);
240    }
241#else
242    #error define get_raw_pixel for sensor bit depth
243#endif
244    return 0;
245}
246
247//-------------------------------------------------------------------
248void patch_bad_pixel(unsigned int x,unsigned  int y) {
249    int sum=0;
250    int nzero=0;
251    int i,j;
252    int val;
253    if ((x>=2) && (x<camera_sensor.raw_rowpix-2) && (y>=2) && (y<camera_sensor.raw_rows-2)) {
254        if ((conf.bad_pixel_removal==1) || (conf.save_raw && conf.dng_raw)) {  // interpolation or DNG saving
255            for (i=-2; i<=2; i+=2)
256                for (j=-2; j<=2; j+=2)
257                    if ((i!=0) && (j!=0)) {
258                        val=get_raw_pixel(x+i, y+j);
259                        if (val) {sum+=val; nzero++;}
260                    }
261                if (nzero) set_raw_pixel(x,y,sum/nzero);
262        } else if (conf.bad_pixel_removal==2)  // or this makes RAW converter (internal/external)
263            set_raw_pixel(x,y,0);
264    }
265}
266
267struct point{
268    int x;
269    int y;
270    struct point *next;
271} *pixel_list=NULL;
272
273void patch_bad_pixels(void) {
274    struct point *pixel=pixel_list;
275    while (pixel) {
276        patch_bad_pixel((*pixel).x,(*pixel).y);
277        pixel=(*pixel).next;
278    }
279}
280
281#define PIXELS_BUF_SIZE 8192
282int make_pixel_list(char * ptr, int size) {
283    int x,y;
284    struct point *pixel;
285    char *endptr;
286       
287        if ( size <=0 ) return 0;
288        if ( size >PIXELS_BUF_SIZE ) ptr[PIXELS_BUF_SIZE]=0;
289
290    while(*ptr) {
291        while (*ptr==' ' || *ptr=='\t') ++ptr;    // whitespaces
292        x=strtol(ptr, &endptr, 0);
293        if (endptr != ptr) {
294            ptr = endptr;
295            if (*ptr++==',') {
296                while (*ptr==' ' || *ptr=='\t') ++ptr;    // whitespaces
297                    if (*ptr!='\n' && *ptr!='\r') {
298                        y=strtol(ptr, &endptr, 0);
299                        if (endptr != ptr) {
300                            ptr = endptr;
301                            pixel=malloc(sizeof(struct point));
302                            if (pixel) {
303                                (*pixel).x=x;
304                                (*pixel).y=y;
305                                (*pixel).next=pixel_list;
306                                pixel_list=pixel;
307                            }
308                        }
309                    }
310                }
311        }
312        while (*ptr && *ptr!='\n') ++ptr;    // unless end of line
313        if (*ptr) ++ptr;
314    }
315        return 0;
316}
317
318int pow_calc( int mult, int x, int x_div, int y, int y_div)
319{
320        return pow_calc_2( mult, x, x_div, y, y_div);
321}
322
323int pow_calc_2( int mult, int x, int x_div, double y, int y_div)
324{
325        double x1 = x;
326        if ( x_div != 1 ) { x1=x1/x_div;}
327        if ( y_div != 1 ) { y=y/y_div;}
328
329        if ( mult==1 )
330                return pow( x1, y );
331                else
332                return mult     * pow( x1, y );
333}
Note: See TracBrowser for help on using the repository browser.