blob: f043ccfae3e0b834aed45021480501be79f3aeb7 [file] [log] [blame]
Nigel Taod4372cb2017-10-12 11:17:41 +11001// Copyright 2017 The Puffs Authors.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// https://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
Nigel Tao25101a02017-06-01 10:15:32 +100014
15// +build ignore
16
17package main
18
Nigel Tao62833892017-06-03 17:35:29 +100019// extract-palette-indexes.go extracts the 1-byte-per-pixel indexes and, for
20// paletted images, the 3-byte-per-entry RGB palette of a paletted or gray GIF
21// and PNG image. It checks that the GIF and PNG encode equivalent images.
Nigel Tao25101a02017-06-01 10:15:32 +100022//
23// Usage: go run extract-palette-indexes.go foo.gif foo.png
24
25import (
Nigel Tao62833892017-06-03 17:35:29 +100026 "bytes"
Nigel Tao25101a02017-06-01 10:15:32 +100027 "fmt"
28 "image"
29 "image/gif"
30 "image/png"
31 "io/ioutil"
32 "os"
33 "path/filepath"
Nigel Tao25101a02017-06-01 10:15:32 +100034)
35
36func main() {
37 if err := main1(); err != nil {
38 os.Stderr.WriteString(err.Error() + "\n")
39 os.Exit(1)
40 }
41}
42
43func main1() error {
Nigel Tao62833892017-06-03 17:35:29 +100044 baseFilename, bPalette, bIndexes := "", []byte(nil), []byte(nil)
Nigel Tao25101a02017-06-01 10:15:32 +100045 for i, a := range os.Args[1:] {
46 b := a[:len(a)-len(filepath.Ext(a))]
Nigel Tao62833892017-06-03 17:35:29 +100047 palette, indexes, err := decode(a)
Nigel Tao25101a02017-06-01 10:15:32 +100048 if err != nil {
49 return err
50 }
51 if i == 0 {
Nigel Tao62833892017-06-03 17:35:29 +100052 baseFilename, bPalette, bIndexes = b, palette, indexes
Nigel Tao25101a02017-06-01 10:15:32 +100053 } else if baseFilename != b {
54 return fmt.Errorf("arguments do not have a common base path")
Nigel Tao62833892017-06-03 17:35:29 +100055 } else if !bytes.Equal(bPalette, palette) {
56 return fmt.Errorf("palettes are not equivalent")
57 } else if !bytes.Equal(bIndexes, indexes) {
58 return fmt.Errorf("indexes are not equivalent")
Nigel Tao25101a02017-06-01 10:15:32 +100059 }
60 }
Nigel Tao62833892017-06-03 17:35:29 +100061 if bPalette != nil {
62 if err := ioutil.WriteFile(baseFilename+".palette", bPalette, 0644); err != nil {
63 return err
64 }
Nigel Tao25101a02017-06-01 10:15:32 +100065 }
Nigel Tao62833892017-06-03 17:35:29 +100066 if bIndexes != nil {
67 if err := ioutil.WriteFile(baseFilename+".indexes", bIndexes, 0644); err != nil {
68 return err
69 }
Nigel Tao25101a02017-06-01 10:15:32 +100070 }
71 return nil
72}
73
Nigel Tao62833892017-06-03 17:35:29 +100074func decode(filename string) (palette []byte, indexes []byte, err error) {
Nigel Tao25101a02017-06-01 10:15:32 +100075 f, err := os.Open(filename)
76 if err != nil {
Nigel Tao62833892017-06-03 17:35:29 +100077 return nil, nil, err
Nigel Tao25101a02017-06-01 10:15:32 +100078 }
79 defer f.Close()
80
81 m, err := image.Image(nil), error(nil)
82 switch ext := filepath.Ext(filename); ext {
83 case ".gif":
84 m, err = gif.Decode(f)
85 case ".png":
86 m, err = png.Decode(f)
87 default:
Nigel Tao62833892017-06-03 17:35:29 +100088 return nil, nil, fmt.Errorf("unsupported filename extension %q", ext)
Nigel Tao25101a02017-06-01 10:15:32 +100089 }
90 if err != nil {
Nigel Tao62833892017-06-03 17:35:29 +100091 return nil, nil, err
Nigel Tao25101a02017-06-01 10:15:32 +100092 }
Nigel Tao62833892017-06-03 17:35:29 +100093 switch m := m.(type) {
94 case *image.Gray:
95 return nil, m.Pix, nil
96 case *image.Paletted:
97 palette = make([]byte, 3*256)
98 allGray := true
99 for i, c := range m.Palette {
100 r, g, b, _ := c.RGBA()
101 palette[3*i+0] = uint8(r >> 8)
102 palette[3*i+1] = uint8(g >> 8)
103 palette[3*i+2] = uint8(b >> 8)
104 if allGray {
105 y := uint32(i)
106 allGray = r>>8 == y && g>>8 == y && b>>8 == y
107 }
108 }
109 if allGray {
110 return nil, m.Pix, nil
111 }
112 return palette, m.Pix, nil
Nigel Tao25101a02017-06-01 10:15:32 +1000113 }
Nigel Tao62833892017-06-03 17:35:29 +1000114 return nil, nil, fmt.Errorf("decoded image type: got %T, want *image.Paletted", m)
Nigel Tao25101a02017-06-01 10:15:32 +1000115}