blob: 04020421126b0d47b8a35fd3a3a030aa96bba2c3 [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"
Nigel Tao25101a02017-06-01 10:15:32 +100033 "os"
34 "path/filepath"
Nigel Tao25101a02017-06-01 10:15:32 +100035)
36
37func main() {
38 if err := main1(); err != nil {
39 os.Stderr.WriteString(err.Error() + "\n")
40 os.Exit(1)
41 }
42}
43
44func main1() error {
Nigel Tao62833892017-06-03 17:35:29 +100045 baseFilename, bPalette, bIndexes := "", []byte(nil), []byte(nil)
Nigel Tao25101a02017-06-01 10:15:32 +100046 for i, a := range os.Args[1:] {
47 b := a[:len(a)-len(filepath.Ext(a))]
Nigel Tao62833892017-06-03 17:35:29 +100048 palette, indexes, err := decode(a)
Nigel Tao25101a02017-06-01 10:15:32 +100049 if err != nil {
50 return err
51 }
52 if i == 0 {
Nigel Tao62833892017-06-03 17:35:29 +100053 baseFilename, bPalette, bIndexes = b, palette, indexes
Nigel Tao25101a02017-06-01 10:15:32 +100054 } else if baseFilename != b {
55 return fmt.Errorf("arguments do not have a common base path")
Nigel Tao62833892017-06-03 17:35:29 +100056 } else if !bytes.Equal(bPalette, palette) {
57 return fmt.Errorf("palettes are not equivalent")
58 } else if !bytes.Equal(bIndexes, indexes) {
59 return fmt.Errorf("indexes are not equivalent")
Nigel Tao25101a02017-06-01 10:15:32 +100060 }
61 }
Nigel Tao62833892017-06-03 17:35:29 +100062 if bPalette != nil {
Nigel Tao226c4762021-08-22 11:05:43 +100063 if err := os.WriteFile(baseFilename+".palette", bPalette, 0644); err != nil {
Nigel Tao62833892017-06-03 17:35:29 +100064 return err
65 }
Nigel Tao25101a02017-06-01 10:15:32 +100066 }
Nigel Tao62833892017-06-03 17:35:29 +100067 if bIndexes != nil {
Nigel Tao226c4762021-08-22 11:05:43 +100068 if err := os.WriteFile(baseFilename+".indexes", bIndexes, 0644); err != nil {
Nigel Tao62833892017-06-03 17:35:29 +100069 return err
70 }
Nigel Tao25101a02017-06-01 10:15:32 +100071 }
72 return nil
73}
74
Nigel Tao62833892017-06-03 17:35:29 +100075func decode(filename string) (palette []byte, indexes []byte, err error) {
Nigel Tao25101a02017-06-01 10:15:32 +100076 f, err := os.Open(filename)
77 if err != nil {
Nigel Tao62833892017-06-03 17:35:29 +100078 return nil, nil, err
Nigel Tao25101a02017-06-01 10:15:32 +100079 }
80 defer f.Close()
81
82 m, err := image.Image(nil), error(nil)
83 switch ext := filepath.Ext(filename); ext {
84 case ".gif":
85 m, err = gif.Decode(f)
86 case ".png":
87 m, err = png.Decode(f)
88 default:
Nigel Tao62833892017-06-03 17:35:29 +100089 return nil, nil, fmt.Errorf("unsupported filename extension %q", ext)
Nigel Tao25101a02017-06-01 10:15:32 +100090 }
91 if err != nil {
Nigel Tao62833892017-06-03 17:35:29 +100092 return nil, nil, err
Nigel Tao25101a02017-06-01 10:15:32 +100093 }
Nigel Tao62833892017-06-03 17:35:29 +100094 switch m := m.(type) {
95 case *image.Gray:
96 return nil, m.Pix, nil
97 case *image.Paletted:
Nigel Tao34cfc3f2018-05-24 10:33:02 +100098 palette = make([]byte, 4*256)
Nigel Tao62833892017-06-03 17:35:29 +100099 allGray := true
100 for i, c := range m.Palette {
Nigel Tao34cfc3f2018-05-24 10:33:02 +1000101 r, g, b, a := c.RGBA()
102 palette[4*i+0] = uint8(b >> 8)
103 palette[4*i+1] = uint8(g >> 8)
104 palette[4*i+2] = uint8(r >> 8)
105 palette[4*i+3] = uint8(a >> 8)
Nigel Tao62833892017-06-03 17:35:29 +1000106 if allGray {
107 y := uint32(i)
108 allGray = r>>8 == y && g>>8 == y && b>>8 == y
109 }
110 }
111 if allGray {
112 return nil, m.Pix, nil
113 }
114 return palette, m.Pix, nil
Nigel Tao25101a02017-06-01 10:15:32 +1000115 }
Nigel Tao62833892017-06-03 17:35:29 +1000116 return nil, nil, fmt.Errorf("decoded image type: got %T, want *image.Paletted", m)
Nigel Tao25101a02017-06-01 10:15:32 +1000117}