PageRenderTime 64ms CodeModel.GetById 17ms app.highlight 43ms RepoModel.GetById 1ms app.codeStats 0ms

/src/image/fax/read.go

https://code.google.com/
Go | 469 lines | 390 code | 43 blank | 36 comment | 69 complexity | 53583a61e17ca24544931dde985ca2ed MD5 | raw file
  1// Copyright 2011 The Go Authors. All rights reserved.
  2// Use of this source code is governed by a BSD-style
  3// license that can be found in the LICENSE file.
  4
  5// Package fax supports CCITT Group 4 image decompression
  6// as described by ITU-T Recommendation T.6.
  7// See http://www.itu.int/rec/T-REC-T.6-198811-I
  8package fax
  9
 10import (
 11	"errors"
 12	"image"
 13	"io"
 14)
 15
 16const (
 17	white = 0xFF
 18	black = 0x00
 19)
 20
 21var negativeWidth = errors.New("fax: negative width specified")
 22
 23// DecodeG4 parses a Group 4 fax image from reader.
 24// The width will be applied as specified and the
 25// (estimated) height helps memory allocation.
 26func DecodeG4(reader io.ByteReader, width, height int) (image.Image, error) {
 27	if width < 0 {
 28		return nil, negativeWidth
 29	}
 30	if width == 0 {
 31		return new(image.Gray), nil
 32	}
 33	if height <= 0 {
 34		height = width
 35	}
 36	// include imaginary first line
 37	height++
 38	pixels := make([]byte, width, width*height)
 39	for i := width - 1; i >= 0; i-- {
 40		pixels[i] = white
 41	}
 42
 43	d := &decoder{
 44		reader:    reader,
 45		pixels:    pixels,
 46		width:     width,
 47		atNewLine: true,
 48		color:     white,
 49	}
 50
 51	// initiate d.head
 52	if err := d.pop(0); err != nil {
 53		return nil, err
 54	}
 55
 56	return d.parse()
 57}
 58
 59type decoder struct {
 60	// reader is the data source
 61	reader io.ByteReader
 62
 63	// head contains the current data in the stream.
 64	// The first upcoming bit is packed in the 32nd bit, the
 65	// second upcoming bit in the 31st, etc.
 66	head uint
 67
 68	// bitCount is the number of bits loaded in head.
 69	bitCount uint
 70
 71	// pixels are black and white values.
 72	pixels []byte
 73
 74	// width is the line length in pixels.
 75	width int
 76
 77	// atNewLine is whether a0 is before the beginning of a line.
 78	atNewLine bool
 79
 80	// color represents the state of a0.
 81	color byte
 82}
 83
 84// pop advances n bits in the stream.
 85// The 24-bit end-of-facsimile block exceeds all
 86// Huffman codes in length.
 87func (d *decoder) pop(n uint) error {
 88	head := d.head
 89	count := d.bitCount
 90	head <<= n
 91	count -= n
 92	for count < 24 {
 93		next, err := d.reader.ReadByte()
 94		if err != nil {
 95			return err
 96		}
 97		head |= uint(next) << (24 - count)
 98		count += 8
 99	}
100	d.head = head
101	d.bitCount = count
102	return nil
103}
104
105// paint adds n d.pixels in the specified color.
106func (d *decoder) paint(n int, color byte) {
107	a := d.pixels
108	for ; n != 0; n-- {
109		a = append(a, color)
110	}
111	d.pixels = a
112}
113
114func (d *decoder) parse() (result image.Image, err error) {
115	// parse until end-of-facsimile block: 0x001001
116	for d.head&0xFE000000 != 0 && err == nil {
117		i := (d.head >> 28) & 0xF
118		err = modeTable[i](d)
119	}
120
121	width := d.width
122	pixels := d.pixels[width:] // strip imaginary line
123	bounds := image.Rect(0, 0, width, len(pixels)/width)
124	result = &image.Gray{pixels, width, bounds}
125	return
126}
127
128var modeTable = [16]func(d *decoder) error{
129	func(d *decoder) error {
130		i := (d.head >> 25) & 7
131		return modeTable2[i](d)
132	},
133	pass,
134	horizontal,
135	horizontal,
136	verticalLeft1,
137	verticalLeft1,
138	verticalRight1,
139	verticalRight1,
140	vertical0, vertical0, vertical0, vertical0,
141	vertical0, vertical0, vertical0, vertical0,
142}
143
144var modeTable2 = [8]func(d *decoder) error{
145	nil,
146	extension,
147	verticalLeft3,
148	verticalRight3,
149	verticalLeft2,
150	verticalLeft2,
151	verticalRight2,
152	verticalRight2,
153}
154
155func pass(d *decoder) error {
156	if e := d.pop(4); e != nil {
157		return e
158	}
159
160	color := d.color
161	width := d.width
162	pixels := d.pixels
163	a := len(pixels)
164	lineStart := (a / width) * width
165	b := a - width // reference element
166	if !d.atNewLine {
167		for b != lineStart && pixels[b] != color {
168			b++
169		}
170	}
171	for b != lineStart && pixels[b] == color {
172		b++
173	}
174	// found b1
175	for b != lineStart && pixels[b] != color {
176		b++
177	}
178	// found b2
179
180	if b == lineStart {
181		d.atNewLine = true
182		d.color = white
183	} else {
184		d.atNewLine = false
185	}
186	d.paint(b-a+width, color)
187	return nil
188}
189
190func vertical0(d *decoder) error {
191	d.vertical(0)
192	return d.pop(1)
193}
194
195func verticalLeft1(d *decoder) error {
196	d.vertical(-1)
197	return d.pop(3)
198}
199
200func verticalLeft2(d *decoder) error {
201	d.vertical(-2)
202	return d.pop(6)
203}
204
205func verticalLeft3(d *decoder) error {
206	d.vertical(-3)
207	return d.pop(7)
208}
209
210func verticalRight1(d *decoder) error {
211	d.vertical(1)
212	return d.pop(3)
213}
214
215func verticalRight2(d *decoder) error {
216	d.vertical(2)
217	return d.pop(6)
218}
219
220func verticalRight3(d *decoder) error {
221	d.vertical(3)
222	return d.pop(7)
223}
224
225func (d *decoder) vertical(offset int) {
226	color := d.color
227	width := d.width
228	pixels := d.pixels
229	a := len(pixels)
230	lineStart := (a / width) * width
231	b := a - width // reference element
232	if !d.atNewLine {
233		for b != lineStart && pixels[b] != color {
234			b++
235		}
236	}
237	for b != lineStart && pixels[b] == color {
238		b++
239	}
240	// found b1
241
242	b += offset
243	if b >= lineStart {
244		b = lineStart
245		d.atNewLine = true
246		d.color = white
247	} else {
248		d.atNewLine = false
249		d.color = color ^ 0xFF
250	}
251	if count := b - a + width; count >= 0 {
252		d.paint(count, color)
253	}
254}
255
256func horizontal(d *decoder) (err error) {
257	if err = d.pop(3); err != nil {
258		return
259	}
260
261	color := d.color
262	flip := color ^ 0xFF
263	var rl1, rl2 int
264	if rl1, err = d.runLength(color); err == nil {
265		rl2, err = d.runLength(flip)
266	}
267
268	// pixels left in the line:
269	remaining := d.width - (len(d.pixels) % d.width)
270	if rl1 > remaining {
271		rl1 = remaining
272	}
273	d.paint(rl1, color)
274	remaining -= rl1
275	if rl2 >= remaining {
276		rl2 = remaining
277		d.atNewLine = true
278		d.color = white
279	} else {
280		d.atNewLine = false
281	}
282	d.paint(rl2, flip)
283	return
284}
285
286// runLength reads the amount of pixels for a color.
287func (d *decoder) runLength(color byte) (count int, err error) {
288	match := uint16(0xFFFF) // lookup entry
289	for match&0xFC0 != 0 && err == nil {
290		if color == black {
291			if d.head&0xF0000000 != 0 {
292				match = blackShortLookup[(d.head>>26)&0x3F]
293			} else if d.head&0xFE000000 != 0 {
294				match = blackLookup[(d.head>>19)&0x1FF]
295			} else {
296				match = sharedLookup[(d.head>>20)&0x1F]
297			}
298		} else {
299			if d.head&0xFE000000 != 0 {
300				match = whiteLookup[(d.head>>23)&0x1FF]
301			} else {
302				match = sharedLookup[(d.head>>20)&0x1F]
303			}
304		}
305
306		err = d.pop(uint(match) >> 12)
307		count += int(match) & 0x0FFF
308	}
309	return
310}
311
312// Lookup tables are used by runLength to find Huffman codes. Their index
313// size is large enough to fit the longest code in the group. Shorter codes
314// have duplicate entries with all possible tailing bits.
315// Entries consist of two parts. The 4 most significant bits contain the
316// Huffman code length in bits and the 12 least significant bits contain
317// the pixel count.
318
319var blackShortLookup = [64]uint16{
320	0x0, 0x0, 0x0, 0x0, 0x6009, 0x6008, 0x5007, 0x5007,
321	0x4006, 0x4006, 0x4006, 0x4006, 0x4005, 0x4005, 0x4005, 0x4005,
322	0x3001, 0x3001, 0x3001, 0x3001, 0x3001, 0x3001, 0x3001, 0x3001,
323	0x3004, 0x3004, 0x3004, 0x3004, 0x3004, 0x3004, 0x3004, 0x3004,
324	0x2003, 0x2003, 0x2003, 0x2003, 0x2003, 0x2003, 0x2003, 0x2003,
325	0x2003, 0x2003, 0x2003, 0x2003, 0x2003, 0x2003, 0x2003, 0x2003,
326	0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002,
327	0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002,
328}
329
330var blackLookup = [512]uint16{
331	0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
332	0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
333	0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
334	0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
335	0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
336	0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
337	0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
338	0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
339	0xa012, 0xa012, 0xa012, 0xa012, 0xa012, 0xa012, 0xa012, 0xa012,
340	0xc034, 0xc034, 0xd280, 0xd2c0, 0xd300, 0xd340, 0xc037, 0xc037,
341	0xc038, 0xc038, 0xd500, 0xd540, 0xd580, 0xd5c0, 0xc03b, 0xc03b,
342	0xc03c, 0xc03c, 0xd600, 0xd640, 0xb018, 0xb018, 0xb018, 0xb018,
343	0xb019, 0xb019, 0xb019, 0xb019, 0xd680, 0xd6c0, 0xc140, 0xc140,
344	0xc180, 0xc180, 0xc1c0, 0xc1c0, 0xd200, 0xd240, 0xc035, 0xc035,
345	0xc036, 0xc036, 0xd380, 0xd3c0, 0xd400, 0xd440, 0xd480, 0xd4c0,
346	0xa040, 0xa040, 0xa040, 0xa040, 0xa040, 0xa040, 0xa040, 0xa040,
347	0x800d, 0x800d, 0x800d, 0x800d, 0x800d, 0x800d, 0x800d, 0x800d,
348	0x800d, 0x800d, 0x800d, 0x800d, 0x800d, 0x800d, 0x800d, 0x800d,
349	0x800d, 0x800d, 0x800d, 0x800d, 0x800d, 0x800d, 0x800d, 0x800d,
350	0x800d, 0x800d, 0x800d, 0x800d, 0x800d, 0x800d, 0x800d, 0x800d,
351	0xb017, 0xb017, 0xb017, 0xb017, 0xc032, 0xc032, 0xc033, 0xc033,
352	0xc02c, 0xc02c, 0xc02d, 0xc02d, 0xc02e, 0xc02e, 0xc02f, 0xc02f,
353	0xc039, 0xc039, 0xc03a, 0xc03a, 0xc03d, 0xc03d, 0xc100, 0xc100,
354	0xa010, 0xa010, 0xa010, 0xa010, 0xa010, 0xa010, 0xa010, 0xa010,
355	0xa011, 0xa011, 0xa011, 0xa011, 0xa011, 0xa011, 0xa011, 0xa011,
356	0xc030, 0xc030, 0xc031, 0xc031, 0xc03e, 0xc03e, 0xc03f, 0xc03f,
357	0xc01e, 0xc01e, 0xc01f, 0xc01f, 0xc020, 0xc020, 0xc021, 0xc021,
358	0xc028, 0xc028, 0xc029, 0xc029, 0xb016, 0xb016, 0xb016, 0xb016,
359	0x800e, 0x800e, 0x800e, 0x800e, 0x800e, 0x800e, 0x800e, 0x800e,
360	0x800e, 0x800e, 0x800e, 0x800e, 0x800e, 0x800e, 0x800e, 0x800e,
361	0x800e, 0x800e, 0x800e, 0x800e, 0x800e, 0x800e, 0x800e, 0x800e,
362	0x800e, 0x800e, 0x800e, 0x800e, 0x800e, 0x800e, 0x800e, 0x800e,
363	0x700a, 0x700a, 0x700a, 0x700a, 0x700a, 0x700a, 0x700a, 0x700a,
364	0x700a, 0x700a, 0x700a, 0x700a, 0x700a, 0x700a, 0x700a, 0x700a,
365	0x700a, 0x700a, 0x700a, 0x700a, 0x700a, 0x700a, 0x700a, 0x700a,
366	0x700a, 0x700a, 0x700a, 0x700a, 0x700a, 0x700a, 0x700a, 0x700a,
367	0x700a, 0x700a, 0x700a, 0x700a, 0x700a, 0x700a, 0x700a, 0x700a,
368	0x700a, 0x700a, 0x700a, 0x700a, 0x700a, 0x700a, 0x700a, 0x700a,
369	0x700a, 0x700a, 0x700a, 0x700a, 0x700a, 0x700a, 0x700a, 0x700a,
370	0x700a, 0x700a, 0x700a, 0x700a, 0x700a, 0x700a, 0x700a, 0x700a,
371	0x700b, 0x700b, 0x700b, 0x700b, 0x700b, 0x700b, 0x700b, 0x700b,
372	0x700b, 0x700b, 0x700b, 0x700b, 0x700b, 0x700b, 0x700b, 0x700b,
373	0x700b, 0x700b, 0x700b, 0x700b, 0x700b, 0x700b, 0x700b, 0x700b,
374	0x700b, 0x700b, 0x700b, 0x700b, 0x700b, 0x700b, 0x700b, 0x700b,
375	0x700b, 0x700b, 0x700b, 0x700b, 0x700b, 0x700b, 0x700b, 0x700b,
376	0x700b, 0x700b, 0x700b, 0x700b, 0x700b, 0x700b, 0x700b, 0x700b,
377	0x700b, 0x700b, 0x700b, 0x700b, 0x700b, 0x700b, 0x700b, 0x700b,
378	0x700b, 0x700b, 0x700b, 0x700b, 0x700b, 0x700b, 0x700b, 0x700b,
379	0x900f, 0x900f, 0x900f, 0x900f, 0x900f, 0x900f, 0x900f, 0x900f,
380	0x900f, 0x900f, 0x900f, 0x900f, 0x900f, 0x900f, 0x900f, 0x900f,
381	0xc080, 0xc080, 0xc0c0, 0xc0c0, 0xc01a, 0xc01a, 0xc01b, 0xc01b,
382	0xc01c, 0xc01c, 0xc01d, 0xc01d, 0xb013, 0xb013, 0xb013, 0xb013,
383	0xb014, 0xb014, 0xb014, 0xb014, 0xc022, 0xc022, 0xc023, 0xc023,
384	0xc024, 0xc024, 0xc025, 0xc025, 0xc026, 0xc026, 0xc027, 0xc027,
385	0xb015, 0xb015, 0xb015, 0xb015, 0xc02a, 0xc02a, 0xc02b, 0xc02b,
386	0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000,
387	0x700c, 0x700c, 0x700c, 0x700c, 0x700c, 0x700c, 0x700c, 0x700c,
388	0x700c, 0x700c, 0x700c, 0x700c, 0x700c, 0x700c, 0x700c, 0x700c,
389	0x700c, 0x700c, 0x700c, 0x700c, 0x700c, 0x700c, 0x700c, 0x700c,
390	0x700c, 0x700c, 0x700c, 0x700c, 0x700c, 0x700c, 0x700c, 0x700c,
391	0x700c, 0x700c, 0x700c, 0x700c, 0x700c, 0x700c, 0x700c, 0x700c,
392	0x700c, 0x700c, 0x700c, 0x700c, 0x700c, 0x700c, 0x700c, 0x700c,
393	0x700c, 0x700c, 0x700c, 0x700c, 0x700c, 0x700c, 0x700c, 0x700c,
394	0x700c, 0x700c, 0x700c, 0x700c, 0x700c, 0x700c, 0x700c, 0x700c,
395}
396
397var whiteLookup = [512]uint16{
398	0x0, 0x0, 0x0, 0x0, 0x801d, 0x801d, 0x801e, 0x801e,
399	0x802d, 0x802d, 0x802e, 0x802e, 0x7016, 0x7016, 0x7016, 0x7016,
400	0x7017, 0x7017, 0x7017, 0x7017, 0x802f, 0x802f, 0x8030, 0x8030,
401	0x600d, 0x600d, 0x600d, 0x600d, 0x600d, 0x600d, 0x600d, 0x600d,
402	0x7014, 0x7014, 0x7014, 0x7014, 0x8021, 0x8021, 0x8022, 0x8022,
403	0x8023, 0x8023, 0x8024, 0x8024, 0x8025, 0x8025, 0x8026, 0x8026,
404	0x7013, 0x7013, 0x7013, 0x7013, 0x801f, 0x801f, 0x8020, 0x8020,
405	0x6001, 0x6001, 0x6001, 0x6001, 0x6001, 0x6001, 0x6001, 0x6001,
406	0x600c, 0x600c, 0x600c, 0x600c, 0x600c, 0x600c, 0x600c, 0x600c,
407	0x8035, 0x8035, 0x8036, 0x8036, 0x701a, 0x701a, 0x701a, 0x701a,
408	0x8027, 0x8027, 0x8028, 0x8028, 0x8029, 0x8029, 0x802a, 0x802a,
409	0x802b, 0x802b, 0x802c, 0x802c, 0x7015, 0x7015, 0x7015, 0x7015,
410	0x701c, 0x701c, 0x701c, 0x701c, 0x803d, 0x803d, 0x803e, 0x803e,
411	0x803f, 0x803f, 0x8000, 0x8000, 0x8140, 0x8140, 0x8180, 0x8180,
412	0x500a, 0x500a, 0x500a, 0x500a, 0x500a, 0x500a, 0x500a, 0x500a,
413	0x500a, 0x500a, 0x500a, 0x500a, 0x500a, 0x500a, 0x500a, 0x500a,
414	0x500b, 0x500b, 0x500b, 0x500b, 0x500b, 0x500b, 0x500b, 0x500b,
415	0x500b, 0x500b, 0x500b, 0x500b, 0x500b, 0x500b, 0x500b, 0x500b,
416	0x701b, 0x701b, 0x701b, 0x701b, 0x803b, 0x803b, 0x803c, 0x803c,
417	0x95c0, 0x9600, 0x9640, 0x96c0, 0x7012, 0x7012, 0x7012, 0x7012,
418	0x7018, 0x7018, 0x7018, 0x7018, 0x8031, 0x8031, 0x8032, 0x8032,
419	0x8033, 0x8033, 0x8034, 0x8034, 0x7019, 0x7019, 0x7019, 0x7019,
420	0x8037, 0x8037, 0x8038, 0x8038, 0x8039, 0x8039, 0x803a, 0x803a,
421	0x60c0, 0x60c0, 0x60c0, 0x60c0, 0x60c0, 0x60c0, 0x60c0, 0x60c0,
422	0x6680, 0x6680, 0x6680, 0x6680, 0x6680, 0x6680, 0x6680, 0x6680,
423	0x81c0, 0x81c0, 0x8200, 0x8200, 0x92c0, 0x9300, 0x8280, 0x8280,
424	0x8240, 0x8240, 0x9340, 0x9380, 0x93c0, 0x9400, 0x9440, 0x9480,
425	0x94c0, 0x9500, 0x9540, 0x9580, 0x7100, 0x7100, 0x7100, 0x7100,
426	0x4002, 0x4002, 0x4002, 0x4002, 0x4002, 0x4002, 0x4002, 0x4002,
427	0x4002, 0x4002, 0x4002, 0x4002, 0x4002, 0x4002, 0x4002, 0x4002,
428	0x4002, 0x4002, 0x4002, 0x4002, 0x4002, 0x4002, 0x4002, 0x4002,
429	0x4002, 0x4002, 0x4002, 0x4002, 0x4002, 0x4002, 0x4002, 0x4002,
430	0x4003, 0x4003, 0x4003, 0x4003, 0x4003, 0x4003, 0x4003, 0x4003,
431	0x4003, 0x4003, 0x4003, 0x4003, 0x4003, 0x4003, 0x4003, 0x4003,
432	0x4003, 0x4003, 0x4003, 0x4003, 0x4003, 0x4003, 0x4003, 0x4003,
433	0x4003, 0x4003, 0x4003, 0x4003, 0x4003, 0x4003, 0x4003, 0x4003,
434	0x5080, 0x5080, 0x5080, 0x5080, 0x5080, 0x5080, 0x5080, 0x5080,
435	0x5080, 0x5080, 0x5080, 0x5080, 0x5080, 0x5080, 0x5080, 0x5080,
436	0x5008, 0x5008, 0x5008, 0x5008, 0x5008, 0x5008, 0x5008, 0x5008,
437	0x5008, 0x5008, 0x5008, 0x5008, 0x5008, 0x5008, 0x5008, 0x5008,
438	0x5009, 0x5009, 0x5009, 0x5009, 0x5009, 0x5009, 0x5009, 0x5009,
439	0x5009, 0x5009, 0x5009, 0x5009, 0x5009, 0x5009, 0x5009, 0x5009,
440	0x6010, 0x6010, 0x6010, 0x6010, 0x6010, 0x6010, 0x6010, 0x6010,
441	0x6011, 0x6011, 0x6011, 0x6011, 0x6011, 0x6011, 0x6011, 0x6011,
442	0x4004, 0x4004, 0x4004, 0x4004, 0x4004, 0x4004, 0x4004, 0x4004,
443	0x4004, 0x4004, 0x4004, 0x4004, 0x4004, 0x4004, 0x4004, 0x4004,
444	0x4004, 0x4004, 0x4004, 0x4004, 0x4004, 0x4004, 0x4004, 0x4004,
445	0x4004, 0x4004, 0x4004, 0x4004, 0x4004, 0x4004, 0x4004, 0x4004,
446	0x4005, 0x4005, 0x4005, 0x4005, 0x4005, 0x4005, 0x4005, 0x4005,
447	0x4005, 0x4005, 0x4005, 0x4005, 0x4005, 0x4005, 0x4005, 0x4005,
448	0x4005, 0x4005, 0x4005, 0x4005, 0x4005, 0x4005, 0x4005, 0x4005,
449	0x4005, 0x4005, 0x4005, 0x4005, 0x4005, 0x4005, 0x4005, 0x4005,
450	0x600e, 0x600e, 0x600e, 0x600e, 0x600e, 0x600e, 0x600e, 0x600e,
451	0x600f, 0x600f, 0x600f, 0x600f, 0x600f, 0x600f, 0x600f, 0x600f,
452	0x5040, 0x5040, 0x5040, 0x5040, 0x5040, 0x5040, 0x5040, 0x5040,
453	0x5040, 0x5040, 0x5040, 0x5040, 0x5040, 0x5040, 0x5040, 0x5040,
454	0x4006, 0x4006, 0x4006, 0x4006, 0x4006, 0x4006, 0x4006, 0x4006,
455	0x4006, 0x4006, 0x4006, 0x4006, 0x4006, 0x4006, 0x4006, 0x4006,
456	0x4006, 0x4006, 0x4006, 0x4006, 0x4006, 0x4006, 0x4006, 0x4006,
457	0x4006, 0x4006, 0x4006, 0x4006, 0x4006, 0x4006, 0x4006, 0x4006,
458	0x4007, 0x4007, 0x4007, 0x4007, 0x4007, 0x4007, 0x4007, 0x4007,
459	0x4007, 0x4007, 0x4007, 0x4007, 0x4007, 0x4007, 0x4007, 0x4007,
460	0x4007, 0x4007, 0x4007, 0x4007, 0x4007, 0x4007, 0x4007, 0x4007,
461	0x4007, 0x4007, 0x4007, 0x4007, 0x4007, 0x4007, 0x4007, 0x4007,
462}
463
464var sharedLookup = [32]uint16{
465	0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
466	0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
467	0xb700, 0xb700, 0xc7c0, 0xc800, 0xc840, 0xc880, 0xc8c0, 0xc900,
468	0xb740, 0xb740, 0xb780, 0xb780, 0xc940, 0xc980, 0xc9c0, 0xca00,
469}