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. If not, see <http://www.gnu.org/licenses/>.
27 (defgroup compface nil
28 "X-Face image conversion."
31 (defcustom uncompface-use-external
(and (not noninteractive
)
32 (executable-find "uncompface")
33 (executable-find "icontopbm")
35 "*Specify which of the internal or the external decoder should be used.
36 nil means to use the internal ELisp-based uncompface program. t means
37 to use the external decoder. In the later case, you need to have the
38 external `uncompface' and `icontopbm' programs installed. The default
39 value is nil if those external programs aren't available, otherwise
40 `undecided' which means to determine it by checking whether the host
41 machine is slow. See also `uncompface-use-external-threshold'. You
42 can skip that check by setting this value as nil or t explicitly."
43 :type
'(choice (const :tag
"Use the internal decoder" nil
)
44 (const :tag
"Use the external decoder" t
)
45 (const :tag
"Autodetection" undecided
))
48 (defcustom uncompface-use-external-threshold
0.1
49 "*Number of seconds to check whether the host machine is slow.
50 If the host takes time larger than this value for decoding an X-Face
51 using the internal ELisp-based uncompface program, it will be changed
52 to using the external `uncompface' and `icontopbm' programs if they
53 are available. Note that the measurement may never be exact."
58 (defmacro uncompface-float-time
(&optional specified-time
)
59 (if (fboundp 'float-time
)
60 `(float-time ,specified-time
)
61 `(let ((time (or ,specified-time
(current-time))))
62 (+ (* (car time
) 65536.0)
64 (cond ((consp (setq time
(cddr time
)))
65 (/ (car time
) 1000000.0))
71 (defun uncompface (face)
73 If `uncompface-use-external' is t, it requires the external programs
74 `uncompface', and `icontopbm'. On a GNU/Linux system these might be
75 in packages with names like `compface' or `faces-xface' and `netpbm'
76 or `libgr-progs', for instance."
77 (cond ((eq uncompface-use-external nil
)
78 (uncompface-internal face
))
79 ((eq uncompface-use-external t
)
81 (unless (featurep 'xemacs
) (set-buffer-multibyte nil
))
83 (let ((coding-system-for-read 'raw-text
)
84 ;; At least "icontopbm" doesn't work with Windows because
85 ;; the line-break code is converted into CRLF by default.
86 (coding-system-for-write 'binary
))
87 (and (eq 0 (apply 'call-process-region
(point-min) (point-max)
89 'delete
'(t nil
) nil
))
91 (goto-char (point-min))
92 (insert "/* Format_version=1, Width=48, Height=48,\
93 Depth=1, Valid_bits_per_item=16 */\n")
94 ;; I just can't get "icontopbm" to work correctly on its
95 ;; own in XEmacs. And Emacs doesn't understand un-raw pbm
97 (if (not (featurep 'xemacs
))
98 (eq 0 (call-process-region (point-min) (point-max)
101 (shell-command-on-region (point-min) (point-max)
102 "icontopbm | pnmnoraw"
107 (let* ((gc-cons-threshold (eval '(lsh -
1 -
1)))
108 (start (current-time)))
110 (uncompface-internal face
)
111 (setq uncompface-use-external
112 (and (> (- (uncompface-float-time (current-time))
113 (uncompface-float-time start
))
114 uncompface-use-external-threshold
)
115 (executable-find "uncompface")
116 (executable-find "icontopbm")
118 (message "Setting `uncompface-use-external' to `%s'"
119 uncompface-use-external
))))))
121 ;; The following section is a bug-for-bug compatible version of
122 ;; `uncompface' program entirely implemented in Emacs-Lisp.
125 ;; The size of 48x48 is actually hard-coded into the code itself,
126 ;; so you cannot simply change those values. So we hard-code
127 ;; them into the compiled code.
128 (defconst uncompface-width
48
129 "Width of X-Face bitmap image.")
130 (defconst uncompface-height
48
131 "Height of X-Face bitmap image.")
133 ;; Again, this is also hard-coded into the compiled code.
134 (defconst uncompface-guesses
137 (let ((vector (make-vector (length x
) nil
))
147 (0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
148 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1
149 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
150 1 1 1 0 0 0 1 1 1 1 0 1 1 1 1 1
151 0 0 0 0 0 1 0 1 0 0 0 1 0 1 1 1
152 0 0 0 0 0 1 0 1 0 0 0 0 1 1 1 1
153 0 0 0 0 0 0 0 0 0 0 0 1 1 0 1 1
154 0 0 0 0 1 1 1 1 1 1 0 1 1 1 1 1
155 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0
156 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
157 0 0 0 0 1 1 0 1 0 0 0 0 1 1 1 1
158 0 0 0 0 0 0 1 1 0 1 1 1 1 1 1 1
159 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
160 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
161 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 1
162 0 1 0 0 0 1 0 1 0 0 1 0 1 1 1 1
163 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
164 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 1
165 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0
166 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
167 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0
168 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1
169 0 0 0 0 0 0 0 1 0 0 1 1 1 1 1 1
170 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1
171 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1
172 1 0 0 0 0 0 0 0 1 1 0 0 1 0 0 1
173 0 0 0 0 1 1 1 1 0 0 0 0 1 1 1 1
174 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
175 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
176 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
177 0 0 0 1 1 0 1 1 0 0 0 1 1 1 1 1
178 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
179 0 1 0 0 1 1 1 1 0 1 0 1 0 1 0 0
180 0 0 0 0 0 1 1 1 0 0 0 1 1 1 1 1
181 0 1 0 1 0 1 1 1 0 1 0 0 0 1 1 1
182 1 1 0 1 0 1 1 1 0 0 1 1 1 1 0 1
183 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
184 0 1 0 1 1 1 1 1 0 0 0 1 1 1 1 1
185 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
186 0 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1
187 0 0 0 0 0 1 0 1 0 0 0 0 1 1 1 1
188 0 0 0 0 0 0 0 1 0 0 0 0 1 1 1 1
189 0 0 0 0 1 1 1 1 0 1 0 1 1 1 1 1
190 1 0 0 1 1 0 1 1 1 1 0 1 1 1 1 1
191 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
192 0 1 0 1 1 1 1 1 0 0 0 1 1 1 0 1
193 0 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1
194 0 0 0 0 1 1 1 1 0 0 0 1 1 1 1 1
195 0 0 0 0 1 1 1 1 0 1 0 1 1 1 1 1
196 0 0 0 0 0 0 1 1 0 0 0 1 1 1 1 1
197 0 1 0 0 1 1 1 1 0 1 0 1 1 1 1 1
198 1 1 1 1 0 1 1 1 0 1 1 1 1 1 1 1
199 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
200 0 0 0 0 1 1 0 1 0 0 0 0 1 1 1 1
201 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1
202 1 1 1 1 0 1 1 1 1 0 1 1 1 1 1 1
203 0 0 0 0 1 1 1 1 0 1 0 0 1 1 1 1
204 1 1 0 1 0 1 1 1 0 0 1 1 1 1 1 1
205 0 1 0 0 1 1 1 1 0 1 1 1 1 1 1 1
206 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
207 0 1 1 0 0 1 1 1 1 0 1 1 1 1 1 1
208 0 1 0 1 0 1 1 0 0 0 1 0 0 1 0 1
209 0 0 0 1 1 1 1 1 0 1 1 1 1 1 1 1
210 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1
211 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
212 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1
213 0 1 0 1 1 1 1 1 0 1 1 1 1 1 1 1
214 0 0 0 0 0 0 0 1 1 1 0 1 1 1 1 1
215 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0
216 0 0 0 0 0 1 0 1 0 0 0 0 1 1 1 1
217 0 0 0 0 0 1 1 1 1 0 1 0 0 0 1 0
218 0 0 0 0 1 0 0 1 0 0 0 0 1 1 1 1
219 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
220 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
221 0 0 0 0 1 1 1 1 0 1 0 1 1 1 1 1
222 0 0 0 1 1 0 0 0 1 1 0 1 0 1 1 1
223 1 0 0 1 0 1 0 0 0 1 1 1 0 0 0 1
224 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1
225 0 0 0 1 1 1 1 1 1 0 1 1 0 1 1 1
226 0 0 0 0 1 1 0 0 0 0 0 0 0 1 1 1
227 0 0 0 0 1 1 1 1 0 0 0 0 1 1 1 1
228 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1
229 0 0 0 0 1 1 1 1 0 0 0 1 1 1 1 1
230 1 0 0 0 0 1 0 0 1 0 0 0 1 1 1 1
231 0 0 0 0 0 1 0 1 0 0 0 1 0 1 0 1
232 0 0 0 0 0 1 0 1 0 0 0 0 1 1 1 1
233 0 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1
234 1 0 0 0 0 1 1 1 1 1 0 1 1 1 1 1
235 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 1
236 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0
237 0 0 0 0 1 1 1 1 0 0 0 0 1 1 1 1
238 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0
239 0 0 0 0 0 1 0 1 0 0 0 0 0 1 0 0
240 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1
241 0 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1
242 1 0 0 1 1 1 1 1 1 0 0 0 1 1 1 1
243 0 1 0 0 1 0 1 0 0 1 0 0 0 0 0 0
244 0 1 0 1 1 1 1 1 0 1 0 1 1 1 1 1
245 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0
246 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1
247 0 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1
248 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1
249 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
250 0 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1
251 0 0 0 0 1 1 1 1 1 1 1 1 1 1 0 1
252 1 1 0 1 0 1 1 1 0 1 0 1 1 1 1 1
253 0 1 0 0 1 1 1 1 0 1 1 1 1 1 1 1
254 0 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1
255 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
256 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
257 1 1 1 1 1 1 1 1 0 1 1 1 0 1 1 1
258 1 1 0 1 1 1 1 1 0 1 1 1 1 1 1 1
259 0 1 0 0 1 1 1 1 1 1 1 0 1 1 1 1
260 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
261 0 1 1 1 0 1 1 1 1 1 1 1 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 0 1 1 1 1 1 1 1 1 1 1 1 1
264 0 0 0 0 1 1 1 1 0 1 0 0 1 1 1 1
265 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
266 1 0 0 1 1 1 0 1 1 1 1 1 1 1 1 1
267 0 0 0 0 1 1 1 1 1 1 1 0 1 1 1 1
268 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1
269 0 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1
270 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
271 0 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1
272 1 1 0 0 1 1 0 1 0 0 0 0 1 1 1 1
273 0 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1
274 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1
275 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
276 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 1
277 0 0 0 0 0 1 0 1 0 0 0 0 0 0 1 0
278 0 0 0 0 0 0 1 0 0 0 0 0 1 1 1 1
279 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0
280 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0
281 0 0 0 0 0 0 0 1 0 0 0 0 0 1 1 0
282 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1
283 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 1
284 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
285 0 0 0 0 0 1 0 1 0 0 0 0 1 1 1 1
286 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0
287 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
288 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
289 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
290 0 0 0 0 1 1 0 0 0 0 0 0 1 1 1 1
291 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0
292 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
293 0 0 0 0 0 0 0 0 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 1 0 1 0 0
296 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 1
297 0 0 0 0 0 0 0 1 0 0 0 1 0 1 0 1
298 1 0 1 0 1 1 1 1 0 0 0 0 1 1 1 1
299 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
300 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0
301 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0
302 0 1 0 0 0 1 1 0 0 0 0 0 1 1 0 0
303 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0
304 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0
305 0 0 0 0 1 1 1 1 0 0 0 1 0 1 0 1
306 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1
307 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0
308 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1
309 0 1 1 1 1 1 1 1 0 1 0 1 1 1 1 1
310 1 1 0 1 1 0 1 1 1 1 1 1 1 1 1 1
311 0 1 0 0 1 1 1 1 0 0 1 1 1 1 1 0
312 0 0 0 0 0 1 0 1 0 0 0 0 1 1 1 1
313 0 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1
314 1 0 0 1 0 1 0 1 0 1 0 0 1 1 1 1
315 0 0 0 0 1 1 0 1 0 0 0 0 1 1 1 1
316 0 0 0 0 0 0 0 1 0 0 0 0 1 1 1 1
317 0 1 0 0 1 1 1 1 0 1 0 1 1 1 1 1
318 1 0 0 1 1 1 1 1 1 1 0 1 1 1 1 1
319 0 0 1 0 0 1 0 1 0 0 0 0 1 1 1 0
320 0 0 0 0 1 1 0 1 0 0 0 0 1 1 0 1
321 0 1 0 0 1 1 1 1 0 1 1 1 1 1 1 1
322 1 0 0 0 1 1 1 1 0 0 0 0 1 1 1 1
323 0 0 0 0 1 1 1 1 1 1 1 1 1 0 1 0
324 0 0 0 0 0 1 0 0 0 1 0 0 1 1 1 1
325 0 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1
326 1 1 1 1 0 1 1 1 0 1 1 1 0 1 1 1
327 0 1 0 0 0 1 1 1 1 1 1 0 1 1 0 1
328 0 0 0 0 0 1 0 1 0 0 0 0 1 1 1 1
329 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
330 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1
331 0 1 0 0 1 1 1 1 0 1 1 0 1 1 1 1
332 1 1 0 1 1 0 0 0 0 1 0 1 1 1 1 1
333 0 0 0 0 1 1 1 1 0 1 1 1 1 1 1 1
334 1 1 0 1 1 1 1 1 0 1 0 1 1 1 1 1
335 0 0 0 0 0 1 1 1 0 0 0 0 1 1 1 1
336 1 0 0 1 0 1 0 0 0 0 0 0 1 1 0 1
337 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1
338 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
339 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0
340 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1
341 0 1 0 0 0 1 1 0 0 1 0 1 0 1 1 1
342 0 0 0 0 0 0 0 1 0 0 0 0 1 1 0 1
343 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0
344 0 0 0 0 0 0 0 1 0 0 0 0 1 1 1 1
345 0 1 0 0 0 1 1 1 0 1 1 0 1 1 0 0
346 0 0 0 0 1 1 0 1 0 0 0 0 1 1 1 1
347 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0
348 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
349 0 0 0 0 1 0 1 1 0 1 0 0 1 1 1 1
350 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0
351 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0
352 1 0 0 1 0 1 0 1 0 0 0 0 0 0 0 1
353 0 0 0 0 1 1 1 1 0 1 1 1 1 1 1 1
354 0 0 0 0 1 1 0 0 0 0 0 0 1 1 1 1
355 0 0 0 0 0 0 0 1 0 0 0 0 1 1 1 0
356 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
357 0 0 0 0 1 1 1 1 0 1 0 0 0 0 0 1
358 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
359 0 0 0 0 0 1 0 0 0 0 1 0 0 1 0 0
360 0 0 0 0 1 1 0 1 0 0 0 0 1 1 1 1
361 0 0 0 0 1 1 1 1 0 1 1 1 1 1 1 1
362 1 1 0 0 1 1 1 1 1 1 0 1 1 1 1 1
363 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
364 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
365 0 0 0 0 0 1 0 0 0 1 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 1 0 0 0 1 0 0 1 1 0
368 1 1 0 0 1 1 1 1 0 0 0 0 0 1 0 1
369 1 1 0 0 1 1 1 1 0 1 1 1 1 1 1 1
370 1 1 0 1 1 1 1 1 1 1 0 1 1 1 1 1
371 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
372 0 0 0 1 0 1 1 1 0 1 0 1 1 1 1 1
373 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1
374 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
375 0 1 0 0 0 1 1 0 0 0 0 0 1 0 0 1
376 0 1 0 0 1 1 1 1 0 1 0 1 1 1 1 1
377 0 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1
378 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1
379 0 0 0 0 1 0 1 0 1 0 0 0 1 0 0 0
380 1 0 1 0 0 1 1 1 0 1 1 1 1 1 1 1
381 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
382 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
383 0 0 0 0 1 1 1 1 0 0 0 0 0 1 0 0
384 1 1 0 1 1 1 1 1 0 1 1 1 1 1 1 1
385 0 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1
386 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1
387 0 0 0 0 1 1 1 0 1 1 1 0 0 1 1 0
388 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1
389 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
390 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
391 0 0 0 0 1 1 1 1 1 1 1 0 1 1 0 0
392 1 0 0 0 1 1 1 1 0 1 0 0 1 1 1 1
393 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
394 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1
395 0 0 0 0 1 1 1 1 1 1 0 0 1 1 1 1
396 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1
397 0 1 1 0 1 1 1 1 0 1 1 1 1 1 1 1
398 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
399 0 0 0 0 0 0 1 1 0 0 0 0 1 1 0 0
400 1 0 0 1 1 1 0 1 0 0 0 0 1 1 1 1
401 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
402 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1)
404 (0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
405 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
406 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0
407 1 1 1 1 0 0 1 1 0 1 0 1 1 1 1 1
408 1 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0
409 0 0 0 1 0 1 1 1 1 0 0 1 1 1 1 1
410 0 0 0 0 0 1 0 0 0 0 1 0 0 0 1 1
411 0 0 0 0 0 1 0 1 1 1 1 1 1 1 1 1
412 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
413 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0
414 0 0 0 0 0 0 1 1 0 0 0 0 0 0 1 1
415 0 0 1 1 0 0 1 1 1 1 0 1 0 1 1 1
416 0 0 0 0 0 1 0 1 0 0 0 0 0 0 1 1
417 0 1 0 1 1 1 1 1 0 0 1 1 1 1 1 1
418 0 0 0 1 0 1 1 1 0 0 1 1 0 0 1 1
419 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
420 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0
421 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0
422 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0
423 0 0 0 1 0 0 0 1 0 1 0 1 0 1 1 1
424 0 0 0 0 0 1 0 1 0 0 1 0 0 1 0 1
425 0 0 0 0 0 1 0 1 0 0 0 0 0 0 1 1
426 0 0 1 1 0 1 0 1 1 0 1 1 1 1 1 1
427 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1
428 0 0 0 0 0 1 1 1 0 1 1 0 1 1 1 1
429 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0
430 0 0 0 1 0 1 1 1 0 0 0 0 0 1 1 0
431 1 1 1 1 1 0 1 0 1 1 1 0 1 0 0 0
432 0 0 0 0 0 0 0 1 0 0 0 0 0 1 1 1
433 0 0 0 1 1 1 1 1 1 0 0 1 1 1 1 1
434 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1
435 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1)
437 (0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0
438 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1
439 0 1 0 0 0 0 1 1 0 0 1 0 1 1 1 0
440 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1)
442 (0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1
443 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1
444 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 1
445 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 1
446 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1
447 0 0 0 0 0 0 0 0 0 1 0 0 1 1 1 0
448 1 1 1 0 0 1 0 0 0 0 0 0 1 1 0 1
449 0 0 0 1 0 0 0 0 0 0 0 0 1 1 1 1
450 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1
451 0 1 0 0 0 1 0 0 0 1 0 0 1 1 1 1
452 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0
453 0 0 0 0 1 1 1 1 0 0 0 0 1 1 1 1
454 1 0 1 0 1 1 1 0 1 0 1 0 1 1 1 1
455 0 1 0 0 0 1 0 1 0 1 1 1 1 1 1 1
456 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1
457 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1
458 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1
459 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 1
460 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
461 0 0 0 1 1 1 0 0 1 1 0 1 1 1 0 1
462 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 1
463 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1
464 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0
465 0 0 0 0 0 0 0 0 1 1 1 1 1 1 0 1
466 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1
467 0 1 0 0 1 1 1 1 0 1 0 1 1 1 1 1
468 0 0 1 1 1 1 0 1 1 1 1 1 1 1 1 1
469 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
470 0 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1
471 0 0 0 1 1 1 0 0 1 1 1 1 1 1 1 1
472 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1
473 1 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1
474 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 1
475 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
476 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 1
477 0 0 0 0 0 0 0 1 0 0 0 0 0 1 1 1
478 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
479 0 0 0 0 0 0 1 0 0 0 0 1 1 1 1 1
480 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 1
481 0 0 0 0 0 1 0 1 0 1 1 1 1 1 1 1
482 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1
483 0 1 0 0 0 0 0 1 0 1 0 1 0 1 1 1
484 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1
485 0 0 0 0 0 1 0 1 0 1 1 1 0 1 1 1
486 0 0 0 0 1 1 0 1 0 1 0 1 1 1 1 1
487 0 1 0 0 1 1 0 1 1 1 1 1 1 1 1 1
488 0 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1
489 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1
490 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
491 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 1
492 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1
493 0 0 0 0 0 1 0 1 0 1 1 1 1 1 0 1
494 0 0 0 1 0 0 0 0 0 0 0 1 0 1 0 1
495 0 0 1 0 1 1 1 1 1 1 1 1 1 1 1 1
496 0 1 0 0 0 0 0 0 0 1 0 1 0 0 0 0
497 0 0 0 0 1 1 0 1 1 1 1 1 1 1 0 1
498 0 0 0 0 0 1 0 0 0 0 0 0 1 1 1 1
499 0 0 0 0 0 1 1 1 0 0 0 1 1 1 1 1
500 0 0 0 0 0 1 1 1 0 1 1 1 1 1 1 1
501 0 0 0 0 1 1 1 1 1 0 1 1 1 1 1 1
502 0 0 0 0 1 1 0 1 0 1 1 1 1 1 1 1
503 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1
504 0 1 0 0 1 1 0 1 0 1 1 1 1 1 0 1
505 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1))
507 (0 0 1 1 0 1 1 1 0 1 1 1 0 0 1 1
508 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 1
509 0 1 0 1 0 1 1 1 0 1 1 1 1 1 1 1
510 1 1 1 1 0 1 0 1 1 1 1 1 1 0 1 1
511 0 1 1 1 0 0 0 0 0 0 1 1 0 0 1 1
512 1 1 1 1 0 0 0 0 1 1 1 1 1 0 0 1
513 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
514 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1)
516 (0 0 0 0 0 0 0 1 0 0 0 1 0 0 1 1
517 0 0 0 0 0 0 1 1 0 1 1 1 1 1 1 1)
521 (0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1
522 0 0 0 0 0 0 0 1 0 0 0 1 1 1 1 1
523 0 0 0 0 0 0 1 1 0 0 0 1 1 1 1 1
524 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1))
533 "Static prediction table for X-Face image compression algorithm.")
535 ;; Macros for inlining critical values.
536 (defmacro uncompface-width
() (list 'quote uncompface-width
))
537 (defmacro uncompface-height
() (list 'quote uncompface-height
))
538 (defmacro uncompface-guesses
() (list 'quote uncompface-guesses
))
540 (defmacro uncompface-loop
(&rest body
)
541 "Eval BODY and repeat if last expression of BODY yields non-nil."
542 (list 'while
(cons 'progn body
))))
544 ;; (defun uncompface-print-bignum (bignum &optional prefix)
545 ;; (princ (format (concat prefix "<%s>\n")
546 ;; (mapconcat (lambda (x) (format "%02x" x))
547 ;; (reverse bignum) " "))))
549 ;; Shut up the byte-compiler.
550 ;; These variables are once bound in `uncompface' and all subfunctions
551 ;; accesses them directly rather than creating their own bindings.
556 ;; Big-number facilities.
557 ;; These functions were used to be implemented with `lsh' and `logand',
558 ;; but rewritten to use `/' and `%'. The last two are mapped into
559 ;; byte-code directly, but the formers are normal functions even in
560 ;; compiled code which involve expensive `funcall' operations.
562 (defsubst uncompface-big-mul-add
(multiplier adder
)
563 "Multiply BIGNUM by MULTIPLIER and add ADDER and put result in `bignum'."
564 (setq bignum
(if (= multiplier
0)
568 (setcar bignum
(%
(setq adder
(+ (* (car bignum
)
572 (setq adder
(/ adder
256))
574 (setq bignum
(cdr bignum
)))
576 (setcdr bignum
(list adder
))))))))
578 ;; This trick is for XEmacs 21.4 which doesn't allow inlining a function
579 ;; using `defsubst' into another function also defined with `defsubst'.
581 (when (featurep 'xemacs
)
582 (defvar uncompface-big-mul-add
(symbol-function 'uncompface-big-mul-add
))
583 (defmacro uncompface-big-mul-add
(multiplier adder
)
584 `(,uncompface-big-mul-add
,multiplier
,adder
))))
586 ;; Separate `eval-when-compile' for the byte compiler
587 ;; to properly define `uncompface-big-mul-add' before `uncompface-big-pop'.
589 (defsubst uncompface-big-pop
(prob)
590 (let ((n (car bignum
)) (i 0))
592 (setq bignum
(cdr bignum
))
594 (while (or (< n
(cdr (car prob
)))
595 (>= n
(+ (cdr (car prob
)) (car (car prob
)))))
596 (setq prob
(cdr prob
)
598 (uncompface-big-mul-add (car (car prob
)) (- n
(cdr (car prob
))))
601 ;; This function cannot be inlined due to recursive calls.
602 (defun uncompface-pop-grays (offset size
)
604 (let ((bits (uncompface-big-pop
605 ;; This is freqs[16] in compface_private.h.
606 '(( 0 .
0) (38 .
0) (38 .
38) (13 .
152)
607 (38 .
76) (13 .
165) (13 .
178) ( 6 .
230)
608 (38 .
114) (13 .
191) (13 .
204) ( 6 .
236)
609 (13 .
217) ( 6 .
242) ( 5 .
248) ( 3 .
253)))))
610 ;; (if (/= (logand bits 1) 0)
611 ;; (aset face offset t))
612 ;; (if (/= (logand bits 2) 0)
613 ;; (aset face (1+ offset) t))
614 ;; (if (/= (logand bits 4) 0)
615 ;; (aset face (+ offset (uncompface-width)) t))
616 ;; (if (/= (logand bits 8) 0)
617 ;; (aset face (+ offset (uncompface-width) 1) t))
619 (aset face
(+ offset
(uncompface-width) 1) t
)
620 (setq bits
(- bits
8)))
622 (aset face
(+ offset
(uncompface-width)) t
)
623 (setq bits
(- bits
4)))
624 (or (eq (if (< bits
2)
626 (aset face
(1+ offset
) t
)
629 (aset face offset t
))
631 (setq size
(/ size
2))
632 (uncompface-pop-grays offset size
)
633 (uncompface-pop-grays (+ offset size
) size
)
634 (uncompface-pop-grays (+ offset
(* (uncompface-width) size
)) size
)
635 (uncompface-pop-grays (+ offset
(* (uncompface-width) size
) size
) size
)))
637 ;; Again, this function call itself recursively.
638 (defun uncompface-uncompress (offset size level
)
639 ;; This used to be (funcall (aref [(lambda ...) ...] (u-big-pop ...)))
640 ;; but this was slow due to function call.
641 (let ((i (uncompface-big-pop (car level
))))
642 (cond ((eq i
0) ; black
643 (uncompface-pop-grays offset size
))
645 (setq size
(/ size
2)
647 (uncompface-uncompress offset size level
)
648 (uncompface-uncompress (+ offset size
) size level
)
649 (uncompface-uncompress (+ offset
(* size
(uncompface-width)))
651 (uncompface-uncompress (+ offset
(* size
(uncompface-width)) size
)
654 ;; (t (error "Cannot happen"))
658 (defmacro uncompface-shift-in
(k dy dx
)
659 `(+ k k
(if (aref face
(+ i
(* ,dy
(uncompface-width)) ,dx
)) 1 0))))
661 (defun uncompface-internal (string &optional raw
)
662 "Decode X-Face data STRING and return an image in the pbm format.
663 If the optional RAW is non-nil, return a raw bitmap as a vector."
664 (let (;; `bignum' and `face' are semi-global variables.
665 ;; Do not use '(0) below, because BIGNUM is modified in-place.
667 (face (make-vector (* (uncompface-width) (uncompface-height)) nil
))
668 ;;(uncompface-big-shift -16)
669 ;;(uncompface-big-mask 65535)
672 (and (>= c ?
!) (<= c ?~
)
673 (uncompface-big-mul-add (1+ (- ?~ ?
!)) (- c ?
!))))
675 ;;(uncompface-print-bignum bignum)
680 (uncompface-uncompress (+ (* (uncompface-width) y
) x
) 16
681 ;; This is levels[4][3] in compface_private.h.
682 '(;; Top of tree almost always grey
683 (( 1 .
255) (251 .
0) ( 4 .
251))
684 (( 1 .
255) (200 .
0) ( 55 .
200))
685 (( 33 .
223) (159 .
0) ( 64 .
159))
686 ;; Grey disallowed at bottom
687 ((131 .
0) ( 0 .
0) (125 .
131))))
688 (< (setq x
(+ x
16)) (uncompface-width)))
689 (< (setq y
(+ y
16)) (uncompface-height)))
691 (let ((i 0) guesses k
)
693 (setq guesses
(cond ((= y
1) (nth 2 (uncompface-guesses)))
694 ((= y
2) (nth 1 (uncompface-guesses)))
695 (t (nth 0 (uncompface-guesses))))
705 (setq k
(uncompface-shift-in k -
2 -
2)))
706 (setq k
(uncompface-shift-in k -
1 -
2)))
707 (setq k
(uncompface-shift-in k
0 -
2))))
711 (setq k
(uncompface-shift-in k -
2 -
1)))
712 (setq k
(uncompface-shift-in k -
1 -
1)))
713 (setq k
(uncompface-shift-in k
0 -
1))))
716 (setq k
(uncompface-shift-in k -
2 0)))
717 (setq k
(uncompface-shift-in k -
1 0)))
720 (setq k
(uncompface-shift-in k -
2 1)))
721 (setq k
(uncompface-shift-in k -
1 1)))
722 (when (<= x
(- (uncompface-width) 2))
725 (setq k
(uncompface-shift-in k -
2 2)))
726 (setq k
(uncompface-shift-in k -
1 2)))))
727 (if (aref (car (cond ((= x
1)
731 ((= x
(1- (uncompface-width)))
732 (cdr (cdr (cdr guesses
))))
735 (aset face i
(not (aref face i
))))
737 (< (setq x
(1+ x
)) (uncompface-width)))
738 (< (setq y
(1+ y
)) (uncompface-height))))
741 (concat (eval-when-compile
742 (format "P1\n%d %d\n" uncompface-width uncompface-height
))
743 (mapconcat (lambda (bit) (if bit
"1" "0")) face
" ")
749 ;; eval: (put 'uncompface-loop 'lisp-indent-hook 0)
752 ;;; compface.el ends here