Source file src/image/decode_example_test.go

     1  // Copyright 2012 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  // This example demonstrates decoding a JPEG image and examining its pixels.
     6  package image_test
     7  
     8  import (
     9  	"bytes"
    10  	"encoding/base64"
    11  	"fmt"
    12  	"image"
    13  	"log"
    14  	"strings"
    15  
    16  	// Packages image/gif and image/jpeg are not used explicitly in the code
    17  	// below, but are imported for their initialization side-effects, which
    18  	// allow image.Decode and image.DecodeConfig to understand GIF and JPEG
    19  	// formatted images. Uncomment the line below to also understand PNG:
    20  	// _ "image/png"
    21  	_ "image/gif"
    22  	_ "image/jpeg"
    23  )
    24  
    25  func Example_decodeConfig() {
    26  	reader := base64.NewDecoder(base64.StdEncoding, strings.NewReader(data))
    27  	config, format, err := image.DecodeConfig(reader)
    28  	if err != nil {
    29  		log.Fatal(err)
    30  	}
    31  	fmt.Println("Width:", config.Width, "Height:", config.Height, "Format:", format)
    32  }
    33  
    34  // ExampleDecode_untrusted demonstrates decoding an untrusted
    35  // image file in two steps so that unexpectedly large
    36  // memory allocations can be safely avoided.
    37  func ExampleDecode_untrusted() {
    38  	// This GIF data is a valid 1x1 image (layout matches package gif tests).
    39  	gifData := []byte{
    40  		'G', 'I', 'F', '8', '9', 'a',
    41  		1, 0, 1, 0,
    42  		128, 0, 0,
    43  		0, 0, 0, 1, 1, 1,
    44  		0x21, 0xf9, 0x04, 0x00, 0x00, 0x00, 0xff, 0x00,
    45  		0x2c,
    46  		0x00, 0x00, 0x00, 0x00,
    47  		0x01, 0x00, 0x01, 0x00,
    48  		0x00,
    49  		0x02, 0x02, 0x4c, 0x01, 0x00,
    50  		0x3b,
    51  	}
    52  
    53  	cfg, _, err := image.DecodeConfig(bytes.NewReader(gifData))
    54  	if err != nil {
    55  		log.Fatal(err)
    56  	}
    57  
    58  	// Use int64 to avoid overflow on 32-bit platforms.
    59  	const maxPixels = 10000
    60  	if int64(cfg.Width)*int64(cfg.Height) > maxPixels {
    61  		fmt.Println("rejected: dimensions too large")
    62  		return
    63  	}
    64  
    65  	m, _, err := image.Decode(bytes.NewReader(gifData))
    66  	if err != nil {
    67  		log.Fatal(err)
    68  	}
    69  	fmt.Println("decoded", m.Bounds().Dx(), m.Bounds().Dy())
    70  	// Output:
    71  	// decoded 1 1
    72  }
    73  
    74  func Example() {
    75  	// Decode the JPEG data. If reading from file, create a reader with
    76  	//
    77  	// reader, err := os.Open("testdata/video-001.q50.420.jpeg")
    78  	// if err != nil {
    79  	//     log.Fatal(err)
    80  	// }
    81  	// defer reader.Close()
    82  	reader := base64.NewDecoder(base64.StdEncoding, strings.NewReader(data))
    83  	m, _, err := image.Decode(reader)
    84  	if err != nil {
    85  		log.Fatal(err)
    86  	}
    87  	bounds := m.Bounds()
    88  
    89  	// Calculate a 16-bin histogram for m's red, green, blue and alpha components.
    90  	//
    91  	// An image's bounds do not necessarily start at (0, 0), so the two loops start
    92  	// at bounds.Min.Y and bounds.Min.X. Looping over Y first and X second is more
    93  	// likely to result in better memory access patterns than X first and Y second.
    94  	var histogram [16][4]int
    95  	for y := bounds.Min.Y; y < bounds.Max.Y; y++ {
    96  		for x := bounds.Min.X; x < bounds.Max.X; x++ {
    97  			r, g, b, a := m.At(x, y).RGBA()
    98  			// A color's RGBA method returns values in the range [0, 65535].
    99  			// Shifting by 12 reduces this to the range [0, 15].
   100  			histogram[r>>12][0]++
   101  			histogram[g>>12][1]++
   102  			histogram[b>>12][2]++
   103  			histogram[a>>12][3]++
   104  		}
   105  	}
   106  
   107  	// Print the results.
   108  	fmt.Printf("%-14s %6s %6s %6s %6s\n", "bin", "red", "green", "blue", "alpha")
   109  	for i, x := range histogram {
   110  		fmt.Printf("0x%04x-0x%04x: %6d %6d %6d %6d\n", i<<12, (i+1)<<12-1, x[0], x[1], x[2], x[3])
   111  	}
   112  	// Output:
   113  	// bin               red  green   blue  alpha
   114  	// 0x0000-0x0fff:    362    793   7245      0
   115  	// 0x1000-0x1fff:    648   2963   1036      0
   116  	// 0x2000-0x2fff:   1072   2301    977      0
   117  	// 0x3000-0x3fff:    819   2266    982      0
   118  	// 0x4000-0x4fff:    537   1303    541      0
   119  	// 0x5000-0x5fff:    321    964    261      0
   120  	// 0x6000-0x6fff:    321    375    177      0
   121  	// 0x7000-0x7fff:    599    278    213      0
   122  	// 0x8000-0x8fff:   3478    228    275      0
   123  	// 0x9000-0x9fff:   2260    233    328      0
   124  	// 0xa000-0xafff:    921    282    374      0
   125  	// 0xb000-0xbfff:    322    335    395      0
   126  	// 0xc000-0xcfff:    228    388    299      0
   127  	// 0xd000-0xdfff:    261    415    277      0
   128  	// 0xe000-0xefff:    516    423    297      0
   129  	// 0xf000-0xffff:   2785   1903   1773  15450
   130  }
   131  
   132  const data = `
   133  /9j/4AAQSkZJRgABAQIAHAAcAAD/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdA
   134  SFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2Nj
   135  Y2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wAARCABnAJYDASIAAhEBAxEB/8QA
   136  HwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIh
   137  MUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVW
   138  V1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXG
   139  x8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQF
   140  BgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAV
   141  YnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOE
   142  hYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq
   143  8vP09fb3+Pn6/9oADAMBAAIRAxEAPwDlwKMD0pwzSiuK57QzGDxS7D6in8Y5ximnAPUfSlcq4m3ilUYp
   144  2OKXHvRcVxnTtS7c07HNFK4DQPakC4PNOA+tOx70XAjK/So5gBGP94fzqfvUVx/qxx/EP51UXqRP4WSE
   145  cmgjilP3jSEZqS0IO/NGDnpUiocDg/McDjvV6HTPOdVWYgsM5KcfzzQ2JySM2jp6VYu7SWzmMUwG4cgj
   146  kMPUVBjjtTGtRu0Zopw+lFFxhinrGzuqqMsxAA9yaXFSRv5cqSEcIwYj6GpuZ30O30fSLKzhUpbpNMv3
   147  5XGTn29BV28jt7pPLuIVljPBBFVreYx+VbqAjycgt3x14zRcNOxGyVFHQkIc/wA61exyKLbuzjdZ046d
   148  ftEuTEw3Rk9SPT8P8Kpbea3tchbyVae4JkjbbGpGdwOM89Af6ViFTWUtGdcXoM2+woK1JtpNtTcoZt+l
   149  Jt7ZqTbRtouFyPFRXI/c9D94fzqzioLsfuD/ALw/nVReqIn8LJCOTSY+tSMOTmkIpXLRu+F0t5pJxPHG
   150  wjjUAuBjJJz1+laD6Pai+WaK9SBX6puzn6ZP+NV/Dkdtc6ZNbyAFwxLAHDYPv6VoQ21nPNEEiQGEFRtk
   151  Gf0NaWTOeW7Of8QwGG4MRZnEbYXPJwRnOR0zWNXW+KrqBLUWi5EjbWCgcAA9c/gRXKYqZaGlK/LqMH0F
   152  FLtHvRSNiYD2pSDTgpp6p0ywUHoTULXYxcktzrdCf7Xo8LP/AKyEmMNjJ46dfbFWJ5TDGNwB9lFUvDV9
   153  YrbfYGbyrjcWG88S57g+vtV26ZIvMlumKwwjLZ6V0WfU54yTvYwtbubea2WNWbzg4bYQeBgj8OtYeKhj
   154  u4y2HQxqxOD1xzxmrWAQCCGB6EGsaikndmsJxeiYzBo280/Z7UbayuaXGY5oIp+2lx9KLjIsVDeD/Rj/
   155  ALy/zq1t96r3y4tT/vL/ADq4P3kRP4WSleTSFKkkKoCW4GaqNcMxIjXj1pxjKT0FKrGC1Nrw3vGrKkYz
   156  5kTAr6455/HH510UdwPtRgWCbzF5+YYUf4Vwun39xpmoR3qASMmQUJwGU9Rnt/8AWrpbrxhb8/ZdOmaQ
   157  gAGZwFH5ZJrpVKVlY5ZYhN6kXiu2eO/ikZlIljAAB5yM549OawSOOlPuLqe+umuLqTfM4OSOAo7ADsKh
   158  hl/cRsTuJHPv7mlKi3sVTxNtGP20VJhThgSQaK52mnZnUqsWrpkyeUrr5pABOAPU1AGaXUCWJISHGPfP
   159  P8qL7BiKnsMg46H3qrbzupbj5mPTPTpXVSglG551SpzSsXJ4/MBUgYIxyKpySyGBYJriV1D7kRpCVH4V
   160  bSeNJ4xchni3DeqnBI+td7F4b0mKIRjT45VbktJlzk455+n6VtYzv2PNwFZWBHBGKVJDGVC54/nXQeMN
   161  NttLNkba1jgWVWDmM8bhg4/nzXLSSbXVj6fyNKUdNRp21RtIRJGrjuM0u3FQ2DbodvcEkfQmrW2vLqLl
   162  k0ejCXNFMj2/jQV9qkxSYNRcsZiq2oI32N2CkhWXJxwOe9XMcVt6hoPn6dFaW0wgRpNzvKDlz6+/0rai
   163  ryv2Jm9LHJai+ZRGCBjnr71ErdAxAY9B611t1Y2cunbbaOQ3FvKZI3UqGlZMbiWwfcfhV231iwvLSM3U
   164  lt5Uq52TuZG+hGMA12xXJGxxzjzybOQtNOvb5j9ktZJhnBIHyg+5PFX38JayqK/2eLJIBUTgkDA9q7ex
   165  itrSHFpGsUbndhRgc+g7VNIyfZJAoJZUbb3I46CtFJMylBo8sdWhmYMuCnylc9wef5VUT7+1chc5NS7h
   166  sUZO5RtIPUH3pkBDOxxxmqM9TQtn+WilhHfHaik43KTG3Z4IyPyrNVjGCsZ+dmwv6V3cXhSG8sYpJLud
   167  JJIwxChdoJGcYx/Wkg8DafA4knvLiQr/ALqj+VQpKw3FtnFFfvbiSMgZJ6/jXp2n3d9cQRBTFsKD96EP
   168  oOxPU/8A68VVtbbRtMVntbePKDLTSHJH/Aj/AEqHTvE66rq72VugMMcbSGTnL4wMAfjT5n0HyW3L+s6b
   169  baxaJBdzN+7bcrxkAhun0rz3VNCv7e7lgigknWI43xLu6jjIHTjtXqfkpPGVYsBkghTikgsYIN/lhgXb
   170  cxLkknp/ShczQ7xtY8vtEmhkj8yGRBuCnehUcnHcVtmwfJ/fQ8e7f/E12txZW91C0U6b42xlST2OR/Ko
   171  Bo1gM/uW55/1jf41nOipu7LhV5FZHIGzI6zwj/vr/Ck+yr3uYf8Ax7/CutbQdMb71tn/ALaN/jSf8I/p
   172  X/PoP++2/wAan6rAr6wzkWt0II+1Rc/7Lf4Vd1eeCSKBbdZDdShYoiZNoyfY10P/AAj2lf8APmP++2/x
   173  oPh/SjKspsozIuNrZORjp3qo0FHYPb3OZt7ae3SzjuItsiRSAgnccl/UA+3Q1yNjKLR4ZZYY5VD7tkv3
   174  WwO/+e1evPp9nI257aJm6bioz1z1+tY+s6Hplnot9PbWMMcqwOFcLyOO1bJWMZSTOPHi+9w3mosrlyd2
   175  9lCj02g9P/1e9a3hzxAbl2ikZRcdQueHHt7j864Y8Z4I4oRzG6urFWU5BHBB7HNJxTFGbR6he6Vpmtgm
   176  eLy5zwZI/lb8fX8azIvBUUTHdfSFP4QsYB/HNZ+k+KEnRY75hHOvAk6K/v7H9K6yyvlnQBmDZ6GsnzR0
   177  N0oy1RzOtaN/Y1tHNFO06u+zYy4I4Jzx9KKveJblXuordSGES5b6n/62PzorKVdp2LjQTVyWz8UWEWlq
   178  jSgyxfJt6EgdDzWTdeLIZGO7zHI/hVajGmWWP+PWL8qwlAIURrhpMAHHJA71pRcZrToZzcoEuo6heakA
   179  GHk245CZ6/X1qPTLq40q+W5t2QybSpDAkEEc55/zilk5k2r91eKhLDzWz2rpsczbbuemeD76fUNG865I
   180  MiysmQMZAAwa3a5j4ftu0ByP+fh/5CulkLLG7INzhSVHqe1Fh3uOoqn9qQQxyhndmHIxwOmSR2xQ13KD
   181  KoiBZOV9JBnt707MVy5RWdNdy7wRGf3bfMinnO1jg+vY03WXLaJO3mhQ20b0zwpYf0qlG7S7icrJs08U
   182  VwumgC+YiQyeVtZH567hzj8aSL949oGhE/2v5pJCDkksQwBHC4/+vXQ8LZ2uYxxCavY7us/xCcaBfn0h
   183  b+VP0bnSrb94ZMJgOecj1rl/GfidUE2k2gy5+SeQjgA/wj3rlas2jdao48qrjLAGkSKPk4Gc1WMj92I+
   184  lIJnU8OfxPWo5inBokmtQTmM4OOh71b0q6vbFmWCbaxHyqQGAP0PT8KhSTzVyo5ocSKA5VfTOTmqsmRd
   185  pl99XjPzThzK3zOeOSeveirNmkgg/fIpYsTkYORxRXmzlTjJqx6EVUcU7mhkKCzdAK59QI9zYxtG1fYU
   186  UVtgtmY4nZEa8Ak9aqFv3rfSiiu1nMeifDv/AJF+T/r4f+QrqqKKQwzQenNFFMCOKFIgNuThdoJ5OPSk
   187  ubeK6t3gnXdG4wwziiii/UTKMOg6dbzJLFE4dSCP3rEdeOM8805tDsGMvySgSsS6rM6gk9eAcUUVftZt
   188  3uyVGNthuq3Eei6DK8H7sRR7YuMgHtXkc8rzTNLM26RyWY+p70UVnLY0iEsUipG7rhZBlDkc1HgYoorM
   189  0HwyBXGeRjmrcUhMg2ghezd//rUUVcTKW5s2jZtY/QDaOKKKK8ip8bPRj8KP/9k=
   190  `
   191  

View as plain text