blob: 11d1d48983facdad6382d7aaf8b80a24d8c667c1 [file] [log] [blame]
Nigel Tao79a94552017-11-30 16:37:20 +11001// Copyright 2017 The Wuffs Authors.
Nigel Taod4372cb2017-10-12 11:17:41 +11002//
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
Nigel Tao788479d2021-08-22 10:52:51 +100015//go:build ignore
Nigel Tao25101a02017-06-01 10:15:32 +100016// +build ignore
17
18package main
19
Nigel Tao62833892017-06-03 17:35:29 +100020// extract-palette-indexes.go extracts the 1-byte-per-pixel indexes and, for
Nigel Tao34cfc3f2018-05-24 10:33:02 +100021// paletted images, the 4-byte-per-entry BGRA (premultiplied alpha) palette of
22// a paletted or gray GIF and PNG image. It checks that the GIF and PNG encode
23// equivalent images.
Nigel Tao25101a02017-06-01 10:15:32 +100024//
25// Usage: go run extract-palette-indexes.go foo.gif foo.png
26
27import (
Nigel Tao62833892017-06-03 17:35:29 +100028 "bytes"
Nigel Tao25101a02017-06-01 10:15:32 +100029 "fmt"
30 "image"
31 "image/gif"
32 "image/png"
33 "io/ioutil"
34 "os"
35 "path/filepath"
Nigel Tao25101a02017-06-01 10:15:32 +100036)
37
38func main() {
39 if err := main1(); err != nil {
40 os.Stderr.WriteString(err.Error() + "\n")
41 os.Exit(1)
42 }
43}
44
45func main1() error {
Nigel Tao62833892017-06-03 17:35:29 +100046 baseFilename, bPalette, bIndexes := "", []byte(nil), []byte(nil)
Nigel Tao25101a02017-06-01 10:15:32 +100047 for i, a := range os.Args[1:] {
48 b := a[:len(a)-len(filepath.Ext(a))]
Nigel Tao62833892017-06-03 17:35:29 +100049 palette, indexes, err := decode(a)
Nigel Tao25101a02017-06-01 10:15:32 +100050 if err != nil {
51 return err
52 }
53 if i == 0 {
Nigel Tao62833892017-06-03 17:35:29 +100054 baseFilename, bPalette, bIndexes = b, palette, indexes
Nigel Tao25101a02017-06-01 10:15:32 +100055 } else if baseFilename != b {
56 return fmt.Errorf("arguments do not have a common base path")
Nigel Tao62833892017-06-03 17:35:29 +100057 } else if !bytes.Equal(bPalette, palette) {
58 return fmt.Errorf("palettes are not equivalent")
59 } else if !bytes.Equal(bIndexes, indexes) {
60 return fmt.Errorf("indexes are not equivalent")
Nigel Tao25101a02017-06-01 10:15:32 +100061 }
62 }
Nigel Tao62833892017-06-03 17:35:29 +100063 if bPalette != nil {
64 if err := ioutil.WriteFile(baseFilename+".palette", bPalette, 0644); err != nil {
65 return err
66 }
Nigel Tao25101a02017-06-01 10:15:32 +100067 }
Nigel Tao62833892017-06-03 17:35:29 +100068 if bIndexes != nil {
69 if err := ioutil.WriteFile(baseFilename+".indexes", bIndexes, 0644); err != nil {
70 return err
71 }
Nigel Tao25101a02017-06-01 10:15:32 +100072 }
73 return nil
74}
75
Nigel Tao62833892017-06-03 17:35:29 +100076func decode(filename string) (palette []byte, indexes []byte, err error) {
Nigel Tao25101a02017-06-01 10:15:32 +100077 f, err := os.Open(filename)
78 if err != nil {
Nigel Tao62833892017-06-03 17:35:29 +100079 return nil, nil, err
Nigel Tao25101a02017-06-01 10:15:32 +100080 }
81 defer f.Close()
82
83 m, err := image.Image(nil), error(nil)
84 switch ext := filepath.Ext(filename); ext {
85 case ".gif":
86 m, err = gif.Decode(f)
87 case ".png":
88 m, err = png.Decode(f)
89 default:
Nigel Tao62833892017-06-03 17:35:29 +100090 return nil, nil, fmt.Errorf("unsupported filename extension %q", ext)
Nigel Tao25101a02017-06-01 10:15:32 +100091 }
92 if err != nil {
Nigel Tao62833892017-06-03 17:35:29 +100093 return nil, nil, err
Nigel Tao25101a02017-06-01 10:15:32 +100094 }
Nigel Tao62833892017-06-03 17:35:29 +100095 switch m := m.(type) {
96 case *image.Gray:
97 return nil, m.Pix, nil
98 case *image.Paletted:
Nigel Tao34cfc3f2018-05-24 10:33:02 +100099 palette = make([]byte, 4*256)
Nigel Tao62833892017-06-03 17:35:29 +1000100 allGray := true
101 for i, c := range m.Palette {
Nigel Tao34cfc3f2018-05-24 10:33:02 +1000102 r, g, b, a := c.RGBA()
103 palette[4*i+0] = uint8(b >> 8)
104 palette[4*i+1] = uint8(g >> 8)
105 palette[4*i+2] = uint8(r >> 8)
106 palette[4*i+3] = uint8(a >> 8)
Nigel Tao62833892017-06-03 17:35:29 +1000107 if allGray {
108 y := uint32(i)
109 allGray = r>>8 == y && g>>8 == y && b>>8 == y
110 }
111 }
112 if allGray {
113 return nil, m.Pix, nil
114 }
115 return palette, m.Pix, nil
Nigel Tao25101a02017-06-01 10:15:32 +1000116 }
Nigel Tao62833892017-06-03 17:35:29 +1000117 return nil, nil, fmt.Errorf("decoded image type: got %T, want *image.Paletted", m)
Nigel Tao25101a02017-06-01 10:15:32 +1000118}