source: trunk/core/histogram.c @ 740

Revision 740, 6.3 KB checked in by reyalp, 4 years ago (diff)

IXUS 980/ SD 990 beta
disable fi2 for sx1, viewport_width for 990 merge

  • Property svn:eol-style set to native
Line 
1#include "stdlib.h"
2#include "platform.h"
3#include "core.h"
4#include "keyboard.h"
5#include "conf.h"
6#include "math.h"
7#include "ubasic.h"
8#include "gui.h"
9#include "gui_draw.h"
10#include "histogram.h"
11
12#define HISTOGRAM_IDLE_STAGE (6)
13
14
15static float identity(float x);
16static float locarithmic(float x);
17
18
19unsigned char histogram[5][HISTO_WIDTH];                    // RGBYG
20long exposition_thresh;
21long under_exposed;
22long over_exposed;
23long histo_magnification;
24
25static unsigned int histogram_proc[5][HISTO_WIDTH];         // RGBYG
26static float histo_max_invw[5], histo_max_center_invw[5];   // RGBYG
27static long histogram_stage=0;
28static unsigned int histo_max[5], histo_max_center[5];      // RGBYG
29static float (*histogram_transform)(float) = identity;
30static int histo_main = HISTO_RGB;
31
32
33float identity(float x)
34{
35    return x;
36}
37
38float locarithmic(float x) {
39    return log(x);
40}
41
42void histogram_set_mode(unsigned int mode) {
43    switch (mode) {
44        case HISTO_MODE_LOG:
45            histogram_transform = locarithmic;
46            break;
47        case HISTO_MODE_LINEAR:
48        default:
49            histogram_transform = identity;
50            break;
51    }
52}
53
54void histogram_set_main(unsigned int main) {
55    histo_main = main;
56}
57
58static int clip(int v) {
59    if (v<0) v=0;
60    if (v>255) v=255;
61    return v;
62}
63
64void histogram_process()
65{
66    static unsigned char *img;
67    int i, hi, c;
68    int y, v, u;
69    static int viewport_size;
70    unsigned int histo_fill[5];
71
72            switch (histogram_stage) {
73        case 0:
74            img=((mode_get()&MODE_MASK) == MODE_PLAY)?vid_get_viewport_fb_d():((kbd_is_key_pressed(KEY_SHOOT_HALF))?vid_get_viewport_fb():vid_get_viewport_live_fb());
75       
76                if (img==NULL){
77                  img = vid_get_viewport_fb();
78                    }
79            viewport_size = vid_get_viewport_height() * vid_get_viewport_width();
80            for (c=0; c<5; ++c) {
81                for (i=0; i<HISTO_WIDTH; ++i) {
82                    histogram_proc[c][i]=0;
83                }
84                histo_max[c] = histo_max_center[c] = 0;
85            }
86
87            histogram_stage=1;
88            break;
89       
90        case 1:
91        case 2:
92        case 3:
93            for (i=(histogram_stage-1)*6; i<viewport_size*3; i+=6*3*2) {
94                y = img[i+1];
95                u = *(signed char*)(&img[i]);
96                if (u&0x00000080) u|=0xFFFFFF00;
97                v = *(signed char*)(&img[i+2]);
98                if (v&0x00000080) v|=0xFFFFFF00;
99
100                hi = y*HISTO_WIDTH/256; // Y
101                ++histogram_proc[HISTO_Y][hi];
102                hi = clip(((y<<12)          + v*5743 + 2048)/4096)*HISTO_WIDTH/256; // R
103                ++histogram_proc[HISTO_R][hi];
104                hi = clip(((y<<12) - u*1411 - v*2925 + 2048)/4096)*HISTO_WIDTH/256; // G
105                ++histogram_proc[HISTO_G][hi];
106                hi = clip(((y<<12) + u*7258          + 2048)/4096)*HISTO_WIDTH/256; // B
107                ++histogram_proc[HISTO_B][hi];
108            }
109
110            ++histogram_stage;
111            break;
112
113        case 4:
114            for (i=0; i<HISTO_WIDTH; ++i) { // G
115                histogram_proc[HISTO_RGB][i]=histogram_proc[HISTO_R][i]+histogram_proc[HISTO_G][i]+histogram_proc[HISTO_B][i];
116            }
117            for (c=0; c<5; ++c) { // calculate maximums
118                for (i=0; i<HISTO_WIDTH; ++i) {
119                    if (histo_max[c]<histogram_proc[c][i])
120                        histo_max[c]=histogram_proc[c][i];
121                    if (histo_max_center[c]<histogram_proc[c][i] && i>=conf.histo_ignore_boundary && i<HISTO_WIDTH-conf.histo_ignore_boundary)
122                        histo_max_center[c]=histogram_proc[c][i];
123                }
124               
125                if (histo_max[c] > 0) {
126                    histo_max_invw[c] = ((float)HISTO_HEIGHT)/histogram_transform((float)histo_max[c]);
127                } else {
128                    histo_max_invw[c] = 0.0f;
129                }
130
131                if (histo_max_center[c] > 0) {
132                    histo_max_center_invw[c] = ((float)HISTO_HEIGHT)/histogram_transform((float)histo_max_center[c]);
133                } else {
134                    histo_max_center_invw[c] = 0.0f;
135                }
136            }
137
138            if (histo_max[HISTO_RGB] > 0) { // over- / under- expos
139                under_exposed = (histogram_proc[HISTO_RGB][0]*8
140                                +histogram_proc[HISTO_RGB][1]*4
141                                +histogram_proc[HISTO_RGB][2]) > exposition_thresh;
142
143                over_exposed = (histogram_proc[HISTO_RGB][HISTO_WIDTH-3]
144                               +histogram_proc[HISTO_RGB][HISTO_WIDTH-2]*4
145                               +histogram_proc[HISTO_RGB][HISTO_WIDTH-1]*8) > exposition_thresh;
146            } else {
147                over_exposed = 0;
148                under_exposed = 1;
149            }
150
151            histogram_stage=5;
152            state_expos_recalculated = 1;
153            break;
154
155        case 5:
156            for (c=0; c<5; ++c) {
157                histo_fill[c]=0;
158                for (i=0; i<HISTO_WIDTH; ++i) {
159                    histogram[c][i] = (histogram_transform((float)histogram_proc[c][i]))*histo_max_center_invw[c];
160                    if (histogram[c][i] > HISTO_HEIGHT)
161                        histogram[c][i] = HISTO_HEIGHT;
162                    histo_fill[c]+=histogram[c][i];
163                }
164            }
165
166            if (conf.histo_auto_ajust) {
167                histo_magnification = histo_fill[histo_main]*1000/(HISTO_HEIGHT*HISTO_WIDTH);
168                if (histo_magnification<200) { // try to ajust if average level is less than 20%
169                    histo_magnification=200*1000/histo_magnification;
170                    for (c=0; c<5; ++c) {
171                        for (i=0;i<HISTO_WIDTH;i++) {
172                            histogram[c][i] = (histogram_transform((float)histogram_proc[c][i]))*histo_max_center_invw[c]*histo_magnification/1000;
173                            if (histogram[c][i] > HISTO_HEIGHT)
174                                histogram[c][i] = HISTO_HEIGHT;
175                        }
176                    }
177                } else
178                    histo_magnification=0;
179            } else {
180                histo_magnification=0;
181            }
182
183            histogram_stage=0;
184            break;
185
186        case HISTOGRAM_IDLE_STAGE:
187            break;
188    }
189
190}
191
192void histogram_stop()
193{
194    histogram_stage=HISTOGRAM_IDLE_STAGE;
195}
196
197
198void histogram_restart()
199{
200    histogram_stage = 0;
201}
202
203
Note: See TracBrowser for help on using the repository browser.