supplierdeeply

Where in the memory I should search for displayed informations?

  • 12 Replies
  • 1397 Views
  • Publish
    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

  • Publish
    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.

  • Publish
    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

    • ******
    • 3118
  • Publish
    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 »


  • Publish
    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?


  • Publish
    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

    • ******
    • 3118
  • Publish
    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

  • Publish
    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

    • ******
    • 9882
  • Publish
    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.

  • Publish
    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