openidec

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

xpm.go (2193B)


      1 package main
      2 
      3 import (
      4 	"fmt"
      5 	"image"
      6 	"image/color"
      7 	"strings"
      8 )
      9 
     10 func ParseXpm(lines []string) (*image.RGBA, int) {
     11 	nr := 0
     12 	var img *image.RGBA
     13 	start := false
     14 	cformat := false
     15 	last := false
     16 	pal := make(map[string]color.RGBA)
     17 	var w, h, cols, cpp, y int
     18 	for _, l := range lines {
     19 		nr++
     20 		if !start && !strings.HasPrefix(l, "/* XPM */") && !strings.HasPrefix(l, "! XPM2") {
     21 			continue
     22 		}
     23 		if !start {
     24 			start = true
     25 			continue
     26 		}
     27 		if strings.Contains(l, "static char ") {
     28 			cformat = true
     29 			continue
     30 		}
     31 		if cformat {
     32 			if strings.HasPrefix(l, "/*") || strings.HasPrefix(l, "//") {
     33 				continue
     34 			}
     35 			if strings.HasSuffix(l, "};") {
     36 				last = true
     37 				l = strings.TrimRight(l, "};")
     38 			}
     39 			l = strings.TrimRight(l, ",")
     40 			l = strings.Trim(l, "\"")
     41 		}
     42 		l = strings.Replace(l, "\t", " ", -1)
     43 		if cols == 0 { /* desc line */
     44 			dsc := strings.Split(l, " ")
     45 			if len(dsc) != 4 {
     46 				return nil, 0
     47 			}
     48 			if len, _ := fmt.Sscanf(dsc[0], "%d", &w); len != 1 {
     49 				return nil, 0
     50 			}
     51 			if len, _ := fmt.Sscanf(dsc[1], "%d", &h); len != 1 {
     52 				return nil, 0
     53 			}
     54 			if len, _ := fmt.Sscanf(dsc[2], "%d", &cols); len != 1 {
     55 				return nil, 0
     56 			}
     57 			if len, _ := fmt.Sscanf(dsc[3], "%d", &cpp); len != 1 {
     58 				return nil, 0
     59 			}
     60 			upLeft := image.Point{0, 0}
     61 			lowRight := image.Point{w, h}
     62 			img = image.NewRGBA(image.Rectangle{upLeft, lowRight})
     63 			continue
     64 		}
     65 		if cols > 0 {
     66 			dsc := strings.Split(l, " c ")
     67 			if len(dsc) != 2 {
     68 				return nil, 0
     69 			}
     70 			rgb := color.RGBA{A: 255}
     71 			len, _ := fmt.Sscanf(dsc[1], "#%02x%02x%02x", &rgb.R, &rgb.G, &rgb.B)
     72 			if len != 3 {
     73 				if dsc[1] != "None" {
     74 					return nil, 0
     75 				}
     76 				rgb.R, rgb.G, rgb.B, rgb.A = 255, 255, 255, 0
     77 			}
     78 			pal[dsc[0]] = rgb
     79 			cols--
     80 			if cols == 0 {
     81 				cols = -1 // done
     82 			}
     83 			continue
     84 		}
     85 		if y >= h && strings.HasPrefix(l, "}") {
     86 			break
     87 		}
     88 		// image data
     89 		for i := 0; i < len(l); i += 1 {
     90 			e := i + cpp
     91 			if e > len(l) {
     92 				return nil, 0
     93 			}
     94 			sym := l[i:e]
     95 			rgba, ok := pal[sym]
     96 			if !ok {
     97 				return nil, 0
     98 			}
     99 			img.Set(i/cpp, y, color.RGBA(rgba))
    100 		}
    101 		y++
    102 		if y >= h && (!cformat || last) {
    103 			break
    104 		}
    105 	}
    106 	if y < h {
    107 		return nil, 0
    108 	}
    109 	return img, nr
    110 }