iconcache.txt 4.18 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
Information about the icon theme cache format used by GTK+
for more information, see the mailing list threads at 

http://mail.gnome.org/archives/gtk-devel-list/2004-April/msg00065.html
http://lists.freedesktop.org/archives/xdg/2004-October/005140.html


Back in May, Owen Taylor proposed [1] caching scheme for icon theme
information, to reduce the amount of stating and disk seeking at
application startup, and to reduce the memory overhead if each app
allocates all the icon theme data separately.

The proposal is to keep the information about the icons in the 
directory tree below each icon theme directory in an mmap()able 
cache file (There is basically one cache file per index.theme file). 

The cache doesn't try to hold all information from the index.theme files
that you would need to do lookups; it turns out that with the icon theme
specification, this isn't even sensible - you can install a 

 $HOME/.local/share/icons/Bluecurve/index.theme

That overrides

 /usr/share/icons/Bluecurve/index.theme

and chances how lookup happens for icons in /usr/share/icons/Bluecurve.

We would like to propose the cache file format as an appendix to the
icon theme specification. One thing which still needs to be investigated
is caching of the actual image data; the file format is has an
IMAGE_DATA_OFFSET member to allow adding that compatibly. An
implementation of the caching scheme for GTK+ can be found at [2]. The
cache generator which is included in the patch depends only on glib, and
it may be a good idea to move it to freedesktop.org as well. 


Regards, Matthias Clasen


The cache file format:

Header:
Anders Carlsson's avatar
Anders Carlsson committed
44 45 46 47
2			CARD16		MAJOR_VERSION	1	
2			CARD16		MINOR_VERSION	0	
4			CARD32		HASH_OFFSET		
4			CARD32		DIRECTORY_LIST_OFFSET
48 49

DirectoryList:
Anders Carlsson's avatar
Anders Carlsson committed
50 51
4			CARD32		N_DIRECTORIES		
4*N_DIRECTORIES		CARD32		DIRECTORY_OFFSET	
52 53

Hash:
Anders Carlsson's avatar
Anders Carlsson committed
54 55
4			CARD32		N_BUCKETS		
4*N_BUCKETS		CARD32		ICON_OFFSET	
56 57

Icon:
Anders Carlsson's avatar
Anders Carlsson committed
58 59 60
4			CARD32		CHAIN_OFFSET		
4			CARD32		NAME_OFFSET		
4			CARD32		IMAGE_LIST_OFFSET	
61 62

ImageList:
Anders Carlsson's avatar
Anders Carlsson committed
63 64
4			CARD32		N_IMAGES		
8*N_IMAGES		Image		IMAGES			
65 66

Image:
Anders Carlsson's avatar
Anders Carlsson committed
67 68 69
2			CARD16		DIRECTORY_INDEX	
2			ICON_FLAGS	FLAGS			
4			CARD32		IMAGE_DATA_OFFSET	
70 71 72 73 74 75 76

ICON_FLAGS
HAS_SUFFIX_PNG	1
HAS_SUFFIX_XPM	2
HAS_SUFFIX_SVG	4
HAS_ICON_FILE	8

Anders Carlsson's avatar
Anders Carlsson committed
77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114
ImageData:
4			CARD32		IMAGE_PIXEL_DATA_OFFSET
4			CARD32		IMAGE_META_DATA_OFFSET

4			CARD32		IMAGE_PIXEL_DATA_TYPE
4			CARD32		IMAGE_PIXEL_DATA_LENGTH
N/A			N/A		PIXEL_DATA

IMAGE_PIXEL_DATA_TYPE
0 GdkPixdata format

MetaData:
4			CARD32		EMBEDDED_RECT_OFFSET
4			CARD32		ATTACH_POINT_LIST_OFFSET
4			CARD32		DISPLAY_NAME_LIST_OFFSET

EmbeddedRect:
2			CARD16		X0
2			CARD16		Y0
2			CARD16		X1
2			CARD16		Y1

AttachPointList:
4			CARD32		N_ATTACH_POINTS
4*N_ATTACH_POINTS	AttachPoint

AttachPoint:
2			CARD16		X
2			CARD16		Y

DisplayNameList:
4			CARD32		N_DISPLAY_NAMES
4*N_DISPLAY_NAMES	DisplayName

DisplayName:
4			CARD32		DISPLAY_LANG_OFFSET
4			CARD32		DISPLAY_NAME_OFFSET
		
115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163

Notes:

* All offsets are from in bytes from the beginning of the file

* Strings are zero-terminated

* Directories are stored as relative paths.

* All numbers are in network (big-endian) order. This is
  necessary because the data will be stored in arch-independent
  directories like /usr/share/icons or even in user's 
  home directories.

* The hash function is that used by g_str_hash()

  unsigned int
  icon_str_hash (gconstpointer key)
  {
    const char *p = key;
    unsigned int h = *p;

    if (h)
      for (p += 1; *p != '\0'; p++)
        h = (h << 5) - h + *p;

    return h;
  }

 This should not be implemented by calling g_str_hash(). For
 optimal results, N_BUCKETS should be typically be prime.

* The same file format is used for icon themes (e.g.,
  /usr/share/icons/Bluecurve) and for unthemed icon directories
  (e.g., /usr/share/pixmaps)

  For an unthemed directory, N_DIRECTORIES==0 and each
  image has a DIRECTORY_INDEX field of 0xFFFF.

* Up-to-dateness of a cache file is determined simply:

    If the mod-time on the directory where the cache file
    lives is newer than the mod-time of the cache file,
    the cache file is out of date.

* Cache files have to be written atomically - write to a
  temporary name, then move over the old file - so that
  clients that have the old cache file open and mmap'ed
  won't get corrupt data.