Source File
scan.go
Belonging Package
image/jpeg
package jpeg
import (
)
func ( *decoder) (, int) {
if .nComp == 1 {
:= image.NewGray(image.Rect(0, 0, 8*, 8*))
.img1 = .SubImage(image.Rect(0, 0, .width, .height)).(*image.Gray)
return
}
:= .comp[0].h
:= .comp[0].v
:= / .comp[1].h
:= / .comp[1].v
var image.YCbCrSubsampleRatio
switch <<4 | {
case 0x11:
= image.YCbCrSubsampleRatio444
case 0x12:
= image.YCbCrSubsampleRatio440
case 0x21:
= image.YCbCrSubsampleRatio422
case 0x22:
= image.YCbCrSubsampleRatio420
case 0x41:
= image.YCbCrSubsampleRatio411
case 0x42:
= image.YCbCrSubsampleRatio410
default:
panic("unreachable")
}
:= image.NewYCbCr(image.Rect(0, 0, 8**, 8**), )
.img3 = .SubImage(image.Rect(0, 0, .width, .height)).(*image.YCbCr)
if .nComp == 4 {
, := .comp[3].h, .comp[3].v
.blackPix = make([]byte, 8***8**)
.blackStride = 8 * *
}
}
func ( *decoder) ( int) error {
if .nComp == 0 {
return FormatError("missing SOF marker")
}
if < 6 || 4+2*.nComp < || %2 != 0 {
return FormatError("SOS has wrong length")
}
if := .readFull(.tmp[:]); != nil {
return
}
:= int(.tmp[0])
if != 4+2* {
return FormatError("SOS length inconsistent with number of components")
}
var [maxComponents]struct {
uint8
uint8 // DC table selector.
uint8 // AC table selector.
}
:= 0
for := 0; < ; ++ {
:= .tmp[1+2*] // Component selector.
:= -1
for , := range .comp[:.nComp] {
if == .c {
=
}
}
if < 0 {
return FormatError("unknown component selector")
}
for := 0; < ; ++ {
if []. == []. {
return FormatError("repeated component selector")
}
}
+= .comp[].h * .comp[].v
[]. = .tmp[2+2*] >> 4
if := [].; > maxTh || (.baseline && > 1) {
return FormatError("bad Td value")
}
[]. = .tmp[2+2*] & 0x0f
if := [].; > maxTh || (.baseline && > 1) {
return FormatError("bad Ta value")
}
if .nComp > 1 && > 10 {
return FormatError("total sampling factors too large")
}
, , , := int32(0), int32(blockSize-1), uint32(0), uint32(0)
if .progressive {
= int32(.tmp[1+2*])
= int32(.tmp[2+2*])
= uint32(.tmp[3+2*] >> 4)
= uint32(.tmp[3+2*] & 0x0f)
if ( == 0 && != 0) || > || blockSize <= {
return FormatError("bad spectral selection bounds")
}
if != 0 && != 1 {
return FormatError("progressive AC coefficients for more than one component")
}
if != 0 && != +1 {
return FormatError("bad successive approximation values")
}
}
, := .comp[0].h, .comp[0].v // The h and v values from the Y components.
:= (.width + 8* - 1) / (8 * )
:= (.height + 8* - 1) / (8 * )
if .img1 == nil && .img3 == nil {
.makeImg(, )
}
if .progressive {
for := 0; < ; ++ {
:= [].
if .progCoeffs[] == nil {
.progCoeffs[] = make([]block, **.comp[].h*.comp[].v)
}
}
}
.bits = bits{}
, := 0, uint8(rst0Marker)
if .progressive {
= .progCoeffs[][**+]
} else {
= block{}
}
if != 0 {
if := .refine(&, &.huff[acTable][[].], , , 1<<); != nil {
return
}
} else {
:=
if == 0 {
, := .decodeHuffman(&.huff[dcTable][[].])
if != nil {
return
}
if > 16 {
return UnsupportedError("excessive DC component")
}
, := .receiveExtend()
if != nil {
return
}
[] +=
[0] = [] <<
}
if <= && .eobRun > 0 {
.eobRun--
:= &.huff[acTable][[].]
for ; <= ; ++ {
, := .decodeHuffman()
if != nil {
return
}
:= >> 4
:= & 0x0f
if != 0 {
+= int32()
if > {
break
}
, := .receiveExtend()
if != nil {
return
}
[unzig[]] = <<
} else {
if != 0x0f {
.eobRun = uint16(1 << )
if != 0 {
, := .decodeBits(int32())
if != nil {
return
}
.eobRun |= uint16()
}
.eobRun--
break
}
+= 0x0f
}
}
}
}
continue
}
if := .reconstructBlock(&, , , int()); != nil {
return
}
} // for j
} // for i
++
if .tmp[0] == 0xff && .tmp[1] == 0x00 {
if := .readFull(.tmp[:2]); != nil {
return
}
}
if .tmp[0] != 0xff || .tmp[1] != {
return FormatError("bad RST marker")
}
++
if == rst7Marker+1 {
= rst0Marker
:=
if .eobRun == 0 {
:
for ; <= ; ++ {
:= int32(0)
, := .decodeHuffman()
if != nil {
return
}
:= >> 4
:= & 0x0f
switch {
case 0:
if != 0x0f {
.eobRun = uint16(1 << )
if != 0 {
, := .decodeBits(int32())
if != nil {
return
}
.eobRun |= uint16()
}
break
}
case 1:
=
, := .decodeBit()
if != nil {
return
}
if ! {
= -
}
default:
return FormatError("unexpected Huffman code")
}
, = .refineNonZeroes(, , , int32(), )
if != nil {
return
}
if > {
return FormatError("too many coefficients")
}
if != 0 {
[unzig[]] =
}
}
}
if .eobRun > 0 {
.eobRun--
if , := .refineNonZeroes(, , , -1, ); != nil {
return
}
}
return nil
}
:= .comp[0].h
:= (.width + 8* - 1) / (8 * )
for := 0; < .nComp; ++ {
if .progCoeffs[] == nil {
continue
}
:= 8 * .comp[0].v / .comp[].v
:= 8 * .comp[0].h / .comp[].h
:= * .comp[].h
for := 0; * < .height; ++ {
for := 0; * < .width; ++ {
if := .reconstructBlock(&.progCoeffs[][*+], , , ); != nil {
return
}
}
}
}
return nil
}
func ( *decoder) ( *block, , , int) error {
:= &.quant[.comp[].tq]
for := 0; < blockSize; ++ {
[unzig[]] *= []
}
idct()
, := []byte(nil), 0
if .nComp == 1 {
, = .img1.Pix[8*(*.img1.Stride+):], .img1.Stride
} else {
switch {
case 0:
, = .img3.Y[8*(*.img3.YStride+):], .img3.YStride
case 1:
, = .img3.Cb[8*(*.img3.CStride+):], .img3.CStride
case 2:
, = .img3.Cr[8*(*.img3.CStride+):], .img3.CStride
case 3:
, = .blackPix[8*(*.blackStride+):], .blackStride
default:
return UnsupportedError("too many components")
}
![]() |
The pages are generated with Golds v0.3.2-preview. (GOOS=darwin GOARCH=amd64) Golds is a Go 101 project developed by Tapir Liu. PR and bug reports are welcome and can be submitted to the issue list. Please follow @Go100and1 (reachable from the left QR code) to get the latest news of Golds. |