// makeTestImages generates an RGBA and a grayscale image and returns // testImages containing the JPEG encoded form as bytes and the expected color // model of the image when decoded. func makeTestImages() ([]testImage, error) { var ims []testImage w := bytes.NewBuffer(nil) im1 := image.NewRGBA(image.Rect(0, 0, width, height)) for i := range im1.Pix { switch { case i%4 == 3: im1.Pix[i] = 255 default: im1.Pix[i] = uint8(i) } } if err := jpeg.Encode(w, im1, nil); err != nil { return nil, err } ims = append(ims, testImage{im: im1, buf: w.Bytes()}) w = bytes.NewBuffer(nil) im2 := image.NewGray(image.Rect(0, 0, width, height)) for i := range im2.Pix { im2.Pix[i] = uint8(i) } if err := jpeg.Encode(w, im2, nil); err != nil { return nil, err } ims = append(ims, testImage{im: im2, buf: w.Bytes()}) return ims, nil }
func testRun(b types.TB, decode decodeFunc) { if !fastjpeg.Available() { b.Skip("Skipping benchmark, djpeg unavailable.") } im, _, err := decode(bytes.NewReader(jpegBytes)) if err != nil { b.Fatal(err) } rect := im.Bounds() w, h := 128, 128 im = resize.Resize(im, rect, w, h) err = jpeg.Encode(ioutil.Discard, im, nil) if err != nil { b.Fatal(err) } }
func init() { // Create image with non-uniform color to make decoding more realistic. // Solid color jpeg images decode faster than non-uniform images. b := new(bytes.Buffer) w, h := 4000, 4000 im := image.NewNRGBA(image.Rect(0, 0, w, h)) for i := range im.Pix { switch { case i%4 == 3: im.Pix[i] = 255 default: im.Pix[i] = uint8(i) } } if err := jpeg.Encode(b, im, nil); err != nil { panic(err) } jpegBytes = b.Bytes() }
// NewUserAttributePhoto creates a user attribute packet // containing the given images. func NewUserAttributePhoto(photos ...image.Image) (uat *UserAttribute, err error) { uat = new(UserAttribute) for _, photo := range photos { var buf bytes.Buffer // RFC 4880, Section 5.12.1. data := []byte{ 0x10, 0x00, // Little-endian image header length (16 bytes) 0x01, // Image header version 1 0x01, // JPEG 0, 0, 0, 0, // 12 reserved octets, must be all zero. 0, 0, 0, 0, 0, 0, 0, 0} if _, err = buf.Write(data); err != nil { return } if err = jpeg.Encode(&buf, photo, nil); err != nil { return } uat.Contents = append(uat.Contents, &OpaqueSubpacket{ SubType: UserAttrImageSubpacket, Contents: buf.Bytes()}) } return }
func (ih *ImageHandler) scaleImage(fileRef blob.Ref) (*formatAndImage, error) { fr, err := ih.newFileReader(fileRef) if err != nil { return nil, err } defer fr.Close() sr := types.NewStatsReader(imageBytesFetchedVar, fr) sr, conf, err := imageConfigFromReader(sr) if err != nil { return nil, err } // TODO(wathiede): build a size table keyed by conf.ColorModel for // common color models for a more exact size estimate. // This value is an estimate of the memory required to decode an image. // PNGs range from 1-64 bits per pixel (not all of which are supported by // the Go standard parser). JPEGs encoded in YCbCr 4:4:4 are 3 byte/pixel. // For all other JPEGs this is an overestimate. For GIFs it is 3x larger // than needed. How accurate this estimate is depends on the mix of // images being resized concurrently. ramSize := int64(conf.Width) * int64(conf.Height) * 3 if err = ih.ResizeSem.Acquire(ramSize); err != nil { return nil, err } defer ih.ResizeSem.Release(ramSize) i, imConfig, err := images.Decode(sr, &images.DecodeOpts{ MaxWidth: ih.MaxWidth, MaxHeight: ih.MaxHeight, }) if err != nil { return nil, err } b := i.Bounds() format := imConfig.Format isSquare := b.Dx() == b.Dy() if ih.Square && !isSquare { i = squareImage(i) b = i.Bounds() } // Encode as a new image var buf bytes.Buffer switch format { case "png": err = png.Encode(&buf, i) case "cr2": // Recompress CR2 files as JPEG format = "jpeg" fallthrough default: err = jpeg.Encode(&buf, i, &jpeg.Options{ Quality: 90, }) } if err != nil { return nil, err } return &formatAndImage{format: format, image: buf.Bytes()}, nil }