| // Copyright 2026 The Wuffs Authors. |
| // |
| // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or |
| // https://www.apache.org/licenses/LICENSE-2.0> or the MIT license |
| // <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your |
| // option. This file may not be copied, modified, or distributed |
| // except according to those terms. |
| // |
| // SPDX-License-Identifier: Apache-2.0 OR MIT |
| |
| //go:build ignore |
| // +build ignore |
| |
| package main |
| |
| // replicate-libwebp-chroma-upsampling.go tests a Go port of libwebp's "fancy" |
| // 4:2:0 chroma upsampling algorithm. This is a 9:3:3:1 triangle filter (the |
| // 2-Dimensional analogue of the 1-Dimensional 3:1 triangle filter). |
| // |
| // libwebp's "fancy" upsampling is very similar to (but not exactly the same |
| // as) libjpeg's "fancy" upsampling. Both are 9:3:3:1 and the weights sum to |
| // 16, but they use a different integer arithmetic rounding algorithm: |
| // |
| // - libwebp uses truncate((weighted_average + 8) / 16), everywhere. |
| // - libjpeg uses truncate((weighted_average + H) / 16), where H is 8 |
| // (rounding up) for even columns and 7 (rounding down) for odd columns. |
| // |
| // libwebp's plain C implementation is the src/dsp/upsampling.c UPSAMPLE_FUNC |
| // macro. While it doesn't affect rounding, the macro also computes Cb and Cr |
| // simultaneously using SWAR (SIMD Within A Register), packing u16x2 into a |
| // u32, which this Go re-implementation does not replicate. libwebp also has |
| // other SIMD-optimized implementations. |
| // |
| // libjpeg's plain C implementation is the jdsample.c h2v2_fancy_upsample |
| // function. libjpeg also has other SIMD-optimized implementations. |
| // |
| // Usage: "go run replicate-libwebp-chroma-upsampling.go" should print nothing, |
| // but it would print a diff if the hard-coded tests fail. |
| |
| import ( |
| "bytes" |
| "errors" |
| "fmt" |
| "os" |
| ) |
| |
| func main() { |
| if err := main1(); err != nil { |
| os.Stderr.WriteString(err.Error() + "\n") |
| os.Exit(1) |
| } |
| } |
| |
| func main1() error { |
| { |
| dst := make([]byte, len(dstSamplesMona)) |
| upsampleImage(dst, 21, 32, srcSamplesMona[:], 16, 16) |
| compare(dst, dstSamplesMona[:], 21, "test/data/mona-lisa.21x32.q90.lossy.webp") |
| } |
| |
| { |
| dst := make([]byte, len(dstSamplesPeac)) |
| upsampleImage(dst, 24, 19, srcSamplesPeac[:], 16, 16) |
| compare(dst, dstSamplesPeac[:], 24, "test/data/peacock.24x19.lossy.webp") |
| } |
| |
| if failed { |
| return errors.New("Failed.") |
| } |
| return nil |
| } |
| |
| func upsampleImage(dst []byte, dstw int, dsth int, src []byte, srcw int, srch int) { |
| if (dstw <= 0) || (dsth <= 0) || (srcw <= 0) || (srch <= 0) { |
| return |
| } |
| |
| // The dsty sequence is 0, 1, 3, 5, 7, 9, ... |
| for dsty := 0; dsty < dsth; { |
| dsty0 := dsty + 0 |
| dsty1 := dsty + 1 |
| srcy0 := dsty >> 1 |
| srcy1 := srcy0 + 1 |
| |
| if dsty == 0 { // First row. |
| dsty1 = -1 |
| srcy1 = 0 |
| dsty = 1 |
| |
| } else if (dsty + 1) >= dsth { // Last row, when dsth is even. |
| dsty1 = -1 |
| srcy1 = srcy0 |
| dsty += 1 |
| |
| } else { // All other rows. |
| dsty += 2 |
| } |
| |
| dst0 := dst[(dsty0+0)*dstw : (dsty0+1)*dstw] |
| dst1 := []byte(nil) |
| if dsty1 >= 0 { |
| dst1 = dst[(dsty1+0)*dstw : (dsty1+1)*dstw] |
| } |
| src0 := src[(srcy0+0)*srcw : (srcy0+1)*srcw] |
| src1 := src[(srcy1+0)*srcw : (srcy1+1)*srcw] |
| upsampleStrip(dst0, dst1, src0, src1) |
| } |
| } |
| |
| func upsampleStrip(dst0 []byte, dst1 []byte, src0 []byte, src1 []byte) { |
| if (len(dst0) <= 0) || |
| ((len(dst0) != len(dst1)) && (len(dst1) != 0)) || |
| ((len(src0) != len(src1)) && (len(src1) != 0)) { |
| return |
| } |
| |
| // t=top, l=left, c=current. |
| tl := uint32(src0[0]) |
| cl := uint32(src1[0]) |
| |
| { |
| dst0[0] = uint8(((3 * tl) + cl + 2) >> 2) |
| } |
| if len(dst1) > 0 { |
| dst1[0] = uint8(((3 * cl) + tl + 2) >> 2) |
| } |
| |
| for x, lastPixelPair := 1, (len(dst0)-1)>>1; x <= lastPixelPair; x++ { |
| tc := uint32(src0[x]) |
| cc := uint32(src1[x]) |
| |
| avg := tl + tc + cl + cc + 8 |
| diag12 := (avg + (2 * (tc + cl))) >> 3 |
| diag03 := (avg + (2 * (tl + cc))) >> 3 |
| |
| { |
| dst0[(2*x)-1] = uint8((diag12 + tl) >> 1) |
| dst0[(2*x)-0] = uint8((diag03 + tc) >> 1) |
| } |
| if len(dst1) > 0 { |
| dst1[(2*x)-1] = uint8((diag03 + cl) >> 1) |
| dst1[(2*x)-0] = uint8((diag12 + cc) >> 1) |
| } |
| |
| tl = tc |
| cl = cc |
| } |
| |
| if (len(dst0) & 1) == 0 { |
| n := len(dst0) - 1 |
| { |
| dst0[n] = uint8(((3 * tl) + cl + 2) >> 2) |
| } |
| if len(dst1) > 0 { |
| dst1[n] = uint8(((3 * cl) + tl + 2) >> 2) |
| } |
| } |
| } |
| |
| func compare(have []byte, want []byte, width int, name string) { |
| if len(have) != len(want) { |
| panic("invalid compare") |
| } else if bytes.Equal(have, want) { |
| return |
| } |
| failed = true |
| |
| fmt.Fprintf(os.Stderr, "Wrong output for %s\n", name) |
| for i := range have { |
| fmt.Fprintf(os.Stderr, " %02X", have[i]-want[i]) |
| if (i % width) == (width - 1) { |
| fmt.Fprintln(os.Stderr) |
| } |
| } |
| } |
| |
| var failed = false |
| |
| // srcSamplesMona are the Cb (Chroma blue) samples, 16x16 in four macroblocks, |
| // from test/data/mona-lisa.21x32.q90.lossy.webp (whose dimensions are 21x32). |
| var srcSamplesMona = [16 * 16]uint8{ |
| 0x6E, 0x6E, 0x6E, 0x6E, 0x6E, 0x6D, 0x69, 0x6B, 0x70, 0x6D, 0x72, 0x6E, 0x73, 0x73, 0x73, 0x73, |
| 0x69, 0x69, 0x69, 0x69, 0x67, 0x6A, 0x70, 0x6D, 0x6C, 0x68, 0x6D, 0x6A, 0x6A, 0x6A, 0x6A, 0x6A, |
| 0x69, 0x69, 0x69, 0x69, 0x5F, 0x66, 0x7A, 0x70, 0x6B, 0x67, 0x6C, 0x69, 0x69, 0x69, 0x69, 0x69, |
| 0x6E, 0x6E, 0x6E, 0x6E, 0x58, 0x63, 0x81, 0x72, 0x6D, 0x6A, 0x6F, 0x6B, 0x70, 0x70, 0x70, 0x70, |
| 0x79, 0x73, 0x73, 0x79, 0x5C, 0x5B, 0x81, 0x77, 0x79, 0x72, 0x76, 0x76, 0x75, 0x75, 0x75, 0x75, |
| 0x7C, 0x77, 0x77, 0x7C, 0x66, 0x6A, 0x85, 0x75, 0x7D, 0x75, 0x7A, 0x79, 0x79, 0x79, 0x79, 0x79, |
| 0x79, 0x74, 0x74, 0x79, 0x69, 0x5E, 0x71, 0x7A, 0x6F, 0x6C, 0x75, 0x79, 0x77, 0x77, 0x77, 0x77, |
| 0x72, 0x6C, 0x6C, 0x72, 0x4F, 0x51, 0x65, 0x71, 0x76, 0x6C, 0x6E, 0x6C, 0x6C, 0x6C, 0x6C, 0x6C, |
| |
| 0x72, 0x6E, 0x7E, 0x6C, 0x57, 0x5C, 0x6F, 0x84, 0x87, 0x7A, 0x73, 0x77, 0x76, 0x76, 0x76, 0x76, |
| 0x74, 0x73, 0x84, 0x7E, 0x6E, 0x7C, 0x7F, 0x74, 0x87, 0x7D, 0x78, 0x7B, 0x7D, 0x7D, 0x7D, 0x7D, |
| 0x78, 0x77, 0x80, 0x85, 0x80, 0x81, 0x84, 0x89, 0x86, 0x83, 0x80, 0x7F, 0x7C, 0x7C, 0x7C, 0x7C, |
| 0x7D, 0x77, 0x75, 0x7E, 0x88, 0x85, 0x85, 0x87, 0x86, 0x86, 0x85, 0x83, 0x83, 0x83, 0x83, 0x83, |
| 0x89, 0x88, 0x75, 0x5A, 0x62, 0x7B, 0x85, 0x7A, 0x8A, 0x89, 0x87, 0x86, 0x86, 0x86, 0x86, 0x86, |
| 0x8A, 0x88, 0x79, 0x66, 0x63, 0x6B, 0x73, 0x76, 0x87, 0x85, 0x83, 0x82, 0x80, 0x80, 0x80, 0x80, |
| 0x8C, 0x88, 0x7F, 0x77, 0x81, 0x81, 0x86, 0x8C, 0x87, 0x85, 0x83, 0x82, 0x87, 0x87, 0x87, 0x87, |
| 0x8D, 0x88, 0x84, 0x83, 0x83, 0x88, 0x8A, 0x88, 0x8A, 0x89, 0x87, 0x86, 0x89, 0x89, 0x89, 0x89, |
| } |
| |
| var dstSamplesMona = [21 * 32]uint8{ |
| 0x6E, 0x6E, 0x6E, 0x6E, 0x6E, 0x6E, 0x6E, 0x6E, 0x6E, 0x6E, 0x6D, 0x6C, 0x6A, 0x6A, 0x6B, 0x6C, 0x6F, 0x6F, 0x6E, 0x6E, 0x71, |
| 0x6D, 0x6D, 0x6D, 0x6D, 0x6D, 0x6D, 0x6D, 0x6D, 0x6C, 0x6C, 0x6C, 0x6C, 0x6B, 0x6B, 0x6B, 0x6C, 0x6E, 0x6E, 0x6D, 0x6D, 0x70, |
| 0x6A, 0x6A, 0x6A, 0x6A, 0x6A, 0x6A, 0x6A, 0x6A, 0x69, 0x69, 0x6A, 0x6C, 0x6D, 0x6E, 0x6D, 0x6D, 0x6D, 0x6C, 0x6A, 0x6B, 0x6D, |
| 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x68, 0x66, 0x66, 0x68, 0x6B, 0x70, 0x71, 0x6F, 0x6D, 0x6C, 0x6B, 0x69, 0x69, 0x6C, |
| 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x67, 0x63, 0x63, 0x66, 0x6B, 0x73, 0x75, 0x71, 0x6E, 0x6C, 0x6A, 0x68, 0x69, 0x6B, |
| 0x6A, 0x6A, 0x6A, 0x6A, 0x6A, 0x6A, 0x6A, 0x67, 0x61, 0x5F, 0x63, 0x6B, 0x76, 0x79, 0x73, 0x6F, 0x6D, 0x6B, 0x69, 0x69, 0x6C, |
| 0x6D, 0x6D, 0x6D, 0x6D, 0x6D, 0x6D, 0x6D, 0x68, 0x5F, 0x5C, 0x61, 0x6B, 0x78, 0x7C, 0x75, 0x70, 0x6E, 0x6C, 0x6A, 0x6B, 0x6D, |
| 0x71, 0x70, 0x70, 0x6F, 0x6F, 0x70, 0x70, 0x6B, 0x5F, 0x5B, 0x5F, 0x69, 0x79, 0x7E, 0x77, 0x72, 0x71, 0x6F, 0x6D, 0x6D, 0x70, |
| |
| 0x76, 0x75, 0x73, 0x72, 0x72, 0x73, 0x75, 0x6F, 0x62, 0x5C, 0x5D, 0x66, 0x78, 0x7E, 0x79, 0x76, 0x76, 0x75, 0x72, 0x71, 0x73, |
| 0x7A, 0x78, 0x75, 0x74, 0x74, 0x75, 0x78, 0x73, 0x65, 0x5F, 0x5F, 0x68, 0x79, 0x7F, 0x79, 0x77, 0x79, 0x78, 0x75, 0x74, 0x76, |
| 0x7B, 0x7A, 0x77, 0x76, 0x76, 0x77, 0x7A, 0x75, 0x69, 0x64, 0x66, 0x6E, 0x7D, 0x80, 0x79, 0x77, 0x7A, 0x7A, 0x76, 0x75, 0x78, |
| 0x7B, 0x7A, 0x78, 0x76, 0x76, 0x78, 0x7A, 0x76, 0x6C, 0x67, 0x67, 0x6D, 0x7A, 0x7E, 0x79, 0x77, 0x79, 0x78, 0x74, 0x74, 0x77, |
| 0x7A, 0x79, 0x76, 0x75, 0x75, 0x76, 0x79, 0x75, 0x6D, 0x66, 0x63, 0x66, 0x71, 0x77, 0x78, 0x77, 0x74, 0x71, 0x6F, 0x70, 0x74, |
| 0x77, 0x76, 0x73, 0x72, 0x72, 0x73, 0x76, 0x72, 0x68, 0x61, 0x5D, 0x60, 0x69, 0x70, 0x75, 0x76, 0x73, 0x70, 0x6D, 0x6E, 0x71, |
| 0x74, 0x72, 0x6F, 0x6E, 0x6E, 0x6F, 0x72, 0x6C, 0x5D, 0x55, 0x55, 0x59, 0x63, 0x6B, 0x70, 0x74, 0x74, 0x72, 0x6E, 0x6D, 0x6F, |
| 0x72, 0x71, 0x6E, 0x6E, 0x70, 0x71, 0x71, 0x69, 0x59, 0x52, 0x53, 0x59, 0x63, 0x6B, 0x72, 0x77, 0x79, 0x78, 0x72, 0x6F, 0x6F, |
| |
| 0x72, 0x71, 0x6F, 0x71, 0x77, 0x77, 0x71, 0x67, 0x5B, 0x56, 0x58, 0x5E, 0x68, 0x71, 0x7B, 0x80, 0x82, 0x80, 0x7A, 0x75, 0x73, |
| 0x73, 0x72, 0x70, 0x73, 0x7B, 0x7C, 0x74, 0x6C, 0x62, 0x5F, 0x62, 0x68, 0x6F, 0x76, 0x7D, 0x82, 0x85, 0x84, 0x7E, 0x79, 0x76, |
| 0x74, 0x73, 0x72, 0x76, 0x7E, 0x80, 0x7C, 0x75, 0x6D, 0x6B, 0x71, 0x76, 0x79, 0x7A, 0x79, 0x7C, 0x83, 0x84, 0x7F, 0x7B, 0x78, |
| 0x75, 0x75, 0x74, 0x78, 0x7F, 0x82, 0x81, 0x7C, 0x76, 0x75, 0x7B, 0x7E, 0x80, 0x7F, 0x7B, 0x7D, 0x83, 0x85, 0x81, 0x7D, 0x7B, |
| 0x77, 0x77, 0x76, 0x79, 0x7E, 0x82, 0x83, 0x81, 0x7D, 0x7D, 0x7F, 0x81, 0x82, 0x83, 0x84, 0x84, 0x86, 0x85, 0x83, 0x81, 0x7F, |
| 0x79, 0x79, 0x78, 0x79, 0x7C, 0x7F, 0x82, 0x83, 0x82, 0x82, 0x82, 0x83, 0x84, 0x85, 0x87, 0x88, 0x87, 0x85, 0x84, 0x83, 0x82, |
| 0x7C, 0x7B, 0x78, 0x77, 0x78, 0x7A, 0x7E, 0x81, 0x84, 0x86, 0x85, 0x84, 0x85, 0x85, 0x87, 0x87, 0x86, 0x86, 0x85, 0x85, 0x84, |
| 0x80, 0x7F, 0x7C, 0x7A, 0x77, 0x75, 0x75, 0x77, 0x7C, 0x80, 0x82, 0x83, 0x84, 0x85, 0x84, 0x85, 0x86, 0x87, 0x87, 0x86, 0x86, |
| |
| 0x86, 0x85, 0x84, 0x80, 0x79, 0x71, 0x68, 0x65, 0x69, 0x70, 0x79, 0x7F, 0x83, 0x83, 0x7F, 0x80, 0x86, 0x89, 0x88, 0x88, 0x87, |
| 0x89, 0x89, 0x88, 0x84, 0x7B, 0x70, 0x63, 0x5E, 0x61, 0x67, 0x72, 0x79, 0x7E, 0x7F, 0x7B, 0x7D, 0x85, 0x89, 0x88, 0x88, 0x87, |
| 0x8A, 0x89, 0x88, 0x84, 0x7C, 0x73, 0x68, 0x63, 0x63, 0x66, 0x6C, 0x71, 0x75, 0x77, 0x77, 0x7B, 0x84, 0x87, 0x86, 0x86, 0x85, |
| 0x8B, 0x8A, 0x89, 0x85, 0x7E, 0x76, 0x6E, 0x6A, 0x6A, 0x6C, 0x6F, 0x72, 0x76, 0x79, 0x7B, 0x7E, 0x84, 0x87, 0x86, 0x85, 0x84, |
| 0x8C, 0x8B, 0x89, 0x85, 0x80, 0x7B, 0x75, 0x74, 0x78, 0x7A, 0x7B, 0x7D, 0x80, 0x83, 0x85, 0x87, 0x87, 0x87, 0x86, 0x85, 0x84, |
| 0x8C, 0x8B, 0x89, 0x86, 0x82, 0x7F, 0x7C, 0x7C, 0x80, 0x82, 0x82, 0x84, 0x86, 0x88, 0x8A, 0x8A, 0x89, 0x87, 0x86, 0x86, 0x85, |
| 0x8D, 0x8C, 0x89, 0x87, 0x84, 0x82, 0x81, 0x81, 0x82, 0x83, 0x85, 0x87, 0x88, 0x89, 0x89, 0x89, 0x89, 0x89, 0x88, 0x88, 0x87, |
| 0x8D, 0x8C, 0x89, 0x87, 0x85, 0x84, 0x83, 0x83, 0x83, 0x84, 0x87, 0x89, 0x8A, 0x8A, 0x89, 0x89, 0x8A, 0x8A, 0x89, 0x89, 0x88, |
| } |
| |
| // srcSamplesPeac are the Cb (Chroma blue) samples, 16x16 in four macroblocks, |
| // from test/data/peacock.24x19.lossy.webp (whose dimensions are 24x19). |
| var srcSamplesPeac = [16 * 16]uint8{ |
| 0x65, 0x65, 0x65, 0x63, 0x63, 0x6C, 0x72, 0x71, 0x66, 0x69, 0x73, 0x76, 0x6E, 0x6E, 0x6E, 0x6E, |
| 0x65, 0x65, 0x65, 0x65, 0x5F, 0x6B, 0x72, 0x6E, 0x69, 0x70, 0x6D, 0x73, 0x6E, 0x6E, 0x6E, 0x6E, |
| 0x67, 0x67, 0x67, 0x67, 0x6B, 0x96, 0x9C, 0x7B, 0x6D, 0x79, 0x63, 0x6F, 0x6E, 0x6E, 0x6E, 0x6E, |
| 0x68, 0x68, 0x68, 0x68, 0x80, 0x7E, 0x84, 0x8F, 0x72, 0x80, 0x5C, 0x6D, 0x6D, 0x6D, 0x6D, 0x6D, |
| 0x6A, 0x6A, 0x6A, 0x6A, 0x63, 0x6B, 0x7F, 0x95, 0x75, 0x74, 0x6F, 0x6A, 0x69, 0x69, 0x69, 0x69, |
| 0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x99, 0x85, 0x74, 0x70, 0x6B, 0x67, 0x65, 0x65, 0x65, 0x65, |
| 0x6C, 0x6C, 0x6C, 0x6C, 0x6D, 0x81, 0xA8, 0x76, 0x6F, 0x6B, 0x66, 0x62, 0x60, 0x60, 0x60, 0x60, |
| 0x6C, 0x6C, 0x6C, 0x6C, 0x68, 0xA0, 0xA4, 0x72, 0x6B, 0x67, 0x62, 0x5F, 0x5C, 0x5C, 0x5C, 0x5C, |
| |
| 0x6B, 0x6B, 0x6B, 0x6B, 0x70, 0xA5, 0xA3, 0x89, 0x64, 0x68, 0x67, 0x60, 0x60, 0x60, 0x60, 0x60, |
| 0x6B, 0x6B, 0x6B, 0x6B, 0x7E, 0xAD, 0xAB, 0x97, 0x64, 0x68, 0x67, 0x60, 0x60, 0x60, 0x60, 0x60, |
| 0x6A, 0x6A, 0x6A, 0x6A, 0x87, 0xAD, 0xAB, 0xA0, 0x64, 0x68, 0x67, 0x60, 0x60, 0x60, 0x60, 0x60, |
| 0x69, 0x69, 0x69, 0x69, 0x85, 0xA5, 0xA3, 0x9E, 0x64, 0x68, 0x67, 0x60, 0x60, 0x60, 0x60, 0x60, |
| 0x69, 0x69, 0x69, 0x69, 0x7C, 0xAA, 0xAC, 0xA0, 0x64, 0x68, 0x67, 0x60, 0x60, 0x60, 0x60, 0x60, |
| 0x68, 0x68, 0x68, 0x68, 0x7C, 0xAA, 0xAC, 0xA0, 0x64, 0x68, 0x67, 0x60, 0x60, 0x60, 0x60, 0x60, |
| 0x68, 0x68, 0x68, 0x68, 0x7C, 0xAA, 0xAC, 0xA0, 0x64, 0x68, 0x67, 0x60, 0x60, 0x60, 0x60, 0x60, |
| 0x68, 0x68, 0x68, 0x68, 0x7C, 0xAA, 0xAC, 0xA0, 0x64, 0x68, 0x67, 0x60, 0x60, 0x60, 0x60, 0x60, |
| } |
| |
| var dstSamplesPeac = [24 * 19]uint8{ |
| 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x64, 0x63, 0x63, 0x65, 0x6A, 0x6E, 0x71, 0x72, 0x71, 0x6E, 0x69, 0x67, 0x68, 0x6C, 0x71, 0x74, 0x75, 0x76, |
| 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x64, 0x63, 0x62, 0x64, 0x69, 0x6D, 0x70, 0x72, 0x71, 0x6E, 0x69, 0x68, 0x6A, 0x6C, 0x70, 0x72, 0x74, 0x75, |
| 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x63, 0x61, 0x63, 0x68, 0x6D, 0x70, 0x71, 0x70, 0x6D, 0x6A, 0x6A, 0x6D, 0x6E, 0x6E, 0x70, 0x72, 0x74, |
| 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x65, 0x63, 0x67, 0x71, 0x77, 0x7B, 0x7A, 0x74, 0x6F, 0x6C, 0x6C, 0x70, 0x70, 0x6C, 0x6C, 0x70, 0x72, |
| 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x68, 0x71, 0x82, 0x8D, 0x90, 0x8B, 0x7E, 0x75, 0x6F, 0x6F, 0x74, 0x72, 0x6A, 0x68, 0x6D, 0x70, |
| 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x6A, 0x6E, 0x78, 0x88, 0x92, 0x95, 0x91, 0x86, 0x7C, 0x73, 0x71, 0x78, 0x74, 0x68, 0x65, 0x6B, 0x6F, |
| 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x6D, 0x76, 0x7D, 0x82, 0x86, 0x89, 0x8A, 0x8A, 0x84, 0x77, 0x74, 0x7B, 0x76, 0x66, 0x62, 0x6A, 0x6E, |
| 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x6D, 0x75, 0x79, 0x79, 0x7C, 0x80, 0x86, 0x8D, 0x89, 0x7A, 0x75, 0x7A, 0x76, 0x68, 0x64, 0x69, 0x6C, |
| |
| 0x6A, 0x6A, 0x6A, 0x6A, 0x6A, 0x6A, 0x6A, 0x6A, 0x6A, 0x6C, 0x6E, 0x74, 0x7C, 0x85, 0x8F, 0x8C, 0x7C, 0x75, 0x76, 0x74, 0x6D, 0x6A, 0x6B, 0x6B, |
| 0x6A, 0x6A, 0x6A, 0x6A, 0x6A, 0x6A, 0x6A, 0x69, 0x66, 0x67, 0x6A, 0x72, 0x7F, 0x88, 0x8E, 0x8A, 0x7C, 0x74, 0x73, 0x72, 0x6F, 0x6D, 0x6A, 0x69, |
| 0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x6A, 0x69, 0x6A, 0x6B, 0x75, 0x89, 0x90, 0x8B, 0x84, 0x79, 0x73, 0x72, 0x70, 0x6D, 0x6B, 0x69, 0x68, |
| 0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x6D, 0x6F, 0x7C, 0x92, 0x96, 0x88, 0x7E, 0x76, 0x72, 0x70, 0x6E, 0x6B, 0x69, 0x67, 0x66, |
| 0x6C, 0x6C, 0x6C, 0x6C, 0x6C, 0x6C, 0x6C, 0x6C, 0x6C, 0x70, 0x78, 0x86, 0x9A, 0x9A, 0x84, 0x77, 0x73, 0x6F, 0x6D, 0x6B, 0x69, 0x66, 0x64, 0x63, |
| 0x6C, 0x6C, 0x6C, 0x6C, 0x6C, 0x6C, 0x6C, 0x6C, 0x6C, 0x73, 0x82, 0x90, 0x9F, 0x9B, 0x82, 0x73, 0x70, 0x6D, 0x6B, 0x69, 0x66, 0x64, 0x62, 0x61, |
| 0x6C, 0x6C, 0x6C, 0x6C, 0x6C, 0x6C, 0x6C, 0x6B, 0x6A, 0x75, 0x8D, 0x9B, 0xA2, 0x99, 0x80, 0x71, 0x6E, 0x6B, 0x69, 0x67, 0x64, 0x62, 0x61, 0x60, |
| 0x6C, 0x6C, 0x6C, 0x6C, 0x6C, 0x6C, 0x6C, 0x6B, 0x6A, 0x78, 0x93, 0xA2, 0xA3, 0x99, 0x83, 0x74, 0x6D, 0x69, 0x68, 0x66, 0x64, 0x62, 0x60, 0x5F, |
| |
| 0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x6C, 0x6D, 0x7B, 0x96, 0xA4, 0xA3, 0x9B, 0x8B, 0x7C, 0x6D, 0x66, 0x67, 0x67, 0x66, 0x64, 0x61, 0x60, |
| 0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x6D, 0x71, 0x80, 0x9A, 0xA7, 0xA6, 0x9F, 0x93, 0x82, 0x6E, 0x65, 0x67, 0x68, 0x67, 0x65, 0x62, 0x60, |
| 0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x6F, 0x77, 0x87, 0x9F, 0xAB, 0xAA, 0xA4, 0x99, 0x88, 0x70, 0x65, 0x67, 0x68, 0x67, 0x65, 0x62, 0x60, |
| } |