Renaming Files

When you save editing results, LZ writes a special file that contains changes applied and references to the original file. By default, it is created in the same directory as the original file and has a name XXX_lzn.jpg

That is, if the original RAW file was DSC_5520.NEF, the associated lzn-file will be named DSC_5520_lzn.jpg

As these two files are interrelated, moving/renaming them can create problems. Usually moving both files to another directory is OK (we will discuss this later). But if you change the name of your raw file, LZ will see it as unrelated to LZN-file. Just renaming the associated lzn-file will not help - you need to change the contents of LZN-file as well.

The Structure of LZN-files

lzn-files are saved in JPEG format. These files contain a thumbnail of the processed image, standard metadata (e.g EXIF) and some application-specific data that can be used by LZ only. JPEG format is flexible enough and lets application add their own sections that will be ignored by other applications (such as image viewers). Format of JPEG is documented e.g. in Wikipedia. In particular, the section used by LZ starts from APP4 marker 0xffe4. This marker is followed by 2-byte section length (this length includes 2 bytes used by the length field itself but not the length of the preceding marker). After that there is the payload - in case of LZ ASCII text formatted as XML.

<LightZoneTransform xmlns="http://www.lightcrafts.com/lightzone/LightZoneTransform" version="8">                                                                
...
  <Image orientation="1" path="/uuu/users/asid/Pictures/tmp/DSC_5520.NEF" relativePath="DSC_5520.NEF"/>
...
    <ExportOptions file="/uuu/users/asid/Pictures/tmp/DSC_5520_lzn.jpg" type="JPEG">
...
</LightZoneTransform>

As you see, the name if the original file is present in 3 places:

  • path="…"
  • relativePath="…"
  • file="…"

The first two references are absolutely critical for finding the RAW file. The 3rd one is probably used for locating info in lzcache only - after changing this field to an arbitrary value (e.g. BogusBogusBogus) LZ was able to open the files without any problems.

When you open a LZN-file, the first place where LZ tries to find the associated RAW-file is defined by relativePath. This means that if you move both lzn and raw files together to another directory, LZ will be able to find the raw based on lzn - the relative path is still the same.

The absolute path path is used only if LZ is unable to find the raw-file at the location defined by the relative path. That is, if you move LZN-file only, leaving RAW at its previous location, LZ will do the following:

  • try to locate RAW using relative path (will fail)
  • try to locate RAW using the absolute path (will succeed)

If you want to rename or change location of your files, you need to do the following:

  • change the name or location of physical files as desired
  • modify LZN-file contents to reflect the new names/paths

Algorithm To Modify LZN-file

You can use binary editor to change the names inside LZN-file - but only if the length of new names/paths is exactly the same as that of the old ones. More precisely, the length of APP4 section should not change.

If new names have different length, the 2-byte length preceding the section needs to be changed to reflect the new lengthl. That is, we need to do the following:

  • locate the start of APP4 section
  • retrieve its length (2 bytes) and the section itself (ASCII-text, XML)
  • modify the extracted APP4 section as needed
  • copy to a new file everything from the old LZN-file preceding APP4 section
  • write to a new file APP4 marker, new length of the section and the section itself
  • copy from the old LZN-file everything following APP4 section

The new file will be a valid JPEG and LZ should be able to open it.

lzntool.py application

I have written a simple utility that can rewrite LZN-files. At this moment it can be invoked from the command-line only, GUI will be added later. The utility is written in Python language. You need either python-2.5 or python-2.6 (the new major 3.x release is not backwards compatible and most applications today are still based on python-2.X). The tool should work both on Linux and Windows (and presumably on Macintosh as well - but I don't have access to Mac for testing).

Here are some examples:

{asid 16:41:52} lzntool.py -h
Usage: lzntool.py [options] lznfile

Options:
  -h, --help            show this help message and exit
  -l, --list            list pathnames as used by LZ. Adding '-v' will print
                        the whole LZ-section
  --setrawpath=SETRAWPATH
                        Modify RAW file pathname in LZN-file. This does not
                        rename the real RAW-file
  --setrawrelpath=SETRAWRELPATH
                        Modify RAW file relpathname in LZN-file. This does not
                        rename the real RAW-file
  --setname=SETNAME     Modify both path and relPath by changing name only,do
                        not modify the directory parts
  -v                    verbose output
  --version             Display version information and exit.

{asid 17:19:46} lzntool.py -l DSC_5526_lzn.jpg
 *** DSC_5526_lzn.jpg ***
    Path:    /uuu/users/asid/Pictures/tmp/DSC_5526.NEF
    relPath: DSC_5526.NEF
    File:    /uuu/users/asid/Pictures/tmp/DSC_5526_lzn.jpg

{asid 17:20:23} lzntool.py -lv DSC_5526_lzn.jpg
<LightZoneTransform xmlns="http://www.lightcrafts.com/lightzone/LightZoneTransform" version="8">
  <Scale Factor="0.38801262"/>                                                                  
  <Image orientation="1" path="/uuu/users/asid/Pictures/tmp/DSC_5526.NEF" relativePath="DSC_5526.NEF"/>
  <Controls>                                                                                           
    <GenericOperation Active="true" Collapsed="false" Locked="false" Mode="Normal" Name="RAW Adjustments" Opacity="100" OperationType="RAW Adjustments" layerControlsIndex="0" regionsInverted="false">
...
</LightZoneTransform>

If you want to change just the name of the file (i.e. the last component in the full pathname), the following will work:

{asid 17:23:20} lzntool.py --setname NEW_FILE_NAME.NEF DSC_5526_lzn.jpg

And here is the new contents of this file:

{asid 17:23:47} lzntool.py -l DSC_5526_lzn.jpg
 *** DSC_5526_lzn.jpg ***
    Path:    /uuu/users/asid/Pictures/tmp/NEW_FILE_NAME.NEF
    relPath: NEW_FILE_NAME.NEF
    File:    /uuu/users/asid/Pictures/tmp/DSC_5526_lzn.jpg

You can set both path and relPath to anything you want:

{asid 17:27:18} lzntool.py --setrawpath /does/not/make/sense.NEF --setrawrelpath ../test/bogus.CRW DSC_5526_lzn.jpg
{asid 17:27:43} lzntool.py -l DSC_5526_lzn.jpg
 *** DSC_5526_lzn.jpg ***
    Path:    /does/not/make/sense.NEF
    relPath: ../test/bogus.CRW
    File:    /uuu/users/asid/Pictures/tmp/DSC_5526_lzn.jpg

but obviously LZ will be unable to find the files. Let us set revert to what we started from:

{asid 17:27:48} lzntool.py --setrawpath=/uuu/users/asid/Pictures/tmp/DSC_5526.NEF --setrawrelpath=DSC_5526.NEF DSC_5526_lzn.jpg

{asid 17:29:42} lzntool.py -l DSC_5526_lzn.jpg
 *** DSC_5526_lzn.jpg ***
    Path:    /uuu/users/asid/Pictures/tmp/DSC_5526.NEF
    relPath: DSC_5526.NEF
    File:    /uuu/users/asid/Pictures/tmp/DSC_5526_lzn.jpg

…and yes, I can open DSC_5526_lzn.jpg with LightZone. Please note that parameters can be entered after option both using a space and = sign, e.g. both

--setname newname
--setname=newname

are fine.


At this moment the tool should be already useful for those who write the batch renaming scripts themselves. For example: you copy/rename your LZN and RAW files pair and then use lzntool.py on LZN-file as needed. Later GUI will be added for easier usage.


For Windows users: you can download a prebuilt Python from ActivePython

After that, put lzntool.py in any directory in your PATH. To prevent data corruption if anything goes wrong, the program writes to a temporary files and only when it is completely written and closed, it replaces the original LZN with it. If there are any unexpected errors due to program limitations or bugs, the program will exit without rewriting the old LZN.

Known Limitations/Bugs

I did not test the program with names containing unusual symbols such as quotation marks or &. They probably need proper escaping before putting them into XML stream. As long as filenames are alphanumeric (plus ., _, / and \) the program should work fine.

The program is attached to this page. Any feedback is welcome (you can find author's email in program source).


A minor bug fixed, a new version is uploaded as lzntool.py-0.11. Rename it to lzntool.py after download (I don't have the privileges needed to remove/rename old versions)

Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License