func hexToColorNRGBA(hex string) color.NRGBA { c := color.NRGBA{} getIntensity := func(str string) uint8 { if u, err := hexToUint8(str); err == nil { return u } return 0 } if len(hex) >= 6 { c.R = getIntensity(hex[0:2]) c.G = getIntensity(hex[2:4]) c.B = getIntensity(hex[4:6]) } if len(hex) == 8 { c.A = getIntensity(hex[6:8]) } else { c.A = 255 } return c }
func writeImagePng(filename string, pixels []float32, xres, yres int) { outImage := image.NewNRGBA(image.Rect(0, 0, xres, yres)) to_byte := func(v float32) uint8 { // apply gamma and convert to 0..255 return uint8(Clamp(255.0*math.Pow(float64(v), 1.0/2.2), 0.0, 255.0)) } for y := 0; y < yres; y++ { for x := 0; x < xres; x++ { var fcolor color.NRGBA fcolor.R = to_byte(pixels[3*(y*xres+x)+0]) fcolor.G = to_byte(pixels[3*(y*xres+x)+1]) fcolor.B = to_byte(pixels[3*(y*xres+x)+2]) fcolor.A = 0xff outImage.Set(x, y, fcolor) } } f, err := os.Create(filename) defer f.Close() if err != nil { Error("Error writing PNG \"%s\"", filename) } else { png.Encode(f, outImage) } }
// Palette returns Palette if any. func (cfg *Config) Palette() color.Palette { if cfg.ColorMode != ColorModeIndexed { return nil } // http://www.adobe.com/devnet-apps/photoshop/fileformatashtml/#50577409_38034 // 0x0417(1046) | (Photoshop 6.0) Transparency Index. // 2 bytes for the index of transparent color, if any. transparentColorIndex := -1 if r, ok := cfg.Res[0x0417]; ok { transparentColorIndex = int(readUint16(r.Data, 0)) } pal := make(color.Palette, len(cfg.ColorModeData)/3) for i := range pal { c := color.NRGBA{ cfg.ColorModeData[i], cfg.ColorModeData[i+256], cfg.ColorModeData[i+512], 0xFF, } if i == transparentColorIndex { c.A = 0 } pal[i] = c } return pal }
func Decode(r io.Reader) (outImage image.Image, err error) { b := make([]byte, 128) if _, err = io.ReadFull(r, b); err != nil { return } else if b[2] != 1 || b[3] != 8 { err = ErrFormat return } w := int(LittleEndian.Uint16(b[8:])) + 1 h := int(LittleEndian.Uint16(b[10:])) + 1 var p []byte if p, err = ioutil.ReadAll(r); len(p) < 769 || p[len(p)-769] != 12 { err = ErrFormat return } b = p p = p[len(p)-768:] palette := make(color.Palette, 0) for i := 0; i < 256; i++ { o := i * 3 color := color.NRGBA{p[o+0], p[o+1], p[o+2], 0xff} if color.R == 0x9f && color.G == 0x5b && color.B == 0x53 { color.A = 0 } palette = append(palette, color) } pix := make([]byte, w*h) i := 0 for y := 0; y < h; y++ { for x := 0; x < w; { data := b[i] i++ if data&0xc0 == 0xc0 { runLen := data & 0x3f data = b[i] i++ for ; runLen > 0; runLen-- { pix[x+y*w] = data x++ } } else { pix[x+y*w] = data x++ } } } outImage = &image.Paletted{ Pix: pix, Stride: w, Rect: image.Rect(0, 0, w, h), Palette: palette, } return }
// Decode decodes a Half-Life image. func Decode(r io.Reader) (outImage image.Image, err error) { b := make([]byte, 40) if _, err = io.ReadFull(r, b); err != nil { return } name := string(bytes.ToLower(b[:bytes.IndexByte(b[:16], 0)])) width := int(LittleEndian.Uint32(b[16:])) height := int(LittleEndian.Uint32(b[20:])) dataOff := int(LittleEndian.Uint32(b[24:])) if dataOff == 0 { outImage = &HLTex{ &image.Paletted{ Pix: nil, Stride: width, Rect: image.Rect(0, 0, width, height), Palette: nil, }, name, } return } else if dataOff < len(b) { err = ErrFormat return } var palOff int if palOff = int(LittleEndian.Uint32(b[36:])); palOff != 0 { palOff += width * height / 64 } else if palOff = int(LittleEndian.Uint32(b[32:])); palOff != 0 { palOff += width * height / 16 } else if palOff = int(LittleEndian.Uint32(b[28:])); palOff != 0 { palOff += width * height / 4 } else { palOff = dataOff + width*height } dataOff -= len(b) palOff -= len(b) var size int b = make([]byte, palOff+2+256*3) if size, err = r.Read(b); err != nil { return } else if size < palOff+2 { err = ErrFormat return } palSize := int(LittleEndian.Uint16(b[palOff:])) palOff += 2 if palSize > 256 || size < palOff+palSize { err = ErrFormat return } palette := make(color.Palette, 0) for i := 0; i < palSize; i++ { o := i * 3 color := color.NRGBA{b[palOff+o+0], b[palOff+o+1], b[palOff+o+2], 0xff} if color.R == color.G && color.G == 0 && color.B == 0xff { color.A = 0 } palette = append(palette, color) } for i := palSize; i < 256; i++ { palette = append(palette, color.NRGBA{0, 0, 0, 0}) } outImage = &HLTex{ &image.Paletted{ Pix: b[dataOff : dataOff+width*height], Stride: width, Rect: image.Rect(0, 0, width, height), Palette: palette, }, name, } return }