// Thumb returns a PNG thumbnail for the given page of the given document.
// The thumbnail shows at most the top three inches of the document, at the given dots-per-inch.
// It requires Ghostscript to be installed in the executable search path as 'gs'.
764002
func (db *DB) Thumb(doc *Doc, page, dpi int) ([]byte, error) {
	if page < 1 || page > doc.Pages {
		return nil, fmt.Errorf("page %d not in range [%d, %d]", page, 1, doc.Pages)
	}

	now := time.Now().UTC()

	b := thumb{ID: doc.ID, Page: page, DPI: dpi, Used: now}
	if err := db.store.Read(db.meta, &b, "PNG"); err == nil {
		db.store.Write(db.meta, &b, "Used")
		return b.PNG, nil
	}

	file := filepath.Join(filepath.Dir(db.file), doc.File)
	if _, err := os.Stat(file); err != nil {
		return nil, err
	}

	pg := strconv.Itoa(page)

	cmd := exec.Command("gs", "-sDEVICE=bbox", "-dQUIET", "-dBATCH", "-dNOPAUSE", "-dSAFER", file)
	data, err := cmd.CombinedOutput()
	f := strings.Fields(string(data))
	if len(f) == 0 || f[0] != "%%BoundingBox:" {
		return nil, fmt.Errorf("invoking gs: %v\n%s", err, data)
	}
	x1, _ := strconv.Atoi(f[1])
	y1, _ := strconv.Atoi(f[2])
	x2, _ := strconv.Atoi(f[3])
	y2, _ := strconv.Atoi(f[4])

	show := 3
	dy := show * 72
	if dy > y2-y1 {
		dy = y2 - y1
	}

	_ = x1
	_ = x2

	gflag := fmt.Sprintf("-g%dx%d", dpi*17/2, dpi*dy/72)
	cflag := fmt.Sprintf("<</Install {0 %d translate}>> setpagedevice", -(y2 - dy))

	cmd = exec.Command("gs", "-sDEVICE=png16m", "-dFirstPage="+pg, "-dLastPage="+pg, "-sOutputFile=-", "-r"+strconv.Itoa(dpi), "-dQUIET", "-dBATCH", "-dNOPAUSE", "-dSAFER", "-dGraphicsAlphaBits=4", "-dTextAlphaBits=4", "-dUseTrimBox", gflag, "-c", cflag, "-f", file)
	cmd.Stderr = os.Stderr
	data, err = cmd.Output()
	if len(data) == 0 && err != nil {
		return nil, fmt.Errorf("invoking gs: %v", err)
	}

	if !bytes.HasPrefix(data, pngHeader) {
		return nil, fmt.Errorf("gs: [%v]\n%s", err, data)
	}

	b.PNG = data
	db.store.Insert(db.meta, &b)
	return b.PNG, nil
}
550785
func (c *Cursor) search(key []byte, pgid pgid) {
	p, n := c.bucket.pageNode(pgid)
	if p != nil && (p.flags&(branchPageFlag|leafPageFlag)) == 0 {
		panic(fmt.Sprintf("invalid page type: %d: %x", p.id, p.flags))
	}
	e := elemRef{page: p, node: n}
	c.stack = append(c.stack, e)

	// If we're on a leaf page/node then find the specific node.
	if e.isLeaf() {
		c.nsearch(key)
		return
	}

	if n != nil {
		c.searchNode(key, n)
		return
	}
	c.searchPage(key, p)
}
328538
func ImportPGPFingerprintSlice(fp []byte) (ret *PGPFingerprint) {
	if fp == nil {
		return nil
	}
	if len(fp) != PGPFingerprintLen {
		return nil
	}

	var tmp PGPFingerprint
	copy(tmp[:], fp)
	return &tmp
}
54112
func (g *Gui) Rune(x, y int) (rune, error) {
	if x < 0 || y < 0 || x >= g.maxX || y >= g.maxY {
		return ' ', errors.New("invalid point")
	}
	c := termbox.CellBuffer()[y*g.maxX+x]
	return c.Ch, nil
}
451862
func (im *Image) WritePng(w io.Writer) error {
	return png.Encode(w, im)
}
1011457
func (f *Fpdf) parsejpg(r io.Reader) (info *ImageInfoType) {
	info = f.newImageInfo()
	var (
		data bytes.Buffer
		err  error
	)
	_, err = data.ReadFrom(r)
	if err != nil {
		f.err = err
		return
	}
	info.data = data.Bytes()

	config, err := jpeg.DecodeConfig(bytes.NewReader(info.data))
	if err != nil {
		f.err = err
		return
	}
	info.w = float64(config.Width)
	info.h = float64(config.Height)
	info.f = "DCTDecode"
	info.bpc = 8
	switch config.ColorModel {
	case color.GrayModel:
		info.cs = "DeviceGray"
	case color.YCbCrModel:
		info.cs = "DeviceRGB"
	case color.CMYKModel:
		info.cs = "DeviceCMYK"
	default:
		f.err = fmt.Errorf("image JPEG buffer has unsupported color space (%v)", config.ColorModel)
		return
	}
	return
}
704332
func (m *meta) write(p *page) {
	if m.root.root >= m.pgid {
		panic(fmt.Sprintf("root bucket pgid (%d) above high water mark (%d)", m.root.root, m.pgid))
	} else if m.freelist >= m.pgid {
		panic(fmt.Sprintf("freelist pgid (%d) above high water mark (%d)", m.freelist, m.pgid))
	}

	// Page id is either going to be 0 or 1 which we can determine by the transaction ID.
	p.id = pgid(m.txid % 2)
	p.flags |= metaPageFlag

	// Calculate the checksum.
	m.checksum = m.sum64()

	m.copy(p.meta())
}
1109732
func (c *Container) bitmapSetRange(bitmap []uint64, i, j uint64) {
	x := i >> 6
	y := (j - 1) >> 6
	var X uint64 = maxBitmap << (i % 64)
	var Y uint64 = maxBitmap >> (63 - ((j - 1) % 64))
	xcnt := popcount(X)
	ycnt := popcount(Y)
	if x == y {
		c.n += int32((j - i) - popcount(bitmap[x]&(X&Y)))
		bitmap[x] |= (X & Y)
	} else {
		c.n += int32(xcnt - popcount(bitmap[x]&X))
		bitmap[x] |= X
		for i := x + 1; i < y; i++ {
			c.n += int32(64 - popcount(bitmap[i]))
			bitmap[i] = maxBitmap
		}
		c.n += int32(ycnt - popcount(bitmap[y]&Y))
		bitmap[y] |= Y
	}
}
1230328
func (d *Document) DisplayCursorPosition() int {
	var position int
	runes := []rune(d.Text)[:d.cursorPosition]
	for i := range runes {
		position += runewidth.RuneWidth(runes[i])
	}
	return position
}
755513
func (dm *DocumentMapping) closestDocMapping(path string) *DocumentMapping {
	pathElements := decodePath(path)
	current := dm
OUTER:
	for _, pathElement := range pathElements {
		for name, subDocMapping := range current.Properties {
			if name == pathElement {
				current = subDocMapping
				continue OUTER
			}
		}
		break
	}
	return current
}
122631
func (s *SubsetFontObj) GlyphIndexToPdfWidth(glyphIndex uint) uint {

	numberOfHMetrics := s.ttfp.NumberOfHMetrics()
	unitsPerEm := s.ttfp.UnitsPerEm()
	if glyphIndex >= numberOfHMetrics {
		glyphIndex = numberOfHMetrics - 1
	}

	width := s.ttfp.Widths()[glyphIndex]
	if unitsPerEm == 1000 {
		return width
	}
	return width * 1000 / unitsPerEm
}
1059738
func (bitmap *bitmap) Bit(index int) int {
	if index >= bitmap.Size {
		panic("index out of range")
	}

	div, mod := index>>3, index&0x07
	return int((uint(bitmap.data[div]) & (1 << uint(7-mod))) >> uint(7-mod))
}
975274
func (s *DocumentVersionMetadata) SetThumbnail(v map[string]*string) *DocumentVersionMetadata {
	s.Thumbnail = v
	return s
}
364497
func (p *page) leafPageElement(index uint16) *leafPageElement {
	n := &((*[0x7FFFFFF]leafPageElement)(unsafe.Pointer(&p.ptr)))[index]
	return n
}
432042
func (s *Certificate) SetThumbprint(v string) *Certificate {
	s.Thumbprint = &v
	return s
}
1013216
func (s *FileSet) File(p Pos) (f *File) {
	if p != NoPos {
		s.mutex.RLock()
		f = s.file(p)
		s.mutex.RUnlock()
	}
	return
}
302625
func DeserializeFingerprint(fpSum []byte) (resource.Fingerprint, error) {
	var fp resource.Fingerprint
	if len(fpSum) != 0 {
		var err error
		fp, err = resource.NewFingerprint(fpSum)
		if err != nil {
			return fp, errors.Trace(err)
		}
	}
	return fp, nil
}