tinygo.org/x/drivers@v0.27.1-0.20240509133757-7dbca2a54349/image/jpeg/scan.go (about) 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 package jpeg 6 7 import ( 8 "image" 9 "image/color" 10 ) 11 12 // makeImg allocates and initializes the destination image. 13 func (d *decoder) makeImg(mxx, myy int) { 14 if d.nComp == 1 { 15 m := image.NewGray(image.Rect(0, 0, 8*mxx, 8*myy)) 16 d.img1 = m.SubImage(image.Rect(0, 0, d.width, d.height)).(*image.Gray) 17 return 18 } 19 20 h0 := d.comp[0].h 21 v0 := d.comp[0].v 22 hRatio := h0 / d.comp[1].h 23 vRatio := v0 / d.comp[1].v 24 var subsampleRatio image.YCbCrSubsampleRatio 25 switch hRatio<<4 | vRatio { 26 case 0x11: 27 subsampleRatio = image.YCbCrSubsampleRatio444 28 case 0x12: 29 subsampleRatio = image.YCbCrSubsampleRatio440 30 case 0x21: 31 subsampleRatio = image.YCbCrSubsampleRatio422 32 case 0x22: 33 subsampleRatio = image.YCbCrSubsampleRatio420 34 case 0x41: 35 subsampleRatio = image.YCbCrSubsampleRatio411 36 case 0x42: 37 subsampleRatio = image.YCbCrSubsampleRatio410 38 default: 39 panic("unreachable") 40 } 41 m := image.NewYCbCr(image.Rect(0, 0, 8*h0*mxx, 8*v0*myy), subsampleRatio) 42 d.img3 = m.SubImage(image.Rect(0, 0, d.width, d.height)).(*image.YCbCr) 43 44 if d.nComp == 4 { 45 h3, v3 := d.comp[3].h, d.comp[3].v 46 d.blackPix = make([]byte, 8*h3*mxx*8*v3*myy) 47 d.blackStride = 8 * h3 * mxx 48 } 49 } 50 51 // processSOSBuf is a Buffer for creating RGBBitmap in processSOS. It needs to 52 // hold four 8 x 8 pix 24bit color images. 53 var processSOSBuf [3 * 8 * 8 * 4]byte 54 55 // Specified in section B.2.3. 56 func (d *decoder) processSOS(n int) error { 57 if d.nComp == 0 { 58 return FormatError("missing SOF marker") 59 } 60 if n < 6 || 4+2*d.nComp < n || n%2 != 0 { 61 return FormatError("SOS has wrong length") 62 } 63 if err := d.readFull(d.tmp[:n]); err != nil { 64 return err 65 } 66 nComp := int(d.tmp[0]) 67 if n != 4+2*nComp { 68 return FormatError("SOS length inconsistent with number of components") 69 } 70 var scan [maxComponents]struct { 71 compIndex uint8 72 td uint8 // DC table selector. 73 ta uint8 // AC table selector. 74 } 75 totalHV := 0 76 for i := 0; i < nComp; i++ { 77 cs := d.tmp[1+2*i] // Component selector. 78 compIndex := -1 79 for j, comp := range d.comp[:d.nComp] { 80 if cs == comp.c { 81 compIndex = j 82 } 83 } 84 if compIndex < 0 { 85 return FormatError("unknown component selector") 86 } 87 scan[i].compIndex = uint8(compIndex) 88 // Section B.2.3 states that "the value of Cs_j shall be different from 89 // the values of Cs_1 through Cs_(j-1)". Since we have previously 90 // verified that a frame's component identifiers (C_i values in section 91 // B.2.2) are unique, it suffices to check that the implicit indexes 92 // into d.comp are unique. 93 for j := 0; j < i; j++ { 94 if scan[i].compIndex == scan[j].compIndex { 95 return FormatError("repeated component selector") 96 } 97 } 98 totalHV += d.comp[compIndex].h * d.comp[compIndex].v 99 100 // The baseline t <= 1 restriction is specified in table B.3. 101 scan[i].td = d.tmp[2+2*i] >> 4 102 if t := scan[i].td; t > maxTh || (d.baseline && t > 1) { 103 return FormatError("bad Td value") 104 } 105 scan[i].ta = d.tmp[2+2*i] & 0x0f 106 if t := scan[i].ta; t > maxTh || (d.baseline && t > 1) { 107 return FormatError("bad Ta value") 108 } 109 } 110 // Section B.2.3 states that if there is more than one component then the 111 // total H*V values in a scan must be <= 10. 112 if d.nComp > 1 && totalHV > 10 { 113 return FormatError("total sampling factors too large") 114 } 115 116 // zigStart and zigEnd are the spectral selection bounds. 117 // ah and al are the successive approximation high and low values. 118 // The spec calls these values Ss, Se, Ah and Al. 119 // 120 // For progressive JPEGs, these are the two more-or-less independent 121 // aspects of progression. Spectral selection progression is when not 122 // all of a block's 64 DCT coefficients are transmitted in one pass. 123 // For example, three passes could transmit coefficient 0 (the DC 124 // component), coefficients 1-5, and coefficients 6-63, in zig-zag 125 // order. Successive approximation is when not all of the bits of a 126 // band of coefficients are transmitted in one pass. For example, 127 // three passes could transmit the 6 most significant bits, followed 128 // by the second-least significant bit, followed by the least 129 // significant bit. 130 // 131 // For sequential JPEGs, these parameters are hard-coded to 0/63/0/0, as 132 // per table B.3. 133 zigStart, zigEnd, ah, al := int32(0), int32(blockSize-1), uint32(0), uint32(0) 134 if d.progressive { 135 zigStart = int32(d.tmp[1+2*nComp]) 136 zigEnd = int32(d.tmp[2+2*nComp]) 137 ah = uint32(d.tmp[3+2*nComp] >> 4) 138 al = uint32(d.tmp[3+2*nComp] & 0x0f) 139 if (zigStart == 0 && zigEnd != 0) || zigStart > zigEnd || blockSize <= zigEnd { 140 return FormatError("bad spectral selection bounds") 141 } 142 if zigStart != 0 && nComp != 1 { 143 return FormatError("progressive AC coefficients for more than one component") 144 } 145 if ah != 0 && ah != al+1 { 146 return FormatError("bad successive approximation values") 147 } 148 } 149 150 // mxx and myy are the number of MCUs (Minimum Coded Units) in the image. 151 h0, v0 := d.comp[0].h, d.comp[0].v // The h and v values from the Y components. 152 mxx := (d.width + 8*h0 - 1) / (8 * h0) 153 myy := (d.height + 8*v0 - 1) / (8 * v0) 154 if d.img1 == nil && d.img3 == nil { 155 // Minimizes memory usage in order to run on TinyGo. In order to keep 156 // the amount of code changes down, the image is created as a 1 x 1 157 // image at this point. 158 d.makeImg(1, 1) 159 } 160 if d.progressive { 161 for i := 0; i < nComp; i++ { 162 compIndex := scan[i].compIndex 163 if d.progCoeffs[compIndex] == nil { 164 d.progCoeffs[compIndex] = make([]block, mxx*myy*d.comp[compIndex].h*d.comp[compIndex].v) 165 } 166 } 167 } 168 169 d.bits = bits{} 170 mcu, expectedRST := 0, uint8(rst0Marker) 171 var ( 172 // b is the decoded coefficients, in natural (not zig-zag) order. 173 b block 174 dc [maxComponents]int32 175 // bx and by are the location of the current block, in units of 8x8 176 // blocks: the third block in the first row has (bx, by) = (2, 0). 177 bx, by int 178 blockCount int 179 ) 180 for my := 0; my < myy; my++ { 181 for mx := 0; mx < mxx; mx++ { 182 for i := 0; i < nComp; i++ { 183 compIndex := scan[i].compIndex 184 hi := d.comp[compIndex].h 185 vi := d.comp[compIndex].v 186 for j := 0; j < hi*vi; j++ { 187 // The blocks are traversed one MCU at a time. For 4:2:0 chroma 188 // subsampling, there are four Y 8x8 blocks in every 16x16 MCU. 189 // 190 // For a sequential 32x16 pixel image, the Y blocks visiting order is: 191 // 0 1 4 5 192 // 2 3 6 7 193 // 194 // For progressive images, the interleaved scans (those with nComp > 1) 195 // are traversed as above, but non-interleaved scans are traversed left 196 // to right, top to bottom: 197 // 0 1 2 3 198 // 4 5 6 7 199 // Only DC scans (zigStart == 0) can be interleaved. AC scans must have 200 // only one component. 201 // 202 // To further complicate matters, for non-interleaved scans, there is no 203 // data for any blocks that are inside the image at the MCU level but 204 // outside the image at the pixel level. For example, a 24x16 pixel 4:2:0 205 // progressive image consists of two 16x16 MCUs. The interleaved scans 206 // will process 8 Y blocks: 207 // 0 1 4 5 208 // 2 3 6 7 209 // The non-interleaved scans will process only 6 Y blocks: 210 // 0 1 2 211 // 3 4 5 212 if nComp != 1 { 213 bx = hi*mx + j%hi 214 by = vi*my + j/hi 215 } else { 216 q := mxx * hi 217 bx = blockCount % q 218 by = blockCount / q 219 blockCount++ 220 if bx*8 >= d.width || by*8 >= d.height { 221 continue 222 } 223 } 224 225 // Load the previous partially decoded coefficients, if applicable. 226 if d.progressive { 227 b = d.progCoeffs[compIndex][by*mxx*hi+bx] 228 } else { 229 b = block{} 230 } 231 232 if ah != 0 { 233 if err := d.refine(&b, &d.huff[acTable][scan[i].ta], zigStart, zigEnd, 1<<al); err != nil { 234 return err 235 } 236 } else { 237 zig := zigStart 238 if zig == 0 { 239 zig++ 240 // Decode the DC coefficient, as specified in section F.2.2.1. 241 value, err := d.decodeHuffman(&d.huff[dcTable][scan[i].td]) 242 if err != nil { 243 return err 244 } 245 if value > 16 { 246 return UnsupportedError("excessive DC component") 247 } 248 dcDelta, err := d.receiveExtend(value) 249 if err != nil { 250 return err 251 } 252 dc[compIndex] += dcDelta 253 b[0] = dc[compIndex] << al 254 } 255 256 if zig <= zigEnd && d.eobRun > 0 { 257 d.eobRun-- 258 } else { 259 // Decode the AC coefficients, as specified in section F.2.2.2. 260 huff := &d.huff[acTable][scan[i].ta] 261 for ; zig <= zigEnd; zig++ { 262 value, err := d.decodeHuffman(huff) 263 if err != nil { 264 return err 265 } 266 val0 := value >> 4 267 val1 := value & 0x0f 268 if val1 != 0 { 269 zig += int32(val0) 270 if zig > zigEnd { 271 break 272 } 273 ac, err := d.receiveExtend(val1) 274 if err != nil { 275 return err 276 } 277 b[unzig[zig]] = ac << al 278 } else { 279 if val0 != 0x0f { 280 d.eobRun = uint16(1 << val0) 281 if val0 != 0 { 282 bits, err := d.decodeBits(int32(val0)) 283 if err != nil { 284 return err 285 } 286 d.eobRun |= uint16(bits) 287 } 288 d.eobRun-- 289 break 290 } 291 zig += 0x0f 292 } 293 } 294 } 295 } 296 297 if d.progressive { 298 // Save the coefficients. 299 d.progCoeffs[compIndex][by*mxx*hi+bx] = b 300 // At this point, we could call reconstructBlock to dequantize and perform the 301 // inverse DCT, to save early stages of a progressive image to the *image.YCbCr 302 // buffers (the whole point of progressive encoding), but in Go, the jpeg.Decode 303 // function does not return until the entire image is decoded, so we "continue" 304 // here to avoid wasted computation. Instead, reconstructBlock is called on each 305 // accumulated block by the reconstructProgressiveImage method after all of the 306 // SOS markers are processed. 307 continue 308 } 309 if dst, err := d.reconstructBlock(&b, bx, by, int(compIndex)); err != nil { 310 return err 311 } else { 312 // Currently, only the YCbCr422 format is supported. 313 switch compIndex { 314 case 0: // Y 315 bx8 := bx * 8 316 by8 := by * 8 317 bx16 := bx8 % 16 318 by16 := by8 % 16 319 for cy := 0; cy < 8; cy++ { 320 for cx := 0; cx < 8; cx++ { 321 processSOSBuf[((cy+by16)*16+(cx+bx16))*3+0] = dst[cy*8+cx] 322 } 323 } 324 case 1: // Cb 325 bx8 := bx * 8 * 2 326 by8 := by * 8 * 2 327 bx16 := bx8 % 16 328 by16 := by8 % 16 329 330 for cy := 0; cy < 8; cy++ { 331 for cx := 0; cx < 8; cx++ { 332 processSOSBuf[((cy*2+0+by16)*16+(cx*2+0+bx16))*3+1] = dst[cy*8+cx] 333 processSOSBuf[((cy*2+0+by16)*16+(cx*2+1+bx16))*3+1] = dst[cy*8+cx] 334 processSOSBuf[((cy*2+1+by16)*16+(cx*2+0+bx16))*3+1] = dst[cy*8+cx] 335 processSOSBuf[((cy*2+1+by16)*16+(cx*2+1+bx16))*3+1] = dst[cy*8+cx] 336 } 337 } 338 case 2: // Cr 339 bx8 := bx * 8 * 2 340 by8 := by * 8 * 2 341 bx16 := bx8 % 16 342 by16 := by8 % 16 343 344 for cy := 0; cy < 8; cy++ { 345 for cx := 0; cx < 8; cx++ { 346 processSOSBuf[((cy*2+0+by16)*16+(cx*2+0+bx16))*3+2] = dst[cy*8+cx] 347 processSOSBuf[((cy*2+0+by16)*16+(cx*2+1+bx16))*3+2] = dst[cy*8+cx] 348 processSOSBuf[((cy*2+1+by16)*16+(cx*2+0+bx16))*3+2] = dst[cy*8+cx] 349 processSOSBuf[((cy*2+1+by16)*16+(cx*2+1+bx16))*3+2] = dst[cy*8+cx] 350 } 351 } 352 353 for cy := 0; cy < 16; cy++ { 354 for cx := 0; cx < 16; cx++ { 355 yy := processSOSBuf[(cy*16+cx)*3+0] 356 cb := processSOSBuf[(cy*16+cx)*3+1] 357 cr := processSOSBuf[(cy*16+cx)*3+2] 358 r, g, b := color.YCbCrToRGB(yy, cb, cr) 359 callbackBuf[cy*16+cx] = uint16(((uint16(r) << 8) & 0xF800) + 360 (((uint16(g) << 8) & 0xFC00) >> 5) + 361 (((uint16(b) << 8) & 0xF800) >> 11)) 362 } 363 } 364 callback(callbackBuf[:8*8*4], int16(bx8-bx16), int16(by8-by16), 16, 16, int16(d.width), int16(d.height)) 365 } 366 } 367 } // for j 368 } // for i 369 mcu++ 370 if d.ri > 0 && mcu%d.ri == 0 && mcu < mxx*myy { 371 // A more sophisticated decoder could use RST[0-7] markers to resynchronize from corrupt input, 372 // but this one assumes well-formed input, and hence the restart marker follows immediately. 373 if err := d.readFull(d.tmp[:2]); err != nil { 374 return err 375 } 376 377 // Section F.1.2.3 says that "Byte alignment of markers is 378 // achieved by padding incomplete bytes with 1-bits. If padding 379 // with 1-bits creates a X’FF’ value, a zero byte is stuffed 380 // before adding the marker." 381 // 382 // Seeing "\xff\x00" here is not spec compliant, as we are not 383 // expecting an *incomplete* byte (that needed padding). Still, 384 // some real world encoders (see golang.org/issue/28717) insert 385 // it, so we accept it and re-try the 2 byte read. 386 // 387 // libjpeg issues a warning (but not an error) for this: 388 // https://github.com/LuaDist/libjpeg/blob/6c0fcb8ddee365e7abc4d332662b06900612e923/jdmarker.c#L1041-L1046 389 if d.tmp[0] == 0xff && d.tmp[1] == 0x00 { 390 if err := d.readFull(d.tmp[:2]); err != nil { 391 return err 392 } 393 } 394 395 if d.tmp[0] != 0xff || d.tmp[1] != expectedRST { 396 return FormatError("bad RST marker") 397 } 398 expectedRST++ 399 if expectedRST == rst7Marker+1 { 400 expectedRST = rst0Marker 401 } 402 // Reset the Huffman decoder. 403 d.bits = bits{} 404 // Reset the DC components, as per section F.2.1.3.1. 405 dc = [maxComponents]int32{} 406 // Reset the progressive decoder state, as per section G.1.2.2. 407 d.eobRun = 0 408 } 409 } // for mx 410 } // for my 411 412 return nil 413 } 414 415 // refine decodes a successive approximation refinement block, as specified in 416 // section G.1.2. 417 func (d *decoder) refine(b *block, h *huffman, zigStart, zigEnd, delta int32) error { 418 // Refining a DC component is trivial. 419 if zigStart == 0 { 420 if zigEnd != 0 { 421 panic("unreachable") 422 } 423 bit, err := d.decodeBit() 424 if err != nil { 425 return err 426 } 427 if bit { 428 b[0] |= delta 429 } 430 return nil 431 } 432 433 // Refining AC components is more complicated; see sections G.1.2.2 and G.1.2.3. 434 zig := zigStart 435 if d.eobRun == 0 { 436 loop: 437 for ; zig <= zigEnd; zig++ { 438 z := int32(0) 439 value, err := d.decodeHuffman(h) 440 if err != nil { 441 return err 442 } 443 val0 := value >> 4 444 val1 := value & 0x0f 445 446 switch val1 { 447 case 0: 448 if val0 != 0x0f { 449 d.eobRun = uint16(1 << val0) 450 if val0 != 0 { 451 bits, err := d.decodeBits(int32(val0)) 452 if err != nil { 453 return err 454 } 455 d.eobRun |= uint16(bits) 456 } 457 break loop 458 } 459 case 1: 460 z = delta 461 bit, err := d.decodeBit() 462 if err != nil { 463 return err 464 } 465 if !bit { 466 z = -z 467 } 468 default: 469 return FormatError("unexpected Huffman code") 470 } 471 472 zig, err = d.refineNonZeroes(b, zig, zigEnd, int32(val0), delta) 473 if err != nil { 474 return err 475 } 476 if zig > zigEnd { 477 return FormatError("too many coefficients") 478 } 479 if z != 0 { 480 b[unzig[zig]] = z 481 } 482 } 483 } 484 if d.eobRun > 0 { 485 d.eobRun-- 486 if _, err := d.refineNonZeroes(b, zig, zigEnd, -1, delta); err != nil { 487 return err 488 } 489 } 490 return nil 491 } 492 493 // refineNonZeroes refines non-zero entries of b in zig-zag order. If nz >= 0, 494 // the first nz zero entries are skipped over. 495 func (d *decoder) refineNonZeroes(b *block, zig, zigEnd, nz, delta int32) (int32, error) { 496 for ; zig <= zigEnd; zig++ { 497 u := unzig[zig] 498 if b[u] == 0 { 499 if nz == 0 { 500 break 501 } 502 nz-- 503 continue 504 } 505 bit, err := d.decodeBit() 506 if err != nil { 507 return 0, err 508 } 509 if !bit { 510 continue 511 } 512 if b[u] >= 0 { 513 b[u] += delta 514 } else { 515 b[u] -= delta 516 } 517 } 518 return zig, nil 519 } 520 521 func (d *decoder) reconstructProgressiveImage() error { 522 // The h0, mxx, by and bx variables have the same meaning as in the 523 // processSOS method. 524 h0 := d.comp[0].h 525 mxx := (d.width + 8*h0 - 1) / (8 * h0) 526 for i := 0; i < d.nComp; i++ { 527 if d.progCoeffs[i] == nil { 528 continue 529 } 530 v := 8 * d.comp[0].v / d.comp[i].v 531 h := 8 * d.comp[0].h / d.comp[i].h 532 stride := mxx * d.comp[i].h 533 for by := 0; by*v < d.height; by++ { 534 for bx := 0; bx*h < d.width; bx++ { 535 if _, err := d.reconstructBlock(&d.progCoeffs[i][by*stride+bx], bx, by, i); err != nil { 536 return err 537 } 538 } 539 } 540 } 541 return nil 542 } 543 544 // reconstructBlockBuf is a Buffer for the 8x8 pix data to be processed by 545 // reconstructBlock. It is defined and used as a package variable to reduce 546 // memory usage. 547 var reconstructBlockBuf [64]byte 548 549 // reconstructBlock dequantizes, performs the inverse DCT and stores the block 550 // to the image. 551 // In the original Go source, it was expanded to a position that matched the 552 // coordinates of the original image. Note that TinyGo does not transform the 553 // coordinate system, so the movement is different. 554 func (d *decoder) reconstructBlock(b *block, bx, by, compIndex int) ([]byte, error) { 555 qt := &d.quant[d.comp[compIndex].tq] 556 for zig := 0; zig < blockSize; zig++ { 557 b[unzig[zig]] *= qt[zig] 558 } 559 idct(b) 560 // Level shift by +128, clip to [0, 255], and write to dst. 561 var buf = reconstructBlockBuf[:] 562 for y := 0; y < 8; y++ { 563 y8 := y * 8 564 for x := 0; x < 8; x++ { 565 c := b[y8+x] 566 if c < -128 { 567 c = 0 568 } else if c > 127 { 569 c = 255 570 } else { 571 c += 128 572 } 573 buf[y*8+x] = uint8(c) 574 } 575 } 576 return buf, nil 577 }