it seem the histogram code do not check every pixel.see code of important steps.
void histogram_process()
{
static unsigned char *img;
int i, hi, c;
int y, v, u;
static int x, img_offset;
static int viewport_size;
unsigned int histo_fill[5];
switch (histogram_stage) {
case 0:
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());
if (img==NULL){
img = vid_get_viewport_fb();
}
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)
viewport_size = vid_get_viewport_height() * vid_get_viewport_buffer_width();
for (c=0; c<5; ++c) {
for (i=0; i<HISTO_WIDTH; ++i) {
histogram_proc[c][i]=0;
}
histo_max[c] = histo_max_center[c] = 0;
}
histogram_stage=1;
break;
case 1:
case 2:
case 3:
x = 0;
int l = 11;
for (i=(histogram_stage-1)*6; i<viewport_size*3; i+=6*3*2) {
y = img[img_offset+i+1];
u = *(signed char*)(&img[img_offset+i]);
if (u&0x00000080) u|=0xFFFFFF00;
v = *(signed char*)(&img[img_offset+i+2]);
if (v&0x00000080) v|=0xFFFFFF00;
hi = y*HISTO_WIDTH/256; // Y
++histogram_proc[HISTO_Y][hi];
hi = clip(((y<<12) + v*5743 + 2048)/4096)*HISTO_WIDTH/256; // R
++histogram_proc[HISTO_R][hi];
hi = clip(((y<<12) - u*1411 - v*2925 + 2048)/4096)*HISTO_WIDTH/256; // G
++histogram_proc[HISTO_G][hi];
hi = clip(((y<<12) + u*7258 + 2048)/4096)*HISTO_WIDTH/256; // B
++histogram_proc[HISTO_B][hi];
// Handle case where viewport memory buffer is wider than the actual buffer.
x++;
if (x == vid_get_viewport_width())
{
i += vid_get_viewport_row_offset();
x = 0;
}
}
++histogram_stage;
break;
for (i=(histogram_stage-1)*6; i<viewport_size*3; i+=6*3*2) {
this do i+=6*3*2 step of 36.there are 3 steps used to calculate and 3 bytes per pixel = 36/9
so only every 4. pixel in the display buffer is check.also the beginning is shift more.(histogram_stage-1)*3 is ok i think.but its
(histogram_stage-1)*6
but the bigges problem i find is that line
// Handle case where viewport memory buffer is wider than the actual buffer.
x++;
if (x == vid_get_viewport_width())
{
i += vid_get_viewport_row_offset();
x = 0;
}
it count to vid_get_viewport_width = 360 on my camera in 4:3 shooting mode and add a offset.but this skip
more data in wrong way.Here is a fix from philmoz i use, so zebra mode/edge overlay work correct.
http://chdk.setepontos.com/index.php?topic=5967.msg62178#msg62178but i think with histogram this do not work, because
i+=6*3*2 read then wrong data and x=360 is reach when 12960 is value of i.this are 4 lines.
because on ixus 1000 in 4:3 shooting mode, pixels 0-60 and 320-480 contain no valid data and should be skip.
Is it not possible for speed to use all pixels for histogram with new Camera ?
My camera have for X resolution 3640 Pixels, 360 /4 is 90 pixels,
If less than 40 pixels are overexposure, histogram do not detect that.
If camera is not fast enough, maybe somebody can enhance the x offset code.
I think there need change the line to
if (x == (vid_get_viewport_width()/4))
but i dont know if the
i=(histogram_stage-1)*6
is ok, so i think there need some pixels subtract
maybe this is ok
or the code can rewritten to look more easy in
a for next loop for y
and a for next loop for x
Or what can do better to get it working ?