// DecodeConfig returns the color model and dimensions of a JPEG image without decoding the entire image. func DecodeConfig(r io.Reader) (config image.Config, err error) { // Recover panic defer func() { if r := recover(); r != nil { var ok bool err, ok = r.(error) if !ok { err = fmt.Errorf("JPEG error: %v", r) } } }() dinfo := C.new_decompress() defer C.destroy_decompress(dinfo) srcManager := makeSourceManager(r, dinfo) defer releaseSourceManager(srcManager) C.jpeg_read_header(dinfo, C.TRUE) config = image.Config{ ColorModel: color.YCbCrModel, Width: int(dinfo.image_width), Height: int(dinfo.image_height), } return }
// DecodeIntoRGB reads a JPEG data stream from r and returns decoded image as an rgb.Image with RGB colors. func DecodeIntoRGB(r io.Reader, options *DecoderOptions) (dest *rgb.Image, err error) { // Recover panic defer func() { if r := recover(); r != nil { log.Println(r) if _, ok := r.(error); !ok { err = fmt.Errorf("JPEG error: %v", r) } } }() dinfo := C.new_decompress() defer C.destroy_decompress(dinfo) srcManager := makeSourceManager(r, dinfo) defer releaseSourceManager(srcManager) C.jpeg_read_header(dinfo, C.TRUE) setupDecoderOptions(dinfo, options) C.jpeg_calc_output_dimensions(dinfo) dest = rgb.NewImage(image.Rect(0, 0, int(dinfo.output_width), int(dinfo.output_height))) dinfo.out_color_space = C.JCS_RGB readScanLines(dinfo, dest.Pix, dest.Stride) return }
// DecodeIntoRGBA reads a JPEG data stream from r and returns decoded image as an image.RGBA with RGBA colors. // This function only works with libjpeg-trubo, not libjpeg. func DecodeIntoRGBA(r io.Reader, options *DecoderOptions) (dest *image.RGBA, err error) { // Recover panic defer func() { if r := recover(); r != nil { log.Println(r) if _, ok := r.(error); !ok { err = fmt.Errorf("JPEG error: %v", r) } } }() dinfo := C.new_decompress() defer C.destroy_decompress(dinfo) srcManager := makeSourceManager(r, dinfo) defer releaseSourceManager(srcManager) C.jpeg_read_header(dinfo, C.TRUE) setupDecoderOptions(dinfo, options) C.jpeg_calc_output_dimensions(dinfo) dest = image.NewRGBA(image.Rect(0, 0, int(dinfo.output_width), int(dinfo.output_height))) colorSpace := C.getJCS_EXT_RGBA() if colorSpace == C.JCS_UNKNOWN { return nil, errors.New("JCS_EXT_RGBA is not supported (probably built without libjpeg-trubo)") } dinfo.out_color_space = colorSpace readScanLines(dinfo, dest.Pix, dest.Stride) return }
// Decode reads a JPEG data stream from r and returns decoded image as an image.Image. // Output image has YCbCr colors or 8bit Grayscale. func Decode(r io.Reader, options *DecoderOptions) (dest image.Image, err error) { // Recover panic defer func() { if r := recover(); r != nil { log.Println(r) if _, ok := r.(error); !ok { err = fmt.Errorf("JPEG error: %v", r) } } }() dinfo := C.new_decompress() defer C.destroy_decompress(dinfo) srcManager := makeSourceManager(r, dinfo) defer releaseSourceManager(srcManager) C.jpeg_read_header(dinfo, C.TRUE) setupDecoderOptions(dinfo, options) switch dinfo.num_components { case 1: if dinfo.jpeg_color_space != C.JCS_GRAYSCALE { return nil, errors.New("Image has unsupported colorspace") } dest, err = decodeGray(dinfo) case 3: switch dinfo.jpeg_color_space { case C.JCS_YCbCr: dest, err = decodeYCbCr(dinfo) case C.JCS_RGB: dest, err = decodeRGB(dinfo) default: return nil, errors.New("Image has unsupported colorspace") } } return }