Refactor mml-smime.el, mml1991.el, mml2015.el
[gnus.git] / contrib / compface.el
blob09a4e7cfd6b0b66f20ebbb981ec25ab2240d5f7f
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>
6 ;; Keywords: news
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)
13 ;; any later version.
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/>.
23 ;;; Commentary:
25 ;;; Code:
27 (defgroup compface nil
28 "X-Face image conversion."
29 :group 'extensions)
31 (defcustom uncompface-use-external (and (not noninteractive)
32 (executable-find "uncompface")
33 (executable-find "icontopbm")
34 'undecided)
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))
46 :group 'compface)
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."
54 :type 'number
55 :group 'compface)
57 (eval-when-compile
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)
63 (cadr time)
64 (cond ((consp (setq time (cddr time)))
65 (/ (car time) 1000000.0))
66 (time
67 (/ time 1000000.0))
69 0)))))))
71 (defun uncompface (face)
72 "Convert FACE to pbm.
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)
80 (with-temp-buffer
81 (unless (featurep 'xemacs) (set-buffer-multibyte nil))
82 (insert face)
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)
88 "uncompface"
89 'delete '(t nil) nil))
90 (progn
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
96 ;; files.
97 (if (not (featurep 'xemacs))
98 (eq 0 (call-process-region (point-min) (point-max)
99 "icontopbm"
100 'delete '(t nil)))
101 (shell-command-on-region (point-min) (point-max)
102 "icontopbm | pnmnoraw"
103 (current-buffer) t)
105 (buffer-string)))))
107 (let* ((gc-cons-threshold (eval '(lsh -1 -1)))
108 (start (current-time)))
109 (prog1
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.
124 (eval-when-compile
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
135 (mapcar (lambda (x)
136 (mapcar (lambda (x)
137 (let ((vector (make-vector (length x) nil))
138 (i 0))
139 (while x
140 (or (zerop (car x))
141 (aset vector i t))
142 (setq x (cdr x)
143 i (1+ i)))
144 vector))
146 '((;; g_00
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)
403 ;; g_10
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)
436 ;; g_20
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)
441 ;; g_40
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))
506 (;; g_01
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)
515 ;; g_11
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)
518 ;; g_21
519 (0 0 0 1 0 1 1 1)
520 ;; g_41
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))
525 (;; g_02
526 (0 1 0 1)
527 ;; g_12
528 (0 1)
529 ;; g_22
531 ;; g_42
532 (0 0 0 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.
552 (eval-when-compile
553 (defvar bignum)
554 (defvar face))
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.
561 (eval-when-compile
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)
565 (cons 0 bignum)
566 (prog1 bignum
567 (while (progn
568 (setcar bignum (% (setq adder (+ (* (car bignum)
569 multiplier)
570 adder))
571 256))
572 (setq adder (/ adder 256))
573 (cdr bignum))
574 (setq bignum (cdr bignum)))
575 (or (= adder 0)
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'.
580 (eval-when-compile
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'.
588 (eval-when-compile
589 (defsubst uncompface-big-pop (prob)
590 (let ((n (car bignum)) (i 0))
591 (if (cdr bignum)
592 (setq bignum (cdr bignum))
593 (setcar bignum 0))
594 (while (or (< n (cdr (car prob)))
595 (>= n (+ (cdr (car prob)) (car (car prob)))))
596 (setq prob (cdr prob)
597 i (1+ i)))
598 (uncompface-big-mul-add (car (car prob)) (- n (cdr (car prob))))
599 i)))
601 ;; This function cannot be inlined due to recursive calls.
602 (defun uncompface-pop-grays (offset size)
603 (if (<= size 3)
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))
618 (when (>= bits 8)
619 (aset face (+ offset (uncompface-width) 1) t)
620 (setq bits (- bits 8)))
621 (when (>= bits 4)
622 (aset face (+ offset (uncompface-width)) t)
623 (setq bits (- bits 4)))
624 (or (eq (if (< bits 2)
625 bits
626 (aset face (1+ offset) t)
627 (- bits 2))
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))
644 ((eq i 1) ; gray
645 (setq size (/ size 2)
646 level (cdr level))
647 (uncompface-uncompress offset size level)
648 (uncompface-uncompress (+ offset size) size level)
649 (uncompface-uncompress (+ offset (* size (uncompface-width)))
650 size level)
651 (uncompface-uncompress (+ offset (* size (uncompface-width)) size)
652 size level))
653 ;; ((eq i 2) nil)
654 ;; (t (error "Cannot happen"))
657 (eval-when-compile
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.
666 (bignum (list 0))
667 (face (make-vector (* (uncompface-width) (uncompface-height)) nil))
668 ;;(uncompface-big-shift -16)
669 ;;(uncompface-big-mask 65535)
670 (y 0) x)
671 (mapc (lambda (c)
672 (and (>= c ?!) (<= c ?~)
673 (uncompface-big-mul-add (1+ (- ?~ ?!)) (- c ?!))))
674 string)
675 ;;(uncompface-print-bignum bignum)
676 ;;(setq y 0)
677 (uncompface-loop
678 (setq x 0)
679 (uncompface-loop
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)))
690 (setq y 0)
691 (let ((i 0) guesses k)
692 (uncompface-loop
693 (setq guesses (cond ((= y 1) (nth 2 (uncompface-guesses)))
694 ((= y 2) (nth 1 (uncompface-guesses)))
695 (t (nth 0 (uncompface-guesses))))
696 x 0)
697 (uncompface-loop
698 (setq k 0)
699 (when (>= x 1)
700 (when (>= x 2)
701 (when (>= x 3)
702 (when (>= y 1)
703 (when (>= y 2)
704 (when (>= y 3)
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))))
708 (when (>= y 1)
709 (when (>= y 2)
710 (when (>= y 3)
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))))
714 (when (>= y 2)
715 (when (>= y 3)
716 (setq k (uncompface-shift-in k -2 0)))
717 (setq k (uncompface-shift-in k -1 0)))
718 (when (>= y 2)
719 (when (>= y 3)
720 (setq k (uncompface-shift-in k -2 1)))
721 (setq k (uncompface-shift-in k -1 1)))
722 (when (<= x (- (uncompface-width) 2))
723 (when (>= y 2)
724 (when (>= y 3)
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)
728 (cdr (cdr guesses)))
729 ((= x 2)
730 (cdr guesses))
731 ((= x (1- (uncompface-width)))
732 (cdr (cdr (cdr guesses))))
734 guesses))) k)
735 (aset face i (not (aref face i))))
736 (setq i (1+ i))
737 (< (setq x (1+ x)) (uncompface-width)))
738 (< (setq y (1+ y)) (uncompface-height))))
739 (if raw
740 face
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 " ")
744 "\n"))))
746 (provide 'compface)
748 ;; Local variables:
749 ;; eval: (put 'uncompface-loop 'lisp-indent-hook 0)
750 ;; End:
752 ;;; compface.el ends here