Documentation
¶
Overview ¶
Package lowleveljpeg provides a JPEG encoder that takes in-DCT-space coefficients instead of in-XY-space pixels.
It can be useful for experimenting with or visualizing in-DCT-space transformations, such as quantization, extrapolation and progressive-like reduction. Or for learning about how the JPEG file format works. But most programmers should use the Go standard library's image/jpeg package instead.
Example (Basic) ¶
Example_basic demonstrates creating an opaque RGBA image and saving it as a JPEG. It uses 4:2:0 chroma subsampling, the most popular choice for colorful (not gray) JPEG images.
package main
import (
"bytes"
"fmt"
"image"
"image/color"
"log"
"os"
"github.com/google/wuffs/lib/lowleveljpeg"
)
func main() {
const width, height = 40, 30
src := image.NewRGBA(image.Rect(0, 0, width, height))
// Fill src with a red/blue gradient.
for y := 0; y < height; y++ {
blue := uint8((float64(y) * 0xFF) / (height - 1))
for x := 0; x < width; x++ {
red := uint8((float64(x) * 0xFF) / (width - 1))
src.SetRGBA(x, y, color.RGBA{red, 0x00, blue, 0xFF})
}
}
// Initialize the encoder.
bounds := src.Bounds()
colorType := lowleveljpeg.ColorTypeYCbCr420
buf := &bytes.Buffer{}
enc := lowleveljpeg.Encoder{}
if err := enc.Reset(buf, colorType, bounds.Dx(), bounds.Dy(), nil); err != nil {
log.Fatalf("enc.Reset: %v", err)
}
// Extract, DCT-transform and add each MCU (Mininum Coded Unit). For 4:2:0
// Chroma subsampling, each MCU is 16×16 and contains 6 blocks: 4 Y, 1 Cb,
// 1 Cr.
dx, dy := colorType.MCUDimensions()
fmt.Printf("MCU Dimensions: %d, %d.\n", dx, dy)
srcU8s := lowleveljpeg.Array6BlockU8{}
srcI16s := lowleveljpeg.Array6BlockI16{}
for y := bounds.Min.Y; y < bounds.Max.Y; y += dy {
for x := bounds.Min.X; x < bounds.Max.X; x += dx {
srcU8s.ExtractYCbCrFrom(src, x, y)
srcI16s.ForwardDCTFrom(&srcU8s)
if err := enc.Add6(buf, &srcI16s); err != nil {
log.Fatalf("enc.Add6: %v", err)
}
}
}
// Change writeTmpFiles to true if you want to visually inspect the output.
const writeTmpFiles = false
const dstFilename = "/tmp/lowleveljpeg_example_basic.jpeg"
if writeTmpFiles {
if err := os.WriteFile(dstFilename, buf.Bytes(), 0644); err != nil {
log.Fatalf("os.WriteFile: %v", err)
}
fmt.Println("Wrote ", dstFilename)
} else {
fmt.Println("Skipped", dstFilename)
}
}
Output: MCU Dimensions: 16, 16. Skipped /tmp/lowleveljpeg_example_basic.jpeg
Example (YCbCr444) ¶
Example_yCbCr444 demonstrates loading an RGB PNG, converting to YCbCr and to DCT space and saving as a 4:4:4 JPEG. Multiple JPEG outputs from the one PNG input demonstrate making further transforms during conversion.
package main
import (
"bytes"
"fmt"
"image/jpeg"
"image/png"
"log"
"os"
"github.com/google/wuffs/lib/lowleveljpeg"
)
func main() {
// levels holds a rough, ad hoc measure of a coefficient's frequency, in
// DCT space. Low (or high) levels[i] mean low (or high) frequency.
//
// levels[0] == 0 is the DC coefficient. The others are AC coefficients.
levels := [64]uint8{
0, 1, 2, 3, 4, 5, 6, 7,
1, 1, 2, 3, 4, 5, 6, 7,
2, 2, 2, 3, 4, 5, 6, 7,
3, 3, 3, 3, 4, 5, 6, 7,
4, 4, 4, 4, 4, 5, 6, 7,
5, 5, 5, 5, 5, 5, 6, 7,
6, 6, 6, 6, 6, 6, 6, 7,
7, 7, 7, 7, 7, 7, 7, 7,
}
// Load the source PNG. We will make numerous JPEG encodings of transformed
// versions of this PNG image.
f, err := os.Open("../../test/data/hippopotamus.regular.png")
if err != nil {
log.Fatalf("os.Open: %v", err)
}
defer f.Close()
src, err := png.Decode(f)
if err != nil {
log.Fatalf("png.Decode: %v", err)
}
// Each example (each output JPEG) has a name fragment and a transform from
// source BlockU8 values to destination BlockI16 values.
examples := []struct {
nameFragment string
quality int
transform func(dst *lowleveljpeg.Array3BlockI16, src *lowleveljpeg.Array3BlockU8)
}{{
// Apply the ForwardDCT with no further changes. The resultant JPEG is
// a low quality (but small in file size) version of the source PNG.
nameFragment: "0_quality25",
quality: 25,
transform: func(dst *lowleveljpeg.Array3BlockI16, src *lowleveljpeg.Array3BlockU8) {
dst[0].ForwardDCTFrom(&src[0])
dst[1].ForwardDCTFrom(&src[1])
dst[2].ForwardDCTFrom(&src[2])
},
}, {
// Ditto, with default quality.
nameFragment: "1_quality75",
quality: 75,
transform: func(dst *lowleveljpeg.Array3BlockI16, src *lowleveljpeg.Array3BlockU8) {
dst[0].ForwardDCTFrom(&src[0])
dst[1].ForwardDCTFrom(&src[1])
dst[2].ForwardDCTFrom(&src[2])
},
}, {
// Ditto, with high quality.
nameFragment: "2_quality100",
quality: 100,
transform: func(dst *lowleveljpeg.Array3BlockI16, src *lowleveljpeg.Array3BlockU8) {
dst[0].ForwardDCTFrom(&src[0])
dst[1].ForwardDCTFrom(&src[1])
dst[2].ForwardDCTFrom(&src[2])
},
}, {
// Like 2_quality100 but swap the Chroma-blue and Chroma-red channels.
nameFragment: "3_swap_cb_cr",
quality: 100,
transform: func(dst *lowleveljpeg.Array3BlockI16, src *lowleveljpeg.Array3BlockU8) {
dst[0].ForwardDCTFrom(&src[0])
dst[1].ForwardDCTFrom(&src[2]) // Note the "1" and "2".
dst[2].ForwardDCTFrom(&src[1]) // Note the "2" and "1".
},
}, {
// Set the 8×8 blocks of the Luma channel to neutral (0x80) except for
// each top-left corner, which is black (0x00). Chromas are unchanged.
nameFragment: "4_chroma_only",
quality: 100,
transform: func(dst *lowleveljpeg.Array3BlockI16, src *lowleveljpeg.Array3BlockU8) {
s0 := lowleveljpeg.BlockU8{}
s0[0] = 0x00
for i := 1; i < 64; i++ {
s0[i] = lowleveljpeg.BlockU8NeutralValue
}
dst[0].ForwardDCTFrom(&s0)
dst[1].ForwardDCTFrom(&src[1])
dst[2].ForwardDCTFrom(&src[2])
},
}, {
// Set the Chroma channels to neutral, as well as any Luma coefficients
// that have any horizontal variation (within an 8×8 block). What
// remains are the DC and vertical-only Luma coefficients.
nameFragment: "5_vertical_luma",
quality: 100,
transform: func(dst *lowleveljpeg.Array3BlockI16, src *lowleveljpeg.Array3BlockU8) {
dst[0].ForwardDCTFrom(&src[0])
for i := 0; i < 64; i++ {
if (i & 7) != 0 {
dst[0][i] = lowleveljpeg.BlockI16NeutralValue
}
}
dst[1] = lowleveljpeg.BlockI16{}
dst[2] = lowleveljpeg.BlockI16{}
},
}, {
// Set the Chroma channels to neutral, as well as any medium- or
// high-frequency Luma coefficients.
nameFragment: "6_low_frequency_luma",
quality: 100,
transform: func(dst *lowleveljpeg.Array3BlockI16, src *lowleveljpeg.Array3BlockU8) {
dst[0] = src[0].ForwardDCT()
for i := 0; i < 64; i++ {
if levels[i] > 2 {
dst[0][i] = 0
}
}
dst[1] = lowleveljpeg.BlockI16{}
dst[2] = lowleveljpeg.BlockI16{}
},
}}
// Process each example.
for _, example := range examples {
// Initialize the encoder.
quants := lowleveljpeg.Array2QuantizationFactors{}
quants.SetToStandardValues(example.quality)
opts := &lowleveljpeg.EncoderOptions{
QuantizationFactors: &quants,
}
bounds := src.Bounds()
buf := &bytes.Buffer{}
enc := lowleveljpeg.Encoder{}
if err := enc.Reset(buf, lowleveljpeg.ColorTypeYCbCr444, bounds.Dx(), bounds.Dy(), opts); err != nil {
log.Fatalf("enc.Reset: %v", err)
}
// Extract, transform and add each MCU (Mininum Coded Unit). For 4:4:4
// Chroma subsampling, each MCU is 8×8 and contains 3 blocks: 1 Y, 1
// Cb, 1 Cr.
srcU8s := lowleveljpeg.Array3BlockU8{}
srcI16s := lowleveljpeg.Array3BlockI16{}
for y := bounds.Min.Y; y < bounds.Max.Y; y += 8 {
for x := bounds.Min.X; x < bounds.Max.X; x += 8 {
srcU8s.ExtractYCbCrFrom(src, x, y)
example.transform(&srcI16s, &srcU8s)
if err := enc.Add3(buf, &srcI16s); err != nil {
log.Fatalf("enc.Add3: %v", err)
}
}
}
// As a basic consistency check, confirm that the resultant bytes are a
// valid JPEG. When copy/pasting this code, you can omit this step.
dstBytes := buf.Bytes()
if _, err := jpeg.Decode(bytes.NewReader(dstBytes)); err != nil {
log.Fatalf("jpeg.Decode: %v", err)
}
// Change writeTmpFiles to true if you want to visually inspect the output.
const writeTmpFiles = false
dstFilename := fmt.Sprintf("/tmp/lowleveljpeg_example_%s.jpeg", example.nameFragment)
if writeTmpFiles {
if err := os.WriteFile(dstFilename, dstBytes, 0644); err != nil {
log.Fatalf("os.WriteFile: %v", err)
}
fmt.Println("Wrote ", dstFilename)
} else {
fmt.Println("Skipped", dstFilename)
}
}
}
Output: Skipped /tmp/lowleveljpeg_example_0_quality25.jpeg Skipped /tmp/lowleveljpeg_example_1_quality75.jpeg Skipped /tmp/lowleveljpeg_example_2_quality100.jpeg Skipped /tmp/lowleveljpeg_example_3_swap_cb_cr.jpeg Skipped /tmp/lowleveljpeg_example_4_chroma_only.jpeg Skipped /tmp/lowleveljpeg_example_5_vertical_luma.jpeg Skipped /tmp/lowleveljpeg_example_6_low_frequency_luma.jpeg
Index ¶
- Constants
- Variables
- func RGBToYCoCg(r, g, b uint8) (uint8, uint8, uint8)
- func YCoCgToRGB(yy, co, cg uint8) (uint8, uint8, uint8)
- type Array1BlockI16
- type Array1BlockU8
- type Array2QuantizationFactors
- type Array3BlockI16
- type Array3BlockU8
- type Array6BlockI16
- type Array6BlockU8
- type BlockI16
- type BlockU8
- type ColorType
- type Encoder
- type EncoderOptions
- type QuadBlockU8
- type QuantizationFactors
- type QuantizationStandardValuesType
Examples ¶
Constants ¶
const ( // BlockU8NeutralValue is the neutral value for a BlockU8, which holds // unsigned uint8 values in the range [0x00, 0xFF]. BlockU8NeutralValue = 0x80 // BlockI16NeutralValue is the neutral value for a BlockI16, which holds // signed int16 values in the range [-0x8000, +0x7FFF]. BlockI16NeutralValue = 0 )
const ( // ColorTypeInvalid, the zero value, is invalid. ColorTypeInvalid = ColorType(0) // ColorTypeGray means a single channel (Gray). ColorTypeGray = ColorType(1) // ColorTypeYCbCr444 means three channels (Luma, Chroma-blue, Chroma-red), // using 4:4:4 Chroma subsampling. ColorTypeYCbCr444 = ColorType(3) // ColorTypeYCbCr420 means three channels (Luma, Chroma-blue, Chroma-red), // using 4:2:0 Chroma subsampling. // // This is the most popular color type for colorful (not gray) JPEG images. ColorTypeYCbCr420 = ColorType(6) )
const ( // QuantizationStandardValuesTypeLuma means to use table K.1 from the JPEG // spec. QuantizationStandardValuesTypeLuma = QuantizationStandardValuesType(0) // QuantizationStandardValuesTypeChroma means to use table K.2 from the // JPEG spec. QuantizationStandardValuesTypeChroma = QuantizationStandardValuesType(1) )
const ( // MinimumQuality and MaximumQuality are the minimum and maximum // (inclusive) values for SetToStandardValues' quality parameter. MinimumQuality = 1 MaximumQuality = 100 // DefaultQuality is the default value used by EncoderOptions for // SetToStandardValues' quality parameter. It matches libjpeg's default // both in terms of numerical value and in behavior. DefaultQuality = 75 // MinimumBaselineQuality is lowest quality level where both the cjpeg // program (from the libjpeg C project) and this Go package will agree on // the exact quantization factors. // // It's still valid to pass a SetToStandardValues quality parameter value // below 24. But when doing so, passing the equivalent to cjpeg will print // a JTRC_16BIT_TABLES warning: "quantization tables are too coarse for // baseline JPEG". cjpeg will therefore produce extended (instead of // baseline) JPEGs, using 2 bytes (instead of 1 byte) per quantization // factor, allowing factors above 0xFF. // // This Go package will instead clamp such quantization factors to 0xFF. // // Both approaches are viable, producing valid JPEGs. This Go package, like // the Go standard library's image/jpeg package, simply chooses to always // produce baseline (instead of extended) JPEGs, for best compatibility // with other JPEG decoders. MinimumBaselineQuality = 24 )
Variables ¶
var ( ErrBadAddNForColorType = errors.New("lowleveljpeg: bad AddN for ColorType") ErrBadArgument = errors.New("lowleveljpeg: bad argument") ErrInvalidBlockI16 = errors.New("lowleveljpeg: invalid BlockI16") ErrNilReceiver = errors.New("lowleveljpeg: nil receiver") ErrPreviouslyReturnedError = errors.New("lowleveljpeg: previously returned error") ErrTooManyAddNCalls = errors.New("lowleveljpeg: too many AddN calls") )
Functions ¶
func RGBToYCoCg ¶
RGBToYCoCg converts an RGB triple to a YCoCg triple.
JPEG uses YCbCr, not YCoCg, but this function allows for experimenting with JPEG-inspired color transformations.
Types ¶
type Array1BlockI16 ¶
type Array1BlockI16 [1]BlockI16
ArrayNBlockT are arrays of N BlockT values. N is the number of blocks in a JPEG MCU (Mininum Coded Unit).
- N = 1 is for ColorTypeGray.
- N = 3 is for ColorTypeYCbCr444.
- N = 6 is for ColorTypeYCbCr420.
func (*Array1BlockI16) ForwardDCTFrom ¶
func (dst *Array1BlockI16) ForwardDCTFrom(src *Array1BlockU8)
ForwardDCTFrom calls ForwardDCTFrom pairwise on dst and src elements.
func (*Array1BlockI16) SetToNeutral ¶
func (b *Array1BlockI16) SetToNeutral()
SetToNeutral calls SetToNeutral on each element.
type Array1BlockU8 ¶
type Array1BlockU8 [1]BlockU8
ArrayNBlockT are arrays of N BlockT values. N is the number of blocks in a JPEG MCU (Mininum Coded Unit).
- N = 1 is for ColorTypeGray.
- N = 3 is for ColorTypeYCbCr444.
- N = 6 is for ColorTypeYCbCr420.
func (*Array1BlockU8) ExtractYCbCrFrom ¶
func (dst *Array1BlockU8) ExtractYCbCrFrom(m image.Image, topLeftX int, topLeftY int)
ExtractYCbCrFrom sets dst to a single channel (Gray) 8×8 MCU (Minimum Coded Unit), with the given top-left corner, from the image m.
func (*Array1BlockU8) ExtractYCoCgFrom ¶
func (dst *Array1BlockU8) ExtractYCoCgFrom(m image.Image, topLeftX int, topLeftY int)
ExtractYCoCgFrom is like ExtractYCbCrFrom but produces Gray (Luma) values according to the (Luma, Chroma-orange, Chroma-green) formulae instead of (Luma, Chroma-blue, Chroma-red).
JPEG uses YCbCr, not YCoCg, but this method allows for experimenting with JPEG-inspired image transformations.
func (*Array1BlockU8) InverseDCTFrom ¶
func (dst *Array1BlockU8) InverseDCTFrom(src *Array1BlockI16)
InverseDCTFrom calls InverseDCTFrom pairwise on dst and src elements.
func (*Array1BlockU8) SetToNeutral ¶
func (b *Array1BlockU8) SetToNeutral()
SetToNeutral calls SetToNeutral on each element.
type Array2QuantizationFactors ¶
type Array2QuantizationFactors [2]QuantizationFactors
Array2QuantizationFactors is an array of 2 QuantizationFactors. The first one is for Luma and the second one is for Chroma.
func (*Array2QuantizationFactors) SetToStandardValues ¶
func (b *Array2QuantizationFactors) SetToStandardValues(quality int)
SetToStandardValues calls SetToStandardValues on each element.
type Array3BlockI16 ¶
type Array3BlockI16 [3]BlockI16
ArrayNBlockT are arrays of N BlockT values. N is the number of blocks in a JPEG MCU (Mininum Coded Unit).
- N = 1 is for ColorTypeGray.
- N = 3 is for ColorTypeYCbCr444.
- N = 6 is for ColorTypeYCbCr420.
func (*Array3BlockI16) ForwardDCTFrom ¶
func (dst *Array3BlockI16) ForwardDCTFrom(src *Array3BlockU8)
ForwardDCTFrom calls ForwardDCTFrom pairwise on dst and src elements.
func (*Array3BlockI16) SetToNeutral ¶
func (b *Array3BlockI16) SetToNeutral()
SetToNeutral calls SetToNeutral on each element.
type Array3BlockU8 ¶
type Array3BlockU8 [3]BlockU8
ArrayNBlockT are arrays of N BlockT values. N is the number of blocks in a JPEG MCU (Mininum Coded Unit).
- N = 1 is for ColorTypeGray.
- N = 3 is for ColorTypeYCbCr444.
- N = 6 is for ColorTypeYCbCr420.
func (*Array3BlockU8) ExtractYCbCrFrom ¶
func (dst *Array3BlockU8) ExtractYCbCrFrom(m image.Image, topLeftX int, topLeftY int)
ExtractYCbCrFrom sets dst to a three channel (Luma, Chroma-blue, Chroma-red) 8×8 4:4:4 MCU (Minimum Coded Unit), with the given top-left corner, from the image m.
func (*Array3BlockU8) ExtractYCoCgFrom ¶
func (dst *Array3BlockU8) ExtractYCoCgFrom(m image.Image, topLeftX int, topLeftY int)
ExtractYCoCgFrom is like ExtractYCbCrFrom but produces (Luma, Chroma-orange, Chroma-green) instead of (Luma, Chroma-blue, Chroma-red).
JPEG uses YCbCr, not YCoCg, but this method allows for experimenting with JPEG-inspired image transformations.
func (*Array3BlockU8) InverseDCTFrom ¶
func (dst *Array3BlockU8) InverseDCTFrom(src *Array3BlockI16)
InverseDCTFrom calls InverseDCTFrom pairwise on dst and src elements.
func (*Array3BlockU8) SetToNeutral ¶
func (b *Array3BlockU8) SetToNeutral()
SetToNeutral calls SetToNeutral on each element.
type Array6BlockI16 ¶
type Array6BlockI16 [6]BlockI16
ArrayNBlockT are arrays of N BlockT values. N is the number of blocks in a JPEG MCU (Mininum Coded Unit).
- N = 1 is for ColorTypeGray.
- N = 3 is for ColorTypeYCbCr444.
- N = 6 is for ColorTypeYCbCr420.
func (*Array6BlockI16) ForwardDCTFrom ¶
func (dst *Array6BlockI16) ForwardDCTFrom(src *Array6BlockU8)
ForwardDCTFrom calls ForwardDCTFrom pairwise on dst and src elements.
func (*Array6BlockI16) SetToNeutral ¶
func (b *Array6BlockI16) SetToNeutral()
SetToNeutral calls SetToNeutral on each element.
type Array6BlockU8 ¶
type Array6BlockU8 [6]BlockU8
ArrayNBlockT are arrays of N BlockT values. N is the number of blocks in a JPEG MCU (Mininum Coded Unit).
- N = 1 is for ColorTypeGray.
- N = 3 is for ColorTypeYCbCr444.
- N = 6 is for ColorTypeYCbCr420.
func (*Array6BlockU8) ExtractYCbCrFrom ¶
func (dst *Array6BlockU8) ExtractYCbCrFrom(m image.Image, topLeftX int, topLeftY int)
ExtractYCbCrFrom sets dst to a three channel (Luma, Chroma-blue, Chroma-red) 16×16 4:2:0 MCU (Minimum Coded Unit, with the given top-left corner, from the image m.
The 6 elements are:
- Luma top left
- Luma top right
- Luma bottom left
- Luma bottom right
- Chroma-blue
- Chroma-red
func (*Array6BlockU8) ExtractYCoCgFrom ¶
func (dst *Array6BlockU8) ExtractYCoCgFrom(m image.Image, topLeftX int, topLeftY int)
ExtractYCoCgFrom is like ExtractYCbCrFrom but produces (Luma, Chroma-orange, Chroma-green) instead of (Luma, Chroma-blue, Chroma-red).
JPEG uses YCbCr, not YCoCg, but this method allows for experimenting with JPEG-inspired image transformations.
func (*Array6BlockU8) InverseDCTFrom ¶
func (dst *Array6BlockU8) InverseDCTFrom(src *Array6BlockI16)
InverseDCTFrom calls InverseDCTFrom pairwise on dst and src elements.
func (*Array6BlockU8) SetToNeutral ¶
func (b *Array6BlockU8) SetToNeutral()
SetToNeutral calls SetToNeutral on each element.
type BlockI16 ¶
type BlockI16 [64]int16
BlockI16 is an 8×8 block of int16 values, such as a block of JPEG coefficients.
It is indexed in DCT (not XY) space. If b is a BlockI16 then b[0] is the DC coefficient and every other element is an AC coefficient.
The horizontal-only AC coefficients are b[1], b[2], ..., b[7], in order from low-frequency to high-frequency.
The vertical-only AC coefficients are b[8], b[16], ..., b[56], in order from low-frequency to high-frequency.
func (*BlockI16) ForwardDCTFrom ¶
ForwardDCTFrom sets *dst to src.ForwardDCT().
func (*BlockI16) InverseDCT ¶
InverseDCT returns the IDCT (Inverse Discrete Cosine Transform) of b.
func (*BlockI16) IsValid ¶
IsValid returns whether b does not contain unexpectedly extreme values for an 8-bit-depth JPEG - one that is invalid to pass to AddN. ForwardDCT or ForwardDCTFrom always returns or sets a BlockI16 that IsValid.
Specifically:
- a DC element is out of range when outside [-1024, +1023].
- an AC element is out of range when outside [-1023, +1023].
A BlockI16 is valid when none of its elements are out of range.
func (*BlockI16) SetToNeutral ¶
func (b *BlockI16) SetToNeutral()
SetToNeutral sets each element to BlockI16NeutralValue.
type BlockU8 ¶
type BlockU8 [64]uint8
BlockU8 is an 8×8 block of uint8 values, such as a block of red, green, blue or gray pixel values.
It is indexed in XY (not DCT) space. If b is a BlockU8 then b[0] is the top-left corner and b[8] is one pixel below that.
func (*BlockU8) DownsampleFrom ¶
func (dst *BlockU8) DownsampleFrom(src *QuadBlockU8)
DownsampleFrom reduces one 16×16 quad-block to one 8×8 block.
func (*BlockU8) ForwardDCT ¶
ForwardDCT returns the FDCT (Forward Discrete Cosine Transform) of b.
func (*BlockU8) InverseDCTFrom ¶
InverseDCTFrom sets *dst to src.InverseDCT().
func (*BlockU8) SetToNeutral ¶
func (b *BlockU8) SetToNeutral()
SetToNeutral sets each element to BlockU8NeutralValue.
type ColorType ¶
type ColorType byte
ColorType is a JPEG image's color type.
func (ColorType) MCUDimensions ¶
MCUDimensions returns the width and height of a Mininum Coded Unit.
type Encoder ¶
type Encoder struct {
// contains filtered or unexported fields
}
Encoder writes JPEG-formatted bytes to an io.Writer.
Call Reset and then AddN multiple times (N depends on the ColorType). Each AddN call encodes a Minimum Coded Unit (an 8×8 or 16×16 group of pixels, depending on the ColorType). Add MCUs in left-to-right top-to-bottom order. The final AddN call also writes the JPEG footer.
AddN takes ArrayNBlockI16 arguments, which are post-FDCT (when encoding) or pre-IDCT (when decoding) coefficients.
To get ArrayNBlockI16 values from pixels, use ExtractYCbCrFrom on an image.Image (to get an array of BlockU8 values) and then FowardDCTFrom (to get an array of BlockI16 values). See Example_basic for an example.
An Encoder makes no allocations, other than the Encoder struct itself and any allocations that the passed io.Writer makes.
An Encoder can be re-used, by calling Reset.
func (*Encoder) Add1 ¶
func (e *Encoder) Add1(w io.Writer, b *Array1BlockI16) error
Add1 adds an 8×8 group of pixels to a ColorTypeGray image.
func (*Encoder) Add3 ¶
func (e *Encoder) Add3(w io.Writer, b *Array3BlockI16) error
Add3 adds an 8×8 group of pixels to a ColorTypeYCbCr444 image.
func (*Encoder) Add6 ¶
func (e *Encoder) Add6(w io.Writer, b *Array6BlockI16) error
Add6 adds a 16×16 group of pixels to a ColorTypeYCbCr420 image.
func (*Encoder) Reset ¶
func (e *Encoder) Reset(w io.Writer, colorType ColorType, width int, height int, options *EncoderOptions) error
Reset makes an Encoder ready to use (ready to make AddN calls), for encoding a JPEG with the given colorType, width and height.
colorType should be ColorTypeGray, ColorTypeYCbCr444 or ColorTypeYCbCr420.
width and height should both be positive but no larger than 0xFFFF, since a JPEG image cannot represent anything larger.
options may be nil, which means to use the default configuration.
type EncoderOptions ¶
type EncoderOptions struct {
// QuantizationFactors are the BlockI16 quantization factors. A nil pointer
// is equivalent to using DefaultQuality.
QuantizationFactors *Array2QuantizationFactors
}
EncoderOptions are optional arguments to Encoder.Reset. The zero value is valid and means to use the default configuration.
type QuadBlockU8 ¶
type QuadBlockU8 [256]uint8
QuadBlockU8 is like a BlockU8 but it is 16×16 instead of 8×8.
It is indexed in XY (not DCT) space. If b is a QuadBlockU8 then b[0] is the top-left corner and b[16] is one pixel below that.
func (*QuadBlockU8) SetToNeutral ¶
func (b *QuadBlockU8) SetToNeutral()
SetToNeutral sets each element to BlockU8NeutralValue.
func (QuadBlockU8) String ¶
func (b QuadBlockU8) String() string
String returns b in human-readable form.
func (*QuadBlockU8) UpsampleFrom ¶
func (dst *QuadBlockU8) UpsampleFrom(src *BlockU8)
UpsampleFrom produces one 16×16 quad-block from one 8×8 block.
It uses a triangle filter.
type QuantizationFactors ¶
type QuantizationFactors [64]uint8
QuantizationFactors is an 8×8 block of uint8 values, used to quantize a BlockI16.
It is indexed in DCT (not XY) space, like a Block16.
func (*QuantizationFactors) IsValid ¶
func (b *QuantizationFactors) IsValid() bool
IsValid returns whether b does not contain any zero-valued elements.
func (*QuantizationFactors) SetToStandardValues ¶
func (b *QuantizationFactors) SetToStandardValues(which QuantizationStandardValuesType, quality int)
SetToStandardValues sets b to one of two standard quantization tables (Tables K.1 or K.2 in the JPEG spec, for Luma and Chroma respectively), scaled by a quality parameter with the same meaning as that used by libjpeg's encoder.
The quality parameter ranges from 1 (low quality) to 100 (high quality), inclusive. Values outside of that range will be clamped to be in [1, 100].
Passing quality = MinimumQuality will set every element of b to 0xFF.
Passing quality = MaximumQuality will set every element of b to 0x01.
func (QuantizationFactors) String ¶
func (b QuantizationFactors) String() string
String returns b in human-readable form.
type QuantizationStandardValuesType ¶
type QuantizationStandardValuesType byte
QuantizationStandardValuesType selects which table from the JPEG specification to use for SetToStandardValues.