1 ;;; compface.el --- functions for converting X-Face headers
2 ;; Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
4 ;; Author: Lars Magne Ingebrigtsen <larsi@gnus.org>
5 ;; TAKAI Kousuke <tak@kmc.gr.jp>
8 ;; This file is part of GNU Emacs.
10 ;; GNU Emacs is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 3, or (at your option)
15 ;; GNU Emacs is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ;; GNU General Public License for more details.
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GNU Emacs; see the file COPYING. If not, write to the
22 ;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
23 ;; Boston, MA 02110-1301, USA.
29 (defgroup compface nil
30 "X-Face image conversion."
33 (defcustom uncompface-use-external (and (not noninteractive)
34 (executable-find "uncompface")
35 (executable-find "icontopbm")
37 "*Specify which of the internal or the external decoder should be used.
38 nil means to use the internal ELisp-based uncompface program. t means
39 to use the external decoder. In the later case, you need to have the
40 external `uncompface' and `icontopbm' programs installed. The default
41 value is nil if those external programs aren't available, otherwise
42 `undecided' which means to determine it by checking whether the host
43 machine is slow. See also `uncompface-use-external-threshold'. You
44 can skip that check by setting this value as nil or t explicitly."
45 :type '(choice (const :tag "Use the internal decoder" nil)
46 (const :tag "Use the external decoder" t)
47 (const :tag "Autodetection" undecided))
50 (defcustom uncompface-use-external-threshold 0.1
51 "*Number of seconds to check whether the host machine is slow.
52 If the host takes time larger than this value for decoding an X-Face
53 using the internal ELisp-based uncompface program, it will be changed
54 to using the external `uncompface' and `icontopbm' programs if they
55 are available. Note that the measurement may never be exact."
60 (defmacro uncompface-float-time (&optional specified-time)
61 (if (fboundp 'float-time)
62 `(float-time ,specified-time)
63 `(let ((time (or ,specified-time (current-time))))
64 (+ (* (car time) 65536.0)
66 (cond ((consp (setq time (cddr time)))
67 (/ (car time) 1000000.0))
73 (defun uncompface (face)
75 If `uncompface-use-external' is t, it requires the external programs
76 `uncompface', and `icontopbm'. On a GNU/Linux system these might be
77 in packages with names like `compface' or `faces-xface' and `netpbm'
78 or `libgr-progs', for instance."
79 (cond ((eq uncompface-use-external nil)
80 (uncompface-internal face))
81 ((eq uncompface-use-external t)
83 (unless (featurep 'xemacs) (set-buffer-multibyte nil))
85 (let ((coding-system-for-read 'raw-text)
86 ;; At least "icontopbm" doesn't work with Windows because
87 ;; the line-break code is converted into CRLF by default.
88 (coding-system-for-write 'binary))
89 (and (eq 0 (apply 'call-process-region (point-min) (point-max)
91 'delete '(t nil) nil))
93 (goto-char (point-min))
94 (insert "/* Format_version=1, Width=48, Height=48,\
95 Depth=1, Valid_bits_per_item=16 */\n")
96 ;; I just can't get "icontopbm" to work correctly on its
97 ;; own in XEmacs. And Emacs doesn't understand un-raw pbm
99 (if (not (featurep 'xemacs))
100 (eq 0 (call-process-region (point-min) (point-max)
103 (shell-command-on-region (point-min) (point-max)
104 "icontopbm | pnmnoraw"
109 (let* ((gc-cons-threshold (eval '(lsh -1 -1)))
110 (start (current-time)))
112 (uncompface-internal face)
113 (setq uncompface-use-external
114 (and (> (- (uncompface-float-time (current-time))
115 (uncompface-float-time start))
116 uncompface-use-external-threshold)
117 (executable-find "uncompface")
118 (executable-find "icontopbm")
120 (message "Setting `uncompface-use-external' to `%s'"
121 uncompface-use-external))))))
123 ;; The following section is a bug-for-bug compatible version of
124 ;; `uncompface' program entirely implemented in Emacs-Lisp.
127 ;; The size of 48x48 is actually hard-coded into the code itself,
128 ;; so you cannot simply change those values. So we hard-code
129 ;; them into the compiled code.
130 (defconst uncompface-width 48
131 "Width of X-Face bitmap image.")
132 (defconst uncompface-height 48
133 "Height of X-Face bitmap image.")
135 ;; Again, this is also hard-coded into the compiled code.
136 (defconst uncompface-guesses
139 (let ((vector (make-vector (length x) nil))
149 (0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
150 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1
151 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
152 1 1 1 0 0 0 1 1 1 1 0 1 1 1 1 1
153 0 0 0 0 0 1 0 1 0 0 0 1 0 1 1 1
154 0 0 0 0 0 1 0 1 0 0 0 0 1 1 1 1
155 0 0 0 0 0 0 0 0 0 0 0 1 1 0 1 1
156 0 0 0 0 1 1 1 1 1 1 0 1 1 1 1 1
157 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0
158 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
159 0 0 0 0 1 1 0 1 0 0 0 0 1 1 1 1
160 0 0 0 0 0 0 1 1 0 1 1 1 1 1 1 1
161 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
162 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
163 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 1
164 0 1 0 0 0 1 0 1 0 0 1 0 1 1 1 1
165 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
166 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 1
167 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0
168 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
169 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0
170 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1
171 0 0 0 0 0 0 0 1 0 0 1 1 1 1 1 1
172 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1
173 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1
174 1 0 0 0 0 0 0 0 1 1 0 0 1 0 0 1
175 0 0 0 0 1 1 1 1 0 0 0 0 1 1 1 1
176 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
177 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
178 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
179 0 0 0 1 1 0 1 1 0 0 0 1 1 1 1 1
180 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
181 0 1 0 0 1 1 1 1 0 1 0 1 0 1 0 0
182 0 0 0 0 0 1 1 1 0 0 0 1 1 1 1 1
183 0 1 0 1 0 1 1 1 0 1 0 0 0 1 1 1
184 1 1 0 1 0 1 1 1 0 0 1 1 1 1 0 1
185 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
186 0 1 0 1 1 1 1 1 0 0 0 1 1 1 1 1
187 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
188 0 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1
189 0 0 0 0 0 1 0 1 0 0 0 0 1 1 1 1
190 0 0 0 0 0 0 0 1 0 0 0 0 1 1 1 1
191 0 0 0 0 1 1 1 1 0 1 0 1 1 1 1 1
192 1 0 0 1 1 0 1 1 1 1 0 1 1 1 1 1
193 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
194 0 1 0 1 1 1 1 1 0 0 0 1 1 1 0 1
195 0 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1
196 0 0 0 0 1 1 1 1 0 0 0 1 1 1 1 1
197 0 0 0 0 1 1 1 1 0 1 0 1 1 1 1 1
198 0 0 0 0 0 0 1 1 0 0 0 1 1 1 1 1
199 0 1 0 0 1 1 1 1 0 1 0 1 1 1 1 1
200 1 1 1 1 0 1 1 1 0 1 1 1 1 1 1 1
201 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
202 0 0 0 0 1 1 0 1 0 0 0 0 1 1 1 1
203 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1
204 1 1 1 1 0 1 1 1 1 0 1 1 1 1 1 1
205 0 0 0 0 1 1 1 1 0 1 0 0 1 1 1 1
206 1 1 0 1 0 1 1 1 0 0 1 1 1 1 1 1
207 0 1 0 0 1 1 1 1 0 1 1 1 1 1 1 1
208 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
209 0 1 1 0 0 1 1 1 1 0 1 1 1 1 1 1
210 0 1 0 1 0 1 1 0 0 0 1 0 0 1 0 1
211 0 0 0 1 1 1 1 1 0 1 1 1 1 1 1 1
212 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1
213 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
214 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1
215 0 1 0 1 1 1 1 1 0 1 1 1 1 1 1 1
216 0 0 0 0 0 0 0 1 1 1 0 1 1 1 1 1
217 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0
218 0 0 0 0 0 1 0 1 0 0 0 0 1 1 1 1
219 0 0 0 0 0 1 1 1 1 0 1 0 0 0 1 0
220 0 0 0 0 1 0 0 1 0 0 0 0 1 1 1 1
221 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
222 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
223 0 0 0 0 1 1 1 1 0 1 0 1 1 1 1 1
224 0 0 0 1 1 0 0 0 1 1 0 1 0 1 1 1
225 1 0 0 1 0 1 0 0 0 1 1 1 0 0 0 1
226 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1
227 0 0 0 1 1 1 1 1 1 0 1 1 0 1 1 1
228 0 0 0 0 1 1 0 0 0 0 0 0 0 1 1 1
229 0 0 0 0 1 1 1 1 0 0 0 0 1 1 1 1
230 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1
231 0 0 0 0 1 1 1 1 0 0 0 1 1 1 1 1
232 1 0 0 0 0 1 0 0 1 0 0 0 1 1 1 1
233 0 0 0 0 0 1 0 1 0 0 0 1 0 1 0 1
234 0 0 0 0 0 1 0 1 0 0 0 0 1 1 1 1
235 0 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1
236 1 0 0 0 0 1 1 1 1 1 0 1 1 1 1 1
237 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 1
238 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0
239 0 0 0 0 1 1 1 1 0 0 0 0 1 1 1 1
240 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0
241 0 0 0 0 0 1 0 1 0 0 0 0 0 1 0 0
242 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1
243 0 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1
244 1 0 0 1 1 1 1 1 1 0 0 0 1 1 1 1
245 0 1 0 0 1 0 1 0 0 1 0 0 0 0 0 0
246 0 1 0 1 1 1 1 1 0 1 0 1 1 1 1 1
247 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0
248 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1
249 0 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1
250 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1
251 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
252 0 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1
253 0 0 0 0 1 1 1 1 1 1 1 1 1 1 0 1
254 1 1 0 1 0 1 1 1 0 1 0 1 1 1 1 1
255 0 1 0 0 1 1 1 1 0 1 1 1 1 1 1 1
256 0 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1
257 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
258 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
259 1 1 1 1 1 1 1 1 0 1 1 1 0 1 1 1
260 1 1 0 1 1 1 1 1 0 1 1 1 1 1 1 1
261 0 1 0 0 1 1 1 1 1 1 1 0 1 1 1 1
262 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
263 0 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1
264 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
265 0 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1
266 0 0 0 0 1 1 1 1 0 1 0 0 1 1 1 1
267 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
268 1 0 0 1 1 1 0 1 1 1 1 1 1 1 1 1
269 0 0 0 0 1 1 1 1 1 1 1 0 1 1 1 1
270 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1
271 0 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1
272 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
273 0 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1
274 1 1 0 0 1 1 0 1 0 0 0 0 1 1 1 1
275 0 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1
276 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1
277 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
278 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 1
279 0 0 0 0 0 1 0 1 0 0 0 0 0 0 1 0
280 0 0 0 0 0 0 1 0 0 0 0 0 1 1 1 1
281 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0
282 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0
283 0 0 0 0 0 0 0 1 0 0 0 0 0 1 1 0
284 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1
285 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 1
286 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
287 0 0 0 0 0 1 0 1 0 0 0 0 1 1 1 1
288 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0
289 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
290 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
291 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
292 0 0 0 0 1 1 0 0 0 0 0 0 1 1 1 1
293 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0
294 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
295 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
296 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
297 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0
298 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 1
299 0 0 0 0 0 0 0 1 0 0 0 1 0 1 0 1
300 1 0 1 0 1 1 1 1 0 0 0 0 1 1 1 1
301 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
302 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0
303 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0
304 0 1 0 0 0 1 1 0 0 0 0 0 1 1 0 0
305 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0
306 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0
307 0 0 0 0 1 1 1 1 0 0 0 1 0 1 0 1
308 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1
309 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0
310 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1
311 0 1 1 1 1 1 1 1 0 1 0 1 1 1 1 1
312 1 1 0 1 1 0 1 1 1 1 1 1 1 1 1 1
313 0 1 0 0 1 1 1 1 0 0 1 1 1 1 1 0
314 0 0 0 0 0 1 0 1 0 0 0 0 1 1 1 1
315 0 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1
316 1 0 0 1 0 1 0 1 0 1 0 0 1 1 1 1
317 0 0 0 0 1 1 0 1 0 0 0 0 1 1 1 1
318 0 0 0 0 0 0 0 1 0 0 0 0 1 1 1 1
319 0 1 0 0 1 1 1 1 0 1 0 1 1 1 1 1
320 1 0 0 1 1 1 1 1 1 1 0 1 1 1 1 1
321 0 0 1 0 0 1 0 1 0 0 0 0 1 1 1 0
322 0 0 0 0 1 1 0 1 0 0 0 0 1 1 0 1
323 0 1 0 0 1 1 1 1 0 1 1 1 1 1 1 1
324 1 0 0 0 1 1 1 1 0 0 0 0 1 1 1 1
325 0 0 0 0 1 1 1 1 1 1 1 1 1 0 1 0
326 0 0 0 0 0 1 0 0 0 1 0 0 1 1 1 1
327 0 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1
328 1 1 1 1 0 1 1 1 0 1 1 1 0 1 1 1
329 0 1 0 0 0 1 1 1 1 1 1 0 1 1 0 1
330 0 0 0 0 0 1 0 1 0 0 0 0 1 1 1 1
331 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
332 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1
333 0 1 0 0 1 1 1 1 0 1 1 0 1 1 1 1
334 1 1 0 1 1 0 0 0 0 1 0 1 1 1 1 1
335 0 0 0 0 1 1 1 1 0 1 1 1 1 1 1 1
336 1 1 0 1 1 1 1 1 0 1 0 1 1 1 1 1
337 0 0 0 0 0 1 1 1 0 0 0 0 1 1 1 1
338 1 0 0 1 0 1 0 0 0 0 0 0 1 1 0 1
339 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1
340 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
341 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0
342 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1
343 0 1 0 0 0 1 1 0 0 1 0 1 0 1 1 1
344 0 0 0 0 0 0 0 1 0 0 0 0 1 1 0 1
345 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0
346 0 0 0 0 0 0 0 1 0 0 0 0 1 1 1 1
347 0 1 0 0 0 1 1 1 0 1 1 0 1 1 0 0
348 0 0 0 0 1 1 0 1 0 0 0 0 1 1 1 1
349 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0
350 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
351 0 0 0 0 1 0 1 1 0 1 0 0 1 1 1 1
352 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0
353 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0
354 1 0 0 1 0 1 0 1 0 0 0 0 0 0 0 1
355 0 0 0 0 1 1 1 1 0 1 1 1 1 1 1 1
356 0 0 0 0 1 1 0 0 0 0 0 0 1 1 1 1
357 0 0 0 0 0 0 0 1 0 0 0 0 1 1 1 0
358 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
359 0 0 0 0 1 1 1 1 0 1 0 0 0 0 0 1
360 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
361 0 0 0 0 0 1 0 0 0 0 1 0 0 1 0 0
362 0 0 0 0 1 1 0 1 0 0 0 0 1 1 1 1
363 0 0 0 0 1 1 1 1 0 1 1 1 1 1 1 1
364 1 1 0 0 1 1 1 1 1 1 0 1 1 1 1 1
365 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
366 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
367 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0
368 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
369 0 0 0 0 0 1 1 0 0 0 1 0 0 1 1 0
370 1 1 0 0 1 1 1 1 0 0 0 0 0 1 0 1
371 1 1 0 0 1 1 1 1 0 1 1 1 1 1 1 1
372 1 1 0 1 1 1 1 1 1 1 0 1 1 1 1 1
373 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
374 0 0 0 1 0 1 1 1 0 1 0 1 1 1 1 1
375 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1
376 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
377 0 1 0 0 0 1 1 0 0 0 0 0 1 0 0 1
378 0 1 0 0 1 1 1 1 0 1 0 1 1 1 1 1
379 0 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1
380 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1
381 0 0 0 0 1 0 1 0 1 0 0 0 1 0 0 0
382 1 0 1 0 0 1 1 1 0 1 1 1 1 1 1 1
383 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
384 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
385 0 0 0 0 1 1 1 1 0 0 0 0 0 1 0 0
386 1 1 0 1 1 1 1 1 0 1 1 1 1 1 1 1
387 0 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1
388 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1
389 0 0 0 0 1 1 1 0 1 1 1 0 0 1 1 0
390 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1
391 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
392 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
393 0 0 0 0 1 1 1 1 1 1 1 0 1 1 0 0
394 1 0 0 0 1 1 1 1 0 1 0 0 1 1 1 1
395 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
396 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1
397 0 0 0 0 1 1 1 1 1 1 0 0 1 1 1 1
398 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1
399 0 1 1 0 1 1 1 1 0 1 1 1 1 1 1 1
400 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
401 0 0 0 0 0 0 1 1 0 0 0 0 1 1 0 0
402 1 0 0 1 1 1 0 1 0 0 0 0 1 1 1 1
403 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
404 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1)
406 (0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
407 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
408 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0
409 1 1 1 1 0 0 1 1 0 1 0 1 1 1 1 1
410 1 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0
411 0 0 0 1 0 1 1 1 1 0 0 1 1 1 1 1
412 0 0 0 0 0 1 0 0 0 0 1 0 0 0 1 1
413 0 0 0 0 0 1 0 1 1 1 1 1 1 1 1 1
414 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
415 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0
416 0 0 0 0 0 0 1 1 0 0 0 0 0 0 1 1
417 0 0 1 1 0 0 1 1 1 1 0 1 0 1 1 1
418 0 0 0 0 0 1 0 1 0 0 0 0 0 0 1 1
419 0 1 0 1 1 1 1 1 0 0 1 1 1 1 1 1
420 0 0 0 1 0 1 1 1 0 0 1 1 0 0 1 1
421 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
422 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0
423 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0
424 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0
425 0 0 0 1 0 0 0 1 0 1 0 1 0 1 1 1
426 0 0 0 0 0 1 0 1 0 0 1 0 0 1 0 1
427 0 0 0 0 0 1 0 1 0 0 0 0 0 0 1 1
428 0 0 1 1 0 1 0 1 1 0 1 1 1 1 1 1
429 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1
430 0 0 0 0 0 1 1 1 0 1 1 0 1 1 1 1
431 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0
432 0 0 0 1 0 1 1 1 0 0 0 0 0 1 1 0
433 1 1 1 1 1 0 1 0 1 1 1 0 1 0 0 0
434 0 0 0 0 0 0 0 1 0 0 0 0 0 1 1 1
435 0 0 0 1 1 1 1 1 1 0 0 1 1 1 1 1
436 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1
437 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1)
439 (0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0
440 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1
441 0 1 0 0 0 0 1 1 0 0 1 0 1 1 1 0
442 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1)
444 (0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1
445 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1
446 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 1
447 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 1
448 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1
449 0 0 0 0 0 0 0 0 0 1 0 0 1 1 1 0
450 1 1 1 0 0 1 0 0 0 0 0 0 1 1 0 1
451 0 0 0 1 0 0 0 0 0 0 0 0 1 1 1 1
452 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1
453 0 1 0 0 0 1 0 0 0 1 0 0 1 1 1 1
454 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0
455 0 0 0 0 1 1 1 1 0 0 0 0 1 1 1 1
456 1 0 1 0 1 1 1 0 1 0 1 0 1 1 1 1
457 0 1 0 0 0 1 0 1 0 1 1 1 1 1 1 1
458 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1
459 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1
460 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1
461 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 1
462 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
463 0 0 0 1 1 1 0 0 1 1 0 1 1 1 0 1
464 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 1
465 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1
466 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0
467 0 0 0 0 0 0 0 0 1 1 1 1 1 1 0 1
468 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1
469 0 1 0 0 1 1 1 1 0 1 0 1 1 1 1 1
470 0 0 1 1 1 1 0 1 1 1 1 1 1 1 1 1
471 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
472 0 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1
473 0 0 0 1 1 1 0 0 1 1 1 1 1 1 1 1
474 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1
475 1 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1
476 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 1
477 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
478 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 1
479 0 0 0 0 0 0 0 1 0 0 0 0 0 1 1 1
480 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
481 0 0 0 0 0 0 1 0 0 0 0 1 1 1 1 1
482 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 1
483 0 0 0 0 0 1 0 1 0 1 1 1 1 1 1 1
484 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1
485 0 1 0 0 0 0 0 1 0 1 0 1 0 1 1 1
486 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1
487 0 0 0 0 0 1 0 1 0 1 1 1 0 1 1 1
488 0 0 0 0 1 1 0 1 0 1 0 1 1 1 1 1
489 0 1 0 0 1 1 0 1 1 1 1 1 1 1 1 1
490 0 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1
491 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1
492 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
493 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 1
494 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1
495 0 0 0 0 0 1 0 1 0 1 1 1 1 1 0 1
496 0 0 0 1 0 0 0 0 0 0 0 1 0 1 0 1
497 0 0 1 0 1 1 1 1 1 1 1 1 1 1 1 1
498 0 1 0 0 0 0 0 0 0 1 0 1 0 0 0 0
499 0 0 0 0 1 1 0 1 1 1 1 1 1 1 0 1
500 0 0 0 0 0 1 0 0 0 0 0 0 1 1 1 1
501 0 0 0 0 0 1 1 1 0 0 0 1 1 1 1 1
502 0 0 0 0 0 1 1 1 0 1 1 1 1 1 1 1
503 0 0 0 0 1 1 1 1 1 0 1 1 1 1 1 1
504 0 0 0 0 1 1 0 1 0 1 1 1 1 1 1 1
505 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1
506 0 1 0 0 1 1 0 1 0 1 1 1 1 1 0 1
507 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1))
509 (0 0 1 1 0 1 1 1 0 1 1 1 0 0 1 1
510 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 1
511 0 1 0 1 0 1 1 1 0 1 1 1 1 1 1 1
512 1 1 1 1 0 1 0 1 1 1 1 1 1 0 1 1
513 0 1 1 1 0 0 0 0 0 0 1 1 0 0 1 1
514 1 1 1 1 0 0 0 0 1 1 1 1 1 0 0 1
515 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
516 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1)
518 (0 0 0 0 0 0 0 1 0 0 0 1 0 0 1 1
519 0 0 0 0 0 0 1 1 0 1 1 1 1 1 1 1)
523 (0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1
524 0 0 0 0 0 0 0 1 0 0 0 1 1 1 1 1
525 0 0 0 0 0 0 1 1 0 0 0 1 1 1 1 1
526 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1))
535 "Static prediction table for X-Face image compression algorithm.")
537 ;; Macros for inlining critical values.
538 (defmacro uncompface-width () (list 'quote uncompface-width))
539 (defmacro uncompface-height () (list 'quote uncompface-height))
540 (defmacro uncompface-guesses () (list 'quote uncompface-guesses))
542 (defmacro uncompface-loop (&rest body)
543 "Eval BODY and repeat if last expression of BODY yields non-nil."
544 (list 'while (cons 'progn body))))
546 ;; (defun uncompface-print-bignum (bignum &optional prefix)
547 ;; (princ (format (concat prefix "<%s>\n")
548 ;; (mapconcat (lambda (x) (format "%02x" x))
549 ;; (reverse bignum) " "))))
551 ;; Shut up the byte-compiler.
552 ;; These variables are once bound in `uncompface' and all subfunctions
553 ;; accesses them directly rather than creating their own bindings.
558 ;; Big-number facilities.
559 ;; These functions were used to be implemented with `lsh' and `logand',
560 ;; but rewritten to use `/' and `%'. The last two are mapped into
561 ;; byte-code directly, but the formers are normal functions even in
562 ;; compiled code which involve expensive `funcall' operations.
564 (defsubst uncompface-big-mul-add (multiplier adder)
565 "Multiply BIGNUM by MULTIPLIER and add ADDER and put result in `bignum'."
566 (setq bignum (if (= multiplier 0)
570 (setcar bignum (% (setq adder (+ (* (car bignum)
574 (setq adder (/ adder 256))
576 (setq bignum (cdr bignum)))
578 (setcdr bignum (list adder))))))))
580 ;; This trick is for XEmacs 21.4 which doesn't allow inlining a function
581 ;; using `defsubst' into another function also defined with `defsubst'.
583 (when (featurep 'xemacs)
584 (defvar uncompface-big-mul-add (symbol-function 'uncompface-big-mul-add))
585 (defmacro uncompface-big-mul-add (multiplier adder)
586 `(,uncompface-big-mul-add ,multiplier ,adder))))
588 ;; Separate `eval-when-compile' for the byte compiler
589 ;; to properly define `uncompface-big-mul-add' before `uncompface-big-pop'.
591 (defsubst uncompface-big-pop (prob)
592 (let ((n (car bignum)) (i 0))
594 (setq bignum (cdr bignum))
596 (while (or (< n (cdr (car prob)))
597 (>= n (+ (cdr (car prob)) (car (car prob)))))
598 (setq prob (cdr prob)
600 (uncompface-big-mul-add (car (car prob)) (- n (cdr (car prob))))
603 ;; This function cannot be inlined due to recursive calls.
604 (defun uncompface-pop-grays (offset size)
606 (let ((bits (uncompface-big-pop
607 ;; This is freqs[16] in compface_private.h.
608 '(( 0 . 0) (38 . 0) (38 . 38) (13 . 152)
609 (38 . 76) (13 . 165) (13 . 178) ( 6 . 230)
610 (38 . 114) (13 . 191) (13 . 204) ( 6 . 236)
611 (13 . 217) ( 6 . 242) ( 5 . 248) ( 3 . 253)))))
612 ;; (if (/= (logand bits 1) 0)
613 ;; (aset face offset t))
614 ;; (if (/= (logand bits 2) 0)
615 ;; (aset face (1+ offset) t))
616 ;; (if (/= (logand bits 4) 0)
617 ;; (aset face (+ offset (uncompface-width)) t))
618 ;; (if (/= (logand bits 8) 0)
619 ;; (aset face (+ offset (uncompface-width) 1) t))
621 (aset face (+ offset (uncompface-width) 1) t)
622 (setq bits (- bits 8)))
624 (aset face (+ offset (uncompface-width)) t)
625 (setq bits (- bits 4)))
626 (or (eq (if (< bits 2)
628 (aset face (1+ offset) t)
631 (aset face offset t))
633 (setq size (/ size 2))
634 (uncompface-pop-grays offset size)
635 (uncompface-pop-grays (+ offset size) size)
636 (uncompface-pop-grays (+ offset (* (uncompface-width) size)) size)
637 (uncompface-pop-grays (+ offset (* (uncompface-width) size) size) size)))
639 ;; Again, this function call itself recursively.
640 (defun uncompface-uncompress (offset size level)
641 ;; This used to be (funcall (aref [(lambda ...) ...] (u-big-pop ...)))
642 ;; but this was slow due to function call.
643 (let ((i (uncompface-big-pop (car level))))
644 (cond ((eq i 0) ; black
645 (uncompface-pop-grays offset size))
647 (setq size (/ size 2)
649 (uncompface-uncompress offset size level)
650 (uncompface-uncompress (+ offset size) size level)
651 (uncompface-uncompress (+ offset (* size (uncompface-width)))
653 (uncompface-uncompress (+ offset (* size (uncompface-width)) size)
656 ;; (t (error "Cannot happen"))
660 (defmacro uncompface-shift-in (k dy dx)
661 `(+ k k (if (aref face (+ i (* ,dy (uncompface-width)) ,dx)) 1 0))))
663 (defun uncompface-internal (string &optional raw)
664 "Decode X-Face data STRING and return an image in the pbm format.
665 If the optional RAW is non-nil, return a raw bitmap as a vector."
666 (let (;; `bignum' and `face' are semi-global variables.
667 ;; Do not use '(0) below, because BIGNUM is modified in-place.
669 (face (make-vector (* (uncompface-width) (uncompface-height)) nil))
670 ;;(uncompface-big-shift -16)
671 ;;(uncompface-big-mask 65535)
674 (and (>= c ?!) (<= c ?~)
675 (uncompface-big-mul-add (1+ (- ?~ ?!)) (- c ?!))))
677 ;;(uncompface-print-bignum bignum)
682 (uncompface-uncompress (+ (* (uncompface-width) y) x) 16
683 ;; This is levels[4][3] in compface_private.h.
684 '(;; Top of tree almost always grey
685 (( 1 . 255) (251 . 0) ( 4 . 251))
686 (( 1 . 255) (200 . 0) ( 55 . 200))
687 (( 33 . 223) (159 . 0) ( 64 . 159))
688 ;; Grey disallowed at bottom
689 ((131 . 0) ( 0 . 0) (125 . 131))))
690 (< (setq x (+ x 16)) (uncompface-width)))
691 (< (setq y (+ y 16)) (uncompface-height)))
693 (let ((i 0) guesses k)
695 (setq guesses (cond ((= y 1) (nth 2 (uncompface-guesses)))
696 ((= y 2) (nth 1 (uncompface-guesses)))
697 (t (nth 0 (uncompface-guesses))))
707 (setq k (uncompface-shift-in k -2 -2)))
708 (setq k (uncompface-shift-in k -1 -2)))
709 (setq k (uncompface-shift-in k 0 -2))))
713 (setq k (uncompface-shift-in k -2 -1)))
714 (setq k (uncompface-shift-in k -1 -1)))
715 (setq k (uncompface-shift-in k 0 -1))))
718 (setq k (uncompface-shift-in k -2 0)))
719 (setq k (uncompface-shift-in k -1 0)))
722 (setq k (uncompface-shift-in k -2 1)))
723 (setq k (uncompface-shift-in k -1 1)))
724 (when (<= x (- (uncompface-width) 2))
727 (setq k (uncompface-shift-in k -2 2)))
728 (setq k (uncompface-shift-in k -1 2)))))
729 (if (aref (car (cond ((= x 1)
733 ((= x (1- (uncompface-width)))
734 (cdr (cdr (cdr guesses))))
737 (aset face i (not (aref face i))))
739 (< (setq x (1+ x)) (uncompface-width)))
740 (< (setq y (1+ y)) (uncompface-height))))
743 (concat (eval-when-compile
744 (format "P1\n%d %d\n" uncompface-width uncompface-height))
745 (mapconcat (lambda (bit) (if bit "1" "0")) face " ")
751 ;; eval: (put 'uncompface-loop 'lisp-indent-hook 0)
754 ;;; compface.el ends here