source: trunk/core/histogram.c @ 1024

Revision 1024, 6.7 KB checked in by reyalP, 2 years ago (diff)

g12 and sx30 updates from philmoz in http://chdk.setepontos.com/index.php?topic=650.msg59326#msg59326

  • Cleaned up the image offset code.
  • minor bug fixes and corrected address for exmem_alloc
  • moved SCREEN_COLOR define into gui_draw.h so it can be easily overridden (found in five places and default value was white on the SX30 and G12).
  • added some defines configured in makefile.inc so that gui_debug_draw_values can be used to show memory properly (was hard wired to VX addresses).
  • 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 "gui.h"
8#include "gui_draw.h"
9#include "histogram.h"
10
11#define HISTOGRAM_IDLE_STAGE (6)
12
13
14static float identity(float x);
15static float logarithmic(float x);
16
17
18unsigned char histogram[5][HISTO_WIDTH];                    // RGBYG
19long exposition_thresh;
20long under_exposed;
21long over_exposed;
22long histo_magnification;
23
24static unsigned int histogram_proc[5][HISTO_WIDTH];         // RGBYG
25static float histo_max_invw[5], histo_max_center_invw[5];   // RGBYG
26static long histogram_stage=0;
27static unsigned int histo_max[5], histo_max_center[5];      // RGBYG
28static float (*histogram_transform)(float) = identity;
29static int histo_main = HISTO_RGB;
30
31
32float identity(float x)
33{
34    return x;
35}
36
37float logarithmic(float x) {
38    return log(x);
39}
40
41void histogram_set_mode(unsigned int mode) {
42    switch (mode) {
43        case HISTO_MODE_LOG:
44            histogram_transform = logarithmic;
45            break;
46        case HISTO_MODE_LINEAR:
47        default:
48            histogram_transform = identity;
49            break;
50    }
51}
52
53void histogram_set_main(unsigned int main) {
54    histo_main = main;
55}
56
57static int clip(int v) {
58    if (v<0) v=0;
59    if (v>255) v=255;
60    return v;
61}
62
63void histogram_process()
64{
65    static unsigned char *img;
66    int i, hi, c;
67    int y, v, u;
68        static int x, img_offset;
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                        img_offset = vid_get_viewport_image_offset();           // offset into viewport for when image size != viewport size (e.g. 16:9 image on 4:3 LCD)
80            viewport_size = vid_get_viewport_height() * vid_get_viewport_buffer_width();
81            for (c=0; c<5; ++c) {
82                for (i=0; i<HISTO_WIDTH; ++i) {
83                    histogram_proc[c][i]=0;
84                }
85                histo_max[c] = histo_max_center[c] = 0;
86            }
87
88            histogram_stage=1;
89            break;
90       
91        case 1:
92        case 2:
93        case 3:
94                        x = 0;
95            for (i=(histogram_stage-1)*6; i<viewport_size*3; i+=6*3*2) {
96                y = img[img_offset+i+1];
97                u = *(signed char*)(&img[img_offset+i]);
98                if (u&0x00000080) u|=0xFFFFFF00;
99                v = *(signed char*)(&img[img_offset+i+2]);
100                if (v&0x00000080) v|=0xFFFFFF00;
101
102                hi = y*HISTO_WIDTH/256; // Y
103                ++histogram_proc[HISTO_Y][hi];
104                hi = clip(((y<<12)          + v*5743 + 2048)/4096)*HISTO_WIDTH/256; // R
105                ++histogram_proc[HISTO_R][hi];
106                hi = clip(((y<<12) - u*1411 - v*2925 + 2048)/4096)*HISTO_WIDTH/256; // G
107                ++histogram_proc[HISTO_G][hi];
108                hi = clip(((y<<12) + u*7258          + 2048)/4096)*HISTO_WIDTH/256; // B
109                ++histogram_proc[HISTO_B][hi];
110
111                                // Handle case where viewport memory buffer is wider than the actual buffer.
112                                x++;
113                                if (x == vid_get_viewport_width())
114                                {
115                                        i += vid_get_viewport_row_offset();
116                                        x = 0;
117                                }
118                        }
119
120            ++histogram_stage;
121            break;
122
123        case 4:
124            for (i=0; i<HISTO_WIDTH; ++i) { // G
125                histogram_proc[HISTO_RGB][i]=histogram_proc[HISTO_R][i]+histogram_proc[HISTO_G][i]+histogram_proc[HISTO_B][i];
126            }
127            for (c=0; c<5; ++c) { // calculate maximums
128                for (i=0; i<HISTO_WIDTH; ++i) {
129                    if (histo_max[c]<histogram_proc[c][i])
130                        histo_max[c]=histogram_proc[c][i];
131                    if (histo_max_center[c]<histogram_proc[c][i] && i>=conf.histo_ignore_boundary && i<HISTO_WIDTH-conf.histo_ignore_boundary)
132                        histo_max_center[c]=histogram_proc[c][i];
133                }
134               
135                if (histo_max[c] > 0) {
136                    histo_max_invw[c] = ((float)HISTO_HEIGHT)/histogram_transform((float)histo_max[c]);
137                } else {
138                    histo_max_invw[c] = 0.0f;
139                }
140
141                if (histo_max_center[c] > 0) {
142                    histo_max_center_invw[c] = ((float)HISTO_HEIGHT)/histogram_transform((float)histo_max_center[c]);
143                } else {
144                    histo_max_center_invw[c] = 0.0f;
145                }
146            }
147
148            if (histo_max[HISTO_RGB] > 0) { // over- / under- expos
149                under_exposed = (histogram_proc[HISTO_RGB][0]*8
150                                +histogram_proc[HISTO_RGB][1]*4
151                                +histogram_proc[HISTO_RGB][2]) > exposition_thresh;
152
153                over_exposed = (histogram_proc[HISTO_RGB][HISTO_WIDTH-3]
154                               +histogram_proc[HISTO_RGB][HISTO_WIDTH-2]*4
155                               +histogram_proc[HISTO_RGB][HISTO_WIDTH-1]*8) > exposition_thresh;
156            } else {
157                over_exposed = 0;
158                under_exposed = 1;
159            }
160
161            histogram_stage=5;
162            state_expos_recalculated = 1;
163            break;
164
165        case 5:
166            for (c=0; c<5; ++c) {
167                histo_fill[c]=0;
168                for (i=0; i<HISTO_WIDTH; ++i) {
169                    histogram[c][i] = (histogram_transform((float)histogram_proc[c][i]))*histo_max_center_invw[c];
170                    if (histogram[c][i] > HISTO_HEIGHT)
171                        histogram[c][i] = HISTO_HEIGHT;
172                    histo_fill[c]+=histogram[c][i];
173                }
174            }
175
176            if (conf.histo_auto_ajust) {
177                histo_magnification = histo_fill[histo_main]*1000/(HISTO_HEIGHT*HISTO_WIDTH);
178                if (histo_magnification<200) { // try to ajust if average level is less than 20%
179                    histo_magnification=200*1000/histo_magnification;
180                    for (c=0; c<5; ++c) {
181                        for (i=0;i<HISTO_WIDTH;i++) {
182                            histogram[c][i] = (histogram_transform((float)histogram_proc[c][i]))*histo_max_center_invw[c]*histo_magnification/1000;
183                            if (histogram[c][i] > HISTO_HEIGHT)
184                                histogram[c][i] = HISTO_HEIGHT;
185                        }
186                    }
187                } else
188                    histo_magnification=0;
189            } else {
190                histo_magnification=0;
191            }
192
193            histogram_stage=0;
194            break;
195
196        case HISTOGRAM_IDLE_STAGE:
197            break;
198    }
199
200}
201
202void histogram_stop()
203{
204    histogram_stage=HISTOGRAM_IDLE_STAGE;
205}
206
207
208void histogram_restart()
209{
210    histogram_stage = 0;
211}
212
213
Note: See TracBrowser for help on using the repository browser.