@@ -16,6 +16,7 @@ package imageproxy
1616
1717import (
1818 "bytes"
19+ "encoding/base64"
1920 "image"
2021 "image/color"
2122 "image/draw"
3940// newImage creates a new NRGBA image with the specified dimensions and pixel
4041// color data. If the length of pixels is 1, the entire image is filled with
4142// that color.
42- func newImage (w , h int , pixels ... color.NRGBA ) image.Image {
43+ func newImage (w , h int , pixels ... color.Color ) image.Image {
4344 m := image .NewNRGBA (image .Rect (0 , 0 , w , h ))
4445 if len (pixels ) == 1 {
4546 draw .Draw (m , m .Bounds (), & image.Uniform {pixels [0 ]}, image .ZP , draw .Src )
@@ -145,6 +146,77 @@ func TestTransform(t *testing.T) {
145146 }
146147}
147148
149+ // Test that each of the eight EXIF orientations is applied to the transformed
150+ // image appropriately.
151+ func TestTransform_EXIF (t * testing.T ) {
152+ ref := newImage (2 , 2 , red , green , blue , yellow )
153+
154+ // reference image encoded as TIF, with each of the 8 EXIF orientations
155+ // applied in reverse and the EXIF tag set. When orientation is
156+ // applied, each should display as the ref image.
157+ tests := []string {
158+ "SUkqAAgAAAAOAAABAwABAAAAAgAAAAEBAwABAAAAAgAAAAIBAwAEAAAAtgAAAAMBAwABAAAACAAAAAYBAwABAAAAAgAAABEBBAABAAAAzgAAABIBAwABAAAAAQAAABUBAwABAAAABAAAABYBAwABAAAAAgAAABcBBAABAAAAGQAAABoBBQABAAAAvgAAABsBBQABAAAAxgAAACgBAwABAAAAAgAAAFIBAwABAAAAAgAAAAAAAAAIAAgACAAIAEgAAAABAAAASAAAAAEAAAB4nPrPwPAfDBn+////n+E/IAAA//9DzAj4AA==" , // Orientation=1
159+ "SUkqAAgAAAAOAAABAwABAAAAAgAAAAEBAwABAAAAAgAAAAIBAwAEAAAAtgAAAAMBAwABAAAACAAAAAYBAwABAAAAAgAAABEBBAABAAAAzgAAABIBAwABAAAAAgAAABUBAwABAAAABAAAABYBAwABAAAAAgAAABcBBAABAAAAGQAAABoBBQABAAAAvgAAABsBBQABAAAAxgAAACgBAwABAAAAAgAAAFIBAwABAAAAAgAAAAAAAAAIAAgACAAIAEgAAAABAAAASAAAAAEAAAB4nGL4z/D/PwPD////GcAUIAAA//9HyAj4AA==" , // Orientation=2
160+ "SUkqAAgAAAAOAAABAwABAAAAAgAAAAEBAwABAAAAAgAAAAIBAwAEAAAAtgAAAAMBAwABAAAACAAAAAYBAwABAAAAAgAAABEBBAABAAAAzgAAABIBAwABAAAAAwAAABUBAwABAAAABAAAABYBAwABAAAAAgAAABcBBAABAAAAFwAAABoBBQABAAAAvgAAABsBBQABAAAAxgAAACgBAwABAAAAAgAAAFIBAwABAAAAAgAAAAAAAAAIAAgACAAIAEgAAAABAAAASAAAAAEAAAB4nPr/n+E/AwOY/A9iAAIAAP//T8AI+AA=" , // Orientation=3
161+ "SUkqAAgAAAAOAAABAwABAAAAAgAAAAEBAwABAAAAAgAAAAIBAwAEAAAAtgAAAAMBAwABAAAACAAAAAYBAwABAAAAAgAAABEBBAABAAAAzgAAABIBAwABAAAABAAAABUBAwABAAAABAAAABYBAwABAAAAAgAAABcBBAABAAAAGgAAABoBBQABAAAAvgAAABsBBQABAAAAxgAAACgBAwABAAAAAgAAAFIBAwABAAAAAgAAAAAAAAAIAAgACAAIAEgAAAABAAAASAAAAAEAAAB4nGJg+P///3+G//8ZGP6DICAAAP//S8QI+A==" , // Orientation=4
162+ "SUkqAAgAAAAOAAABAwABAAAAAgAAAAEBAwABAAAAAgAAAAIBAwAEAAAAtgAAAAMBAwABAAAACAAAAAYBAwABAAAAAgAAABEBBAABAAAAzgAAABIBAwABAAAABQAAABUBAwABAAAABAAAABYBAwABAAAAAgAAABcBBAABAAAAGAAAABoBBQABAAAAvgAAABsBBQABAAAAxgAAACgBAwABAAAAAgAAAFIBAwABAAAAAgAAAAAAAAAIAAgACAAIAEgAAAABAAAASAAAAAEAAAB4nPrPwABC/xn+M/wHkYAAAAD//0PMCPg=" , // Orientation=5
163+ "SUkqAAgAAAAOAAABAwABAAAAAgAAAAEBAwABAAAAAgAAAAIBAwAEAAAAtgAAAAMBAwABAAAACAAAAAYBAwABAAAAAgAAABEBBAABAAAAzgAAABIBAwABAAAABgAAABUBAwABAAAABAAAABYBAwABAAAAAgAAABcBBAABAAAAGAAAABoBBQABAAAAvgAAABsBBQABAAAAxgAAACgBAwABAAAAAgAAAFIBAwABAAAAAgAAAAAAAAAIAAgACAAIAEgAAAABAAAASAAAAAEAAAB4nGL4z/D/PwgzMIDQf0AAAAD//0vECPg=" , // Orientation=6
164+ "SUkqAAgAAAAOAAABAwABAAAAAgAAAAEBAwABAAAAAgAAAAIBAwAEAAAAtgAAAAMBAwABAAAACAAAAAYBAwABAAAAAgAAABEBBAABAAAAzgAAABIBAwABAAAABwAAABUBAwABAAAABAAAABYBAwABAAAAAgAAABcBBAABAAAAFgAAABoBBQABAAAAvgAAABsBBQABAAAAxgAAACgBAwABAAAAAgAAAFIBAwABAAAAAgAAAAAAAAAIAAgACAAIAEgAAAABAAAASAAAAAEAAAB4nPr/nwECGf7/BxGAAAAA//9PwAj4" , // Orientation=7
165+ "SUkqAAgAAAAOAAABAwABAAAAAgAAAAEBAwABAAAAAgAAAAIBAwAEAAAAtgAAAAMBAwABAAAACAAAAAYBAwABAAAAAgAAABEBBAABAAAAzgAAABIBAwABAAAACAAAABUBAwABAAAABAAAABYBAwABAAAAAgAAABcBBAABAAAAFQAAABoBBQABAAAAvgAAABsBBQABAAAAxgAAACgBAwABAAAAAgAAAFIBAwABAAAAAgAAAAAAAAAIAAgACAAIAEgAAAABAAAASAAAAAEAAAB4nGJg+P//P4QAQ0AAAAD//0fICPgA" , // Orientation=8
166+ }
167+
168+ for _ , src := range tests {
169+ in , err := base64 .StdEncoding .DecodeString (src )
170+ if err != nil {
171+ t .Errorf ("error decoding source: %v" , err )
172+ }
173+ out , err := Transform (in , Options {Height : - 1 , Width : - 1 , Format : "tiff" })
174+ if err != nil {
175+ t .Errorf ("Transform(%q) returned error: %v" , src , err )
176+ }
177+ d , _ , err := image .Decode (bytes .NewReader (out ))
178+ if err != nil {
179+ t .Errorf ("error decoding transformed image: %v" , err )
180+ }
181+
182+ // construct new image with same colors as decoded image for easy comparison
183+ got := newImage (2 , 2 , d .At (0 , 0 ), d .At (1 , 0 ), d .At (0 , 1 ), d .At (1 , 1 ))
184+ if want := ref ; ! reflect .DeepEqual (got , want ) {
185+ t .Errorf ("Transform(%v) returned image %#v, want %#v" , src , got , want )
186+ }
187+ }
188+ }
189+
190+ // Test that EXIF orientation and any additional transforms don't conflict.
191+ // This is tested with orientation=7, which involves both a rotation and a
192+ // flip, combined with an additional rotation transform.
193+ func TestTransform_EXIF_Rotate (t * testing.T ) {
194+ // base64-encoded TIF image (2x2 yellow green blue red) with EXIF
195+ // orientation=7. When orientation applied, displays as (2x2 red green
196+ // blue yellow).
197+ src := "SUkqAAgAAAAOAAABAwABAAAAAgAAAAEBAwABAAAAAgAAAAIBAwAEAAAAtgAAAAMBAwABAAAACAAAAAYBAwABAAAAAgAAABEBBAABAAAAzgAAABIBAwABAAAABwAAABUBAwABAAAABAAAABYBAwABAAAAAgAAABcBBAABAAAAFgAAABoBBQABAAAAvgAAABsBBQABAAAAxgAAACgBAwABAAAAAgAAAFIBAwABAAAAAgAAAAAAAAAIAAgACAAIAEgAAAABAAAASAAAAAEAAAB4nPr/nwECGf7/BxGAAAAA//9PwAj4"
198+
199+ in , err := base64 .StdEncoding .DecodeString (src )
200+ if err != nil {
201+ t .Errorf ("error decoding source: %v" , err )
202+ }
203+ out , err := Transform (in , Options {Rotate : 90 , Format : "tiff" })
204+ if err != nil {
205+ t .Errorf ("Transform(%q) returned error: %v" , src , err )
206+ }
207+ d , _ , err := image .Decode (bytes .NewReader (out ))
208+ if err != nil {
209+ t .Errorf ("error decoding transformed image: %v" , err )
210+ }
211+
212+ // construct new image with same colors as decoded image for easy comparison
213+ got := newImage (2 , 2 , d .At (0 , 0 ), d .At (1 , 0 ), d .At (0 , 1 ), d .At (1 , 1 ))
214+ want := newImage (2 , 2 , green , yellow , red , blue )
215+ if ! reflect .DeepEqual (got , want ) {
216+ t .Errorf ("Transform(%v) returned image %#v, want %#v" , src , got , want )
217+ }
218+ }
219+
148220func TestTransformImage (t * testing.T ) {
149221 // ref is a 2x2 reference image containing four colors
150222 ref := newImage (2 , 2 , red , green , blue , yellow )
0 commit comments