source: trunk/core/raw.c @ 2798

Revision 2787, 13.4 KB checked in by philmoz, 4 days ago (diff)

Fix errors in raw handling for 14 bit sensor.

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