Where in the memory I should search for displayed informations? - Script Writing - CHDK Forum supplierdeeply

Where in the memory I should search for displayed informations?

  • 12 Replies
  • 5068 Views
Where in the memory I should search for displayed informations?
« on: 30 / September / 2011, 21:14:03 »
Advertisements
The problem: I'm in a play mode and I need to get the number of currently displayed picture. Where in the camera memory I should search it?

I tried to peek in a loop through adresses and check if one contains the number but I haven't found that. Maybe somebody, who understand more about Canon firmware know, where it's possible to find it?

(background: I need it to write a script, which will delete RAW of currently displayed image to make this process much more simple).
if (2*b || !2*b) {
    cout<<question
}

Compile error: poor Yorick

Re: Where in the memory I should search for displayed informations?
« Reply #1 on: 01 / October / 2011, 06:27:53 »
get_target_file_num() gives number of next image so just subtract one.

Re: Where in the memory I should search for displayed informations?
« Reply #2 on: 01 / October / 2011, 07:09:51 »
Thank you for the answer. Nevertheless, that's not what I'm looking for. I need to get the image of currently displayed image, it's not the same as the last taken image. I can display every image that camera taken before and I need a number of this one, which is displayed...
if (2*b || !2*b) {
    cout<<question
}

Compile error: poor Yorick

*

Offline srsa_4c

  • ******
  • 4451
Re: Where in the memory I should search for displayed informations?
« Reply #3 on: 01 / October / 2011, 07:47:20 »
Two (well, 3) possibilities come to my mind.
- Try to find out, whether there is a flash parameter holding that value (its format may not be that obvious, look at the canon total shots counter for example (in chdk source, /platform/[camera]/shooting.c, look for "#define PARAM_FILE_COUNTER      [value]") . As the camera remembers which picture was the last one displayed, that value should be stored somewhere.
Looked at two cameras: an old one: IXUS 30, doesn't store the last displayed image's index; SX100IS: the last displayed image's index is stored somewhere, but not as flash param (maybe somewhere in the card's filesystem). Conclusion: this method won't help.
- Use the "dump memory" debug feature at least twice during image browsing (and note the image number currently displayed), then use a hex editor on the pc. There may be false positives (portions of the file system, temporary locations).
- The hard way: analyse the firmware dump (look for format strings used at the right places)...
The format string used for the currently displayed image's file number is "%03d-%04d".
« Last Edit: 02 / October / 2011, 17:50:20 by srsa_4c »


Re: Where in the memory I should search for displayed informations?
« Reply #4 on: 04 / May / 2012, 01:54:14 »
I tried the method suggested by srsa_4c and it worked. Dumping the memory while displaying a few different pictures, and analysing the dumps with the unix-style (CYGWIN) command

strings -tx CRW_xxxx.JPG | grep JPG

i got something like this:

  10684 A/DCIM/100CANON/CRW_0001.JPG
  508e0 A/DCIM/100CANON/IMG_0001.JPG
  51134 A/DCIM/100CANON/IMG_0001.JPG
  b2d60 A/DCIM/100CANON/IMG_0002.JPG
  b2d88 A/DCIM/100CANON/IMG_0001.JPG
  b2db0 A/DCIM/100CANON/IMG_0005.JPG
  b2dd8 A/DCIM/100CANON/IMG_0002.JPG
  b2e00 A/DCIM/100CANON/IMG_0006.JPG
  b2e28 A/DCIM/100CANON/IMG_0006.JPG
....

Comparing all the dumps with the respective filename displayed, i found out, that in my case (Powershot SX200IS) the address 0x508e0 is the one to go for. The Filename could be read out with a LUA command (peek()). The address remained the same with a few different versions of CHDK i checked (DE). I didn't check different cameras, though.

Does anybody know, if someone has incorporated this into CHDK itself in the meantime?


Re: Where in the memory I should search for displayed informations?
« Reply #5 on: 04 / May / 2012, 09:36:48 »
Interesting. I have almost forgot about this question. Thank you for your answers. I'm trying to get the dump and use strings to search it (on sx130 adressess are different, as I can see in the memory browser). But I can't find the dump on SD.

I have set +/- to "Ram dump" and when I press this button in ALT mode the green led lights for a few seconds suggesting the dump is being written. But then I can't find any new file on SD. I have checked in root directory, in CHDK directory and its subdirs. I have also checked the second partition.

User guide doesn't say, where the dump should appear.


Nevermind, in desperacy I have looked into DCIM/100CANON without any hope and I found them there;) I'll play with that.

I'm using:
sx130is 1.01c
CHDK: trunk, 1.1.0-1823.

EDIT

So, here's a Lua function that reads the path if the address is given. For sx130is the address is 0xaf7d0


Code: (lua) [Select]

img_address = 0xaf7d0

function get_path_from_address(address)
    --path contains 8*4 characters
    local path=""
    for v=1,8 do
        local value=peek(address)
        for i=1, 4 do
            value2=value/(256)
            n=value-value2*256
            value=value2
            c=string.char(n)
            path=path..c
            --print(n.." "..c)
            --sleep(1000)
        end
        address=address+4
    end
    return(path)
end

print(get_path_from_address(img_address))
wait_click(0)
[/lua]


Next step would be to replace the jpg name with corresponding raw file to remove it. Or do some other operations. It would be even nice to have a CHDK option like 'remove RAW when JPG is removed'.
« Last Edit: 04 / May / 2012, 10:34:35 by outslider »
if (2*b || !2*b) {
    cout<<question
}

Compile error: poor Yorick

*

Offline srsa_4c

  • ******
  • 4451
Re: Where in the memory I should search for displayed informations?
« Reply #6 on: 04 / May / 2012, 11:13:44 »
Next step would be to replace the jpg name with corresponding raw file to remove it. Or do some other operations. It would be even nice to have a CHDK option like 'remove RAW when JPG is removed'.
You may encounter some issues if you rename / move / remove certain files "behind the camera's back", see reyalp's notes: http://chdk.setepontos.com/index.php?topic=2045.msg18862#msg18862

Re: Where in the memory I should search for displayed informations?
« Reply #7 on: 04 / May / 2012, 11:45:16 »
Thank you, very interesting report on camera behavior. However I use mostly DNG format with the filenames like IMG_XXXX.DNG so camera doesn't recognize these files. I'm not interested in USB connections, I prefer SD cards.

For me the aim is to have a method to in-camera remove DNG files that I don't need anymore. Now I'm looking for a method to lua-check whether file exists or not. I was playing with os.stat but I see, that stat can't be executed on file that doesn't exist. I believe there's a way such like:

Code: (lua) [Select]
function file_exists(name)
   local f=io.open(name,"r")
   if f~=nil then io.close(f) return true else return false end
end

taken from http://stackoverflow.com/questions/4990990/lua-check-if-a-file-exists

but it requires opening a file.


EDIT

Here's the draft of the script. GUI and the interfaces are prepared. Currently the script can't delete anything. I lost my patience as for this day ;p If anybody interested then feel free to add the deleting stuff to the script.

All suggestions are welcome.

Code: (lua) [Select]
--[[
@title remove raw of displayed jpg
@param s Safe test  (1=don't delete)
@default s 0
@param a img address    (in decimal)
@default a 718800
--]]

require "drawings"

--address has to be obtained from RAM dump,
--see: [url]http://chdk.setepontos.com/index.php?topic=6897.msg73715#msg73715[/url] (thx, srsa_4c & heinzM)
--for SX130 IS = 0xaf7d0; in decimal 718800
--for SX200 IS = 0x508e0; in decimal 329952
--good idea is to set this param in code, not in params

img_address = a
set_console_layout(0,0,40,2)


function get_path_from_address(address)
    --path contains 7*4 characters
    local path=""
    for v=1,7 do
        local value=peek(address)
        for i=1, 4 do
            value2=value/(256)
            n=value-value2*256
            value=value2
            c=string.char(n)
            path=path..c
            --print(n.." "..c)
            --sleep(1000)
        end
        address=address+4
    end
    return(path)
end

--print(get_path_from_address(img_address))
--wait_click(0)

function get_input()
    KEYS_TABLE={"left","up","right","down","set","shoot_half","shoot_full","menu","display","erase","zoom_in","zoom_out"}
    REPEATABLE_KEYS_TABLE={"left","up","right","down","zoom_out","zoom_in"}
    PRESSED_KEY=nil
    for key_nr=1, table.getn(REPEATABLE_KEYS_TABLE) do
        if is_pressed(REPEATABLE_KEYS_TABLE[key_nr]) then PRESSED_KEY=REPEATABLE_KEYS_TABLE[key_nr]
            end
        end
    if PRESSED_KEY~=nil then
        repeat
            if get_tick_count()-PRESSED_TIME>350 then sleep(10); return PRESSED_KEY end
            until not is_pressed(PRESSED_KEY)
        end
    wait_click(60000)
    PRESSED_TIME=get_tick_count()
    for key_nr=1, table.getn(KEYS_TABLE) do
        if is_key(KEYS_TABLE[key_nr]) then PRESSED_KEY=KEYS_TABLE[key_nr]; return KEYS_TABLE[key_nr] end
        end
    end


function file_exists(name)
    local f=io.open(name,"r")
    if f~=nil then io.close(f) return true else return false end
end


function ask_about_remove(jpg_file,raw_file)
   
    local running=true
    local input
    local selected=0
    local status="none"
    local x0=50
    local y0=15
    local raw_color="green"
   
    if (raw_file=="not found") then raw_color="red" end
   
    gui_window=draw.add("rectf",x0,y0,x0+250,y0+200,"white","grey",2)
    gui_winbar=draw.add("rectf",x0,y0,x0+250,y0+20,"white","grey",2)
    gui_title=draw.add("string",x0+10,y0+2,"What you want to do?","white","grey")

    gui_mess1=draw.add("string",x0+10,y0+25,"You have selected:","white","grey")
    gui_mess2=draw.add("string",x0+10,y0+45,jpg_file,"green","grey")
    gui_mess3=draw.add("string",x0+10,y0+65,"Appropriate RAW:","white","grey")
    gui_mess4=draw.add("string",x0+10,y0+85,raw_file,raw_color,"grey")
   
    gui_mess5=draw.add("string",x0+10,y0+110,"What to do?","white","grey")
   
    gui_ans1=draw.add("string",x0+10,y0+130," Remove both ","green","black")
    gui_ans2=draw.add("string",x0+10,y0+150," Remove RAW ","white","grey")
    gui_ans3=draw.add("string",x0+10,y0+170," Remove JPG ","white","grey")
   
    draw.overdraw()
   
    while (running) do
        input=get_input()
       
        if(input=="up" or input=="left") then selected=selected-1 end
        if(input=="down" or input=="right") then selected=selected+1 end
        if(selected>2) then selected=0 end
        if(selected<0) then selected=2 end
       
        if(selected==0) then
            status="both"
            draw.replace(gui_ans1,"string",x0+10,y0+130," Remove both ","green","black")
            draw.replace(gui_ans2,"string",x0+10,y0+150," Remove RAW ","white","grey")
            draw.replace(gui_ans3,"string",x0+10,y0+170," Remove JPG ","white","grey")
        end
        if(selected==1) then
            status="raw"
            draw.replace(gui_ans1,"string",x0+10,y0+130," Remove both ","white","grey")
            draw.replace(gui_ans2,"string",x0+10,y0+150," Remove RAW ","green","black")
            draw.replace(gui_ans3,"string",x0+10,y0+170," Remove JPG ","white","grey")
        end
        if(selected==2) then
            status="jpg"
            draw.replace(gui_ans1,"string",x0+10,y0+130," Remove both ","white","grey")
            draw.replace(gui_ans2,"string",x0+10,y0+150," Remove RAW ","white","grey")
            draw.replace(gui_ans3,"string",x0+10,y0+170," Remove JPG ","green","black")
        end
       
        draw.overdraw()
       
        if(input=="set") then
            running=false
        end
       
        if(input=="menu") then
            running=false
            status="none"
        end
    end
   
    draw.clear()
    draw_clear()
   
    return(status)
end
   

----- loop -----
running=true
while (running) do
    input=get_input()
    if (input=="left" or input=="right" or input=="zoom_in" or input=="zoom_out" or input=="set") then
        click(input)
    end


   


    jpg_path=get_path_from_address(img_address)
    raw_path="not found"

    --there could be other methods to check the other raw filename formats.
    --IMG_XXXX.DNG
    raw_path_check=string.sub(jpg_path,1,string.len(jpg_path)-3).."DNG"
    if(file_exists(raw_path_check)) then raw_path=raw_path_check end
    --IMG_XXXX.CRW
    raw_path_check=string.sub(jpg_path,1,string.len(jpg_path)-3).."CRW"
    if(file_exists(raw_path_check)) then raw_path=raw_path_check end
    --IMG_XXXX.CR2
    raw_path_check=string.sub(jpg_path,1,string.len(jpg_path)-3).."CR2"
    if(file_exists(raw_path_check)) then raw_path=raw_path_check end

    --print("JPG: "..jpg_path)
    --print("RAW: "..raw_path)
   
    if (input=="erase" or input=="shoot_half") then
        --sleep helps camera to refresh the image file data
        sleep(1000)
        shall_we_remove=ask_about_remove(jpg_path,raw_path)
        print(shall_we_remove)
        wait_click(0)
    end
   
end



« Last Edit: 04 / May / 2012, 14:08:09 by outslider »
if (2*b || !2*b) {
    cout<<question
}

Compile error: poor Yorick


*

Offline reyalp

  • ******
  • 14079
Re: Where in the memory I should search for displayed informations?
« Reply #8 on: 05 / May / 2012, 00:46:51 »
I was playing with os.stat but I see, that stat can't be executed on file that doesn't exist.
It will return nil if the file doesn't exist. You won't be able to distinguish this from other cases (on dryos at least, vx has working errno) but the same goes for the fopen method.

On later dryos cameras, not having the A/ at the front will trigger an assert. Don't do that ;)
Don't forget what the H stands for.

Re: Where in the memory I should search for displayed informations?
« Reply #9 on: 05 / May / 2012, 14:09:35 »
I was playing with os.stat but I see, that stat can't be executed on file that doesn't exist.
It will return nil if the file doesn't exist.

For me stat on non-existing file broke the script and an error was displayed. Something like bad pointer to a table - I don't remember ('stat' is the element of the table 'os'). Fopen method works well ;)

On later dryos cameras, not having the A/ at the front will trigger an assert. Don't do that ;)

I hope that the path that camera keeps in memory is OK :) And of course the script might require some camera-dependend changes, especially if the path length is different.
if (2*b || !2*b) {
    cout<<question
}

Compile error: poor Yorick

 

Related Topics