Skip to content
Projeler
Gruplar
Parçacıklar
Yardım
Yükleniyor...
Oturum aç / Kaydol
Gezinmeyi değiştir
C
core
Proje
Proje
Ayrıntılar
Etkinlik
Cycle Analytics
Depo (repository)
Depo (repository)
Dosyalar
Kayıtlar (commit)
Dallar (branch)
Etiketler
Katkıda bulunanlar
Grafik
Karşılaştır
Grafikler
Konular (issue)
0
Konular (issue)
0
Liste
Pano
Etiketler
Kilometre Taşları
Birleştirme (merge) Talepleri
0
Birleştirme (merge) Talepleri
0
CI / CD
CI / CD
İş akışları (pipeline)
İşler
Zamanlamalar
Grafikler
Paketler
Paketler
Wiki
Wiki
Parçacıklar
Parçacıklar
Üyeler
Üyeler
Collapse sidebar
Close sidebar
Etkinlik
Grafik
Grafikler
Yeni bir konu (issue) oluştur
İşler
Kayıtlar (commit)
Konu (issue) Panoları
Kenar çubuğunu aç
LibreOffice
core
Commits
ab65925b
Kaydet (Commit)
ab65925b
authored
Ock 17, 2015
tarafından
Luboš Luňák
Dosyalara gözat
Seçenekler
Dosyalara Gözat
İndir
Eposta Yamaları
Sade Fark
"area" scaling for opengl that has good results for downscaling
Change-Id: I0e4ad776cbf31f9a130aedf0f9741927560b5ac1
üst
c22dbb26
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
267 additions
and
0 deletions
+267
-0
Package_opengl.mk
vcl/Package_opengl.mk
+2
-0
program.hxx
vcl/inc/opengl/program.hxx
+2
-0
salbmp.hxx
vcl/inc/opengl/salbmp.hxx
+1
-0
areaScaleFastFragmentShader.glsl
vcl/opengl/areaScaleFastFragmentShader.glsl
+43
-0
areaScaleFragmentShader.glsl
vcl/opengl/areaScaleFragmentShader.glsl
+131
-0
program.cxx
vcl/opengl/program.cxx
+12
-0
scale.cxx
vcl/opengl/scale.cxx
+76
-0
No files found.
vcl/Package_opengl.mk
Dosyayı görüntüle @
ab65925b
...
...
@@ -10,6 +10,8 @@
$(eval $(call gb_Package_Package,vcl_opengl_shader,$(SRCDIR)/vcl/opengl))
$(eval $(call gb_Package_add_files,vcl_opengl_shader,$(LIBO_ETC_FOLDER)/opengl,\
areaScaleFastFragmentShader.glsl \
areaScaleFragmentShader.glsl \
blendedTextureFragmentShader.glsl \
blendedTextureVertexShader.glsl \
dumbVertexShader.glsl \
...
...
vcl/inc/opengl/program.hxx
Dosyayı görüntüle @
ab65925b
...
...
@@ -55,6 +55,8 @@ public:
void
SetUniform2f
(
const
OString
&
rName
,
GLfloat
v1
,
GLfloat
v2
);
void
SetUniform1fv
(
const
OString
&
rName
,
GLsizei
nCount
,
GLfloat
*
aValues
);
void
SetUniform2fv
(
const
OString
&
rName
,
GLsizei
nCount
,
GLfloat
*
aValues
);
void
SetUniform1i
(
const
OString
&
rName
,
GLint
v1
);
void
SetUniform1iv
(
const
OString
&
rName
,
GLsizei
nCount
,
GLint
*
aValues
);
void
SetColor
(
const
OString
&
rName
,
const
Color
&
rColor
);
void
SetColor
(
const
OString
&
rName
,
SalColor
nColor
,
sal_uInt8
nTransparency
);
void
SetColorf
(
const
OString
&
rName
,
SalColor
nColor
,
double
fTransparency
);
...
...
vcl/inc/opengl/salbmp.hxx
Dosyayı görüntüle @
ab65925b
...
...
@@ -104,6 +104,7 @@ private:
bool
ImplScaleFilter
(
const
double
&
rScaleX
,
const
double
&
rScaleY
,
GLenum
nFilter
);
void
ImplCreateKernel
(
const
double
&
fScale
,
const
Kernel
&
rKernel
,
GLfloat
*&
pWeights
,
sal_uInt32
&
aKernelSize
);
bool
ImplScaleConvolution
(
const
double
&
rScaleX
,
const
double
&
rScaleY
,
const
Kernel
&
aKernel
);
bool
ImplScaleArea
(
double
rScaleX
,
double
rScaleY
);
public
:
...
...
vcl/opengl/areaScaleFastFragmentShader.glsl
0 → 100644
Dosyayı görüntüle @
ab65925b
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
/* TODO Use textureOffset for newest version of GLSL */
uniform
sampler2D
sampler
;
uniform
int
xscale
;
uniform
int
yscale
;
uniform
float
xstep
;
uniform
float
ystep
;
uniform
float
ratio
;
// = 1.0/(xscale*yscale)
varying
vec2
tex_coord
;
/*
Just make the resulting color the average of all the source pixels
(which is an area (xscale)x(yscale) ).
*/
void
main
(
void
)
{
vec4
sum
=
vec4
(
0
.
0
,
0
.
0
,
0
.
0
,
0
.
0
);
vec2
offset
=
vec2
(
0
.
0
,
0
.
0
);
for
(
int
y
=
0
;
y
<
yscale
;
++
y
)
{
for
(
int
x
=
0
;
x
<
xscale
;
++
x
)
{
sum
+=
texture2D
(
sampler
,
tex_coord
.
st
+
offset
);
offset
.
x
+=
xstep
;
}
offset
.
y
+=
ystep
;
offset
.
x
=
0
.
0
;
}
sum
*=
ratio
;
gl_FragColor
=
sum
;
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
vcl/opengl/areaScaleFragmentShader.glsl
0 → 100644
Dosyayı görüntüle @
ab65925b
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
/* TODO Use textureOffset for newest version of GLSL */
uniform
sampler2D
sampler
;
uniform
int
swidth
;
uniform
int
sheight
;
uniform
float
xscale
;
uniform
float
yscale
;
uniform
float
xsrcconvert
;
uniform
float
ysrcconvert
;
uniform
float
xdestconvert
;
uniform
float
ydestconvert
;
varying
vec2
tex_coord
;
void
main
(
void
)
{
// Convert to pixel coordinates again.
int
dx
=
int
(
tex_coord
.
s
*
xdestconvert
);
int
dy
=
int
(
tex_coord
.
t
*
ydestconvert
);
// Note: These values are always the same for the same X (or Y),
// so they could be precalculated in C++ and passed to the shader,
// but GLSL has limits on the size of uniforms passed to it,
// so it'd need something like texture buffer objects from newer
// GLSL versions, and it seems the hassle is not really worth it.
// How much each column/row will contribute to the resulting pixel.
// assert( xscale <= 100 ); assert( yscale <= 100 );
float
xratio
[
100
+
2
];
float
yratio
[
100
+
2
];
// For finding the first and last source pixel.
int
xpixel
[
100
+
2
];
int
ypixel
[
100
+
2
];
int
xpos
=
0
;
int
ypos
=
0
;
// Compute the range of source pixels which will make up this destination pixel.
float
fsx1
=
dx
*
xscale
;
float
fsx2
=
fsx1
+
xscale
;
// To whole pixel coordinates.
int
sx1
=
ceil
(
fsx1
);
int
sx2
=
floor
(
fsx2
);
// Range checking.
sx2
=
min
(
sx2
,
swidth
-
1
);
sx1
=
min
(
sx1
,
sx2
);
// How much one full column contributes to the resulting pixel.
float
width
=
min
(
xscale
,
swidth
-
fsx1
);
if
(
sx1
-
fsx1
>
0
.
001
)
{
// The first column contributes only partially.
xpixel
[
xpos
]
=
sx1
-
1
;
xratio
[
xpos
]
=
(
sx1
-
fsx1
)
/
width
;
++
xpos
;
}
for
(
int
sx
=
sx1
;
sx
<
sx2
;
++
sx
)
{
// Columns that fully contribute to the resulting pixel.
xpixel
[
xpos
]
=
sx
;
xratio
[
xpos
]
=
1
.
0
/
width
;
++
xpos
;
}
if
(
fsx2
-
sx2
>
0
.
001
)
{
// The last column contributes only partially.
xpixel
[
xpos
]
=
sx2
;
xratio
[
xpos
]
=
min
(
min
(
fsx2
-
sx2
,
1
.
0
)
/
width
,
1
.
0
);
++
xpos
;
}
// The same for Y.
float
fsy1
=
dy
*
yscale
;
float
fsy2
=
fsy1
+
yscale
;
int
sy1
=
ceil
(
fsy1
);
int
sy2
=
floor
(
fsy2
);
sy2
=
min
(
sy2
,
sheight
-
1
);
sy1
=
min
(
sy1
,
sy2
);
float
height
=
min
(
yscale
,
sheight
-
fsy1
);
if
(
sy1
-
fsy1
>
0
.
001
)
{
ypixel
[
ypos
]
=
sy1
-
1
;
yratio
[
ypos
]
=
(
sy1
-
fsy1
)
/
height
;
++
ypos
;
}
for
(
int
sy
=
sy1
;
sy
<
sy2
;
++
sy
)
{
ypixel
[
ypos
]
=
sy
;
yratio
[
ypos
]
=
1
.
0
/
height
;
++
ypos
;
}
if
(
fsy2
-
sy2
>
0
.
001
)
{
ypixel
[
ypos
]
=
sy2
;
yratio
[
ypos
]
=
min
(
min
(
fsy2
-
sy2
,
1
.
0
)
/
height
,
1
.
0
);
++
ypos
;
}
int
xstart
=
xpixel
[
0
];
int
xend
=
xpixel
[
xpos
-
1
];
int
ystart
=
ypixel
[
0
];
int
yend
=
ypixel
[
ypos
-
1
];
vec4
sum
=
vec4
(
0
.
0
,
0
.
0
,
0
.
0
,
0
.
0
);
ypos
=
0
;
for
(
int
y
=
ystart
;
y
<=
yend
;
++
y
,
++
ypos
)
{
vec4
tmp
=
vec4
(
0
.
0
,
0
.
0
,
0
.
0
,
0
.
0
);
xpos
=
0
;
for
(
int
x
=
xstart
;
x
<=
xend
;
++
x
,
++
xpos
)
{
vec2
offset
=
vec2
(
x
*
xsrcconvert
,
y
*
ysrcconvert
);
tmp
+=
texture2D
(
sampler
,
offset
)
*
xratio
[
xpos
];
}
sum
+=
tmp
*
yratio
[
ypos
];
}
gl_FragColor
=
sum
;
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
vcl/opengl/program.cxx
Dosyayı görüntüle @
ab65925b
...
...
@@ -148,6 +148,18 @@ void OpenGLProgram::SetUniform2fv( const OString& rName, GLsizei nCount, GLfloat
glUniform2fv
(
nUniform
,
nCount
,
aValues
);
}
void
OpenGLProgram
::
SetUniform1i
(
const
OString
&
rName
,
GLint
v1
)
{
GLuint
nUniform
=
GetUniformLocation
(
rName
);
glUniform1i
(
nUniform
,
v1
);
}
void
OpenGLProgram
::
SetUniform1iv
(
const
OString
&
rName
,
GLsizei
nCount
,
GLint
*
aValues
)
{
GLuint
nUniform
=
GetUniformLocation
(
rName
);
glUniform1iv
(
nUniform
,
nCount
,
aValues
);
}
void
OpenGLProgram
::
SetColor
(
const
OString
&
rName
,
SalColor
nColor
,
sal_uInt8
nTransparency
)
{
GLuint
nUniform
=
GetUniformLocation
(
rName
);
...
...
vcl/opengl/scale.cxx
Dosyayı görüntüle @
ab65925b
...
...
@@ -188,6 +188,78 @@ bool OpenGLSalBitmap::ImplScaleConvolution(
return
true
;
}
/*
"Area" scaling algorithm, which seems to give better results for downscaling
than other algorithms. The principle (taken from opencv, see resize.cl)
is that each resulting pixel is the average of all the source pixel values
it represents. Which is trivial in the case of exact multiples for downscaling,
the generic case needs to also consider that some source pixels contribute
only partially to their resulting pixels (becauses of non-integer multiples).
*/
bool
OpenGLSalBitmap
::
ImplScaleArea
(
double
rScaleX
,
double
rScaleY
)
{
int
nNewWidth
(
mnWidth
*
rScaleX
);
int
nNewHeight
(
mnHeight
*
rScaleY
);
if
(
nNewWidth
==
mnWidth
&&
nNewHeight
==
mnHeight
)
return
true
;
double
ixscale
=
1
/
rScaleX
;
double
iyscale
=
1
/
rScaleY
;
bool
fast
=
(
ixscale
==
int
(
ixscale
)
&&
iyscale
==
int
(
iyscale
)
&&
int
(
nNewWidth
*
ixscale
)
==
mnWidth
&&
int
(
nNewHeight
*
iyscale
)
==
mnHeight
);
// The generic case has arrays only up to 100 ratio downscaling, which is hopefully enough
// in practice, but protect against buffer overflows in case such an extreme case happens
// (and in such case the precision of the generic algorithm probably doesn't matter anyway).
if
(
ixscale
>
100
||
iyscale
>
100
)
fast
=
true
;
// TODO Make sure the framebuffer is alright
OpenGLProgram
*
pProgram
=
mpContext
->
UseProgram
(
"textureVertexShader"
,
fast
?
OUString
(
"areaScaleFastFragmentShader"
)
:
OUString
(
"areaScaleFragmentShader"
));
if
(
pProgram
==
0
)
return
false
;
OpenGLTexture
aScratchTex
=
OpenGLTexture
(
nNewWidth
,
nNewHeight
);
OpenGLFramebuffer
*
pFramebuffer
=
mpContext
->
AcquireFramebuffer
(
aScratchTex
);
if
(
fast
)
{
pProgram
->
SetUniform1i
(
"xscale"
,
ixscale
);
pProgram
->
SetUniform1i
(
"yscale"
,
iyscale
);
pProgram
->
SetUniform1f
(
"xstep"
,
1.0
/
mnWidth
);
pProgram
->
SetUniform1f
(
"ystep"
,
1.0
/
mnHeight
);
pProgram
->
SetUniform1f
(
"ratio"
,
1.0
/
(
ixscale
*
iyscale
));
}
else
{
pProgram
->
SetUniform1f
(
"xscale"
,
ixscale
);
pProgram
->
SetUniform1f
(
"yscale"
,
iyscale
);
pProgram
->
SetUniform1i
(
"swidth"
,
mnWidth
);
pProgram
->
SetUniform1i
(
"sheight"
,
mnHeight
);
// For converting between <0,mnWidth-1> and <0.0,1.0> coordinate systems.
pProgram
->
SetUniform1f
(
"xsrcconvert"
,
1.0
/
(
mnWidth
-
1
));
pProgram
->
SetUniform1f
(
"ysrcconvert"
,
1.0
/
(
mnHeight
-
1
));
pProgram
->
SetUniform1f
(
"xdestconvert"
,
1.0
*
(
nNewWidth
-
1
));
pProgram
->
SetUniform1f
(
"ydestconvert"
,
1.0
*
(
nNewHeight
-
1
));
}
pProgram
->
SetTexture
(
"sampler"
,
maTexture
);
pProgram
->
DrawTexture
(
maTexture
);
pProgram
->
Clean
();
maTexture
=
aScratchTex
;
mpContext
->
ReleaseFramebuffer
(
pFramebuffer
);
mnWidth
=
nNewWidth
;
mnHeight
=
nNewHeight
;
CHECK_GL_ERROR
();
return
true
;
}
bool
OpenGLSalBitmap
::
ImplScale
(
const
double
&
rScaleX
,
const
double
&
rScaleY
,
sal_uInt32
nScaleFlag
)
{
SAL_INFO
(
"vcl.opengl"
,
"::ImplScale"
);
...
...
@@ -209,6 +281,10 @@ bool OpenGLSalBitmap::ImplScale( const double& rScaleX, const double& rScaleY, s
return
ImplScaleConvolution
(
rScaleX
,
rScaleY
,
aKernel
);
}
else
if
(
nScaleFlag
==
BMP_SCALE_BESTQUALITY
&&
rScaleX
<=
1
&&
rScaleY
<=
1
)
{
// Use are scaling for best quality, but only if downscaling.
return
ImplScaleArea
(
rScaleX
,
rScaleY
);
}
else
if
(
nScaleFlag
==
BMP_SCALE_LANCZOS
||
nScaleFlag
==
BMP_SCALE_BESTQUALITY
)
{
const
Lanczos3Kernel
aKernel
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment