source: trunk/core/raw_merge.c @ 1714

Revision 1714, 14.8 KB checked in by philmoz, 15 months ago (diff)

Fix raw sum & average file operations.

  • Property svn:eol-style set to native
Line 
1#include "raw_merge.h"
2#include "stdlib.h"
3#include "platform.h"
4#include "gui_mpopup.h"
5#include "gui_mbox.h"
6#include "raw.h"
7#include "gui_lang.h"
8#include "lang.h"
9#include "conf.h"
10#include "module_exportlist.h"
11
12#define TEMP_FILE_NAME   "A/raw16.tmp"
13#define TEMP_FILE_NAME_1 "A/raw16_1.tmp"
14
15static int raw_action;
16static int raw_count;
17static unsigned short *row;
18static unsigned char *rawrow;
19static char namebuf[100];
20
21// note: if processing with dcraw etc, zeros may get replaced with interpolated values
22// this may or may not be what you want
23static int raw_subtract_values(int from, int sub) {
24/*    if ( sub > conf.sub_in_dark_value ) {
25        int result = from - sub;
26        if ( result < conf.sub_out_dark_value ) {
27            return conf.sub_out_dark_value;
28        }
29        else {
30            return result;
31        }
32    }
33    else {
34        return from;
35    }*/
36
37 int result;
38 if ((from==0) || (sub==0)) return 0; // bad pixel
39 result = from - sub + camera_sensor.black_level;
40 if (result<camera_sensor.black_level) result=camera_sensor.black_level;
41 if (result>camera_sensor.white_level) result=camera_sensor.white_level;
42 return result;
43
44}
45/* subtract "sub" from "from" and store the result in "dest"*/
46/* TODO allow replacing if dest == from or sub*/
47int raw_subtract(const char *from, const char *sub, const char *dest) {
48    unsigned req=(hook_raw_size()>>10) + 1;
49    unsigned avail=GetFreeCardSpaceKb();
50    FILE *ffrom = NULL, *fsub = NULL, *fdest = NULL;
51    char *baccum = 0,*bsub = 0;
52    int status = 0;
53    unsigned short s,d;
54    int i,j;
55
56    static struct utimbuf t;
57
58    struct STD_stat st;
59
60    if (safe_stat((char *)from,&st) != 0 || st.st_size!=hook_raw_size())
61        return 0;
62
63    if (safe_stat((char *)sub,&st) != 0 || st.st_size!=hook_raw_size())
64        return 0;
65
66     if( (baccum=malloc(camera_sensor.raw_rowlen)) &&
67        (bsub=malloc(camera_sensor.raw_rowlen)) &&
68        (ffrom=fopen(from, "rb")) &&
69        (fsub=fopen(sub, "rb")) &&
70        (fdest=fopen(dest, "wb")) &&
71        avail > req)
72    {
73        started();
74        for (j = 0; j < camera_sensor.raw_rows; j++) {
75            fread(baccum,1, camera_sensor.raw_rowlen,ffrom);
76            fread(bsub,1, camera_sensor.raw_rowlen,fsub);
77
78#if CAM_MODULE_SENSOR_BITS_PER_PIXEL==10
79
80            for(i = 0;i<camera_sensor.raw_rowlen; i+=10) {
81                s =((0x3fc&(((unsigned short)bsub[i+1])<<2)) | (bsub[i+0] >> 6));
82                d =((0x3fc&(((unsigned short)baccum[i+1])<<2)) | (baccum[i+0] >> 6));
83                d = raw_subtract_values(d,s);
84                baccum[i]=(baccum[i]&0x3F)|(d<<6);
85                baccum[i+1]=d>>2;
86
87                s =((0x3f0&(((unsigned short)bsub[i+0])<<4)) | (bsub[i+3] >> 4));
88                d =((0x3f0&(((unsigned short)baccum[i+0])<<4)) | (baccum[i+3] >> 4));
89                d = raw_subtract_values(d,s);
90                baccum[i]=(baccum[i]&0xC0)|(d>>4);
91                baccum[i+3]=(baccum[i+3]&0x0F)|(d<<4);
92
93                s =((0x3c0&(((unsigned short)bsub[i+3])<<6)) | (bsub[i+2] >> 2));
94                d =((0x3c0&(((unsigned short)baccum[i+3])<<6)) | (baccum[i+2] >> 2));
95                d = raw_subtract_values(d,s);
96                baccum[i+2]=(baccum[i+2]&0x03)|(d<<2);
97                baccum[i+3]=(baccum[i+3]&0xF0)|(d>>6);
98
99                s =((0x300&(((unsigned short)bsub[i+2])<<8)) | (bsub[i+5]));
100                d =((0x300&(((unsigned short)baccum[i+2])<<8)) | (baccum[i+5]));
101                d = raw_subtract_values(d,s);
102                baccum[i+2]=(baccum[i+2]&0xFC)|(d>>8);
103                baccum[i+5]=d;
104
105
106                s =((0x3fc&(((unsigned short)bsub[i+4])<<2)) | (bsub[i+7] >> 6));
107                d =((0x3fc&(((unsigned short)baccum[i+4])<<2)) | (baccum[i+7] >> 6));
108                d = raw_subtract_values(d,s);
109                baccum[i+4]=d>>2;
110                baccum[i+7]=(baccum[i+7]&0x3F)|(d<<6);
111
112
113                s =((0x3f0&(((unsigned short)bsub[i+7])<<4)) | (bsub[i+6] >> 4));
114                d =((0x3f0&(((unsigned short)baccum[i+7])<<4)) | (baccum[i+6] >> 4));
115                d = raw_subtract_values(d,s);
116                baccum[i+6]=(baccum[i+6]&0x0F)|(d<<4);
117                baccum[i+7]=(baccum[i+7]&0xC0)|(d>>4);
118
119                s =((0x3c0&(((unsigned short)bsub[i+6])<<6)) | (bsub[i+9] >> 2));
120                d =((0x3c0&(((unsigned short)baccum[i+6])<<6)) | (baccum[i+9] >> 2));
121                d = raw_subtract_values(d,s);
122                baccum[i+6]=(baccum[i+6]&0xF0)|(d>>6);
123                baccum[i+9]=(baccum[i+9]&0x03)|(d<<2);
124
125
126                s =((0x300&(((unsigned short)bsub[i+9])<<8)) | (bsub[i+8]));
127                d =((0x300&(((unsigned short)baccum[i+9])<<8)) | (baccum[i+8]));
128                d = raw_subtract_values(d,s);
129                baccum[i+8]=d;
130                baccum[i+9]=(baccum[i+9]&0xFC)|(d>>8);
131            }
132
133#elif CAM_MODULE_SENSOR_BITS_PER_PIXEL==12
134
135            for(i = 0;i<camera_sensor.raw_rowlen; i+=6) {
136
137                s=((0xFF0&(((unsigned short)bsub[i+1])<<4))   | (bsub[i+0] >> 4));
138                d=((0xFF0&(((unsigned short)baccum[i+1])<<4)) | (baccum[i+0] >> 4));
139                d = raw_subtract_values(d,s);
140                baccum[i+0]=(baccum[i+0]&0x0F)|(d<<4);
141                baccum[i+1]=d>>4;
142
143                s=((0xF00&(((unsigned short)bsub[i+0])<<8))   | (bsub[i+3]     ));
144                d=((0xF00&(((unsigned short)baccum[i+0])<<8)) | (baccum[i+3]   ));
145                d = raw_subtract_values(d,s);
146                baccum[i+0]=(baccum[i+0]&0xF0)|(d>>8);
147                baccum[i+3]=d;
148
149                s=((0xFF0&(((unsigned short)bsub[i+2])<<4))   | (bsub[i+5] >> 4));
150                d=((0xFF0&(((unsigned short)baccum[i+2])<<4)) | (baccum[i+5] >> 4));
151                d = raw_subtract_values(d,s);
152                baccum[i+2]=d>>4;
153                baccum[i+5]=(baccum[i+5]&0x0F)|(d<<4);
154
155                s=((0xF00&(((unsigned short)bsub[i+5])<<8))   | (bsub[i+4]     ));
156                d=((0xF00&(((unsigned short)baccum[i+5])<<8)) | (baccum[i+4]     ));
157                d = raw_subtract_values(d,s);
158                baccum[i+4]=d;
159                baccum[i+5]=(baccum[i+5]&0xF0)|(d>>8);
160            }
161
162#else
163 #error define set_raw_pixel for sensor bit depth
164#endif
165
166            fwrite(baccum,1,camera_sensor.raw_rowlen,fdest);
167            if ( (j & 0x1F) == 0 ) {
168                gui_browser_progress_show((char *)dest, j*100/camera_sensor.raw_rows);
169            }
170        }
171        gui_browser_progress_show((char *)dest, 100);
172        finished();
173        status = 1;
174    }
175    free(baccum);
176    free(bsub);
177    if(ffrom)
178        fclose(ffrom);
179    if(fsub)
180        fclose(fsub);
181    if(fdest) {
182        fclose(fdest);
183        t.actime = t.modtime = time(NULL);
184        utime((char *)dest, &t);
185    }
186    return status;
187}
188
189int raw_merge_start(int action){
190  unsigned int req, avail;
191  req=((camera_sensor.raw_rowpix*camera_sensor.raw_rows)>>18)+1;
192  avail=GetFreeCardSpaceKb()>>10;
193  if (avail<req) {
194    sprintf(namebuf,lang_str(LANG_AVERAGE_NO_CARD_SPACE),req,avail);
195    gui_mbox_init((int)"", (int)namebuf, MBOX_BTN_OK|MBOX_TEXT_CENTER, NULL);
196    return 0;
197  }
198  raw_action=action;
199  raw_count=0;
200  row=malloc(camera_sensor.raw_rowpix*sizeof(unsigned short));
201  if (!row)
202    return 0;
203  rawrow=malloc(camera_sensor.raw_rowlen);
204  if (!rawrow) {
205    free(row);
206    return 0;
207  }
208  return 1;
209}
210
211void raw_merge_add_file(const char * filename) {
212  int  t,src,i,j,nrow;
213  FILE *fbrawin=NULL,*fbrawout,*fcraw;
214  struct STD_stat st;
215
216  if (!filename)
217    return;
218
219  safe_stat(filename,&st);
220  if (st.st_size!=hook_raw_size())
221    return;
222
223  started();
224
225  fcraw=fopen(filename,"rb");
226  if (fcraw) {
227    if (raw_count)
228      fbrawin=fopen(TEMP_FILE_NAME,"rb");
229    if (!raw_count || fbrawin){
230      fbrawout=fopen(TEMP_FILE_NAME_1,"w+b");
231      if (fbrawout){
232        fread(rawrow, 1, camera_sensor.raw_rowlen, fcraw);
233        if (raw_count)
234          fread(row, 1, camera_sensor.raw_rowpix*sizeof(unsigned short), fbrawin);
235        else
236          for (i=0;i<camera_sensor.raw_rowpix;i++)
237            row[i]=0;
238
239        for (nrow=0,j=0;nrow<camera_sensor.raw_rows;nrow++,j++){
240
241#if CAM_MODULE_SENSOR_BITS_PER_PIXEL==10
242
243          for (i=0,src=0; i<camera_sensor.raw_rowpix; i+=8, src+=10){
244            row[i+0]+=((0x3fc&(((unsigned short)rawrow[src+1])<<2)) | (rawrow[src+0] >> 6));
245            row[i+1]+=((0x3f0&(((unsigned short)rawrow[src+0])<<4)) | (rawrow[src+3] >> 4));
246            row[i+2]+=((0x3c0&(((unsigned short)rawrow[src+3])<<6)) | (rawrow[src+2] >> 2));
247            row[i+3]+=((0x300&(((unsigned short)rawrow[src+2])<<8)) | (rawrow[src+5]));
248            row[i+4]+=((0x3fc&(((unsigned short)rawrow[src+4])<<2)) | (rawrow[src+7] >> 6));
249            row[i+5]+=((0x3f0&(((unsigned short)rawrow[src+7])<<4)) | (rawrow[src+6] >> 4));
250            row[i+6]+=((0x3c0&(((unsigned short)rawrow[src+6])<<6)) | (rawrow[src+9] >> 2));
251            row[i+7]+=((0x300&(((unsigned short)rawrow[src+9])<<8)) | (rawrow[src+8]));
252          }
253
254#elif CAM_MODULE_SENSOR_BITS_PER_PIXEL==12
255
256          for (i=0,src=0; i<camera_sensor.raw_rowpix; i+=4, src+=6){
257            row[i+0]+=((0xFF0&(((unsigned short)rawrow[src+1])<<4)) | (rawrow[src+0] >> 4));
258            row[i+1]+=((0xF00&(((unsigned short)rawrow[src+0])<<8)) | (rawrow[src+3]     ));
259            row[i+2]+=((0xFF0&(((unsigned short)rawrow[src+2])<<4)) | (rawrow[src+5] >> 4));
260            row[i+3]+=((0xF00&(((unsigned short)rawrow[src+5])<<8)) | (rawrow[src+4]     ));
261          }
262
263#else
264 #error define set_raw_pixel for sensor bit depth
265#endif
266
267          fwrite(row, 1, camera_sensor.raw_rowpix*sizeof(unsigned short), fbrawout);
268          if (raw_count)
269            fread(row, 1, camera_sensor.raw_rowpix*sizeof(unsigned short), fbrawin);
270          else
271            for (i=0;i<camera_sensor.raw_rowpix;i++)
272              row[i]=0;
273          fread(rawrow, 1, camera_sensor.raw_rowlen, fcraw);
274          if (j>=camera_sensor.raw_rows/10) {
275            j-=camera_sensor.raw_rows/10;
276            gui_browser_progress_show(filename, nrow*100/camera_sensor.raw_rows);
277          }
278        }
279        raw_count++;
280        strcpy(namebuf,filename);
281        fclose(fbrawout);
282      }
283      if (fbrawin)
284        fclose(fbrawin);
285    }
286    fclose(fcraw);
287  }
288  remove(TEMP_FILE_NAME);
289  rename(TEMP_FILE_NAME_1,TEMP_FILE_NAME);
290  finished();
291}
292
293void raw_merge_end(void) {
294  int src,i,j,nrow;
295  FILE *fbraw, *fcraw;
296  static struct utimbuf t;
297  if (!raw_count)
298    return;
299
300  i=strlen(namebuf)-3;
301  if (strncmp(namebuf+i,"CR",2)==0)
302    strcpy(namebuf+i,"WAV");
303  else
304    strcpy(namebuf+i,"CRW");
305
306  started();
307  fbraw=fopen(TEMP_FILE_NAME,"r+b");
308  if (fbraw) {
309    fcraw=fopen(namebuf,"w+b");
310    if (fcraw) {
311      fread(row, 1, camera_sensor.raw_rowpix*sizeof(unsigned short), fbraw);
312      for (nrow=0,j=0;nrow<camera_sensor.raw_rows;nrow++,j++) {
313        for (i=0;i<camera_sensor.raw_rowpix;i++) {
314          if (raw_action==RAW_OPERATION_AVERAGE)
315            row[i]/=raw_count;
316          else {
317            if (row[i]>camera_sensor.black_level*(raw_count-1))
318              row[i]-=camera_sensor.black_level*(raw_count-1);
319            else
320              row[i]=0;
321            if (row[i]>camera_sensor.white_level)
322              row[i]=camera_sensor.white_level;
323          }
324        }
325#if CAM_MODULE_SENSOR_BITS_PER_PIXEL==10
326        for (i=0,src=0;i<camera_sensor.raw_rowpix;i+=8,src+=10) {
327          rawrow[src+0]=(row[i+0]<<6)|(row[i+1]>>4);
328          rawrow[src+1]=(row[i+0]>>2);
329          rawrow[src+2]=(row[i+2]<<2)|(row[i+3]>>8);
330          rawrow[src+3]=(row[i+1]<<4)|(row[i+2]>>6);
331          rawrow[src+4]=(row[i+4]>>2);
332          rawrow[src+5]=(row[i+3]);
333          rawrow[src+6]=(row[i+5]<<4)|(row[i+6]>>6);
334          rawrow[src+7]=(row[i+4]<<6)|(row[i+5]>>4);
335          rawrow[src+8]=(row[i+7]);
336          rawrow[src+9]=(row[i+6]<<2)|(row[i+7]>>8);
337        }
338#elif CAM_MODULE_SENSOR_BITS_PER_PIXEL==12
339        for (i=0,src=0; i<camera_sensor.raw_rowpix; i+=4, src+=6){
340          rawrow[src+0]=(row[i+0]<<4)|(row[i+1]>>8);
341          rawrow[src+1]=(row[i+0]>>4);
342          rawrow[src+2]=(row[i+2]>>4);
343          rawrow[src+3]= row[i+1];
344          rawrow[src+4]= row[i+3];
345          rawrow[src+5]=(row[i+2]<<4)|(row[i+3]>>8);
346        }
347#else
348 #error define set_raw_pixel for sensor bit depth
349#endif
350
351        fwrite(rawrow, 1, camera_sensor.raw_rowlen, fcraw);
352        fread(row, 1, camera_sensor.raw_rowpix*sizeof(unsigned short), fbraw);
353        if (j>=camera_sensor.raw_rows/5) {
354          j-=camera_sensor.raw_rows/5;
355          gui_browser_progress_show(namebuf, nrow*100/camera_sensor.raw_rows);
356        }
357      }
358      fclose(fcraw);
359    }
360    fclose(fbraw);
361  }
362
363  t.actime = t.modtime = time(NULL);
364  utime(namebuf, &t);
365  remove(TEMP_FILE_NAME);
366
367  finished();
368  free(rawrow);
369  free(row);
370}
371
372
373// =========  MODULE INIT =================
374#include "module_load.h"
375int module_idx=-1;
376
377/***************** BEGIN OF AUXILARY PART *********************
378  ATTENTION: DO NOT REMOVE OR CHANGE SIGNATURES IN THIS SECTION
379 **************************************************************/
380
381struct librawop_sym librawop = {
382                        MAKE_API_VERSION(1,0),          // apiver: increase major if incompatible changes made in module,
383                                                                                // increase minor if compatible changes made(including extending this struct)
384                        raw_merge_start,
385                        raw_merge_add_file,
386                        raw_merge_end,
387                        raw_subtract
388                };
389
390
391void* MODULE_EXPORT_LIST[] = {
392        /* 0 */ (void*)EXPORTLIST_MAGIC_NUMBER,
393        /* 1 */ (void*)1,
394               
395                        &librawop
396                };
397
398
399//---------------------------------------------------------
400// PURPOSE:   Bind module symbols with chdk.
401//              Required function
402// PARAMETERS: pointer to chdk list of export
403// RETURN VALUE: 1 error, 0 ok
404//---------------------------------------------------------
405int _module_loader( unsigned int* chdk_export_list )
406{
407  if ( chdk_export_list[0] != EXPORTLIST_MAGIC_NUMBER )
408     return 1;
409
410  if ( !API_VERSION_MATCH_REQUIREMENT( camera_sensor.api_version, 1, 0 ) )
411         return 1;
412
413  return 0;
414}
415
416
417
418//---------------------------------------------------------
419// PURPOSE: Finalize module operations (close allocs, etc)
420// RETURN VALUE: 0-ok, 1-fail
421//---------------------------------------------------------
422int _module_unloader()
423{
424  return 0;
425}
426
427
428/******************** Module Information structure ******************/
429
430struct ModuleInfo _module_info = {      MODULEINFO_V1_MAGICNUM,
431                                                                        sizeof(struct ModuleInfo),
432
433                                                                        ANY_CHDK_BRANCH, 0,                     // Requirements of CHDK version
434                                                                        ANY_PLATFORM_ALLOWED,           // Specify platform dependency
435                                                                        MODULEINFO_FLAG_SYSTEM,         // flag
436#if CAM_MODULE_SENSOR_BITS_PER_PIXEL==10
437                                                                        (int32_t)"RAW operations-10bpp(dll)",// Module name
438#else
439                                                                        (int32_t)"RAW operations-12bpp(dll)",// Module name
440#endif
441                                                                        1, 0,                                           // Module version
442#if CAM_MODULE_SENSOR_BITS_PER_PIXEL==10
443                                                                        (int32_t)"Implementation of RAW operations\n(Avg, Sum, Sub) for 10bit sensor"
444#else
445                                                                        (int32_t)"Implementation of RAW operations\n(Avg, Sum, Sub) for 12bit sensor"
446#endif
447                                                                 };
448
449
450/*************** END OF AUXILARY PART *******************/
Note: See TracBrowser for help on using the repository browser.