mirror of
https://github.com/opencloud-eu/opencloud.git
synced 2026-02-24 02:56:52 -05:00
Compare commits
40 Commits
dependabot
...
next-relea
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
131e1fb518 | ||
|
|
6dba9bf64d | ||
|
|
49a018e973 | ||
|
|
7ed88774b2 | ||
|
|
bb8347af64 | ||
|
|
c7f2945341 | ||
|
|
07ec21e7a7 | ||
|
|
ee56c55456 | ||
|
|
6ab1d477ca | ||
|
|
e06ab0261f | ||
|
|
26a47558ad | ||
|
|
f8d50fb092 | ||
|
|
52cf1aa729 | ||
|
|
1524ef6271 | ||
|
|
7dcfef0506 | ||
|
|
475f983634 | ||
|
|
778bd51479 | ||
|
|
afdd36ebec | ||
|
|
2834e465ca | ||
|
|
4967272514 | ||
|
|
93a7846c8c | ||
|
|
03930391d4 | ||
|
|
eace29a438 | ||
|
|
9585f8968c | ||
|
|
d4b7feaa5f | ||
|
|
1ee1006b90 | ||
|
|
d0e2c1148c | ||
|
|
3d258b253e | ||
|
|
2bb8421a98 | ||
|
|
160b7a25d1 | ||
|
|
e6cca60129 | ||
|
|
8b5db43a67 | ||
|
|
5e92a07539 | ||
|
|
432c8aae23 | ||
|
|
e25cc7a549 | ||
|
|
b9418ee492 | ||
|
|
d4990b8fee | ||
|
|
088d7bd835 | ||
|
|
de4742e66f | ||
|
|
45bf10fd78 |
33
CHANGELOG.md
33
CHANGELOG.md
@@ -1,5 +1,38 @@
|
||||
# Changelog
|
||||
|
||||
## [5.2.0](https://github.com/opencloud-eu/opencloud/releases/tag/v5.2.0) - 2026-02-24
|
||||
|
||||
### ❤️ Thanks to all contributors! ❤️
|
||||
|
||||
@AlexAndBear, @JammingBen, @butonic, @pat-s, @rhafer
|
||||
|
||||
### 📈 Enhancement
|
||||
|
||||
- feat(web): change surface colors to more modern ones [[#2377](https://github.com/opencloud-eu/opencloud/pull/2377)]
|
||||
- Add openCloudEducationExternalId to user [[#2357](https://github.com/opencloud-eu/opencloud/pull/2357)]
|
||||
- feat: app-registry adjust default mime-types [[#2354](https://github.com/opencloud-eu/opencloud/pull/2354)]
|
||||
- feat: support desktop and mobile specific `client_id` and `scopes` [[#2072](https://github.com/opencloud-eu/opencloud/pull/2072)]
|
||||
|
||||
### 🐛 Bug Fixes
|
||||
|
||||
- fix(oidc_auth): Fix userinfo cache expiration logic [[#2360](https://github.com/opencloud-eu/opencloud/pull/2360)]
|
||||
|
||||
### 📚 Documentation
|
||||
|
||||
- adr(webfinger): Align example config with implementation [[#2353](https://github.com/opencloud-eu/opencloud/pull/2353)]
|
||||
|
||||
### 📦️ Dependencies
|
||||
|
||||
- build(deps): bump github.com/grpc-ecosystem/grpc-gateway/v2 from 2.27.7 to 2.28.0 [[#2375](https://github.com/opencloud-eu/opencloud/pull/2375)]
|
||||
- build(deps): bump github.com/open-policy-agent/opa from 1.13.1 to 1.13.2 [[#2374](https://github.com/opencloud-eu/opencloud/pull/2374)]
|
||||
- build(deps): bump google.golang.org/grpc from 1.78.0 to 1.79.1 [[#2362](https://github.com/opencloud-eu/opencloud/pull/2362)]
|
||||
- build(deps): bump github.com/onsi/ginkgo/v2 from 2.28.0 to 2.28.1 [[#2366](https://github.com/opencloud-eu/opencloud/pull/2366)]
|
||||
- build(deps): bump go.opentelemetry.io/contrib/zpages from 0.64.0 to 0.65.0 [[#2363](https://github.com/opencloud-eu/opencloud/pull/2363)]
|
||||
- build(deps): bump golang.org/x/net from 0.49.0 to 0.50.0 [[#2356](https://github.com/opencloud-eu/opencloud/pull/2356)]
|
||||
- build(deps): bump github.com/go-resty/resty/v2 from 2.17.1 to 2.17.2 [[#2355](https://github.com/opencloud-eu/opencloud/pull/2355)]
|
||||
- build(deps): bump go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp from 0.64.0 to 0.65.0 [[#2321](https://github.com/opencloud-eu/opencloud/pull/2321)]
|
||||
- build(deps): bump github.com/open-policy-agent/opa from 1.12.3 to 1.13.1 [[#2350](https://github.com/opencloud-eu/opencloud/pull/2350)]
|
||||
|
||||
## [5.1.0](https://github.com/opencloud-eu/opencloud/releases/tag/v5.1.0) - 2026-02-16
|
||||
|
||||
### ❤️ Thanks to all contributors! ❤️
|
||||
|
||||
4
go.mod
4
go.mod
@@ -48,7 +48,7 @@ require (
|
||||
github.com/jellydator/ttlcache/v3 v3.4.0
|
||||
github.com/jinzhu/now v1.1.5
|
||||
github.com/justinas/alice v1.2.0
|
||||
github.com/kovidgoyal/imaging v1.8.20
|
||||
github.com/kovidgoyal/imaging v1.8.19
|
||||
github.com/leonelquinteros/gotext v1.7.2
|
||||
github.com/libregraph/idm v0.5.0
|
||||
github.com/libregraph/lico v0.66.0
|
||||
@@ -105,7 +105,7 @@ require (
|
||||
go.opentelemetry.io/otel/trace v1.40.0
|
||||
golang.org/x/crypto v0.48.0
|
||||
golang.org/x/exp v0.0.0-20250210185358-939b2ce775ac
|
||||
golang.org/x/image v0.36.0
|
||||
golang.org/x/image v0.35.0
|
||||
golang.org/x/net v0.50.0
|
||||
golang.org/x/oauth2 v0.35.0
|
||||
golang.org/x/sync v0.19.0
|
||||
|
||||
8
go.sum
8
go.sum
@@ -747,8 +747,8 @@ github.com/kovidgoyal/go-parallel v1.1.1 h1:1OzpNjtrUkBPq3UaqrnvOoB2F9RttSt811ui
|
||||
github.com/kovidgoyal/go-parallel v1.1.1/go.mod h1:BJNIbe6+hxyFWv7n6oEDPj3PA5qSw5OCtf0hcVxWJiw=
|
||||
github.com/kovidgoyal/go-shm v1.0.0 h1:HJEel9D1F9YhULvClEHJLawoRSj/1u/EDV7MJbBPgQo=
|
||||
github.com/kovidgoyal/go-shm v1.0.0/go.mod h1:Yzb80Xf9L3kaoB2RGok9hHwMIt7Oif61kT6t3+VnZds=
|
||||
github.com/kovidgoyal/imaging v1.8.20 h1:74GZ7C2rIm3rqmGEjK1GvvPOOnJ0SS5iDOa6Flfo0b0=
|
||||
github.com/kovidgoyal/imaging v1.8.20/go.mod h1:d3phGYkTChGYkY4y++IjpHgUGhWGELDc2NEQAqxwZZg=
|
||||
github.com/kovidgoyal/imaging v1.8.19 h1:zWJdQqF2tfSKjvoB7XpLRhVGbYsze++M0iaqZ4ZkhNk=
|
||||
github.com/kovidgoyal/imaging v1.8.19/go.mod h1:I0q8RdoEuyc4G8GFOF9CaluTUHQSf68d6TmsqpvfRI8=
|
||||
github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
|
||||
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
@@ -1393,8 +1393,8 @@ golang.org/x/exp v0.0.0-20250210185358-939b2ce775ac/go.mod h1:hH+7mtFmImwwcMvScy
|
||||
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
|
||||
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||
golang.org/x/image v0.18.0/go.mod h1:4yyo5vMFQjVjUcVk4jEQcU9MGy/rulF5WvUILseCM2E=
|
||||
golang.org/x/image v0.36.0 h1:Iknbfm1afbgtwPTmHnS2gTM/6PPZfH+z2EFuOkSbqwc=
|
||||
golang.org/x/image v0.36.0/go.mod h1:YsWD2TyyGKiIX1kZlu9QfKIsQ4nAAK9bdgdrIsE7xy4=
|
||||
golang.org/x/image v0.35.0 h1:LKjiHdgMtO8z7Fh18nGY6KDcoEtVfsgLDPeLyguqb7I=
|
||||
golang.org/x/image v0.35.0/go.mod h1:MwPLTVgvxSASsxdLzKrl8BRFuyqMyGhLwmC+TO1Sybk=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
|
||||
@@ -4,16 +4,16 @@
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
# Translators:
|
||||
# ii kaka, 2025
|
||||
# iikaka88, 2025
|
||||
#
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: EMAIL\n"
|
||||
"POT-Creation-Date: 2026-02-03 00:13+0000\n"
|
||||
"POT-Creation-Date: 2026-02-24 00:11+0000\n"
|
||||
"PO-Revision-Date: 2025-01-27 10:17+0000\n"
|
||||
"Last-Translator: ii kaka, 2025\n"
|
||||
"Last-Translator: iikaka88, 2025\n"
|
||||
"Language-Team: Japanese (https://app.transifex.com/opencloud-eu/teams/204053/ja/)\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
|
||||
@@ -4,16 +4,16 @@
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
# Translators:
|
||||
# ii kaka, 2025
|
||||
# iikaka88, 2025
|
||||
#
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: EMAIL\n"
|
||||
"POT-Creation-Date: 2026-02-03 00:13+0000\n"
|
||||
"POT-Creation-Date: 2026-02-24 00:11+0000\n"
|
||||
"PO-Revision-Date: 2025-01-27 10:17+0000\n"
|
||||
"Last-Translator: ii kaka, 2025\n"
|
||||
"Last-Translator: iikaka88, 2025\n"
|
||||
"Language-Team: Japanese (https://app.transifex.com/opencloud-eu/teams/204053/ja/)\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
|
||||
523
vendor/github.com/kovidgoyal/imaging/jpeg/dct.go
generated
vendored
523
vendor/github.com/kovidgoyal/imaging/jpeg/dct.go
generated
vendored
@@ -1,523 +0,0 @@
|
||||
// Copyright 2025 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package jpeg
|
||||
|
||||
// Discrete Cosine Transformation (DCT) implementations using the algorithm from
|
||||
// Christoph Loeffler, Adriaan Lightenberg, and George S. Mostchytz,
|
||||
// "Practical Fast 1-D DCT Algorithms with 11 Multiplications," ICASSP 1989.
|
||||
// https://ieeexplore.ieee.org/document/266596
|
||||
//
|
||||
// Since the paper is paywalled, the rest of this comment gives a summary.
|
||||
//
|
||||
// A 1-dimensional forward DCT (1D FDCT) takes as input 8 values x0..x7
|
||||
// and transforms them in place into the result values.
|
||||
//
|
||||
// The mathematical definition of the N-point 1D FDCT is:
|
||||
//
|
||||
// X[k] = α_k Σ_n x[n] * cos (2n+1)*k*π/2N
|
||||
//
|
||||
// where α₀ = √2 and α_k = 1 for k > 0.
|
||||
//
|
||||
// For our purposes, N=8, so the angles end up being multiples of π/16.
|
||||
// The most direct implementation of this definition would require 64 multiplications.
|
||||
//
|
||||
// Loeffler's paper presents a more efficient computation that requires only
|
||||
// 11 multiplications and works in terms of three basic operations:
|
||||
//
|
||||
// - A "butterfly" x0, x1 = x0+x1, x0-x1.
|
||||
// The inverse is x0, x1 = (x0+x1)/2, (x0-x1)/2.
|
||||
//
|
||||
// - A scaling of x0 by k: x0 *= k. The inverse is scaling by 1/k.
|
||||
//
|
||||
// - A rotation of x0, x1 by θ, defined as:
|
||||
// x0, x1 = x0 cos θ + x1 sin θ, -x0 sin θ + x1 cos θ.
|
||||
// The inverse is rotation by -θ.
|
||||
//
|
||||
// The algorithm proceeds in four stages:
|
||||
//
|
||||
// Stage 1:
|
||||
// - butterfly x0, x7; x1, x6; x2, x5; x3, x4.
|
||||
//
|
||||
// Stage 2:
|
||||
// - butterfly x0, x3; x1, x2
|
||||
// - rotate x4, x7 by 3π/16
|
||||
// - rotate x5, x6 by π/16.
|
||||
//
|
||||
// Stage 3:
|
||||
// - butterfly x0, x1; x4, x6; x7, x5
|
||||
// - rotate x2, x3 by 6π/16 and scale by √2.
|
||||
//
|
||||
// Stage 4:
|
||||
// - butterfly x7, x4
|
||||
// - scale x5, x6 by √2.
|
||||
//
|
||||
// Finally, the values are permuted. The permutation can be read as either:
|
||||
// - x0, x4, x2, x6, x7, x3, x5, x1 = x0, x1, x2, x3, x4, x5, x6, x7 (paper's form)
|
||||
// - x0, x1, x2, x3, x4, x5, x6, x7 = x0, x7, x2, x5, x1, x6, x3, x4 (sorted by LHS)
|
||||
//
|
||||
// The code below uses the second form to make it easier to merge adjacent stores.
|
||||
// (Note that unlike in recursive FFT implementations, the permutation here is
|
||||
// not always mapping indexes to their bit reversals.)
|
||||
//
|
||||
// As written above, the rotation requires four multiplications, but it can be
|
||||
// reduced to three by refactoring (see [dctBox] below), and the scaling in
|
||||
// stage 3 can be merged into the rotation constants, so the overall cost
|
||||
// of a 1D FDCT is 11 multiplies.
|
||||
//
|
||||
// The 1D inverse DCT (IDCT) is the 1D FDCT run backward
|
||||
// with all the basic operations inverted.
|
||||
|
||||
// dctBox implements a 3-multiply, 3-add rotation+scaling.
|
||||
// Given x0, x1, k*cos θ, and k*sin θ, dctBox returns the
|
||||
// rotated and scaled coordinates.
|
||||
// (It is called dctBox because the rotate+scale operation
|
||||
// is drawn as a box in Figures 1 and 2 in the paper.)
|
||||
func dctBox(x0, x1, kcos, ksin int32) (y0, y1 int32) {
|
||||
// y0 = x0*kcos + x1*ksin
|
||||
// y1 = -x0*ksin + x1*kcos
|
||||
ksum := kcos * (x0 + x1)
|
||||
y0 = ksum + (ksin-kcos)*x1
|
||||
y1 = ksum - (kcos+ksin)*x0
|
||||
return y0, y1
|
||||
}
|
||||
|
||||
// A block is an 8x8 input to a 2D DCT (either the FDCT or IDCT).
|
||||
// The input is actually only 8x8 uint8 values, and the outputs are 8x8 int16,
|
||||
// but it is convenient to use int32s for intermediate storage,
|
||||
// so we define only a single block type of [8*8]int32.
|
||||
//
|
||||
// A 2D DCT is implemented as 1D DCTs over the rows and columns.
|
||||
//
|
||||
// dct_test.go defines a String method for nice printing in tests.
|
||||
type block [blockSize]int32
|
||||
|
||||
const blockSize = 8 * 8
|
||||
|
||||
// Note on Numerical Precision
|
||||
//
|
||||
// The inputs to both the FDCT and IDCT are uint8 values stored in a block,
|
||||
// and the outputs are int16s in the same block, but the overall operation
|
||||
// uses int32 values as fixed-point intermediate values.
|
||||
// In the code comments below, the notation "QN.M" refers to a
|
||||
// signed value of 1+N+M significant bits, one of which is the sign bit,
|
||||
// and M of which hold fractional (sub-integer) precision.
|
||||
// For example, 255 as a Q8.0 value is stored as int32(255),
|
||||
// while 255 as a Q8.1 value is stored as int32(510),
|
||||
// and 255.5 as a Q8.1 value is int32(511).
|
||||
// The notation UQN.M refers to an unsigned value of N+M significant bits.
|
||||
// See https://en.wikipedia.org/wiki/Q_(number_format) for more.
|
||||
//
|
||||
// In general we only need to keep about 16 significant bits, but it is more
|
||||
// efficient and somewhat more precise to let unnecessary fractional bits
|
||||
// accumulate and shift them away in bulk rather than after every operation.
|
||||
// As such, it is important to keep track of the number of fractional bits
|
||||
// in each variable at different points in the code, to avoid mistakes like
|
||||
// adding numbers with different fractional precisions, as well as to keep
|
||||
// track of the total number of bits, to avoid overflow. A comment like:
|
||||
//
|
||||
// // x[123] now Q8.2.
|
||||
//
|
||||
// means that x1, x2, and x3 are all Q8.2 (11-bit) values.
|
||||
// Keeping extra precision bits also reduces the size of the errors introduced
|
||||
// by using right shift to approximate rounded division.
|
||||
|
||||
// Constants needed for the implementation.
|
||||
// These are all 60-bit precision fixed-point constants.
|
||||
// The function c(val, b) rounds the constant to b bits.
|
||||
// c is simple enough that calls to it with constant args
|
||||
// are inlined and constant-propagated down to an inline constant.
|
||||
// Each constant is commented with its Ivy definition (see robpike.io/ivy),
|
||||
// using this scaling helper function:
|
||||
//
|
||||
// op fix x = floor 0.5 + x * 2**60
|
||||
const (
|
||||
cos1 = 1130768441178740757 // fix cos 1*pi/16
|
||||
sin1 = 224923827593068887 // fix sin 1*pi/16
|
||||
cos3 = 958619196450722178 // fix cos 3*pi/16
|
||||
sin3 = 640528868967736374 // fix sin 3*pi/16
|
||||
sqrt2 = 1630477228166597777 // fix sqrt 2
|
||||
sqrt2_cos6 = 623956622067911264 // fix (sqrt 2)*cos 6*pi/16
|
||||
sqrt2_sin6 = 1506364539328854985 // fix (sqrt 2)*sin 6*pi/16
|
||||
sqrt2inv = 815238614083298888 // fix 1/sqrt 2
|
||||
sqrt2inv_cos6 = 311978311033955632 // fix (1/sqrt 2)*cos 6*pi/16
|
||||
sqrt2inv_sin6 = 753182269664427492 // fix (1/sqrt 2)*sin 6*pi/16
|
||||
)
|
||||
|
||||
func c(x uint64, bits int) int32 {
|
||||
return int32((x + (1 << (59 - bits))) >> (60 - bits))
|
||||
}
|
||||
|
||||
// fdct implements the forward DCT.
|
||||
// Inputs are UQ8.0; outputs are Q13.0.
|
||||
func fdct(b *block) {
|
||||
fdctCols(b)
|
||||
fdctRows(b)
|
||||
}
|
||||
|
||||
// fdctCols applies the 1D DCT to the columns of b.
|
||||
// Inputs are UQ8.0 in [0,255] but interpreted as [-128,127].
|
||||
// Outputs are Q10.18.
|
||||
func fdctCols(b *block) {
|
||||
for i := range 8 {
|
||||
x0 := b[0*8+i]
|
||||
x1 := b[1*8+i]
|
||||
x2 := b[2*8+i]
|
||||
x3 := b[3*8+i]
|
||||
x4 := b[4*8+i]
|
||||
x5 := b[5*8+i]
|
||||
x6 := b[6*8+i]
|
||||
x7 := b[7*8+i]
|
||||
|
||||
// x[01234567] are UQ8.0 in [0,255].
|
||||
|
||||
// Stage 1: four butterflies.
|
||||
// In general a butterfly of QN.M inputs produces Q(N+1).M outputs.
|
||||
// A butterfly of UQN.M inputs produces a UQ(N+1).M sum and a QN.M difference.
|
||||
|
||||
x0, x7 = x0+x7, x0-x7
|
||||
x1, x6 = x1+x6, x1-x6
|
||||
x2, x5 = x2+x5, x2-x5
|
||||
x3, x4 = x3+x4, x3-x4
|
||||
// x[0123] now UQ9.0 in [0, 510].
|
||||
// x[4567] now Q8.0 in [-255,255].
|
||||
|
||||
// Stage 2: two boxes and two butterflies.
|
||||
// A box on QN.M inputs with B-bit constants
|
||||
// produces Q(N+1).(M+B) outputs.
|
||||
// (The +1 is from the addition.)
|
||||
|
||||
x4, x7 = dctBox(x4, x7, c(cos3, 18), c(sin3, 18))
|
||||
x5, x6 = dctBox(x5, x6, c(cos1, 18), c(sin1, 18))
|
||||
// x[47] now Q9.18 in [-354, 354].
|
||||
// x[56] now Q9.18 in [-300, 300].
|
||||
|
||||
x0, x3 = x0+x3, x0-x3
|
||||
x1, x2 = x1+x2, x1-x2
|
||||
// x[01] now UQ10.0 in [0, 1020].
|
||||
// x[23] now Q9.0 in [-510, 510].
|
||||
|
||||
// Stage 3: one box and three butterflies.
|
||||
|
||||
x2, x3 = dctBox(x2, x3, c(sqrt2_cos6, 18), c(sqrt2_sin6, 18))
|
||||
// x[23] now Q10.18 in [-943, 943].
|
||||
|
||||
x0, x1 = x0+x1, x0-x1
|
||||
// x0 now UQ11.0 in [0, 2040].
|
||||
// x1 now Q10.0 in [-1020, 1020].
|
||||
|
||||
// Store x0, x1, x2, x3 to their permuted targets.
|
||||
// The original +128 in every input value
|
||||
// has cancelled out except in the "DC signal" x0.
|
||||
// Subtracting 128*8 here is equivalent to subtracting 128
|
||||
// from every input before we started, but cheaper.
|
||||
// It also converts x0 from UQ11.18 to Q10.18.
|
||||
b[0*8+i] = (x0 - 128*8) << 18
|
||||
b[4*8+i] = x1 << 18
|
||||
b[2*8+i] = x2
|
||||
b[6*8+i] = x3
|
||||
|
||||
x4, x6 = x4+x6, x4-x6
|
||||
x7, x5 = x7+x5, x7-x5
|
||||
// x[4567] now Q10.18 in [-654, 654].
|
||||
|
||||
// Stage 4: two √2 scalings and one butterfly.
|
||||
|
||||
x5 = (x5 >> 12) * c(sqrt2, 12)
|
||||
x6 = (x6 >> 12) * c(sqrt2, 12)
|
||||
// x[56] still Q10.18 in [-925, 925] (= 654√2).
|
||||
x7, x4 = x7+x4, x7-x4
|
||||
// x[47] still Q10.18 in [-925, 925] (not Q11.18!).
|
||||
// This is not obvious at all! See "Note on 925" below.
|
||||
|
||||
// Store x4 x5 x6 x7 to their permuted targets.
|
||||
b[1*8+i] = x7
|
||||
b[3*8+i] = x5
|
||||
b[5*8+i] = x6
|
||||
b[7*8+i] = x4
|
||||
}
|
||||
}
|
||||
|
||||
// fdctRows applies the 1D DCT to the rows of b.
|
||||
// Inputs are Q10.18; outputs are Q13.0.
|
||||
func fdctRows(b *block) {
|
||||
for i := range 8 {
|
||||
x := b[8*i : 8*i+8 : 8*i+8]
|
||||
x0 := x[0]
|
||||
x1 := x[1]
|
||||
x2 := x[2]
|
||||
x3 := x[3]
|
||||
x4 := x[4]
|
||||
x5 := x[5]
|
||||
x6 := x[6]
|
||||
x7 := x[7]
|
||||
|
||||
// x[01234567] are Q10.18 [-1020, 1020].
|
||||
|
||||
// Stage 1: four butterflies.
|
||||
|
||||
x0, x7 = x0+x7, x0-x7
|
||||
x1, x6 = x1+x6, x1-x6
|
||||
x2, x5 = x2+x5, x2-x5
|
||||
x3, x4 = x3+x4, x3-x4
|
||||
// x[01234567] now Q11.18 in [-2040, 2040].
|
||||
|
||||
// Stage 2: two boxes and two butterflies.
|
||||
|
||||
x4, x7 = dctBox(x4>>14, x7>>14, c(cos3, 14), c(sin3, 14))
|
||||
x5, x6 = dctBox(x5>>14, x6>>14, c(cos1, 14), c(sin1, 14))
|
||||
// x[47] now Q12.18 in [-2830, 2830].
|
||||
// x[56] now Q12.18 in [-2400, 2400].
|
||||
x0, x3 = x0+x3, x0-x3
|
||||
x1, x2 = x1+x2, x1-x2
|
||||
// x[01234567] now Q12.18 in [-4080, 4080].
|
||||
|
||||
// Stage 3: one box and three butterflies.
|
||||
|
||||
x2, x3 = dctBox(x2>>14, x3>>14, c(sqrt2_cos6, 14), c(sqrt2_sin6, 14))
|
||||
// x[23] now Q13.18 in [-7539, 7539].
|
||||
x0, x1 = x0+x1, x0-x1
|
||||
// x[01] now Q13.18 in [-8160, 8160].
|
||||
x4, x6 = x4+x6, x4-x6
|
||||
x7, x5 = x7+x5, x7-x5
|
||||
// x[4567] now Q13.18 in [-5230, 5230].
|
||||
|
||||
// Stage 4: two √2 scalings and one butterfly.
|
||||
|
||||
x5 = (x5 >> 14) * c(sqrt2, 14)
|
||||
x6 = (x6 >> 14) * c(sqrt2, 14)
|
||||
// x[56] still Q13.18 in [-7397, 7397] (= 5230√2).
|
||||
x7, x4 = x7+x4, x7-x4
|
||||
// x[47] still Q13.18 in [-7395, 7395] (= 2040*3.6246).
|
||||
// See "Note on 925" below.
|
||||
|
||||
// Cut from Q13.18 to Q13.0.
|
||||
x0 = (x0 + 1<<17) >> 18
|
||||
x1 = (x1 + 1<<17) >> 18
|
||||
x2 = (x2 + 1<<17) >> 18
|
||||
x3 = (x3 + 1<<17) >> 18
|
||||
x4 = (x4 + 1<<17) >> 18
|
||||
x5 = (x5 + 1<<17) >> 18
|
||||
x6 = (x6 + 1<<17) >> 18
|
||||
x7 = (x7 + 1<<17) >> 18
|
||||
|
||||
// Note: Unlike in fdctCols, saved all stores for the end
|
||||
// because they are adjacent memory locations and some systems
|
||||
// can use multiword stores.
|
||||
x[0] = x0
|
||||
x[1] = x7
|
||||
x[2] = x2
|
||||
x[3] = x5
|
||||
x[4] = x1
|
||||
x[5] = x6
|
||||
x[6] = x3
|
||||
x[7] = x4
|
||||
}
|
||||
}
|
||||
|
||||
// "Note on 925", deferred from above to avoid interrupting code.
|
||||
//
|
||||
// In fdctCols, heading into stage 2, the values x4, x5, x6, x7 are in [-255, 255].
|
||||
// Let's call those specific values b4, b5, b6, b7, and trace how x[4567] evolve:
|
||||
//
|
||||
// Stage 2:
|
||||
//
|
||||
// x4 = b4*cos3 + b7*sin3
|
||||
// x7 = -b4*sin3 + b7*cos3
|
||||
// x5 = b5*cos1 + b6*sin1
|
||||
// x6 = -b5*sin1 + b6*cos1
|
||||
//
|
||||
// Stage 3:
|
||||
//
|
||||
// x4 = x4+x6 = b4*cos3 + b7*sin3 - b5*sin1 + b6*cos1
|
||||
// x6 = x4-x6 = b4*cos3 + b7*sin3 + b5*sin1 - b6*cos1
|
||||
// x7 = x7+x5 = -b4*sin3 + b7*cos3 + b5*cos1 + b6*sin1
|
||||
// x5 = x7-x5 = -b4*sin3 + b7*cos3 - b5*cos1 - b6*sin1
|
||||
//
|
||||
// Stage 4:
|
||||
//
|
||||
// x7 = x7+x4 = -b4*sin3 + b7*cos3 + b5*cos1 + b6*sin1 + b4*cos3 + b7*sin3 - b5*sin1 + b6*cos1
|
||||
// = b4*(cos3-sin3) + b5*(cos1-sin1) + b6*(cos1+sin1) + b7*(cos3+sin3)
|
||||
// < 255*(0.2759 + 0.7857 + 1.1759 + 1.3871) = 255*3.6246 < 925.
|
||||
//
|
||||
// x4 = x7-x4 = -b4*sin3 + b7*cos3 + b5*cos1 + b6*sin1 - b4*cos3 - b7*sin3 + b5*sin1 - b6*cos1
|
||||
// = -b4*(cos3+sin3) + b5*(cos1+sin1) + b6*(sin1-cos1) + b7*(cos3-sin3)
|
||||
// < same 925.
|
||||
//
|
||||
// The fact that x5, x6 are also at most 925 is not a coincidence: we are computing
|
||||
// the same kinds of numbers for all four, just with different paths to them.
|
||||
//
|
||||
// In fdctRows, the same analysis applies, but the initial values are
|
||||
// in [-2040, 2040] instead of [-255, 255], so the bound is 2040*3.6246 < 7395.
|
||||
|
||||
// idct implements the inverse DCT.
|
||||
// Inputs are UQ8.0; outputs are Q10.3.
|
||||
func idct(b *block) {
|
||||
// A 2D IDCT is a 1D IDCT on rows followed by columns.
|
||||
idctRows(b)
|
||||
idctCols(b)
|
||||
}
|
||||
|
||||
// idctRows applies the 1D IDCT to the rows of b.
|
||||
// Inputs are UQ8.0; outputs are Q9.20.
|
||||
func idctRows(b *block) {
|
||||
for i := range 8 {
|
||||
x := b[8*i : 8*i+8 : 8*i+8]
|
||||
x0 := x[0]
|
||||
x7 := x[1]
|
||||
x2 := x[2]
|
||||
x5 := x[3]
|
||||
x1 := x[4]
|
||||
x6 := x[5]
|
||||
x3 := x[6]
|
||||
x4 := x[7]
|
||||
|
||||
// Run FDCT backward.
|
||||
// Independent operations have been reordered somewhat
|
||||
// to make precision tracking easier.
|
||||
//
|
||||
// Note that "x0, x1 = x0+x1, x0-x1" is now a reverse butterfly
|
||||
// and carries with it an implicit divide by two: the extra bit
|
||||
// is added to the precision, not the value size.
|
||||
|
||||
// x[01234567] are UQ8.0 in [0, 255].
|
||||
|
||||
// Stages 4, 3, 2: x0, x1, x2, x3.
|
||||
|
||||
x0 <<= 17
|
||||
x1 <<= 17
|
||||
// x0, x1 now UQ8.17.
|
||||
x0, x1 = x0+x1, x0-x1
|
||||
// x0 now UQ8.18 in [0, 255].
|
||||
// x1 now Q7.18 in [-127½, 127½].
|
||||
|
||||
// Note: (1/sqrt 2)*((cos 6*pi/16)+(sin 6*pi/16)) < 0.924, so no new high bit.
|
||||
x2, x3 = dctBox(x2, x3, c(sqrt2inv_cos6, 18), -c(sqrt2inv_sin6, 18))
|
||||
// x[23] now Q8.18 in [-236, 236].
|
||||
x1, x2 = x1+x2, x1-x2
|
||||
x0, x3 = x0+x3, x0-x3
|
||||
// x[0123] now Q8.19 in [-246, 246].
|
||||
|
||||
// Stages 4, 3, 2: x4, x5, x6, x7.
|
||||
|
||||
x4 <<= 7
|
||||
x7 <<= 7
|
||||
// x[47] now UQ8.7
|
||||
x7, x4 = x7+x4, x7-x4
|
||||
// x7 now UQ8.8 in [0, 255].
|
||||
// x4 now Q7.8 in [-127½, 127½].
|
||||
|
||||
x6 = x6 * c(sqrt2inv, 8)
|
||||
x5 = x5 * c(sqrt2inv, 8)
|
||||
// x[56] now UQ8.8 in [0, 181].
|
||||
// Note that 1/√2 has five 0s in its binary representation after
|
||||
// the 8th bit, so this multipliy is actually producing 12 bits of precision.
|
||||
|
||||
x7, x5 = x7+x5, x7-x5
|
||||
x4, x6 = x4+x6, x4-x6
|
||||
// x[4567] now Q8.9 in [-218, 218].
|
||||
|
||||
x4, x7 = dctBox(x4>>2, x7>>2, c(cos3, 12), -c(sin3, 12))
|
||||
x5, x6 = dctBox(x5>>2, x6>>2, c(cos1, 12), -c(sin1, 12))
|
||||
// x[4567] now Q9.19 in [-303, 303].
|
||||
|
||||
// Stage 1.
|
||||
|
||||
x0, x7 = x0+x7, x0-x7
|
||||
x1, x6 = x1+x6, x1-x6
|
||||
x2, x5 = x2+x5, x2-x5
|
||||
x3, x4 = x3+x4, x3-x4
|
||||
// x[01234567] now Q9.20 in [-275, 275].
|
||||
|
||||
// Note: we don't need all 20 bits of "precision",
|
||||
// but it is faster to let idctCols shift it away as part
|
||||
// of other operations rather than downshift here.
|
||||
|
||||
x[0] = x0
|
||||
x[1] = x1
|
||||
x[2] = x2
|
||||
x[3] = x3
|
||||
x[4] = x4
|
||||
x[5] = x5
|
||||
x[6] = x6
|
||||
x[7] = x7
|
||||
}
|
||||
}
|
||||
|
||||
// idctCols applies the 1D IDCT to the columns of b.
|
||||
// Inputs are Q9.20.
|
||||
// Outputs are Q10.3. That is, the result is the IDCT*8.
|
||||
func idctCols(b *block) {
|
||||
for i := range 8 {
|
||||
x0 := b[0*8+i]
|
||||
x7 := b[1*8+i]
|
||||
x2 := b[2*8+i]
|
||||
x5 := b[3*8+i]
|
||||
x1 := b[4*8+i]
|
||||
x6 := b[5*8+i]
|
||||
x3 := b[6*8+i]
|
||||
x4 := b[7*8+i]
|
||||
|
||||
// x[012345678] are Q9.20.
|
||||
|
||||
// Start by adding 0.5 to x0 (the incoming DC signal).
|
||||
// The butterflies will add it to all the other values,
|
||||
// and then the final shifts will round properly.
|
||||
x0 += 1 << 19
|
||||
|
||||
// Stages 4, 3, 2: x0, x1, x2, x3.
|
||||
|
||||
x0, x1 = (x0+x1)>>2, (x0-x1)>>2
|
||||
// x[01] now Q9.19.
|
||||
// Note: (1/sqrt 2)*((cos 6*pi/16)+(sin 6*pi/16)) < 1, so no new high bit.
|
||||
x2, x3 = dctBox(x2>>13, x3>>13, c(sqrt2inv_cos6, 12), -c(sqrt2inv_sin6, 12))
|
||||
// x[0123] now Q9.19.
|
||||
|
||||
x1, x2 = x1+x2, x1-x2
|
||||
x0, x3 = x0+x3, x0-x3
|
||||
// x[0123] now Q9.20.
|
||||
|
||||
// Stages 4, 3, 2: x4, x5, x6, x7.
|
||||
|
||||
x7, x4 = x7+x4, x7-x4
|
||||
// x[47] now Q9.21.
|
||||
|
||||
x5 = (x5 >> 13) * c(sqrt2inv, 14)
|
||||
x6 = (x6 >> 13) * c(sqrt2inv, 14)
|
||||
// x[56] now Q9.21.
|
||||
|
||||
x7, x5 = x7+x5, x7-x5
|
||||
x4, x6 = x4+x6, x4-x6
|
||||
// x[4567] now Q9.22.
|
||||
|
||||
x4, x7 = dctBox(x4>>14, x7>>14, c(cos3, 12), -c(sin3, 12))
|
||||
x5, x6 = dctBox(x5>>14, x6>>14, c(cos1, 12), -c(sin1, 12))
|
||||
// x[4567] now Q10.20.
|
||||
|
||||
x0, x7 = x0+x7, x0-x7
|
||||
x1, x6 = x1+x6, x1-x6
|
||||
x2, x5 = x2+x5, x2-x5
|
||||
x3, x4 = x3+x4, x3-x4
|
||||
// x[01234567] now Q10.21.
|
||||
|
||||
x0 >>= 18
|
||||
x1 >>= 18
|
||||
x2 >>= 18
|
||||
x3 >>= 18
|
||||
x4 >>= 18
|
||||
x5 >>= 18
|
||||
x6 >>= 18
|
||||
x7 >>= 18
|
||||
// x[01234567] now Q10.3.
|
||||
|
||||
b[0*8+i] = x0
|
||||
b[1*8+i] = x1
|
||||
b[2*8+i] = x2
|
||||
b[3*8+i] = x3
|
||||
b[4*8+i] = x4
|
||||
b[5*8+i] = x5
|
||||
b[6*8+i] = x6
|
||||
b[7*8+i] = x7
|
||||
}
|
||||
}
|
||||
194
vendor/github.com/kovidgoyal/imaging/jpeg/idct.go
generated
vendored
Normal file
194
vendor/github.com/kovidgoyal/imaging/jpeg/idct.go
generated
vendored
Normal file
@@ -0,0 +1,194 @@
|
||||
// Copyright 2009 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package jpeg
|
||||
|
||||
// This is a Go translation of idct.c from
|
||||
//
|
||||
// http://standards.iso.org/ittf/PubliclyAvailableStandards/ISO_IEC_13818-4_2004_Conformance_Testing/Video/verifier/mpeg2decode_960109.tar.gz
|
||||
//
|
||||
// which carries the following notice:
|
||||
|
||||
/* Copyright (C) 1996, MPEG Software Simulation Group. All Rights Reserved. */
|
||||
|
||||
/*
|
||||
* Disclaimer of Warranty
|
||||
*
|
||||
* These software programs are available to the user without any license fee or
|
||||
* royalty on an "as is" basis. The MPEG Software Simulation Group disclaims
|
||||
* any and all warranties, whether express, implied, or statuary, including any
|
||||
* implied warranties or merchantability or of fitness for a particular
|
||||
* purpose. In no event shall the copyright-holder be liable for any
|
||||
* incidental, punitive, or consequential damages of any kind whatsoever
|
||||
* arising from the use of these programs.
|
||||
*
|
||||
* This disclaimer of warranty extends to the user of these programs and user's
|
||||
* customers, employees, agents, transferees, successors, and assigns.
|
||||
*
|
||||
* The MPEG Software Simulation Group does not represent or warrant that the
|
||||
* programs furnished hereunder are free of infringement of any third-party
|
||||
* patents.
|
||||
*
|
||||
* Commercial implementations of MPEG-1 and MPEG-2 video, including shareware,
|
||||
* are subject to royalty fees to patent holders. Many of these patents are
|
||||
* general enough such that they are unavoidable regardless of implementation
|
||||
* design.
|
||||
*
|
||||
*/
|
||||
|
||||
const blockSize = 64 // A DCT block is 8x8.
|
||||
|
||||
type block [blockSize]int32
|
||||
|
||||
const (
|
||||
w1 = 2841 // 2048*sqrt(2)*cos(1*pi/16)
|
||||
w2 = 2676 // 2048*sqrt(2)*cos(2*pi/16)
|
||||
w3 = 2408 // 2048*sqrt(2)*cos(3*pi/16)
|
||||
w5 = 1609 // 2048*sqrt(2)*cos(5*pi/16)
|
||||
w6 = 1108 // 2048*sqrt(2)*cos(6*pi/16)
|
||||
w7 = 565 // 2048*sqrt(2)*cos(7*pi/16)
|
||||
|
||||
w1pw7 = w1 + w7
|
||||
w1mw7 = w1 - w7
|
||||
w2pw6 = w2 + w6
|
||||
w2mw6 = w2 - w6
|
||||
w3pw5 = w3 + w5
|
||||
w3mw5 = w3 - w5
|
||||
|
||||
r2 = 181 // 256/sqrt(2)
|
||||
)
|
||||
|
||||
// idct performs a 2-D Inverse Discrete Cosine Transformation.
|
||||
//
|
||||
// The input coefficients should already have been multiplied by the
|
||||
// appropriate quantization table. We use fixed-point computation, with the
|
||||
// number of bits for the fractional component varying over the intermediate
|
||||
// stages.
|
||||
//
|
||||
// For more on the actual algorithm, see Z. Wang, "Fast algorithms for the
|
||||
// discrete W transform and for the discrete Fourier transform", IEEE Trans. on
|
||||
// ASSP, Vol. ASSP- 32, pp. 803-816, Aug. 1984.
|
||||
func idct(src *block) {
|
||||
// Horizontal 1-D IDCT.
|
||||
for y := range 8 {
|
||||
y8 := y * 8
|
||||
s := src[y8 : y8+8 : y8+8] // Small cap improves performance, see https://golang.org/issue/27857
|
||||
// If all the AC components are zero, then the IDCT is trivial.
|
||||
if s[1] == 0 && s[2] == 0 && s[3] == 0 &&
|
||||
s[4] == 0 && s[5] == 0 && s[6] == 0 && s[7] == 0 {
|
||||
dc := s[0] << 3
|
||||
s[0] = dc
|
||||
s[1] = dc
|
||||
s[2] = dc
|
||||
s[3] = dc
|
||||
s[4] = dc
|
||||
s[5] = dc
|
||||
s[6] = dc
|
||||
s[7] = dc
|
||||
continue
|
||||
}
|
||||
|
||||
// Prescale.
|
||||
x0 := (s[0] << 11) + 128
|
||||
x1 := s[4] << 11
|
||||
x2 := s[6]
|
||||
x3 := s[2]
|
||||
x4 := s[1]
|
||||
x5 := s[7]
|
||||
x6 := s[5]
|
||||
x7 := s[3]
|
||||
|
||||
// Stage 1.
|
||||
x8 := w7 * (x4 + x5)
|
||||
x4 = x8 + w1mw7*x4
|
||||
x5 = x8 - w1pw7*x5
|
||||
x8 = w3 * (x6 + x7)
|
||||
x6 = x8 - w3mw5*x6
|
||||
x7 = x8 - w3pw5*x7
|
||||
|
||||
// Stage 2.
|
||||
x8 = x0 + x1
|
||||
x0 -= x1
|
||||
x1 = w6 * (x3 + x2)
|
||||
x2 = x1 - w2pw6*x2
|
||||
x3 = x1 + w2mw6*x3
|
||||
x1 = x4 + x6
|
||||
x4 -= x6
|
||||
x6 = x5 + x7
|
||||
x5 -= x7
|
||||
|
||||
// Stage 3.
|
||||
x7 = x8 + x3
|
||||
x8 -= x3
|
||||
x3 = x0 + x2
|
||||
x0 -= x2
|
||||
x2 = (r2*(x4+x5) + 128) >> 8
|
||||
x4 = (r2*(x4-x5) + 128) >> 8
|
||||
|
||||
// Stage 4.
|
||||
s[0] = (x7 + x1) >> 8
|
||||
s[1] = (x3 + x2) >> 8
|
||||
s[2] = (x0 + x4) >> 8
|
||||
s[3] = (x8 + x6) >> 8
|
||||
s[4] = (x8 - x6) >> 8
|
||||
s[5] = (x0 - x4) >> 8
|
||||
s[6] = (x3 - x2) >> 8
|
||||
s[7] = (x7 - x1) >> 8
|
||||
}
|
||||
|
||||
// Vertical 1-D IDCT.
|
||||
for x := range 8 {
|
||||
// Similar to the horizontal 1-D IDCT case, if all the AC components are zero, then the IDCT is trivial.
|
||||
// However, after performing the horizontal 1-D IDCT, there are typically non-zero AC components, so
|
||||
// we do not bother to check for the all-zero case.
|
||||
s := src[x : x+57 : x+57] // Small cap improves performance, see https://golang.org/issue/27857
|
||||
|
||||
// Prescale.
|
||||
y0 := (s[8*0] << 8) + 8192
|
||||
y1 := s[8*4] << 8
|
||||
y2 := s[8*6]
|
||||
y3 := s[8*2]
|
||||
y4 := s[8*1]
|
||||
y5 := s[8*7]
|
||||
y6 := s[8*5]
|
||||
y7 := s[8*3]
|
||||
|
||||
// Stage 1.
|
||||
y8 := w7*(y4+y5) + 4
|
||||
y4 = (y8 + w1mw7*y4) >> 3
|
||||
y5 = (y8 - w1pw7*y5) >> 3
|
||||
y8 = w3*(y6+y7) + 4
|
||||
y6 = (y8 - w3mw5*y6) >> 3
|
||||
y7 = (y8 - w3pw5*y7) >> 3
|
||||
|
||||
// Stage 2.
|
||||
y8 = y0 + y1
|
||||
y0 -= y1
|
||||
y1 = w6*(y3+y2) + 4
|
||||
y2 = (y1 - w2pw6*y2) >> 3
|
||||
y3 = (y1 + w2mw6*y3) >> 3
|
||||
y1 = y4 + y6
|
||||
y4 -= y6
|
||||
y6 = y5 + y7
|
||||
y5 -= y7
|
||||
|
||||
// Stage 3.
|
||||
y7 = y8 + y3
|
||||
y8 -= y3
|
||||
y3 = y0 + y2
|
||||
y0 -= y2
|
||||
y2 = (r2*(y4+y5) + 128) >> 8
|
||||
y4 = (r2*(y4-y5) + 128) >> 8
|
||||
|
||||
// Stage 4.
|
||||
s[8*0] = (y7 + y1) >> 14
|
||||
s[8*1] = (y3 + y2) >> 14
|
||||
s[8*2] = (y0 + y4) >> 14
|
||||
s[8*3] = (y8 + y6) >> 14
|
||||
s[8*4] = (y8 - y6) >> 14
|
||||
s[8*5] = (y0 - y4) >> 14
|
||||
s[8*6] = (y3 - y2) >> 14
|
||||
s[8*7] = (y7 - y1) >> 14
|
||||
}
|
||||
}
|
||||
45
vendor/github.com/kovidgoyal/imaging/jpeg/scan.go
generated
vendored
45
vendor/github.com/kovidgoyal/imaging/jpeg/scan.go
generated
vendored
@@ -303,9 +303,7 @@ func (d *decoder) processSOS(n int) error {
|
||||
// SOS markers are processed.
|
||||
continue
|
||||
}
|
||||
if err := d.reconstructBlock(&b, bx, by, int(compIndex)); err != nil {
|
||||
return err
|
||||
}
|
||||
d.reconstructBlock(&b, bx, by, int(compIndex))
|
||||
} // for j
|
||||
} // for i
|
||||
mcu++
|
||||
@@ -457,15 +455,23 @@ func (d *decoder) reconstructProgressiveImage() error {
|
||||
stride := mxx * d.comp[i].h
|
||||
for by := 0; by*v < d.height; by++ {
|
||||
for bx := 0; bx*h < d.width; bx++ {
|
||||
if err := d.reconstructBlock(&d.progCoeffs[i][by*stride+bx], bx, by, i); err != nil {
|
||||
return err
|
||||
}
|
||||
d.reconstructBlock(&d.progCoeffs[i][by*stride+bx], bx, by, i)
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func level_shift(c int32) uint8 {
|
||||
if c < -128 {
|
||||
return 0
|
||||
}
|
||||
if c > 127 {
|
||||
return 255
|
||||
}
|
||||
return uint8(c + 128)
|
||||
}
|
||||
|
||||
func (d *decoder) storeFlexBlock(b *block, bx, by, compIndex int) {
|
||||
h, v := d.comp[compIndex].expand.h, d.comp[compIndex].expand.v
|
||||
dst, stride := []byte(nil), 0
|
||||
@@ -484,15 +490,7 @@ func (d *decoder) storeFlexBlock(b *block, bx, by, compIndex int) {
|
||||
y8 := y * 8
|
||||
yv := y * v
|
||||
for x := range 8 {
|
||||
c := b[y8+x]
|
||||
var val uint8
|
||||
if c < -128 {
|
||||
val = 0
|
||||
} else if c > 127 {
|
||||
val = 255
|
||||
} else {
|
||||
val = uint8(c + 128)
|
||||
}
|
||||
val := level_shift(b[y8+x])
|
||||
xh := x * h
|
||||
for yy := range v {
|
||||
for xx := range h {
|
||||
@@ -505,7 +503,7 @@ func (d *decoder) storeFlexBlock(b *block, bx, by, compIndex int) {
|
||||
|
||||
// reconstructBlock dequantizes, performs the inverse DCT and stores the block
|
||||
// to the image.
|
||||
func (d *decoder) reconstructBlock(b *block, bx, by, compIndex int) error {
|
||||
func (d *decoder) reconstructBlock(b *block, bx, by, compIndex int) {
|
||||
qt := &d.quant[d.comp[compIndex].tq]
|
||||
for zig := range blockSize {
|
||||
b[unzig[zig]] *= qt[zig]
|
||||
@@ -517,7 +515,7 @@ func (d *decoder) reconstructBlock(b *block, bx, by, compIndex int) error {
|
||||
} else {
|
||||
if d.flex {
|
||||
d.storeFlexBlock(b, bx, by, compIndex)
|
||||
return nil
|
||||
return
|
||||
}
|
||||
switch compIndex {
|
||||
case 0:
|
||||
@@ -528,8 +526,6 @@ func (d *decoder) reconstructBlock(b *block, bx, by, compIndex int) error {
|
||||
dst, stride = d.img3.Cr[8*(by*d.img3.CStride+bx):], d.img3.CStride
|
||||
case 3:
|
||||
dst, stride = d.blackPix[8*(by*d.blackStride+bx):], d.blackStride
|
||||
default:
|
||||
return UnsupportedError("too many components")
|
||||
}
|
||||
}
|
||||
// Level shift by +128, clip to [0, 255], and write to dst.
|
||||
@@ -537,18 +533,9 @@ func (d *decoder) reconstructBlock(b *block, bx, by, compIndex int) error {
|
||||
y8 := y * 8
|
||||
yStride := y * stride
|
||||
for x := range 8 {
|
||||
c := b[y8+x]
|
||||
if c < -128 {
|
||||
c = 0
|
||||
} else if c > 127 {
|
||||
c = 255
|
||||
} else {
|
||||
c += 128
|
||||
}
|
||||
dst[yStride+x] = uint8(c)
|
||||
dst[yStride+x] = level_shift(b[y8+x])
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// findRST advances past the next RST restart marker that matches expectedRST.
|
||||
|
||||
2
vendor/github.com/kovidgoyal/imaging/publish.py
generated
vendored
2
vendor/github.com/kovidgoyal/imaging/publish.py
generated
vendored
@@ -5,7 +5,7 @@ import os
|
||||
import subprocess
|
||||
|
||||
|
||||
VERSION = "1.8.20"
|
||||
VERSION = "1.8.19"
|
||||
|
||||
|
||||
def run(*args: str):
|
||||
|
||||
4
vendor/modules.txt
vendored
4
vendor/modules.txt
vendored
@@ -910,7 +910,7 @@ github.com/kovidgoyal/go-parallel
|
||||
# github.com/kovidgoyal/go-shm v1.0.0
|
||||
## explicit; go 1.24.0
|
||||
github.com/kovidgoyal/go-shm
|
||||
# github.com/kovidgoyal/imaging v1.8.20
|
||||
# github.com/kovidgoyal/imaging v1.8.19
|
||||
## explicit; go 1.24.0
|
||||
github.com/kovidgoyal/imaging
|
||||
github.com/kovidgoyal/imaging/apng
|
||||
@@ -2477,7 +2477,7 @@ golang.org/x/exp/slices
|
||||
golang.org/x/exp/slog
|
||||
golang.org/x/exp/slog/internal
|
||||
golang.org/x/exp/slog/internal/buffer
|
||||
# golang.org/x/image v0.36.0
|
||||
# golang.org/x/image v0.35.0
|
||||
## explicit; go 1.24.0
|
||||
golang.org/x/image/bmp
|
||||
golang.org/x/image/ccitt
|
||||
|
||||
Reference in New Issue
Block a user