Attachment #463677: Patch v2 - libjpeg-turbo added on top of libjpeg in /jpeg directory for bug #573948

View | Details | Raw Unified | Return to bug 573948
Collapse All | Expand All

(-)a/config/autoconf.mk.in (+4 lines)
Line     Link Here 
 Lines 158-173   MOZ_RAW = @MOZ_RAW@ Link Here 
158
MOZ_SYDNEYAUDIO = @MOZ_SYDNEYAUDIO@
158
MOZ_SYDNEYAUDIO = @MOZ_SYDNEYAUDIO@
159
MOZ_WAVE = @MOZ_WAVE@
159
MOZ_WAVE = @MOZ_WAVE@
160
MOZ_MEDIA = @MOZ_MEDIA@
160
MOZ_MEDIA = @MOZ_MEDIA@
161
MOZ_VORBIS = @MOZ_VORBIS@
161
MOZ_VORBIS = @MOZ_VORBIS@
162
MOZ_WEBM = @MOZ_WEBM@
162
MOZ_WEBM = @MOZ_WEBM@
163
VPX_AS = @VPX_AS@
163
VPX_AS = @VPX_AS@
164
VPX_ASFLAGS = @VPX_ASFLAGS@
164
VPX_ASFLAGS = @VPX_ASFLAGS@
165
VPX_X86_ASM = @VPX_X86_ASM@
165
VPX_X86_ASM = @VPX_X86_ASM@
166
LIBJPEG_TURBO_AS = @LIBJPEG_TURBO_AS@
167
LIBJPEG_TURBO_ASFLAGS = @LIBJPEG_TURBO_ASFLAGS@
168
LIBJPEG_TURBO_X86_ASM = @LIBJPEG_TURBO_X86_ASM@
169
LIBJPEG_TURBO_X64_ASM = @LIBJPEG_TURBO_X64_ASM@
166
NS_PRINTING = @NS_PRINTING@
170
NS_PRINTING = @NS_PRINTING@
167
MOZ_CRASHREPORTER = @MOZ_CRASHREPORTER@
171
MOZ_CRASHREPORTER = @MOZ_CRASHREPORTER@
168
MOZ_HELP_VIEWER = @MOZ_HELP_VIEWER@
172
MOZ_HELP_VIEWER = @MOZ_HELP_VIEWER@
169
MOC= @MOC@
173
MOC= @MOC@
170
MOZ_NSS_PATCH = @MOZ_NSS_PATCH@
174
MOZ_NSS_PATCH = @MOZ_NSS_PATCH@
171
MOZ_WEBGL = @MOZ_WEBGL@
175
MOZ_WEBGL = @MOZ_WEBGL@
172
176
173
MOZ_JAVAXPCOM = @MOZ_JAVAXPCOM@
177
MOZ_JAVAXPCOM = @MOZ_JAVAXPCOM@
(-)a/configure.in (+69 lines)
Line     Link Here 
 Lines 4883-4898   MOZ_RAW=1 Link Here 
4883
MOZ_SYDNEYAUDIO=
4883
MOZ_SYDNEYAUDIO=
4884
MOZ_VORBIS=
4884
MOZ_VORBIS=
4885
MOZ_WAVE=1
4885
MOZ_WAVE=1
4886
MOZ_MEDIA=
4886
MOZ_MEDIA=
4887
MOZ_WEBM=1
4887
MOZ_WEBM=1
4888
VPX_AS=
4888
VPX_AS=
4889
VPX_ASFLAGS=
4889
VPX_ASFLAGS=
4890
VPX_X86_ASM=
4890
VPX_X86_ASM=
4891
LIBJPEG_TURBO_AS=
4892
LIBJPEG_TURBO_ASFLAGS=
4893
LIBJPEG_TURBO_X86_ASM=
4894
LIBJPEG_TURBO_X64_ASM=
4891
MOZ_PANGO=1
4895
MOZ_PANGO=1
4892
MOZ_PERMISSIONS=1
4896
MOZ_PERMISSIONS=1
4893
MOZ_PLACES=1
4897
MOZ_PLACES=1
4894
MOZ_PLAINTEXT_EDITOR_ONLY=
4898
MOZ_PLAINTEXT_EDITOR_ONLY=
4895
MOZ_PLUGINS=1
4899
MOZ_PLUGINS=1
4896
MOZ_PREF_EXTENSIONS=1
4900
MOZ_PREF_EXTENSIONS=1
4897
MOZ_PROFILELOCKING=1
4901
MOZ_PROFILELOCKING=1
4898
MOZ_PSM=1
4902
MOZ_PSM=1
 Lines 6160-6175   MOZ_ARG_WITH_STRING(crashreporter-enable Link Here 
6160
    MOZ_CRASHREPORTER_ENABLE_PERCENT="$val"])
6164
    MOZ_CRASHREPORTER_ENABLE_PERCENT="$val"])
6161
6165
6162
if test -z "$MOZ_CRASHREPORTER_ENABLE_PERCENT"; then
6166
if test -z "$MOZ_CRASHREPORTER_ENABLE_PERCENT"; then
6163
   MOZ_CRASHREPORTER_ENABLE_PERCENT=100
6167
   MOZ_CRASHREPORTER_ENABLE_PERCENT=100
6164
fi
6168
fi
6165
AC_DEFINE_UNQUOTED(MOZ_CRASHREPORTER_ENABLE_PERCENT, $MOZ_CRASHREPORTER_ENABLE_PERCENT)
6169
AC_DEFINE_UNQUOTED(MOZ_CRASHREPORTER_ENABLE_PERCENT, $MOZ_CRASHREPORTER_ENABLE_PERCENT)
6166
6170
6167
dnl ========================================================
6171
dnl ========================================================
6172
dnl = libjpeg-turbo configuration
6173
dnl ========================================================
6174
6175
dnl Detect if we can use yasm to compile libjpeg-turbo's optimized assembly
6176
dnl files.
6177
AC_MSG_CHECKING([for YASM assembler])
6178
AC_CHECK_PROGS(LIBJPEG_TURBO_AS, yasm, "")
6179
6180
dnl XXX jlebar -- need a yasm version check here.
6181
6182
if test -n "LIBJPEG_TURBO_AS"; then
6183
6184
  LIBJPEG_TURBO_AS="yasm"
6185
6186
  dnl We have YASM; see if we support it on this platform.
6187
  case "$OS_ARCH:$OS_TEST" in
6188
  Linux:x86|Linux:i?86)
6189
    LIBJPEG_TURBO_ASFLAGS="-f elf32 -rnasm -pnasm -DPIC -DELF"
6190
    LIBJPEG_TURBO_X86_ASM=1
6191
  ;;
6192
  Linux:x86_64)
6193
    LIBJPEG_TURBO_ASFLAGS="-f elf64 -rnasm -pnasm -D__x86_64__ -DPIC -DELF"
6194
    LIBJPEG_TURBO_X64_ASM=1
6195
  ;;
6196
  SunOS:i?86)
6197
    LIBJPEG_TURBO_ASFLAGS="-f elf32 -rnasm -pnasm -DPIC -DELF"
6198
    LIBJPEG_TURBO_X86_ASM=1
6199
  ;;
6200
  SunOS:x86_64)
6201
    LIBJPEG_TURBO_ASFLAGS="-f elf64 -rnasm -pnasm -D__x86_64__ -DPIC -DELF"
6202
    LIBJPEG_TURBO_X64_ASM=1
6203
  ;;
6204
  Darwin:i?86)
6205
    LIBJPEG_TURBO_ASFLAGS="-f macho32 -rnasm -pnasm -DPIC -DMACHO"
6206
    LIBJPEG_TURBO_X86_ASM=1
6207
  ;;
6208
  Darwin:x86_64)
6209
    LIBJPEG_TURBO_ASFLAGS="-f macho64 -rnasm -pnasm -D__x86_64__ -DPIC -DMACHO"
6210
    LIBJPEG_TURBO_X64_ASM=1
6211
  ;;
6212
  WINNT:x86|WINNT:i?86)
6213
    LIBJPEG_TURBO_ASFLAGS="-f win32 -rnasm -pnasm -DPIC -DWIN32"
6214
    LIBJPEG_TURBO_X86_ASM=1
6215
  ;;
6216
  WINNT:x86_64)
6217
    LIBJPEG_TURBO_ASFLAGS="-f win64 -rnasm -pnasm -D__x86_64__ -DPIC -DWIN64"
6218
    LIBJPEG_TURBO_X64_ASM=1
6219
  ;;
6220
  esac
6221
6222
fi # end have YASM
6223
6224
if test -n "$LIBJPEG_TURBO_X86_ASM"; then
6225
  AC_DEFINE(LIBJPEG_TURBO_X86_ASM)
6226
elif test -n "$LIBJPEG_TURBO_X64_ASM"; then
6227
  AC_DEFINE(LIBJPEG_TURBO_X64_ASM)
6228
else
6229
  AC_MSG_WARN([No assembler or assembly support for libjpeg-turbo.  Using unoptimized C routines.])
6230
fi
6231
6232
dnl ========================================================
6168
dnl = Enable compilation of specific extension modules
6233
dnl = Enable compilation of specific extension modules
6169
dnl ========================================================
6234
dnl ========================================================
6170
6235
6171
MOZ_ARG_ENABLE_STRING(extensions,
6236
MOZ_ARG_ENABLE_STRING(extensions,
6172
[  --enable-extensions     Enable extensions],
6237
[  --enable-extensions     Enable extensions],
6173
[ for option in `echo $enableval | sed 's/,/ /g'`; do
6238
[ for option in `echo $enableval | sed 's/,/ /g'`; do
6174
    if test "$option" = "yes" -o "$option" = "all"; then
6239
    if test "$option" = "yes" -o "$option" = "all"; then
6175
        AC_MSG_ERROR([--enable-extensions=$option is no longer supported.])
6240
        AC_MSG_ERROR([--enable-extensions=$option is no longer supported.])
 Lines 8872-8887   AC_SUBST(MOZ_SYDNEYAUDIO) Link Here 
8872
AC_SUBST(MOZ_WAVE)
8937
AC_SUBST(MOZ_WAVE)
8873
AC_SUBST(MOZ_VORBIS)
8938
AC_SUBST(MOZ_VORBIS)
8874
AC_SUBST(MOZ_WEBM)
8939
AC_SUBST(MOZ_WEBM)
8875
AC_SUBST(MOZ_OGG)
8940
AC_SUBST(MOZ_OGG)
8876
AC_SUBST(MOZ_ALSA_LIBS)
8941
AC_SUBST(MOZ_ALSA_LIBS)
8877
AC_SUBST(VPX_AS)
8942
AC_SUBST(VPX_AS)
8878
AC_SUBST(VPX_ASFLAGS)
8943
AC_SUBST(VPX_ASFLAGS)
8879
AC_SUBST(VPX_X86_ASM)
8944
AC_SUBST(VPX_X86_ASM)
8945
AC_SUBST(LIBJPEG_TURBO_AS)
8946
AC_SUBST(LIBJPEG_TURBO_ASFLAGS)
8947
AC_SUBST(LIBJPEG_TURBO_X86_ASM)
8948
AC_SUBST(LIBJPEG_TURBO_X64_ASM)
8880
8949
8881
if test "$USING_HCC"; then
8950
if test "$USING_HCC"; then
8882
   CC='${topsrcdir}/build/hcc'
8951
   CC='${topsrcdir}/build/hcc'
8883
   CC="$CC '$_OLDCC'"
8952
   CC="$CC '$_OLDCC'"
8884
   CXX='${topsrcdir}/build/hcpp'
8953
   CXX='${topsrcdir}/build/hcpp'
8885
   CXX="$CXX '$_OLDCXX'"
8954
   CXX="$CXX '$_OLDCXX'"
8886
   AC_SUBST(CC)
8955
   AC_SUBST(CC)
8887
   AC_SUBST(CXX)
8956
   AC_SUBST(CXX)
(-)a/jpeg/BUILDING.txt (+328 lines)
Line     Link Here 
Line 0    Link Here 
1
*******************************************************************************
2
**     Building on Unix Platforms, Cygwin, and MinGW
3
*******************************************************************************
4
5
==================
6
Build Requirements
7
==================
8
9
-- autoconf 2.56 or later
10
-- automake 1.7 or later
11
-- libtool 1.4 or later
12
   * If using MinGW, these can be obtained by installing the MSYS DTK
13
14
-- NASM
15
   * 0.98 or later is required for a 32-bit build
16
   * NASM 2.05 or later is required for a 64-bit build
17
   * NASM 2.07 or later is required for a 64-bit build on OS/X.  This can be
18
     obtained from MacPorts (http://www.macports.org/).
19
20
   The NASM 2.05 RPMs do not work on older Linux systems, such as Enterprise
21
   Linux 4.  On such systems, you can easily build and install NASM 2.05
22
   from the source RPM by executing the following as root:
23
24
     ARCH=`uname -m`
25
     wget http://www.nasm.us/pub/nasm/releasebuilds/2.05.01/nasm-2.05.01-1.src.rpm
26
     rpmbuild --rebuild nasm-2.05.01-1.src.rpm
27
     rpm -Uvh /usr/src/redhat/RPMS/$ARCH/nasm-2.05.01-1.$ARCH.rpm
28
29
   NOTE: NASM build will fail if texinfo is not installed.
30
31
-- GCC v4.1 or later recommended for best performance
32
33
======================
34
Building libjpeg-turbo
35
======================
36
37
The following procedure will build libjpeg-turbo on Linux, FreeBSD, 32-bit
38
OS X, and Solaris/x86 systems (on Solaris, this generates a 32-bit library.
39
See below for 64-bit build instructions.)
40
41
  cd libjpeg-turbo
42
  autoreconf -fiv
43
  sh ./configure
44
  make
45
46
NOTE: Running autoreconf is only necessary if building libjpeg-turbo from the
47
SVN repository.
48
49
This will generate the following files under .libs/
50
51
  libjpeg.a
52
      Static link library for libjpeg-turbo
53
54
  libjpeg.so.62.0.0 (Linux, Solaris)
55
  libjpeg.62.dylib (OS X)
56
  libjpeg-62.dll (MinGW)
57
  cygjpeg-62.dll (Cygwin)
58
      Shared library for libjpeg-turbo
59
60
  libjpeg.so (Linux, Solaris)
61
  libjpeg.dylib (OS X)
62
  libjpeg.dll.a (Cygwin, MinGW)
63
      Development stub for libjpeg-turbo shared library
64
65
  libturbojpeg.a
66
      Static link library for TurboJPEG/OSS
67
68
  libturbojpeg.so (Linux, Solaris)
69
  libturbojpeg.dylib (OS X)
70
      Shared library and development stub for TurboJPEG/OSS
71
72
  libturbojpeg.dll (MinGW)
73
  cygturbojpeg.dll (Cygwin)
74
      Shared library for TurboJPEG/OSS
75
76
  libturbojpeg.dll.a (Cygwin, MinGW)
77
      Development stub for TurboJPEG/OSS shared library
78
79
========================
80
Installing libjpeg-turbo
81
========================
82
83
If you intend to install these libraries and the associated header files, then
84
replace 'make' in the instructions above with
85
86
  make install prefix={base dir} libdir={library directory}
87
88
For example,
89
90
  make install prefix=/usr/local libdir=/usr/local/lib64
91
92
will install the header files in /usr/local/include and the library files in
93
/usr/local/lib64.  If 'prefix' and 'libdir' are not specified, then the default
94
is to install the header files in /opt/libjpeg-turbo/include and the library
95
files in /opt/libjpeg-turbo/lib.
96
97
NOTE: You can specify a prefix of /usr and a libdir of, for instance,
98
/usr/lib64 to overwrite the system's version of libjpeg.  If you do this,
99
however, then be sure to BACK UP YOUR SYSTEM'S INSTALLATION OF LIBJPEG before
100
overwriting it.  It is recommended that you instead install libjpeg-turbo into
101
a non-system directory and manipulate the LD_LIBRARY_PATH or create sym links
102
to force applications to use libjpeg-turbo instead of libjpeg.  See
103
README-turbo.txt for more information.
104
105
=============
106
Build Recipes
107
=============
108
109
32-bit Library Build on 64-bit Linux
110
------------------------------------
111
112
Add
113
114
  --host i686-pc-linux-gnu CFLAGS='-O3 -m32' CXXFLAGS='-O3 -m32' LDFLAGS=-m32
115
116
to the configure command line.
117
118
119
64-bit Library Build on 64-bit OS/X
120
-----------------------------------
121
122
Add
123
124
  --host x86_64-apple-darwin NASM=/opt/local/bin/nasm
125
126
to the configure command line.  NASM 2.07 or later from MacPorts must be
127
installed.
128
129
130
32-bit Library Build on 64-bit OS/X
131
-----------------------------------
132
133
Add
134
135
  CFLAGS='-O3 -m32' CXXFLAGS='-O3 -m32' LDFLAGS=-m32
136
137
to the configure command line.
138
139
140
64-bit Backward-Compatible Library Build on 64-bit OS/X
141
-------------------------------------------------------
142
143
Add
144
145
  --host x86_64-apple-darwin NASM=/opt/local/bin/nasm \
146
  CFLAGS='-isysroot /Developer/SDKs/MacOSX10.4u.sdk \
147
    -mmacosx-version-min=10.4 -O3' \
148
    CXXFLAGS='-isysroot /Developer/SDKs/MacOSX10.4u.sdk \
149
    -mmacosx-version-min=10.4 -O3' \
150
    LDFLAGS='-isysroot /Developer/SDKs/MacOSX10.4u.sdk \
151
    -mmacosx-version-min=10.4'
152
153
to the configure command line.  The OS X 10.4 SDK, and NASM 2.07 or later from
154
MacPorts, must be installed.
155
156
157
32-bit Backward-Compatible Library Build on OS/X
158
------------------------------------------------
159
160
Add
161
162
  CFLAGS='-isysroot /Developer/SDKs/MacOSX10.4u.sdk \
163
    -mmacosx-version-min=10.4 -O3 -m32' \
164
    CXXFLAGS='-isysroot /Developer/SDKs/MacOSX10.4u.sdk \
165
    -mmacosx-version-min=10.4 -O3 -m32' \
166
    LDFLAGS='-isysroot /Developer/SDKs/MacOSX10.4u.sdk \
167
    -mmacosx-version-min=10.4 -m32'
168
169
to the configure command line.  The OS X 10.4 SDK must be installed.
170
171
172
64-bit Library Build on 64-bit Solaris
173
--------------------------------------
174
175
Add
176
177
  --host x86_64-pc-solaris CFLAGS='-O3 -m64' CXXFLAGS='-O3 -m64' LDFLAGS=-m64
178
179
to the configure command line.
180
181
182
32-bit Library Build on 64-bit FreeBSD
183
--------------------------------------
184
185
Add
186
187
  --host i386-unknown-freebsd CC='gcc -B /usr/lib32' CXX='g++ -B/usr/lib32' \
188
    CFLAGS='-O3 -m32' CXXFLAGS='-O3 -m32' LDFLAGS='-B/usr/lib32'
189
190
to the configure command line.  NASM 2.07 or later from FreeBSD ports must be
191
installed.
192
193
194
MinGW Build on Cygwin
195
---------------------
196
197
Add
198
199
  --host mingw32
200
201
to the configure command line.  This will produce libraries which do not
202
depend on cygwin1.dll or other Cygwin DLL's.
203
204
205
Sun Studio
206
----------
207
208
Add
209
210
  CC=cc CXX=CC
211
212
to the configure command line.  libjpeg-turbo will automatically be built with
213
the maximum optimization level (-xO5) unless you override CFLAGS and CXXFLAGS.
214
215
To build a 64-bit version of libjpeg-turbo using Sun Studio, add
216
217
  --host x86_64-pc-solaris CC=cc CXX=CC CFLAGS='-xO5 -m64' \
218
    CXXFLAGS='-xO5 -m64' LDFLAGS=-m64
219
220
to the configure command line.
221
222
223
*******************************************************************************
224
**     Building on Windows (Visual C++)
225
*******************************************************************************
226
227
==================
228
Build Requirements
229
==================
230
231
-- GNU Make v3.7 or later
232
   * Can be found in MSYS (http://www.mingw.org/download.shtml) or
233
     Cygwin (http://www.cygwin.com/)
234
235
-- Windows SDK for Windows Server 2008 and .NET Framework 3.5 (or a later
236
   version)
237
238
   http://msdn.microsoft.com/en-us/windows/dd146047.aspx
239
240
   * The Windows SDK includes both 32-bit and 64-bit Visual C++ compilers and
241
     everything necessary to build libjpeg-turbo.  If you do not already have
242
     Visual C++ installed, then this is the recommended solution.  Also tested
243
     with Microsoft Visual C++ 2008 Express Edition (both are free downloads.)
244
   * Add the compiler and SDK binary directories (for instance,
245
     c:\Program Files\Microsoft Visual Studio 9.0\VC\BIN;
246
     c:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE;
247
     c:\Program Files\Microsoft SDKs\Windows\v6.1\bin)
248
     to the system or user PATH environment variable prior to building
249
     libjpeg-turbo.
250
   * Add the compiler and SDK include directories (for instance,
251
     c:\Program Files\Microsoft Visual Studio 9.0\VC\INCLUDE;
252
     c:\Program Files\Microsoft SDKs\Windows\v6.1\include)
253
     to the system or user INCLUDE environment variable prior to building
254
     libjpeg-turbo.
255
   * Add the compiler library directory (for instance,
256
     c:\Program Files\Microsoft Visual Studio 9.0\VC\LIB;
257
     c:\Program Files\Microsoft SDKs\Windows\v6.1\lib)
258
     to the system or user LIB environment variable prior to building
259
     libjpeg-turbo.
260
261
-- NASM (http://www.nasm.us/) 0.98 or later (NASM 2.05 or later is required for
262
   a 64-bit build)
263
264
======================
265
Building libjpeg-turbo
266
======================
267
268
  cd libjpeg-turbo
269
  make -f win/Makefile
270
271
This will generate the following files under libjpeg-turbo\windows\:
272
273
  jpeg-static.lib        Static link library for libjpeg-turbo
274
  jpeg62.dll             Shared library for libjpeg-turbo
275
  jpeg.lib               Development stub for libjpeg-turbo shared library
276
  turbojpeg-static.lib   Static link library for TurboJPEG/OSS
277
  turbojpeg.dll          Shared library for TurboJPEG/OSS
278
  turbojpeg.lib          Development stub for TurboJPEG/OSS shared library
279
280
If a 64-bit Windows platform is detected, then the build system will attempt
281
to build a 64-bit version of libjpeg-turbo.  You can override this by running
282
283
  make -f win/Makefile WIN64=no
284
285
286
*******************************************************************************
287
**     Creating Release Packages
288
*******************************************************************************
289
290
The following commands can be used to create various types of release packages:
291
292
make rpm
293
294
  Create RedHat-style binary RPM package.  Requires RPM v4 or later.
295
296
make srpm
297
298
  This runs 'make dist' to create a pristine source tarball, then creates a
299
  RedHat-style source RPM package from the tarball.  Requires RPM v4 or later.
300
301
make deb
302
303
  Create Debian-style binary package.  Requires dpkg.
304
305
make dmg
306
307
  Create Macintosh package/disk image.  This requires the PackageMaker
308
  application, which must be installed in /Developer/Applications/Utilities.
309
310
make udmg
311
312
  On 64-bit OS X systems, this creates a version of the Macintosh package and
313
  disk image which contains universal i386/x86-64 binaries.  The 32-bit fork of
314
  these binaries is backward compatible with OS X 10.4 and later.  The 64-bit
315
  fork can be made backward compatible as well by using the instructions in
316
  the "Build Recipes" section.  OS X 10.4 compatibility SDK required.
317
318
make nsi
319
320
  When using MinGW, this creates a Win32 installer for the GCC version of the
321
  libjpeg-turbo SDK.  This requires the Nullsoft Install System
322
  (http://nsis.sourceforge.net/.)  makensis.exe should be in your PATH.
323
324
make -f win/Makefile nsi
325
326
  This creates a Win32 installer for the Visual C++ version of the
327
  libjpeg-turbo SDK.  This requires the Nullsoft Install System
328
  (http://nsis.sourceforge.net/.)  makensis.exe should be in your PATH.
(-)a/jpeg/ChangeLog.txt (+48 lines)
Line     Link Here 
Line 0    Link Here 
1
Significant changes since 1.0.0
2
===============================
3
4
[1] The Huffman decoder will now handle erroneous Huffman codes (for instance,
5
from a corrupt JPEG image.)  Previously, these would cause libjpeg-turbo to
6
crash under certain circumstances.
7
8
9
Significant changes since 0.0.93
10
================================
11
12
[1] 2983700: Further FreeBSD build tweaks (no longer necessary to specify
13
--host when configuring on a 64-bit system)
14
15
[2] Created sym. links in the Unix/Linux packages so that the TurboJPEG
16
include file can always be found in /opt/libjpeg-turbo/include, the 32-bit
17
static libraries can always be found in /opt/libjpeg-turbo/lib32, and the
18
64-bit static libraries can always be found in /opt/libjpeg-turbo/lib64.
19
20
[3] The Unix/Linux distribution packages now include the libjpeg run-time
21
programs (cjpeg, etc.) and man pages.
22
23
[4] Created a 32-bit supplementary package for amd64 Debian systems which
24
contains just the 32-bit libjpeg-turbo libraries.
25
26
[5] Moved the libraries from */lib32 to */lib in the i386 Debian package.
27
28
[6] Include distribution package for Cygwin
29
30
[7] No longer necessary to specify --without-simd on non-x86 architectures, and
31
unit tests now work on those architectures.
32
33
34
Significant changes since 0.0.91
35
================================
36
37
[1] 2982659, Fixed x86-64 build on FreeBSD systems
38
39
[2] 2988188: Added support for Windows 64-bit systems
40
41
42
Significant changes since 0.0.90
43
================================
44
45
[1] Added documentation to .deb packages
46
47
[2] 2968313: Fixed data corruption issues when decompressing large JPEG images
48
and/or using buffered I/O with the libjpeg-turbo decompressor
(-)a/jpeg/LGPL.txt (+504 lines)
Line     Link Here 
Line 0    Link Here 
1
		  GNU LESSER GENERAL PUBLIC LICENSE
2
		       Version 2.1, February 1999
3
4
 Copyright (C) 1991, 1999 Free Software Foundation, Inc.
5
     59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
6
 Everyone is permitted to copy and distribute verbatim copies
7
 of this license document, but changing it is not allowed.
8
9
[This is the first released version of the Lesser GPL.  It also counts
10
 as the successor of the GNU Library Public License, version 2, hence
11
 the version number 2.1.]
12
13
			    Preamble
14
15
  The licenses for most software are designed to take away your
16
freedom to share and change it.  By contrast, the GNU General Public
17
Licenses are intended to guarantee your freedom to share and change
18
free software--to make sure the software is free for all its users.
19
20
  This license, the Lesser General Public License, applies to some
21
specially designated software packages--typically libraries--of the
22
Free Software Foundation and other authors who decide to use it.  You
23
can use it too, but we suggest you first think carefully about whether
24
this license or the ordinary General Public License is the better
25
strategy to use in any particular case, based on the explanations below.
26
27
  When we speak of free software, we are referring to freedom of use,
28
not price.  Our General Public Licenses are designed to make sure that
29
you have the freedom to distribute copies of free software (and charge
30
for this service if you wish); that you receive source code or can get
31
it if you want it; that you can change the software and use pieces of
32
it in new free programs; and that you are informed that you can do
33
these things.
34
35
  To protect your rights, we need to make restrictions that forbid
36
distributors to deny you these rights or to ask you to surrender these
37
rights.  These restrictions translate to certain responsibilities for
38
you if you distribute copies of the library or if you modify it.
39
40
  For example, if you distribute copies of the library, whether gratis
41
or for a fee, you must give the recipients all the rights that we gave
42
you.  You must make sure that they, too, receive or can get the source
43
code.  If you link other code with the library, you must provide
44
complete object files to the recipients, so that they can relink them
45
with the library after making changes to the library and recompiling
46
it.  And you must show them these terms so they know their rights.
47
48
  We protect your rights with a two-step method: (1) we copyright the
49
library, and (2) we offer you this license, which gives you legal
50
permission to copy, distribute and/or modify the library.
51
52
  To protect each distributor, we want to make it very clear that
53
there is no warranty for the free library.  Also, if the library is
54
modified by someone else and passed on, the recipients should know
55
that what they have is not the original version, so that the original
56
author's reputation will not be affected by problems that might be
57
introduced by others.
58
59
  Finally, software patents pose a constant threat to the existence of
60
any free program.  We wish to make sure that a company cannot
61
effectively restrict the users of a free program by obtaining a
62
restrictive license from a patent holder.  Therefore, we insist that
63
any patent license obtained for a version of the library must be
64
consistent with the full freedom of use specified in this license.
65
66
  Most GNU software, including some libraries, is covered by the
67
ordinary GNU General Public License.  This license, the GNU Lesser
68
General Public License, applies to certain designated libraries, and
69
is quite different from the ordinary General Public License.  We use
70
this license for certain libraries in order to permit linking those
71
libraries into non-free programs.
72
73
  When a program is linked with a library, whether statically or using
74
a shared library, the combination of the two is legally speaking a
75
combined work, a derivative of the original library.  The ordinary
76
General Public License therefore permits such linking only if the
77
entire combination fits its criteria of freedom.  The Lesser General
78
Public License permits more lax criteria for linking other code with
79
the library.
80
81
  We call this license the "Lesser" General Public License because it
82
does Less to protect the user's freedom than the ordinary General
83
Public License.  It also provides other free software developers Less
84
of an advantage over competing non-free programs.  These disadvantages
85
are the reason we use the ordinary General Public License for many
86
libraries.  However, the Lesser license provides advantages in certain
87
special circumstances.
88
89
  For example, on rare occasions, there may be a special need to
90
encourage the widest possible use of a certain library, so that it becomes
91
a de-facto standard.  To achieve this, non-free programs must be
92
allowed to use the library.  A more frequent case is that a free
93
library does the same job as widely used non-free libraries.  In this
94
case, there is little to gain by limiting the free library to free
95
software only, so we use the Lesser General Public License.
96
97
  In other cases, permission to use a particular library in non-free
98
programs enables a greater number of people to use a large body of
99
free software.  For example, permission to use the GNU C Library in
100
non-free programs enables many more people to use the whole GNU
101
operating system, as well as its variant, the GNU/Linux operating
102
system.
103
104
  Although the Lesser General Public License is Less protective of the
105
users' freedom, it does ensure that the user of a program that is
106
linked with the Library has the freedom and the wherewithal to run
107
that program using a modified version of the Library.
108
109
  The precise terms and conditions for copying, distribution and
110
modification follow.  Pay close attention to the difference between a
111
"work based on the library" and a "work that uses the library".  The
112
former contains code derived from the library, whereas the latter must
113
be combined with the library in order to run.
114
115
		  GNU LESSER GENERAL PUBLIC LICENSE
116
   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
117
118
  0. This License Agreement applies to any software library or other
119
program which contains a notice placed by the copyright holder or
120
other authorized party saying it may be distributed under the terms of
121
this Lesser General Public License (also called "this License").
122
Each licensee is addressed as "you".
123
124
  A "library" means a collection of software functions and/or data
125
prepared so as to be conveniently linked with application programs
126
(which use some of those functions and data) to form executables.
127
128
  The "Library", below, refers to any such software library or work
129
which has been distributed under these terms.  A "work based on the
130
Library" means either the Library or any derivative work under
131
copyright law: that is to say, a work containing the Library or a
132
portion of it, either verbatim or with modifications and/or translated
133
straightforwardly into another language.  (Hereinafter, translation is
134
included without limitation in the term "modification".)
135
136
  "Source code" for a work means the preferred form of the work for
137
making modifications to it.  For a library, complete source code means
138
all the source code for all modules it contains, plus any associated
139
interface definition files, plus the scripts used to control compilation
140
and installation of the library.
141
142
  Activities other than copying, distribution and modification are not
143
covered by this License; they are outside its scope.  The act of
144
running a program using the Library is not restricted, and output from
145
such a program is covered only if its contents constitute a work based
146
on the Library (independent of the use of the Library in a tool for
147
writing it).  Whether that is true depends on what the Library does
148
and what the program that uses the Library does.
149
  
150
  1. You may copy and distribute verbatim copies of the Library's
151
complete source code as you receive it, in any medium, provided that
152
you conspicuously and appropriately publish on each copy an
153
appropriate copyright notice and disclaimer of warranty; keep intact
154
all the notices that refer to this License and to the absence of any
155
warranty; and distribute a copy of this License along with the
156
Library.
157
158
  You may charge a fee for the physical act of transferring a copy,
159
and you may at your option offer warranty protection in exchange for a
160
fee.
161
162
  2. You may modify your copy or copies of the Library or any portion
163
of it, thus forming a work based on the Library, and copy and
164
distribute such modifications or work under the terms of Section 1
165
above, provided that you also meet all of these conditions:
166
167
    a) The modified work must itself be a software library.
168
169
    b) You must cause the files modified to carry prominent notices
170
    stating that you changed the files and the date of any change.
171
172
    c) You must cause the whole of the work to be licensed at no
173
    charge to all third parties under the terms of this License.
174
175
    d) If a facility in the modified Library refers to a function or a
176
    table of data to be supplied by an application program that uses
177
    the facility, other than as an argument passed when the facility
178
    is invoked, then you must make a good faith effort to ensure that,
179
    in the event an application does not supply such function or
180
    table, the facility still operates, and performs whatever part of
181
    its purpose remains meaningful.
182
183
    (For example, a function in a library to compute square roots has
184
    a purpose that is entirely well-defined independent of the
185
    application.  Therefore, Subsection 2d requires that any
186
    application-supplied function or table used by this function must
187
    be optional: if the application does not supply it, the square
188
    root function must still compute square roots.)
189
190
These requirements apply to the modified work as a whole.  If
191
identifiable sections of that work are not derived from the Library,
192
and can be reasonably considered independent and separate works in
193
themselves, then this License, and its terms, do not apply to those
194
sections when you distribute them as separate works.  But when you
195
distribute the same sections as part of a whole which is a work based
196
on the Library, the distribution of the whole must be on the terms of
197
this License, whose permissions for other licensees extend to the
198
entire whole, and thus to each and every part regardless of who wrote
199
it.
200
201
Thus, it is not the intent of this section to claim rights or contest
202
your rights to work written entirely by you; rather, the intent is to
203
exercise the right to control the distribution of derivative or
204
collective works based on the Library.
205
206
In addition, mere aggregation of another work not based on the Library
207
with the Library (or with a work based on the Library) on a volume of
208
a storage or distribution medium does not bring the other work under
209
the scope of this License.
210
211
  3. You may opt to apply the terms of the ordinary GNU General Public
212
License instead of this License to a given copy of the Library.  To do
213
this, you must alter all the notices that refer to this License, so
214
that they refer to the ordinary GNU General Public License, version 2,
215
instead of to this License.  (If a newer version than version 2 of the
216
ordinary GNU General Public License has appeared, then you can specify
217
that version instead if you wish.)  Do not make any other change in
218
these notices.
219
220
  Once this change is made in a given copy, it is irreversible for
221
that copy, so the ordinary GNU General Public License applies to all
222
subsequent copies and derivative works made from that copy.
223
224
  This option is useful when you wish to copy part of the code of
225
the Library into a program that is not a library.
226
227
  4. You may copy and distribute the Library (or a portion or
228
derivative of it, under Section 2) in object code or executable form
229
under the terms of Sections 1 and 2 above provided that you accompany
230
it with the complete corresponding machine-readable source code, which
231
must be distributed under the terms of Sections 1 and 2 above on a
232
medium customarily used for software interchange.
233
234
  If distribution of object code is made by offering access to copy
235
from a designated place, then offering equivalent access to copy the
236
source code from the same place satisfies the requirement to
237
distribute the source code, even though third parties are not
238
compelled to copy the source along with the object code.
239
240
  5. A program that contains no derivative of any portion of the
241
Library, but is designed to work with the Library by being compiled or
242
linked with it, is called a "work that uses the Library".  Such a
243
work, in isolation, is not a derivative work of the Library, and
244
therefore falls outside the scope of this License.
245
246
  However, linking a "work that uses the Library" with the Library
247
creates an executable that is a derivative of the Library (because it
248
contains portions of the Library), rather than a "work that uses the
249
library".  The executable is therefore covered by this License.
250
Section 6 states terms for distribution of such executables.
251
252
  When a "work that uses the Library" uses material from a header file
253
that is part of the Library, the object code for the work may be a
254
derivative work of the Library even though the source code is not.
255
Whether this is true is especially significant if the work can be
256
linked without the Library, or if the work is itself a library.  The
257
threshold for this to be true is not precisely defined by law.
258
259
  If such an object file uses only numerical parameters, data
260
structure layouts and accessors, and small macros and small inline
261
functions (ten lines or less in length), then the use of the object
262
file is unrestricted, regardless of whether it is legally a derivative
263
work.  (Executables containing this object code plus portions of the
264
Library will still fall under Section 6.)
265
266
  Otherwise, if the work is a derivative of the Library, you may
267
distribute the object code for the work under the terms of Section 6.
268
Any executables containing that work also fall under Section 6,
269
whether or not they are linked directly with the Library itself.
270
271
  6. As an exception to the Sections above, you may also combine or
272
link a "work that uses the Library" with the Library to produce a
273
work containing portions of the Library, and distribute that work
274
under terms of your choice, provided that the terms permit
275
modification of the work for the customer's own use and reverse
276
engineering for debugging such modifications.
277
278
  You must give prominent notice with each copy of the work that the
279
Library is used in it and that the Library and its use are covered by
280
this License.  You must supply a copy of this License.  If the work
281
during execution displays copyright notices, you must include the
282
copyright notice for the Library among them, as well as a reference
283
directing the user to the copy of this License.  Also, you must do one
284
of these things:
285
286
    a) Accompany the work with the complete corresponding
287
    machine-readable source code for the Library including whatever
288
    changes were used in the work (which must be distributed under
289
    Sections 1 and 2 above); and, if the work is an executable linked
290
    with the Library, with the complete machine-readable "work that
291
    uses the Library", as object code and/or source code, so that the
292
    user can modify the Library and then relink to produce a modified
293
    executable containing the modified Library.  (It is understood
294
    that the user who changes the contents of definitions files in the
295
    Library will not necessarily be able to recompile the application
296
    to use the modified definitions.)
297
298
    b) Use a suitable shared library mechanism for linking with the
299
    Library.  A suitable mechanism is one that (1) uses at run time a
300
    copy of the library already present on the user's computer system,
301
    rather than copying library functions into the executable, and (2)
302
    will operate properly with a modified version of the library, if
303
    the user installs one, as long as the modified version is
304
    interface-compatible with the version that the work was made with.
305
306
    c) Accompany the work with a written offer, valid for at
307
    least three years, to give the same user the materials
308
    specified in Subsection 6a, above, for a charge no more
309
    than the cost of performing this distribution.
310
311
    d) If distribution of the work is made by offering access to copy
312
    from a designated place, offer equivalent access to copy the above
313
    specified materials from the same place.
314
315
    e) Verify that the user has already received a copy of these
316
    materials or that you have already sent this user a copy.
317
318
  For an executable, the required form of the "work that uses the
319
Library" must include any data and utility programs needed for
320
reproducing the executable from it.  However, as a special exception,
321
the materials to be distributed need not include anything that is
322
normally distributed (in either source or binary form) with the major
323
components (compiler, kernel, and so on) of the operating system on
324
which the executable runs, unless that component itself accompanies
325
the executable.
326
327
  It may happen that this requirement contradicts the license
328
restrictions of other proprietary libraries that do not normally
329
accompany the operating system.  Such a contradiction means you cannot
330
use both them and the Library together in an executable that you
331
distribute.
332
333
  7. You may place library facilities that are a work based on the
334
Library side-by-side in a single library together with other library
335
facilities not covered by this License, and distribute such a combined
336
library, provided that the separate distribution of the work based on
337
the Library and of the other library facilities is otherwise
338
permitted, and provided that you do these two things:
339
340
    a) Accompany the combined library with a copy of the same work
341
    based on the Library, uncombined with any other library
342
    facilities.  This must be distributed under the terms of the
343
    Sections above.
344
345
    b) Give prominent notice with the combined library of the fact
346
    that part of it is a work based on the Library, and explaining
347
    where to find the accompanying uncombined form of the same work.
348
349
  8. You may not copy, modify, sublicense, link with, or distribute
350
the Library except as expressly provided under this License.  Any
351
attempt otherwise to copy, modify, sublicense, link with, or
352
distribute the Library is void, and will automatically terminate your
353
rights under this License.  However, parties who have received copies,
354
or rights, from you under this License will not have their licenses
355
terminated so long as such parties remain in full compliance.
356
357
  9. You are not required to accept this License, since you have not
358
signed it.  However, nothing else grants you permission to modify or
359
distribute the Library or its derivative works.  These actions are
360
prohibited by law if you do not accept this License.  Therefore, by
361
modifying or distributing the Library (or any work based on the
362
Library), you indicate your acceptance of this License to do so, and
363
all its terms and conditions for copying, distributing or modifying
364
the Library or works based on it.
365
366
  10. Each time you redistribute the Library (or any work based on the
367
Library), the recipient automatically receives a license from the
368
original licensor to copy, distribute, link with or modify the Library
369
subject to these terms and conditions.  You may not impose any further
370
restrictions on the recipients' exercise of the rights granted herein.
371
You are not responsible for enforcing compliance by third parties with
372
this License.
373
374
  11. If, as a consequence of a court judgment or allegation of patent
375
infringement or for any other reason (not limited to patent issues),
376
conditions are imposed on you (whether by court order, agreement or
377
otherwise) that contradict the conditions of this License, they do not
378
excuse you from the conditions of this License.  If you cannot
379
distribute so as to satisfy simultaneously your obligations under this
380
License and any other pertinent obligations, then as a consequence you
381
may not distribute the Library at all.  For example, if a patent
382
license would not permit royalty-free redistribution of the Library by
383
all those who receive copies directly or indirectly through you, then
384
the only way you could satisfy both it and this License would be to
385
refrain entirely from distribution of the Library.
386
387
If any portion of this section is held invalid or unenforceable under any
388
particular circumstance, the balance of the section is intended to apply,
389
and the section as a whole is intended to apply in other circumstances.
390
391
It is not the purpose of this section to induce you to infringe any
392
patents or other property right claims or to contest validity of any
393
such claims; this section has the sole purpose of protecting the
394
integrity of the free software distribution system which is
395
implemented by public license practices.  Many people have made
396
generous contributions to the wide range of software distributed
397
through that system in reliance on consistent application of that
398
system; it is up to the author/donor to decide if he or she is willing
399
to distribute software through any other system and a licensee cannot
400
impose that choice.
401
402
This section is intended to make thoroughly clear what is believed to
403
be a consequence of the rest of this License.
404
405
  12. If the distribution and/or use of the Library is restricted in
406
certain countries either by patents or by copyrighted interfaces, the
407
original copyright holder who places the Library under this License may add
408
an explicit geographical distribution limitation excluding those countries,
409
so that distribution is permitted only in or among countries not thus
410
excluded.  In such case, this License incorporates the limitation as if
411
written in the body of this License.
412
413
  13. The Free Software Foundation may publish revised and/or new
414
versions of the Lesser General Public License from time to time.
415
Such new versions will be similar in spirit to the present version,
416
but may differ in detail to address new problems or concerns.
417
418
Each version is given a distinguishing version number.  If the Library
419
specifies a version number of this License which applies to it and
420
"any later version", you have the option of following the terms and
421
conditions either of that version or of any later version published by
422
the Free Software Foundation.  If the Library does not specify a
423
license version number, you may choose any version ever published by
424
the Free Software Foundation.
425
426
  14. If you wish to incorporate parts of the Library into other free
427
programs whose distribution conditions are incompatible with these,
428
write to the author to ask for permission.  For software which is
429
copyrighted by the Free Software Foundation, write to the Free
430
Software Foundation; we sometimes make exceptions for this.  Our
431
decision will be guided by the two goals of preserving the free status
432
of all derivatives of our free software and of promoting the sharing
433
and reuse of software generally.
434
435
			    NO WARRANTY
436
437
  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
438
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
439
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
440
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
441
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
442
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
443
PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
444
LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
445
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
446
447
  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
448
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
449
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
450
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
451
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
452
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
453
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
454
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
455
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
456
DAMAGES.
457
458
		     END OF TERMS AND CONDITIONS
459
460
           How to Apply These Terms to Your New Libraries
461
462
  If you develop a new library, and you want it to be of the greatest
463
possible use to the public, we recommend making it free software that
464
everyone can redistribute and change.  You can do so by permitting
465
redistribution under these terms (or, alternatively, under the terms of the
466
ordinary General Public License).
467
468
  To apply these terms, attach the following notices to the library.  It is
469
safest to attach them to the start of each source file to most effectively
470
convey the exclusion of warranty; and each file should have at least the
471
"copyright" line and a pointer to where the full notice is found.
472
473
    <one line to give the library's name and a brief idea of what it does.>
474
    Copyright (C) <year>  <name of author>
475
476
    This library is free software; you can redistribute it and/or
477
    modify it under the terms of the GNU Lesser General Public
478
    License as published by the Free Software Foundation; either
479
    version 2.1 of the License, or (at your option) any later version.
480
481
    This library is distributed in the hope that it will be useful,
482
    but WITHOUT ANY WARRANTY; without even the implied warranty of
483
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
484
    Lesser General Public License for more details.
485
486
    You should have received a copy of the GNU Lesser General Public
487
    License along with this library; if not, write to the Free Software
488
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
489
490
Also add information on how to contact you by electronic and paper mail.
491
492
You should also get your employer (if you work as a programmer) or your
493
school, if any, to sign a "copyright disclaimer" for the library, if
494
necessary.  Here is a sample; alter the names:
495
496
  Yoyodyne, Inc., hereby disclaims all copyright interest in the
497
  library `Frob' (a library for tweaking knobs) written by James Random Hacker.
498
499
  <signature of Ty Coon>, 1 April 1990
500
  Ty Coon, President of Vice
501
502
That's all there is to it!
503
504
(-)a/jpeg/LICENSE.txt (+53 lines)
Line     Link Here 
Line 0    Link Here 
1
                wxWindows Library Licence, Version 3.1
2
                ======================================
3
4
  Copyright (C) 1998-2005 Julian Smart, Robert Roebling et al
5
6
  Everyone is permitted to copy and distribute verbatim copies
7
  of this licence document, but changing it is not allowed.
8
9
                       WXWINDOWS LIBRARY LICENCE
10
     TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
11
  
12
  This library is free software; you can redistribute it and/or modify it
13
  under the terms of the GNU Library General Public Licence as published by
14
  the Free Software Foundation; either version 2 of the Licence, or (at
15
  your option) any later version.
16
  
17
  This library is distributed in the hope that it will be useful, but
18
  WITHOUT ANY WARRANTY; without even the implied warranty of
19
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library
20
  General Public Licence for more details.
21
22
  You should have received a copy of the GNU Library General Public Licence
23
  along with this software, usually in a file named COPYING.LIB.  If not,
24
  write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
25
  Boston, MA 02111-1307 USA.
26
27
  EXCEPTION NOTICE
28
29
  1. As a special exception, the copyright holders of this library give
30
  permission for additional uses of the text contained in this release of
31
  the library as licenced under the wxWindows Library Licence, applying
32
  either version 3.1 of the Licence, or (at your option) any later version of
33
  the Licence as published by the copyright holders of version
34
  3.1 of the Licence document.
35
36
  2. The exception is that you may use, copy, link, modify and distribute
37
  under your own terms, binary object code versions of works based
38
  on the Library.
39
40
  3. If you copy code from files distributed under the terms of the GNU
41
  General Public Licence or the GNU Library General Public Licence into a
42
  copy of this library, as this licence permits, the exception does not
43
  apply to the code that you add in this way.  To avoid misleading anyone as
44
  to the status of such modified files, you must delete this exception
45
  notice from such code and/or adjust the licensing conditions notice
46
  accordingly.
47
48
  4. If you write modifications of your own for this library, it is your
49
  choice whether to permit this exception to apply to your modifications. 
50
  If you do not wish that, you must delete the exception notice from such
51
  code and/or adjust the licensing conditions notice accordingly.
52
53
(-)a/jpeg/MOZCHANGES (-5 / +36 lines)
Line     Link Here 
 Lines 1-10    Link Here 
1
To upgrade to a new revision of libjpeg-turbo, do the following:
1
2
2
Changes made to pristine jpeg source by mozilla.org developers.
3
* Check out libjpeg-turbo from SVN:
3
4
4
2003/08/18 -- change default mapping for METHODDEF, LOCAL, GLOBAL, EXTERN to better match NSPR
5
    $ svn co https://libjpeg-turbo.svn.sourceforge.net/svnroot/libjpeg-turbo/trunk libjpeg-turbo
5
6
6
2003/03/14  -- mingw bustage fix. w32api uses different header guard define
7
* In a clean clone of mozilla-central, run the following commands
7
               for <basestd.h> than msvc.
8
8
9
????/??/??  -- Lots of undocumented changes. :(
9
    rm -rf jpeg
10
    svn export --ignore-externals /path/to/libjpeg-turbo jpeg
11
    cd jpeg
10
12
13
    # Remove packaging files, Windows-specific config, test images, and wxWindows-licensed files.
14
    rm -rf release win
15
    rm *.jpg *.ppm *.bmp bmp.c bmp.h jpegut.c jpgtest.cxx rrtimer.h rrutil.h turbojpeg.h turbojpegl.c
16
17
    # Restore files
18
    hg revert --no-backup Makefile.in jconfig.h jmorecfg.h simd/Makefile.in simd/jsimdcfg.inc jchuff.c jdhuff.c jdhuff.h MOZCHANGES
19
20
    # Add or remove other files to sync us with the SVN repository.
21
    hg addremove
22
23
24
== 8/4/2010 (initial commit, SVN r222 2010-08-03) ==
25
26
* Modified jmorecfg.h to define UINT8, UINT16, INT16, and INT32 in terms of
27
  prtypes to fix a build error on Windows.
28
29
* Removed the following files which are licensed under the wxWindows license:
30
31
    bmp.c, bmp.h, jpegut.c, jpgtest.cxx, rrtimer.h, rrutil.h, turbojpeg.h,
32
    turbojpegl.c
33
34
* Reverted the following files to what was previously in Mozilla's tree
35
  (nominally libjpeg 6.2):
36
37
    jchuff.c, jdhuff.c, jdhuff.h
38
39
  since the versions of these files in libjpeg-turbo are also under the
40
  wxWindows license.  (It would have been nicer to revert them to the new
41
  libjepg-8b code, but that doesn't easily integrate with libjepg-turbo.)
(-)a/jpeg/Makefile.am (+211 lines)
Line     Link Here 
Line 0    Link Here 
1
lib_LTLIBRARIES = libjpeg.la libturbojpeg.la
2
libjpeg_la_LDFLAGS = -version-number 62:0:0 -no-undefined
3
libturbojpeg_la_LDFLAGS = -avoid-version -no-undefined
4
include_HEADERS = jerror.h jmorecfg.h jpeglib.h turbojpeg.h
5
nodist_include_HEADERS = jconfig.h
6
7
HDRS = jchuff.h jdct.h jdhuff.h jerror.h jinclude.h jmemsys.h jmorecfg.h \
8
	jpegint.h jpeglib.h jversion.h jsimd.h jsimddct.h
9
10
libjpeg_la_SOURCES = $(HDRS) jcapimin.c jcapistd.c jccoefct.c jccolor.c \
11
	jcdctmgr.c jchuff.c jcinit.c jcmainct.c jcmarker.c jcmaster.c \
12
	jcomapi.c jcparam.c jcphuff.c jcprepct.c jcsample.c jctrans.c \
13
	jdapimin.c jdapistd.c jdatadst.c jdatasrc.c jdcoefct.c jdcolor.c \
14
	jddctmgr.c jdhuff.c jdinput.c jdmainct.c jdmarker.c jdmaster.c \
15
	jdmerge.c jdphuff.c jdpostct.c jdsample.c jdtrans.c jerror.c \
16
	jfdctflt.c jfdctfst.c jfdctint.c jidctflt.c jidctfst.c jidctint.c \
17
	jidctred.c jquant1.c jquant2.c jutils.c jmemmgr.c jmemnobs.c
18
19
libturbojpeg_la_SOURCES = $(libjpeg_la_SOURCES) turbojpegl.c turbojpeg.h \
20
	turbojpeg-mapfile
21
22
if VERSION_SCRIPT
23
24
libturbojpeg_la_LDFLAGS += $(VERSION_SCRIPT_FLAG)$(srcdir)/turbojpeg-mapfile
25
26
endif
27
28
if WITH_SIMD
29
30
SUBDIRS = simd
31
libjpeg_la_LIBADD = simd/libsimd.la
32
libturbojpeg_la_LIBADD = simd/libsimd.la
33
34
else
35
36
libjpeg_la_SOURCES += jsimd_none.c
37
38
endif
39
40
TSTHDRS = rrutil.h rrtimer.h
41
42
bin_PROGRAMS = cjpeg djpeg jpegtran rdjpgcom wrjpgcom
43
noinst_PROGRAMS = jpgtest jpegut
44
45
jpgtest_SOURCES = $(TSTHDRS) jpgtest.cxx bmp.h bmp.c
46
47
jpgtest_LDADD = libturbojpeg.la
48
49
jpegut_SOURCES = $(TSTHDRS) jpegut.c bmp.h bmp.c
50
51
jpegut_LDADD = libturbojpeg.la
52
53
cjpeg_SOURCES = cdjpeg.h cderror.h cdjpeg.c cjpeg.c rdbmp.c rdgif.c \
54
	rdppm.c rdswitch.c rdtarga.c 
55
56
cjpeg_LDADD = libjpeg.la
57
58
cjpeg_CFLAGS = -DBMP_SUPPORTED -DGIF_SUPPORTED -DPPM_SUPPORTED \
59
	-DTARGA_SUPPORTED
60
61
djpeg_SOURCES = cdjpeg.h cderror.h cdjpeg.c djpeg.c rdcolmap.c rdswitch.c \
62
	wrbmp.c wrgif.c wrppm.c wrtarga.c
63
64
djpeg_LDADD = libjpeg.la
65
66
djpeg_CFLAGS = -DBMP_SUPPORTED -DGIF_SUPPORTED -DPPM_SUPPORTED \
67
	-DTARGA_SUPPORTED
68
69
jpegtran_SOURCES = jpegtran.c rdswitch.c cdjpeg.c transupp.c transupp.h
70
71
jpegtran_LDADD = libjpeg.la
72
73
rdjpgcom_SOURCES = rdjpgcom.c
74
75
rdjpgcom_LDADD = libjpeg.la
76
77
wrjpgcom_SOURCES = wrjpgcom.c
78
79
wrjpgcom_LDADD = libjpeg.la
80
81
82
dist_man1_MANS = cjpeg.1 djpeg.1 jpegtran.1 rdjpgcom.1 wrjpgcom.1
83
84
DOCS= README install.doc usage.doc wizard.doc example.c libjpeg.doc \
85
	structure.doc coderules.doc filelist.doc jconfig.doc change.log \
86
	README-turbo.txt rdrle.c wrrle.c LICENSE.txt LGPL.txt BUILDING.txt \
87
	ChangeLog.txt
88
89
TESTFILES= testorig.jpg testorig.ppm testimg.bmp testimgflt.jpg \
90
	testimgfst.jpg testimgint.jpg testimgp.jpg testimgfst.ppm testimgint.ppm \
91
	testimg-nosimd.bmp testimgfst-nosimd.ppm testorig-nosimd.ppm \
92
	testimgflt-nosimd.jpg testimgint-nosimd.jpg testimgfst-nosimd.jpg \
93
	testimgp-nosimd.jpg
94
95
EXTRA_DIST = win release $(DOCS) $(TESTFILES)
96
97
dist-hook:
98
	rm -rf `find $(distdir) -name .svn`
99
100
101
if WITH_SIMD
102
103
test: testclean cjpeg djpeg jpegtran jpegut
104
	./jpegut
105
	./cjpeg -dct int -outfile testoutint.jpg $(srcdir)/testorig.ppm
106
	./cjpeg -dct fast -opt -outfile testoutfst.jpg $(srcdir)/testorig.ppm
107
	./cjpeg -dct float -outfile testoutflt.jpg $(srcdir)/testorig.ppm
108
	cmp $(srcdir)/testimgint.jpg testoutint.jpg
109
	cmp $(srcdir)/testimgfst.jpg testoutfst.jpg
110
	cmp $(srcdir)/testimgflt.jpg testoutflt.jpg
111
	./djpeg -dct int -fast -ppm -outfile testoutint.ppm $(srcdir)/testorig.jpg
112
	./djpeg -dct fast -ppm -outfile testoutfst.ppm $(srcdir)/testorig.jpg
113
	./djpeg -dct float -ppm -outfile testoutflt.ppm $(srcdir)/testorig.jpg
114
	cmp $(srcdir)/testimgint.ppm testoutint.ppm
115
	cmp $(srcdir)/testimgfst.ppm testoutfst.ppm
116
	cmp $(srcdir)/testorig.ppm testoutflt.ppm
117
	./djpeg -dct int -bmp -colors 256 -outfile testout.bmp  $(srcdir)/testorig.jpg
118
	cmp $(srcdir)/testimg.bmp testout.bmp
119
	./cjpeg -dct int -progressive -outfile testoutp.jpg $(srcdir)/testorig.ppm
120
	cmp $(srcdir)/testimgp.jpg testoutp.jpg
121
	./jpegtran -outfile testoutt.jpg testoutp.jpg
122
	cmp $(srcdir)/testimgint.jpg testoutt.jpg
123
124
else
125
126
test: testclean cjpeg djpeg jpegtran jpegut
127
	./jpegut
128
	./cjpeg -dct int -outfile testoutint.jpg $(srcdir)/testorig-nosimd.ppm
129
	./cjpeg -dct fast -opt -outfile testoutfst.jpg $(srcdir)/testorig-nosimd.ppm
130
	./cjpeg -dct float -outfile testoutflt.jpg $(srcdir)/testorig-nosimd.ppm
131
	cmp $(srcdir)/testimgint-nosimd.jpg testoutint.jpg
132
	cmp $(srcdir)/testimgfst-nosimd.jpg testoutfst.jpg
133
	cmp $(srcdir)/testimgflt-nosimd.jpg testoutflt.jpg
134
	./djpeg -dct int -fast -ppm -outfile testoutint.ppm $(srcdir)/testorig.jpg
135
	./djpeg -dct fast -ppm -outfile testoutfst.ppm $(srcdir)/testorig.jpg
136
	./djpeg -dct float -ppm -outfile testoutflt.ppm $(srcdir)/testorig.jpg
137
	cmp $(srcdir)/testimgint.ppm testoutint.ppm
138
	cmp $(srcdir)/testimgfst-nosimd.ppm testoutfst.ppm
139
	cmp $(srcdir)/testorig-nosimd.ppm testoutflt.ppm
140
	./djpeg -dct int -bmp -colors 256 -outfile testout.bmp  $(srcdir)/testorig.jpg
141
	cmp $(srcdir)/testimg-nosimd.bmp testout.bmp
142
	./cjpeg -dct int -progressive -outfile testoutp.jpg $(srcdir)/testorig-nosimd.ppm
143
	cmp $(srcdir)/testimgp-nosimd.jpg testoutp.jpg
144
	./jpegtran -outfile testoutt.jpg testoutp.jpg
145
	cmp $(srcdir)/testimgint-nosimd.jpg testoutt.jpg
146
147
endif
148
149
testclean:
150
	rm -f testout*
151
	rm -f *_GRAYQ[0-9]*.bmp
152
	rm -f *_GRAYQ[0-9]*.ppm
153
	rm -f *_GRAYQ[0-9]*.jpg
154
	rm -f *_420Q[0-9]*.bmp
155
	rm -f *_420Q[0-9]*.ppm
156
	rm -f *_420Q[0-9]*.jpg
157
	rm -f *_422Q[0-9]*.bmp
158
	rm -f *_422Q[0-9]*.ppm
159
	rm -f *_422Q[0-9]*.jpg
160
	rm -f *_444Q[0-9]*.bmp
161
	rm -f *_444Q[0-9]*.ppm
162
	rm -f *_444Q[0-9]*.jpg
163
164
rpm: all
165
	sh $(srcdir)/release/makerpm ${PACKAGE_NAME} ${VERSION} ${BUILD} \
166
		${RPMARCH} ${srcdir}
167
168
srpm: dist-gzip
169
	sh $(srcdir)/release/makesrpm ${PACKAGE_NAME} ${VERSION} ${BUILD} ${srcdir}
170
171
deb: all
172
	sh $(srcdir)/release/makedpkg ${PACKAGE_NAME} ${VERSION} ${BUILD} \
173
		${DEBARCH} ${srcdir}
174
175
if X86_64
176
177
udmg: all
178
	sh $(srcdir)/release/makemacpkg ${PACKAGE_NAME} ${VERSION} ${BUILD} \
179
		${srcdir} universal
180
181
endif
182
183
dmg: all
184
	sh $(srcdir)/release/makemacpkg ${PACKAGE_NAME} ${VERSION} ${BUILD} ${srcdir}
185
186
if X86_64
187
188
sunpkg: all
189
	sh $(srcdir)/release/makesunpkg ${PACKAGE_NAME} ${VERSION} ${BUILD} \
190
		${DEBARCH} ${srcdir} $(CC) $(CXX) combined
191
192
nsi: all
193
	makensis -nocd -DVERSION=$(VERSION) -DAPPNAME=libjpeg-turbo-gcc64 \
194
		-DWLIBDIR=.libs -DWSRCDIR=$(srcdir) -DWBLDDIR=. -DWHDRDIR=. -DWIN64 \
195
		-DPLATFORM="GCC 64-bit" -DGCC $(srcdir)/release/libjpeg-turbo.nsi
196
197
else
198
199
sunpkg: all
200
	sh $(srcdir)/release/makesunpkg ${PACKAGE_NAME} ${VERSION} ${BUILD} \
201
		${DEBARCH} ${srcdir} $(CC) $(CXX)
202
203
nsi: all
204
	makensis -nocd -DVERSION=$(VERSION) -DAPPNAME=libjpeg-turbo-gcc \
205
		-DWLIBDIR=.libs -DWSRCDIR=$(srcdir) -DWBLDDIR=. -DWHDRDIR=. \
206
		-DPLATFORM="GCC" -DGCC $(srcdir)/release/libjpeg-turbo.nsi
207
208
endif
209
210
cygwinpkg: all
211
	sh $(srcdir)/release/makecygwinpkg ${PACKAGE_NAME} ${VERSION} ${srcdir}
(-)a/jpeg/Makefile.in (-40 / +116 lines)
Line     Link Here 
 Lines 10-30    Link Here 
10
# Software distributed under the License is distributed on an "AS IS" basis,
10
# Software distributed under the License is distributed on an "AS IS" basis,
11
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
11
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12
# for the specific language governing rights and limitations under the
12
# for the specific language governing rights and limitations under the
13
# License.
13
# License.
14
#
14
#
15
# The Original Code is mozilla.org code.
15
# The Original Code is mozilla.org code.
16
#
16
#
17
# The Initial Developer of the Original Code is
17
# The Initial Developer of the Original Code is
18
# Netscape Communications Corporation.
18
# Mozilla Corporation
19
# Portions created by the Initial Developer are Copyright (C) 1998
19
# Portions created by the Initial Developer are Copyright (C) 2010
20
# the Initial Developer. All Rights Reserved.
20
# the Initial Developer. All Rights Reserved.
21
#
21
#
22
# Contributor(s):
22
# Contributor(s):
23
#  Justin Lebar <justin.lebar@gmail.com>
23
#
24
#
24
# Alternatively, the contents of this file may be used under the terms of
25
# Alternatively, the contents of this file may be used under the terms of
25
# either the GNU General Public License Version 2 or later (the "GPL"), or
26
# either the GNU General Public License Version 2 or later (the "GPL"), or
26
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27
# in which case the provisions of the GPL or the LGPL are applicable instead
28
# in which case the provisions of the GPL or the LGPL are applicable instead
28
# of those above. If you wish to allow use of your version of this file only
29
# of those above. If you wish to allow use of your version of this file only
29
# under the terms of either the GPL or the LGPL, and not to allow others to
30
# under the terms of either the GPL or the LGPL, and not to allow others to
30
# use your version of this file under the terms of the MPL, indicate your
31
# use your version of this file under the terms of the MPL, indicate your
 Lines 37-126    Link Here 
37
38
38
DEPTH		= ..
39
DEPTH		= ..
39
topsrcdir	= @top_srcdir@
40
topsrcdir	= @top_srcdir@
40
srcdir		= @srcdir@
41
srcdir		= @srcdir@
41
VPATH		= @srcdir@
42
VPATH		= @srcdir@
42
43
43
include $(DEPTH)/config/autoconf.mk
44
include $(DEPTH)/config/autoconf.mk
44
45
46
DIRS		= simd
45
MODULE		= jpeg
47
MODULE		= jpeg
46
LIBRARY_NAME	= mozjpeg
48
LIBRARY_NAME	= mozjpeg
47
49
48
ifeq ($(OS_ARCH),WINNT)
50
ifeq ($(OS_ARCH),WINNT)
49
LIBRARY_NAME	= jpeg32$(VERSION_NUMBER)
51
LIBRARY_NAME	= jpeg32$(VERSION_NUMBER)
50
# FIXME: bug 413019
52
# FIXME: bug 413019
51
ifndef GNU_CC
53
ifndef GNU_CC
52
OS_COMPILE_CFLAGS += -GL-
54
OS_COMPILE_CFLAGS += -GL-
53
endif
55
endif
54
endif
56
endif
55
57
56
GRE_MODULE	= 1
58
GRE_MODULE	= 1
57
59
58
CSRCS		= \
60
CSRCS		= \
61
		jcomapi.c \
59
		jdapimin.c \
62
		jdapimin.c \
60
		jdapistd.c \
63
		jdapistd.c \
64
		jdatadst.c \
61
		jdatasrc.c \
65
		jdatasrc.c \
62
		jdatadst.c \
66
		jdcoefct.c \
67
		jdcolor.c \
68
		jddctmgr.c \
69
		jdhuff.c \
70
		jdinput.c \
71
		jdmainct.c \
72
		jdmarker.c \
63
		jdmaster.c \
73
		jdmaster.c \
64
		jdinput.c \
74
		jdmerge.c \
65
		jdmarker.c \
66
		jdhuff.c \
67
		jdphuff.c \
75
		jdphuff.c \
68
		jdmainct.c \
69
		jdcoefct.c \
70
		jdpostct.c \
76
		jdpostct.c \
71
		jddctmgr.c \
72
		jidctfst.c \
73
		jidctflt.c \
74
		jidctint.c \
75
		jdsample.c \
77
		jdsample.c \
76
		jdcolor.c \
78
		jdtrans.c \
77
		jquant1.c \
78
		jquant2.c \
79
		jdmerge.c \
80
		jcomapi.c \
81
		jutils.c \
82
		jerror.c \
79
		jerror.c \
83
		jmemmgr.c \
84
		jmemnobs.c \
85
		jfdctflt.c \
80
		jfdctflt.c \
86
		jfdctfst.c \
81
		jfdctfst.c \
87
		jfdctint.c \
82
		jfdctint.c \
88
		$(NULL)
83
		jidctflt.c \
89
84
		jidctfst.c \
90
EXPORTS		= \
85
		jidctint.c \
91
		jconfig.h \
86
		jidctred.c \
92
		jerror.h \
87
		jmemmgr.c \
93
		jinclude.h \
88
		jmemnobs.c \
94
		jmorecfg.h \
89
		jpegtran.c \
95
		jpeglib.h \
90
		jquant1.c \
96
		jpegint.h \
91
		jquant2.c \
97
		jwinfig.h \
92
		jutils.c \
98
		jos2fig.h \
99
		$(NULL)
93
		$(NULL)
100
94
101
# These files enable support for writing JPEGs
95
# These files enable support for writing JPEGs
102
# (on certain platforms, or if JPEG image encoder support is required)
96
# (on certain platforms, or if JPEG image encoder support is required)
103
ifneq (,$(filter os2 windows,$(MOZ_WIDGET_TOOLKIT))$(filter jpeg,$(MOZ_IMG_ENCODERS)))
97
ifneq (,$(filter os2 windows,$(MOZ_WIDGET_TOOLKIT))$(filter jpeg,$(MOZ_IMG_ENCODERS)))
104
CSRCS		+= \
98
CSRCS		+= \
105
		jcapimin.c \
99
		jcapimin.c \
106
		jcparam.c \
107
		jcapistd.c \
100
		jcapistd.c \
108
		jcmarker.c \
101
		jccoefct.c \
102
		jccolor.c \
103
		jcdctmgr.c \
104
		jchuff.c \
109
		jcinit.c \
105
		jcinit.c \
110
		jcmainct.c \
106
		jcmainct.c \
111
		jchuff.c \
107
		jcmarker.c \
108
		jcmaster.c \
109
		jcparam.c \
110
		jcphuff.c \
111
		jcprepct.c \
112
		jcsample.c \
112
		jcsample.c \
113
		jcmaster.c \
114
		jccoefct.c \
115
		jccolor.c \
116
		jcphuff.c \
117
		jcdctmgr.c \
118
		jcprepct.c \
119
		$(NULL)
113
		$(NULL)
120
114
121
endif
115
endif
122
116
117
AS=$(LIBJPEG_TURBO_AS)
118
ASM_SUFFIX=asm
119
ASFLAGS=$(LIBJPEG_TURBO_ASFLAGS) -I$(topsrcdir)/modules/libjpeg-turbo/simd/
120
121
ifeq ($(AS),yasm)
122
  # yasm doesn't like -c
123
  AS_DASH_C_FLAG=
124
endif
125
126
# No SIMD support?
127
ifeq (,$(LIBJPEG_TURBO_X86_ASM)$(LIBJPEG_TURBO_X64_ASM))
128
  CSRCS += jsimd_none.c
129
endif
130
131
ifeq (1,$(LIBJPEG_TURBO_X64_ASM))
132
  CSRCS   += simd/jsimd_x86_64.c
133
  ASFILES += \
134
	simd/jccolss2-64.asm \
135
	simd/jcqnts2f-64.asm \
136
	simd/jcqnts2i-64.asm \
137
	simd/jcsamss2-64.asm \
138
	simd/jdcolss2-64.asm \
139
	simd/jdmerss2-64.asm \
140
	simd/jdsamss2-64.asm \
141
	simd/jfss2fst-64.asm \
142
	simd/jfss2int-64.asm \
143
	simd/jfsseflt-64.asm \
144
	simd/jiss2flt-64.asm \
145
	simd/jiss2fst-64.asm \
146
	simd/jiss2int-64.asm \
147
	simd/jiss2red-64.asm \
148
	$(NULL)
149
endif
150
151
ifeq (1,$(LIBJPEG_TURBO_X86_ASM))
152
  CSRCS   +=simd/jsimd_i386.c
153
  ASFILES += \
154
	simd/jccolmmx.asm \
155
	simd/jccolss2.asm \
156
	simd/jcqnt3dn.asm \
157
	simd/jcqntmmx.asm \
158
	simd/jcqnts2f.asm \
159
	simd/jcqnts2i.asm \
160
	simd/jcqntsse.asm \
161
	simd/jcsammmx.asm \
162
	simd/jcsamss2.asm \
163
	simd/jdcolmmx.asm \
164
	simd/jdcolss2.asm \
165
	simd/jdmermmx.asm \
166
	simd/jdmerss2.asm \
167
	simd/jdsammmx.asm \
168
	simd/jdsamss2.asm \
169
	simd/jf3dnflt.asm \
170
	simd/jfmmxfst.asm \
171
	simd/jfmmxint.asm \
172
	simd/jfss2fst.asm \
173
	simd/jfss2int.asm \
174
	simd/jfsseflt.asm \
175
	simd/ji3dnflt.asm \
176
	simd/jimmxfst.asm \
177
	simd/jimmxint.asm \
178
	simd/jimmxred.asm \
179
	simd/jiss2flt.asm \
180
	simd/jiss2fst.asm \
181
	simd/jiss2int.asm \
182
	simd/jiss2red.asm \
183
	simd/jisseflt.asm \
184
	simd/jsimdcpu.asm \
185
	$(NULL)
186
endif
187
188
189
# jwinfig.h, jos2fig.h  ? XXX
190
EXPORTS		= \
191
		jconfig.h \
192
		jerror.h \
193
		jinclude.h \
194
		jmorecfg.h \
195
		jpegint.h \
196
		jpeglib.h \
197
		$(NULL)
198
123
# need static lib for some of the libimg componentry to link properly
199
# need static lib for some of the libimg componentry to link properly
124
FORCE_STATIC_LIB = 1
200
FORCE_STATIC_LIB = 1
125
201
126
include $(topsrcdir)/config/rules.mk
202
include $(topsrcdir)/config/rules.mk
(-)a/jpeg/README (+7 lines)
Line     Link Here 
 Lines 1-8    Link Here 
1
libjpeg-turbo note:  This is the legacy document from the original libjpeg v6b
2
release, which is included for reference.  The Internet addresses given below
3
are likely non-functional.  For more information about the libjpeg project,
4
please see http://www.ijg.org.  For more information about libjpeg-turbo,
5
please see http://libjpeg-turbo.virtualgl.org.
6
7
1
The Independent JPEG Group's JPEG software
8
The Independent JPEG Group's JPEG software
2
==========================================
9
==========================================
3
10
4
README for release 6b of 27-Mar-1998
11
README for release 6b of 27-Mar-1998
5
====================================
12
====================================
6
13
7
This distribution contains the sixth public release of the Independent JPEG
14
This distribution contains the sixth public release of the Independent JPEG
8
Group's free JPEG software.  You are welcome to redistribute this software and
15
Group's free JPEG software.  You are welcome to redistribute this software and
(-)a/jpeg/README-turbo.txt (+202 lines)
Line     Link Here 
Line 0    Link Here 
1
*******************************************************************************
2
**     Background
3
*******************************************************************************
4
5
libjpeg-turbo is a high-speed version of libjpeg for x86 and x86-64 processors
6
which uses SIMD instructions (MMX, SSE2, etc.) to accelerate baseline JPEG
7
compression and decompression.  libjpeg-turbo is generally 2-4x as fast
8
as the unmodified version of libjpeg, all else being equal.
9
10
libjpeg-turbo was originally based on libjpeg/SIMD by Miyasaka Masaru, but
11
the TigerVNC and VirtualGL projects made numerous enhancements to the codec,
12
including improved support for Mac OS X, 64-bit support, support for 32-bit
13
and big endian pixel formats, accelerated Huffman encoding/decoding, and
14
various bug fixes.  The goal was to produce a fully open source codec that
15
could replace the partially closed source TurboJPEG/IPP codec used by VirtualGL
16
and TurboVNC.  libjpeg-turbo generally performs in the range of 80-120% of
17
TurboJPEG/IPP.  It is faster in some areas but slower in others.
18
19
It was decided to split libjpeg-turbo into a separate SDK so that other
20
projects could take advantage of this technology.  The libjpeg-turbo shared
21
libraries can be used as drop-in replacements for libjpeg on most systems.
22
23
24
*******************************************************************************
25
**     License
26
*******************************************************************************
27
28
Some of the optimizations to the Huffman encoder/decoder were borrowed from
29
VirtualGL, and thus the libjpeg-turbo distribution, as a whole, falls under the
30
wxWindows Library Licence, Version 3.1.  A copy of this license can be found in
31
this directory under LICENSE.txt.  The wxWindows Library License is based on
32
the LGPL but includes provisions which allow the Library to be statically
33
linked into proprietary libraries and applications without requiring the
34
resulting binaries to be distributed under the terms of the LGPL.
35
36
The rest of the source code, apart from these modifications, falls under a less
37
restrictive, BSD-style license (see README.)
38
39
40
*******************************************************************************
41
**     Using libjpeg-turbo
42
*******************************************************************************
43
44
=============================
45
Replacing libjpeg at Run Time
46
=============================
47
48
If a Unix application is dynamically linked with libjpeg, then you can replace
49
libjpeg with libjpeg-turbo at run time by manipulating the LD_LIBRARY_PATH.
50
For instance:
51
52
  [Using libjpeg]
53
  > time cjpeg <vgl_5674_0098.ppm >vgl_5674_0098.jpg
54
  real  0m0.392s
55
  user  0m0.074s
56
  sys   0m0.020s
57
58
  [Using libjpeg-turbo]
59
  > export LD_LIBRARY_PATH=/opt/libjpeg-turbo/{lib}:$LD_LIBRARY_PATH
60
  > time cjpeg <vgl_5674_0098.ppm >vgl_5674_0098.jpg
61
  real  0m0.109s
62
  user  0m0.029s
63
  sys   0m0.010s
64
65
NOTE: {lib} can be lib, lib32, lib64, or lib/64, depending on the O/S and
66
architecture.
67
68
System administrators can also replace the libjpeg sym links in /usr/{lib} with
69
links to the libjpeg dynamic library located in /opt/libjpeg-turbo/{lib}.  This
70
will effectively accelerate every dynamically linked libjpeg application on the
71
system.
72
73
The Windows distribution of the libjpeg-turbo SDK installs jpeg62.dll into
74
c:\libjpeg-turbo\bin, and the PATH environment variable can be modified such
75
that this directory is searched before any others that might contain
76
jpeg62.dll.  However, if jpeg62.dll also exists in an application's install
77
directory, then Windows will load the application's version of it first.  Thus,
78
if an application ships with jpeg62.dll, then back up the application's version
79
of jpeg62.dll and copy c:\libjpeg-turbo\bin\jpeg62.dll into the application's
80
install directory to accelerate it.
81
82
The version of jpeg62.dll distributed in the libjpeg-turbo SDK requires the
83
Visual C++ 2008 C run time DLL (msvcr90.dll).  This library ships with more
84
recent versions of Windows, but users of older versions can obtain it from the
85
Visual C++ 2008 Redistributable Package, which is available as a free download
86
from Microsoft's web site.
87
88
NOTE:  Features of libjpeg which require passing a C run time structure, such
89
as a file handle, from an application to libjpeg will probably not work with
90
the distributed version of jpeg62.dll unless the application is also built to
91
use the Visual C++ 2008 C run time DLL.  In particular, this affects
92
jpeg_stdio_dest() and jpeg_stdio_src().
93
94
Mac applications typically embed their own copies of libjpeg.62.dylib inside
95
the (hidden) application bundle, so it is not possible to globally replace
96
libjpeg on OS X systems.  If an application uses a shared library version of
97
libjpeg, then it may be possible to replace the application's version of it.
98
This would generally involve copying libjpeg.62.dylib into the appropriate
99
place in the application bundle and using install_name_tool to repoint the
100
dylib to the new directory.  This requires an advanced knowledge of OS X and
101
would not survive an upgrade or a re-install of the application.  Thus, it is
102
not recommended for most users.
103
104
=======================
105
Replacing TurboJPEG/IPP
106
=======================
107
108
libjpeg-turbo is a drop-in replacement for the TurboJPEG/IPP SDK used by
109
VirtualGL 2.1.x and TurboVNC 0.6 (and prior.)  libjpeg-turbo contains a wrapper
110
library (TurboJPEG/OSS) that emulates the TurboJPEG API using libjpeg-turbo
111
instead of the closed source Intel Performance Primitives.  You can replace the
112
TurboJPEG/IPP package on Linux systems with the libjpeg-turbo package in order
113
to make existing releases of VirtualGL 2.1.x and TurboVNC use the new codec at
114
run time.  Note that the 64-bit libjpeg-turbo packages contain only 64-bit
115
binaries, whereas the TurboJPEG/IPP 64-bit packages contained both 64-bit and
116
32-bit binaries.  Thus, to replace a TurboJPEG/IPP 64-bit package, install
117
both the 64-bit and 32-bit versions of libjpeg-turbo.
118
119
You can also build the VirtualGL 2.1.x and TurboVNC 0.6 source code with
120
the libjpeg-turbo SDK instead of TurboJPEG/IPP.  It should work identically.
121
libjpeg-turbo also includes static library versions of TurboJPEG/OSS, which
122
are used to build TurboVNC 1.0 and later.
123
124
========================================
125
Using libjpeg-turbo in Your Own Programs
126
========================================
127
128
For the most part, libjpeg-turbo should work identically to libjpeg, so in
129
most cases, an application can be built against libjpeg and then run against
130
libjpeg-turbo.  On Unix systems, you can build against libjpeg-turbo instead
131
of libjpeg by setting
132
133
  CPATH=/opt/libjpeg-turbo/include
134
  and
135
  LIBRARY_PATH=/opt/libjpeg-turbo/{lib}
136
137
({lib} = lib32 or lib64, depending on whether you are building a 32-bit or a
138
64-bit application.)
139
140
If using Cygwin, then set
141
142
  CPATH=/cygdrive/c/libjpeg-turbo-gcc[64]/include
143
  and
144
  LIBRARY_PATH=/cygdrive/c/libjpeg-turbo-gcc[64]/lib
145
146
If using MinGW, then set
147
148
  CPATH=/c/libjpeg-turbo-gcc[64]/include
149
  and
150
  LIBRARY_PATH=/c/libjpeg-turbo-gcc[64]/lib
151
152
Building against libjpeg-turbo is useful, for instance, if you want to build an
153
application that leverages the libjpeg-turbo colorspace extensions (see below.)
154
On Linux and Solaris systems, you would still need to manipulate the
155
LD_LIBRARY_PATH or sym links appropriately to use libjpeg-turbo at run time.
156
On such systems, you can pass -R /opt/libjpeg-turbo/{lib} to the linker to
157
force the use of libjpeg-turbo at run time rather than libjpeg (also useful if
158
you want to leverage the colorspace extensions), or you can link against the
159
libjpeg-turbo static library.
160
161
To force a Linux, Solaris, or MinGW application to link against the static
162
version of libjpeg-turbo, you can use the following linker options:
163
164
  -Wl,-Bstatic -ljpeg -Wl,-Bdynamic
165
166
On OS X, simply add /opt/libjpeg-turbo/lib/libjpeg.a to the linker command
167
line (this also works on Linux and Solaris.)
168
169
To build Visual C++ applications using libjpeg-turbo, add
170
c:\libjpeg-turbo[64]\include to your system or user INCLUDE environment
171
variable and c:\libjpeg-turbo[64]\lib to your system or user LIB environment
172
variable, and then link against either jpeg.lib (to use jpeg62.dll) or
173
jpeg-static.lib (to use the static version of libjpeg-turbo.)
174
175
=====================
176
Colorspace Extensions
177
=====================
178
179
libjpeg-turbo includes extensions which allow JPEG images to be compressed
180
directly from (and decompressed directly to) buffers which use BGR, BGRA,
181
RGBA, ABGR, and ARGB pixel ordering.  This is implemented with six new
182
colorspace constants:
183
184
  JCS_EXT_RGB   /* red/green/blue */
185
  JCS_EXT_RGBX  /* red/green/blue/x */
186
  JCS_EXT_BGR   /* blue/green/red */
187
  JCS_EXT_BGRX  /* blue/green/red/x */
188
  JCS_EXT_XBGR  /* x/blue/green/red */
189
  JCS_EXT_XRGB  /* x/red/green/blue */
190
191
Setting cinfo.in_color_space (compression) or cinfo.out_color_space
192
(decompression) to one of these values will cause libjpeg-turbo to read the
193
red, green, and blue values from (or write them to) the appropriate position in
194
the pixel when YUV conversion is performed.
195
196
Your application can check for the existence of these extensions at compile
197
time with:
198
199
  #ifdef JCS_EXTENSIONS
200
201
At run time, attempting to use these extensions with a version of libjpeg
202
that doesn't support them will result in a "Bogus input colorspace" error.
(-)a/jpeg/acinclude.m4 (+136 lines)
Line     Link Here 
Line 0    Link Here 
1
# AC_PROG_NASM
2
# --------------------------
3
# Check that NASM exists and determine flags
4
AC_DEFUN([AC_PROG_NASM],[
5
6
AC_CHECK_PROGS(NASM, [nasm nasmw])
7
test -z "$NASM" && AC_MSG_ERROR([no nasm (Netwide Assembler) found])
8
9
AC_MSG_CHECKING([for object file format of host system])
10
case "$host_os" in
11
  cygwin* | mingw* | pw32* | interix*)
12
    case "$host_cpu" in
13
      x86_64)
14
        objfmt='Win64-COFF'
15
        ;;
16
      *)
17
        objfmt='Win32-COFF'
18
        ;;
19
    esac
20
  ;;
21
  msdosdjgpp* | go32*)
22
    objfmt='COFF'
23
  ;;
24
  os2-emx*)			# not tested
25
    objfmt='MSOMF'		# obj
26
  ;;
27
  linux*coff* | linux*oldld*)
28
    objfmt='COFF'		# ???
29
  ;;
30
  linux*aout*)
31
    objfmt='a.out'
32
  ;;
33
  linux*)
34
    case "$host_cpu" in
35
      x86_64)
36
        objfmt='ELF64'
37
        ;;
38
      *)
39
        objfmt='ELF'
40
        ;;
41
    esac
42
  ;;
43
  freebsd* | netbsd* | openbsd*)
44
    if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then
45
      objfmt='BSD-a.out'
46
    else
47
      case "$host_cpu" in
48
        x86_64 | amd64)
49
          objfmt='ELF64'
50
          ;;
51
        *)
52
          objfmt='ELF'
53
          ;;
54
      esac
55
    fi
56
  ;;
57
  solaris* | sunos* | sysv* | sco*)
58
    case "$host_cpu" in
59
      x86_64)
60
        objfmt='ELF64'
61
        ;;
62
      *)
63
        objfmt='ELF'
64
        ;;
65
    esac
66
  ;;
67
  darwin* | rhapsody* | nextstep* | openstep* | macos*)
68
    case "$host_cpu" in
69
      x86_64)
70
        objfmt='Mach-O64'
71
        ;;
72
      *)
73
        objfmt='Mach-O'
74
        ;;
75
    esac
76
  ;;
77
  *)
78
    objfmt='ELF ?'
79
  ;;
80
esac
81
82
AC_MSG_RESULT([$objfmt])
83
if test "$objfmt" = 'ELF ?'; then
84
  objfmt='ELF'
85
  AC_MSG_WARN([unexpected host system. assumed that the format is $objfmt.])
86
fi
87
88
AC_MSG_CHECKING([for object file format specifier (NAFLAGS) ])
89
case "$objfmt" in
90
  MSOMF)      NAFLAGS='-fobj -DOBJ32';;
91
  Win32-COFF) NAFLAGS='-fwin32 -DWIN32';;
92
  Win64-COFF) NAFLAGS='-fwin64 -DWIN64 -D__x86_64__';;
93
  COFF)       NAFLAGS='-fcoff -DCOFF';;
94
  a.out)      NAFLAGS='-faout -DAOUT';;
95
  BSD-a.out)  NAFLAGS='-faoutb -DAOUT';;
96
  ELF)        NAFLAGS='-felf -DELF';;
97
  ELF64)      NAFLAGS='-felf64 -DELF -D__x86_64__';;
98
  RDF)        NAFLAGS='-frdf -DRDF';;
99
  Mach-O)     NAFLAGS='-fmacho -DMACHO';;
100
  Mach-O64)   NAFLAGS='-fmacho64 -DMACHO -D__x86_64__';;
101
esac
102
AC_MSG_RESULT([$NAFLAGS])
103
AC_SUBST([NAFLAGS])
104
105
AC_MSG_CHECKING([whether the assembler ($NASM $NAFLAGS) works])
106
cat > conftest.asm <<EOF
107
[%line __oline__ "configure"
108
        section .text
109
        global  _main,main
110
_main:
111
main:   xor     eax,eax
112
        ret
113
]EOF
114
try_nasm='$NASM $NAFLAGS -o conftest.o conftest.asm'
115
if AC_TRY_EVAL(try_nasm) && test -s conftest.o; then
116
  AC_MSG_RESULT(yes)
117
else
118
  echo "configure: failed program was:" >&AC_FD_CC
119
  cat conftest.asm >&AC_FD_CC
120
  rm -rf conftest*
121
  AC_MSG_RESULT(no)
122
  AC_MSG_ERROR([installation or configuration problem: assembler cannot create object files.])
123
fi
124
125
AC_MSG_CHECKING([whether the linker accepts assembler output])
126
try_nasm='${CC-cc} -o conftest${ac_exeext} $LDFLAGS conftest.o $LIBS 1>&AC_FD_CC'
127
if AC_TRY_EVAL(try_nasm) && test -s conftest${ac_exeext}; then
128
  rm -rf conftest*
129
  AC_MSG_RESULT(yes)
130
else
131
  rm -rf conftest*
132
  AC_MSG_RESULT(no)
133
  AC_MSG_ERROR([configuration problem: maybe object file format mismatch.])
134
fi
135
136
])
(-)a/jpeg/cjpeg.1 (+292 lines)
Line     Link Here 
Line 0    Link Here 
1
.TH CJPEG 1 "20 March 1998"
2
.SH NAME
3
cjpeg \- compress an image file to a JPEG file
4
.SH SYNOPSIS
5
.B cjpeg
6
[
7
.I options
8
]
9
[
10
.I filename
11
]
12
.LP
13
.SH DESCRIPTION
14
.LP
15
.B cjpeg
16
compresses the named image file, or the standard input if no file is
17
named, and produces a JPEG/JFIF file on the standard output.
18
The currently supported input file formats are: PPM (PBMPLUS color
19
format), PGM (PBMPLUS gray-scale format), BMP, Targa, and RLE (Utah Raster
20
Toolkit format).  (RLE is supported only if the URT library is available.)
21
.SH OPTIONS
22
All switch names may be abbreviated; for example,
23
.B \-grayscale
24
may be written
25
.B \-gray
26
or
27
.BR \-gr .
28
Most of the "basic" switches can be abbreviated to as little as one letter.
29
Upper and lower case are equivalent (thus
30
.B \-BMP
31
is the same as
32
.BR \-bmp ).
33
British spellings are also accepted (e.g.,
34
.BR \-greyscale ),
35
though for brevity these are not mentioned below.
36
.PP
37
The basic switches are:
38
.TP
39
.BI \-quality " N"
40
Scale quantization tables to adjust image quality.  Quality is 0 (worst) to
41
100 (best); default is 75.  (See below for more info.)
42
.TP
43
.B \-grayscale
44
Create monochrome JPEG file from color input.  Be sure to use this switch when
45
compressing a grayscale BMP file, because
46
.B cjpeg
47
isn't bright enough to notice whether a BMP file uses only shades of gray.
48
By saying
49
.BR \-grayscale ,
50
you'll get a smaller JPEG file that takes less time to process.
51
.TP
52
.B \-optimize
53
Perform optimization of entropy encoding parameters.  Without this, default
54
encoding parameters are used.
55
.B \-optimize
56
usually makes the JPEG file a little smaller, but
57
.B cjpeg
58
runs somewhat slower and needs much more memory.  Image quality and speed of
59
decompression are unaffected by
60
.BR \-optimize .
61
.TP
62
.B \-progressive
63
Create progressive JPEG file (see below).
64
.TP
65
.B \-targa
66
Input file is Targa format.  Targa files that contain an "identification"
67
field will not be automatically recognized by
68
.BR cjpeg ;
69
for such files you must specify
70
.B \-targa
71
to make
72
.B cjpeg
73
treat the input as Targa format.
74
For most Targa files, you won't need this switch.
75
.PP
76
The
77
.B \-quality
78
switch lets you trade off compressed file size against quality of the
79
reconstructed image: the higher the quality setting, the larger the JPEG file,
80
and the closer the output image will be to the original input.  Normally you
81
want to use the lowest quality setting (smallest file) that decompresses into
82
something visually indistinguishable from the original image.  For this
83
purpose the quality setting should be between 50 and 95; the default of 75 is
84
often about right.  If you see defects at
85
.B \-quality
86
75, then go up 5 or 10 counts at a time until you are happy with the output
87
image.  (The optimal setting will vary from one image to another.)
88
.PP
89
.B \-quality
90
100 will generate a quantization table of all 1's, minimizing loss in the
91
quantization step (but there is still information loss in subsampling, as well
92
as roundoff error).  This setting is mainly of interest for experimental
93
purposes.  Quality values above about 95 are
94
.B not
95
recommended for normal use; the compressed file size goes up dramatically for
96
hardly any gain in output image quality.
97
.PP
98
In the other direction, quality values below 50 will produce very small files
99
of low image quality.  Settings around 5 to 10 might be useful in preparing an
100
index of a large image library, for example.  Try
101
.B \-quality
102
2 (or so) for some amusing Cubist effects.  (Note: quality
103
values below about 25 generate 2-byte quantization tables, which are
104
considered optional in the JPEG standard.
105
.B cjpeg
106
emits a warning message when you give such a quality value, because some
107
other JPEG programs may be unable to decode the resulting file.  Use
108
.B \-baseline
109
if you need to ensure compatibility at low quality values.)
110
.PP
111
The
112
.B \-progressive
113
switch creates a "progressive JPEG" file.  In this type of JPEG file, the data
114
is stored in multiple scans of increasing quality.  If the file is being
115
transmitted over a slow communications link, the decoder can use the first
116
scan to display a low-quality image very quickly, and can then improve the
117
display with each subsequent scan.  The final image is exactly equivalent to a
118
standard JPEG file of the same quality setting, and the total file size is
119
about the same --- often a little smaller.
120
.B Caution:
121
progressive JPEG is not yet widely implemented, so many decoders will be
122
unable to view a progressive JPEG file at all.
123
.PP
124
Switches for advanced users:
125
.TP
126
.B \-dct int
127
Use integer DCT method (default).
128
.TP
129
.B \-dct fast
130
Use fast integer DCT (less accurate).
131
.TP
132
.B \-dct float
133
Use floating-point DCT method.
134
The float method is very slightly more accurate than the int method, but is
135
much slower unless your machine has very fast floating-point hardware.  Also
136
note that results of the floating-point method may vary slightly across
137
machines, while the integer methods should give the same results everywhere.
138
The fast integer method is much less accurate than the other two.
139
.TP
140
.BI \-restart " N"
141
Emit a JPEG restart marker every N MCU rows, or every N MCU blocks if "B" is
142
attached to the number.
143
.B \-restart 0
144
(the default) means no restart markers.
145
.TP
146
.BI \-smooth " N"
147
Smooth the input image to eliminate dithering noise.  N, ranging from 1 to
148
100, indicates the strength of smoothing.  0 (the default) means no smoothing.
149
.TP
150
.BI \-maxmemory " N"
151
Set limit for amount of memory to use in processing large images.  Value is
152
in thousands of bytes, or millions of bytes if "M" is attached to the
153
number.  For example,
154
.B \-max 4m
155
selects 4000000 bytes.  If more space is needed, temporary files will be used.
156
.TP
157
.BI \-outfile " name"
158
Send output image to the named file, not to standard output.
159
.TP
160
.B \-verbose
161
Enable debug printout.  More
162
.BR \-v 's
163
give more output.  Also, version information is printed at startup.
164
.TP
165
.B \-debug
166
Same as
167
.BR \-verbose .
168
.PP
169
The
170
.B \-restart
171
option inserts extra markers that allow a JPEG decoder to resynchronize after
172
a transmission error.  Without restart markers, any damage to a compressed
173
file will usually ruin the image from the point of the error to the end of the
174
image; with restart markers, the damage is usually confined to the portion of
175
the image up to the next restart marker.  Of course, the restart markers
176
occupy extra space.  We recommend
177
.B \-restart 1
178
for images that will be transmitted across unreliable networks such as Usenet.
179
.PP
180
The
181
.B \-smooth
182
option filters the input to eliminate fine-scale noise.  This is often useful
183
when converting dithered images to JPEG: a moderate smoothing factor of 10 to
184
50 gets rid of dithering patterns in the input file, resulting in a smaller
185
JPEG file and a better-looking image.  Too large a smoothing factor will
186
visibly blur the image, however.
187
.PP
188
Switches for wizards:
189
.TP
190
.B \-baseline
191
Force baseline-compatible quantization tables to be generated.  This clamps
192
quantization values to 8 bits even at low quality settings.  (This switch is
193
poorly named, since it does not ensure that the output is actually baseline
194
JPEG.  For example, you can use
195
.B \-baseline
196
and
197
.B \-progressive
198
together.)
199
.TP
200
.BI \-qtables " file"
201
Use the quantization tables given in the specified text file.
202
.TP
203
.BI \-qslots " N[,...]"
204
Select which quantization table to use for each color component.
205
.TP
206
.BI \-sample " HxV[,...]"
207
Set JPEG sampling factors for each color component.
208
.TP
209
.BI \-scans " file"
210
Use the scan script given in the specified text file.
211
.PP
212
The "wizard" switches are intended for experimentation with JPEG.  If you
213
don't know what you are doing, \fBdon't use them\fR.  These switches are
214
documented further in the file wizard.doc.
215
.SH EXAMPLES
216
.LP
217
This example compresses the PPM file foo.ppm with a quality factor of
218
60 and saves the output as foo.jpg:
219
.IP
220
.B cjpeg \-quality
221
.I 60 foo.ppm
222
.B >
223
.I foo.jpg
224
.SH HINTS
225
Color GIF files are not the ideal input for JPEG; JPEG is really intended for
226
compressing full-color (24-bit) images.  In particular, don't try to convert
227
cartoons, line drawings, and other images that have only a few distinct
228
colors.  GIF works great on these, JPEG does not.  If you want to convert a
229
GIF to JPEG, you should experiment with
230
.BR cjpeg 's
231
.B \-quality
232
and
233
.B \-smooth
234
options to get a satisfactory conversion.
235
.B \-smooth 10
236
or so is often helpful.
237
.PP
238
Avoid running an image through a series of JPEG compression/decompression
239
cycles.  Image quality loss will accumulate; after ten or so cycles the image
240
may be noticeably worse than it was after one cycle.  It's best to use a
241
lossless format while manipulating an image, then convert to JPEG format when
242
you are ready to file the image away.
243
.PP
244
The
245
.B \-optimize
246
option to
247
.B cjpeg
248
is worth using when you are making a "final" version for posting or archiving.
249
It's also a win when you are using low quality settings to make very small
250
JPEG files; the percentage improvement is often a lot more than it is on
251
larger files.  (At present,
252
.B \-optimize
253
mode is always selected when generating progressive JPEG files.)
254
.SH ENVIRONMENT
255
.TP
256
.B JPEGMEM
257
If this environment variable is set, its value is the default memory limit.
258
The value is specified as described for the
259
.B \-maxmemory
260
switch.
261
.B JPEGMEM
262
overrides the default value specified when the program was compiled, and
263
itself is overridden by an explicit
264
.BR \-maxmemory .
265
.SH SEE ALSO
266
.BR djpeg (1),
267
.BR jpegtran (1),
268
.BR rdjpgcom (1),
269
.BR wrjpgcom (1)
270
.br
271
.BR ppm (5),
272
.BR pgm (5)
273
.br
274
Wallace, Gregory K.  "The JPEG Still Picture Compression Standard",
275
Communications of the ACM, April 1991 (vol. 34, no. 4), pp. 30-44.
276
.SH AUTHOR
277
Independent JPEG Group
278
.SH BUGS
279
Arithmetic coding is not supported for legal reasons.
280
.PP
281
GIF input files are no longer supported, to avoid the Unisys LZW patent.
282
Use a Unisys-licensed program if you need to read a GIF file.  (Conversion
283
of GIF files to JPEG is usually a bad idea anyway.)
284
.PP
285
Not all variants of BMP and Targa file formats are supported.
286
.PP
287
The
288
.B \-targa
289
switch is not a bug, it's a feature.  (It would be a bug if the Targa format
290
designers had not been clueless.)
291
.PP
292
Still not as fast as we'd like.
(-)a/jpeg/ckconfig.c (-402 lines)
Line     Link Here 
 Lines 1-402    Link Here 
1
/*
2
 * ckconfig.c
3
 *
4
 * Copyright (C) 1991-1994, Thomas G. Lane.
5
 * This file is part of the Independent JPEG Group's software.
6
 * For conditions of distribution and use, see the accompanying README file.
7
 */
8
9
/*
10
 * This program is intended to help you determine how to configure the JPEG
11
 * software for installation on a particular system.  The idea is to try to
12
 * compile and execute this program.  If your compiler fails to compile the
13
 * program, make changes as indicated in the comments below.  Once you can
14
 * compile the program, run it, and it will produce a "jconfig.h" file for
15
 * your system.
16
 *
17
 * As a general rule, each time you try to compile this program,
18
 * pay attention only to the *first* error message you get from the compiler.
19
 * Many C compilers will issue lots of spurious error messages once they
20
 * have gotten confused.  Go to the line indicated in the first error message,
21
 * and read the comments preceding that line to see what to change.
22
 *
23
 * Almost all of the edits you may need to make to this program consist of
24
 * changing a line that reads "#define SOME_SYMBOL" to "#undef SOME_SYMBOL",
25
 * or vice versa.  This is called defining or undefining that symbol.
26
 */
27
28
29
/* First we must see if your system has the include files we need.
30
 * We start out with the assumption that your system has all the ANSI-standard
31
 * include files.  If you get any error trying to include one of these files,
32
 * undefine the corresponding HAVE_xxx symbol.
33
 */
34
35
#define HAVE_STDDEF_H		/* replace 'define' by 'undef' if error here */
36
#ifdef HAVE_STDDEF_H		/* next line will be skipped if you undef... */
37
#include <stddef.h>
38
#endif
39
40
#define HAVE_STDLIB_H		/* same thing for stdlib.h */
41
#ifdef HAVE_STDLIB_H
42
#include <stdlib.h>
43
#endif
44
45
#include <stdio.h>		/* If you ain't got this, you ain't got C. */
46
47
/* We have to see if your string functions are defined by
48
 * strings.h (old BSD convention) or string.h (everybody else).
49
 * We try the non-BSD convention first; define NEED_BSD_STRINGS
50
 * if the compiler says it can't find string.h.
51
 */
52
53
#undef NEED_BSD_STRINGS
54
55
#ifdef NEED_BSD_STRINGS
56
#include <strings.h>
57
#else
58
#include <string.h>
59
#endif
60
61
/* On some systems (especially older Unix machines), type size_t is
62
 * defined only in the include file <sys/types.h>.  If you get a failure
63
 * on the size_t test below, try defining NEED_SYS_TYPES_H.
64
 */
65
66
#undef NEED_SYS_TYPES_H		/* start by assuming we don't need it */
67
#ifdef NEED_SYS_TYPES_H
68
#include <sys/types.h>
69
#endif
70
71
72
/* Usually type size_t is defined in one of the include files we've included
73
 * above.  If not, you'll get an error on the "typedef size_t my_size_t;" line.
74
 * In that case, first try defining NEED_SYS_TYPES_H just above.
75
 * If that doesn't work, you'll have to search through your system library
76
 * to figure out which include file defines "size_t".  Look for a line that
77
 * says "typedef something-or-other size_t;".  Then, change the line below
78
 * that says "#include <someincludefile.h>" to instead include the file
79
 * you found size_t in, and define NEED_SPECIAL_INCLUDE.  If you can't find
80
 * type size_t anywhere, try replacing "#include <someincludefile.h>" with
81
 * "typedef unsigned int size_t;".
82
 */
83
84
#undef NEED_SPECIAL_INCLUDE	/* assume we DON'T need it, for starters */
85
86
#ifdef NEED_SPECIAL_INCLUDE
87
#include <someincludefile.h>
88
#endif
89
90
typedef size_t my_size_t;	/* The payoff: do we have size_t now? */
91
92
93
/* The next question is whether your compiler supports ANSI-style function
94
 * prototypes.  You need to know this in order to choose between using
95
 * makefile.ansi and using makefile.unix.
96
 * The #define line below is set to assume you have ANSI function prototypes.
97
 * If you get an error in this group of lines, undefine HAVE_PROTOTYPES.
98
 */
99
100
#define HAVE_PROTOTYPES
101
102
#ifdef HAVE_PROTOTYPES
103
int testfunction (int arg1, int * arg2); /* check prototypes */
104
105
struct methods_struct {		/* check method-pointer declarations */
106
  int (*error_exit) (char *msgtext);
107
  int (*trace_message) (char *msgtext);
108
  int (*another_method) (void);
109
};
110
111
int testfunction (int arg1, int * arg2) /* check definitions */
112
{
113
  return arg2[arg1];
114
}
115
116
int test2function (void)	/* check void arg list */
117
{
118
  return 0;
119
}
120
#endif
121
122
123
/* Now we want to find out if your compiler knows what "unsigned char" means.
124
 * If you get an error on the "unsigned char un_char;" line,
125
 * then undefine HAVE_UNSIGNED_CHAR.
126
 */
127
128
#define HAVE_UNSIGNED_CHAR
129
130
#ifdef HAVE_UNSIGNED_CHAR
131
unsigned char un_char;
132
#endif
133
134
135
/* Now we want to find out if your compiler knows what "unsigned short" means.
136
 * If you get an error on the "unsigned short un_short;" line,
137
 * then undefine HAVE_UNSIGNED_SHORT.
138
 */
139
140
#define HAVE_UNSIGNED_SHORT
141
142
#ifdef HAVE_UNSIGNED_SHORT
143
unsigned short un_short;
144
#endif
145
146
147
/* Now we want to find out if your compiler understands type "void".
148
 * If you get an error anywhere in here, undefine HAVE_VOID.
149
 */
150
151
#define HAVE_VOID
152
153
#ifdef HAVE_VOID
154
/* Caution: a C++ compiler will insist on complete prototypes */
155
typedef void * void_ptr;	/* check void * */
156
#ifdef HAVE_PROTOTYPES		/* check ptr to function returning void */
157
typedef void (*void_func) (int a, int b);
158
#else
159
typedef void (*void_func) ();
160
#endif
161
162
#ifdef HAVE_PROTOTYPES		/* check void function result */
163
void test3function (void_ptr arg1, void_func arg2)
164
#else
165
void test3function (arg1, arg2)
166
     void_ptr arg1;
167
     void_func arg2;
168
#endif
169
{
170
  char * locptr = (char *) arg1; /* check casting to and from void * */
171
  arg1 = (void *) locptr;
172
  (*arg2) (1, 2);		/* check call of fcn returning void */
173
}
174
#endif
175
176
177
/* Now we want to find out if your compiler knows what "const" means.
178
 * If you get an error here, undefine HAVE_CONST.
179
 */
180
181
#define HAVE_CONST
182
183
#ifdef HAVE_CONST
184
static const int carray[3] = {1, 2, 3};
185
186
#ifdef HAVE_PROTOTYPES
187
int test4function (const int arg1)
188
#else
189
int test4function (arg1)
190
     const int arg1;
191
#endif
192
{
193
  return carray[arg1];
194
}
195
#endif
196
197
198
/* If you get an error or warning about this structure definition,
199
 * define INCOMPLETE_TYPES_BROKEN.
200
 */
201
202
#undef INCOMPLETE_TYPES_BROKEN
203
204
#ifndef INCOMPLETE_TYPES_BROKEN
205
typedef struct undefined_structure * undef_struct_ptr;
206
#endif
207
208
209
/* If you get an error about duplicate names,
210
 * define NEED_SHORT_EXTERNAL_NAMES.
211
 */
212
213
#undef NEED_SHORT_EXTERNAL_NAMES
214
215
#ifndef NEED_SHORT_EXTERNAL_NAMES
216
217
int possibly_duplicate_function ()
218
{
219
  return 0;
220
}
221
222
int possibly_dupli_function ()
223
{
224
  return 1;
225
}
226
227
#endif
228
229
230
231
/************************************************************************
232
 *  OK, that's it.  You should not have to change anything beyond this
233
 *  point in order to compile and execute this program.  (You might get
234
 *  some warnings, but you can ignore them.)
235
 *  When you run the program, it will make a couple more tests that it
236
 *  can do automatically, and then it will create jconfig.h and print out
237
 *  any additional suggestions it has.
238
 ************************************************************************
239
 */
240
241
242
#ifdef HAVE_PROTOTYPES
243
int is_char_signed (int arg)
244
#else
245
int is_char_signed (arg)
246
     int arg;
247
#endif
248
{
249
  if (arg == 189) {		/* expected result for unsigned char */
250
    return 0;			/* type char is unsigned */
251
  }
252
  else if (arg != -67) {	/* expected result for signed char */
253
    printf("Hmm, it seems 'char' is not eight bits wide on your machine.\n");
254
    printf("I fear the JPEG software will not work at all.\n\n");
255
  }
256
  return 1;			/* assume char is signed otherwise */
257
}
258
259
260
#ifdef HAVE_PROTOTYPES
261
int is_shifting_signed (long arg)
262
#else
263
int is_shifting_signed (arg)
264
     long arg;
265
#endif
266
/* See whether right-shift on a long is signed or not. */
267
{
268
  long res = arg >> 4;
269
270
  if (res == -0x7F7E80CL) {	/* expected result for signed shift */
271
    return 1;			/* right shift is signed */
272
  }
273
  /* see if unsigned-shift hack will fix it. */
274
  /* we can't just test exact value since it depends on width of long... */
275
  res |= (~0L) << (32-4);
276
  if (res == -0x7F7E80CL) {	/* expected result now? */
277
    return 0;			/* right shift is unsigned */
278
  }
279
  printf("Right shift isn't acting as I expect it to.\n");
280
  printf("I fear the JPEG software will not work at all.\n\n");
281
  return 0;			/* try it with unsigned anyway */
282
}
283
284
285
#ifdef HAVE_PROTOTYPES
286
int main (int argc, char ** argv)
287
#else
288
int main (argc, argv)
289
     int argc;
290
     char ** argv;
291
#endif
292
{
293
  char signed_char_check = (char) (-67);
294
  FILE *outfile;
295
296
  /* Attempt to write jconfig.h */
297
  if ((outfile = fopen("jconfig.h", "w")) == NULL) {
298
    printf("Failed to write jconfig.h\n");
299
    return 1;
300
  }
301
302
  /* Write out all the info */
303
  fprintf(outfile, "/* jconfig.h --- generated by ckconfig.c */\n");
304
  fprintf(outfile, "/* see jconfig.doc for explanations */\n\n");
305
#ifdef HAVE_PROTOTYPES
306
  fprintf(outfile, "#define HAVE_PROTOTYPES\n");
307
#else
308
  fprintf(outfile, "#undef HAVE_PROTOTYPES\n");
309
#endif
310
#ifdef HAVE_UNSIGNED_CHAR
311
  fprintf(outfile, "#define HAVE_UNSIGNED_CHAR\n");
312
#else
313
  fprintf(outfile, "#undef HAVE_UNSIGNED_CHAR\n");
314
#endif
315
#ifdef HAVE_UNSIGNED_SHORT
316
  fprintf(outfile, "#define HAVE_UNSIGNED_SHORT\n");
317
#else
318
  fprintf(outfile, "#undef HAVE_UNSIGNED_SHORT\n");
319
#endif
320
#ifdef HAVE_VOID
321
  fprintf(outfile, "/* #define void char */\n");
322
#else
323
  fprintf(outfile, "#define void char\n");
324
#endif
325
#ifdef HAVE_CONST
326
  fprintf(outfile, "/* #define const */\n");
327
#else
328
  fprintf(outfile, "#define const\n");
329
#endif
330
  if (is_char_signed((int) signed_char_check))
331
    fprintf(outfile, "#undef CHAR_IS_UNSIGNED\n");
332
  else
333
    fprintf(outfile, "#define CHAR_IS_UNSIGNED\n");
334
#ifdef HAVE_STDDEF_H
335
  fprintf(outfile, "#define HAVE_STDDEF_H\n");
336
#else
337
  fprintf(outfile, "#undef HAVE_STDDEF_H\n");
338
#endif
339
#ifdef HAVE_STDLIB_H
340
  fprintf(outfile, "#define HAVE_STDLIB_H\n");
341
#else
342
  fprintf(outfile, "#undef HAVE_STDLIB_H\n");
343
#endif
344
#ifdef NEED_BSD_STRINGS
345
  fprintf(outfile, "#define NEED_BSD_STRINGS\n");
346
#else
347
  fprintf(outfile, "#undef NEED_BSD_STRINGS\n");
348
#endif
349
#ifdef NEED_SYS_TYPES_H
350
  fprintf(outfile, "#define NEED_SYS_TYPES_H\n");
351
#else
352
  fprintf(outfile, "#undef NEED_SYS_TYPES_H\n");
353
#endif
354
  fprintf(outfile, "#undef NEED_FAR_POINTERS\n");
355
#ifdef NEED_SHORT_EXTERNAL_NAMES
356
  fprintf(outfile, "#define NEED_SHORT_EXTERNAL_NAMES\n");
357
#else
358
  fprintf(outfile, "#undef NEED_SHORT_EXTERNAL_NAMES\n");
359
#endif
360
#ifdef INCOMPLETE_TYPES_BROKEN
361
  fprintf(outfile, "#define INCOMPLETE_TYPES_BROKEN\n");
362
#else
363
  fprintf(outfile, "#undef INCOMPLETE_TYPES_BROKEN\n");
364
#endif
365
  fprintf(outfile, "\n#ifdef JPEG_INTERNALS\n\n");
366
  if (is_shifting_signed(-0x7F7E80B1L))
367
    fprintf(outfile, "#undef RIGHT_SHIFT_IS_UNSIGNED\n");
368
  else
369
    fprintf(outfile, "#define RIGHT_SHIFT_IS_UNSIGNED\n");
370
  fprintf(outfile, "\n#endif /* JPEG_INTERNALS */\n");
371
  fprintf(outfile, "\n#ifdef JPEG_CJPEG_DJPEG\n\n");
372
  fprintf(outfile, "#define BMP_SUPPORTED		/* BMP image file format */\n");
373
  fprintf(outfile, "#define GIF_SUPPORTED		/* GIF image file format */\n");
374
  fprintf(outfile, "#define PPM_SUPPORTED		/* PBMPLUS PPM/PGM image file format */\n");
375
  fprintf(outfile, "#undef RLE_SUPPORTED		/* Utah RLE image file format */\n");
376
  fprintf(outfile, "#define TARGA_SUPPORTED		/* Targa image file format */\n\n");
377
  fprintf(outfile, "#undef TWO_FILE_COMMANDLINE	/* You may need this on non-Unix systems */\n");
378
  fprintf(outfile, "#undef NEED_SIGNAL_CATCHER	/* Define this if you use jmemname.c */\n");
379
  fprintf(outfile, "#undef DONT_USE_B_MODE\n");
380
  fprintf(outfile, "/* #define PROGRESS_REPORT */	/* optional */\n");
381
  fprintf(outfile, "\n#endif /* JPEG_CJPEG_DJPEG */\n");
382
383
  /* Close the jconfig.h file */
384
  fclose(outfile);
385
386
  /* User report */
387
  printf("Configuration check for Independent JPEG Group's software done.\n");
388
  printf("\nI have written the jconfig.h file for you.\n\n");
389
#ifdef HAVE_PROTOTYPES
390
  printf("You should use makefile.ansi as the starting point for your Makefile.\n");
391
#else
392
  printf("You should use makefile.unix as the starting point for your Makefile.\n");
393
#endif
394
395
#ifdef NEED_SPECIAL_INCLUDE
396
  printf("\nYou'll need to change jconfig.h to include the system include file\n");
397
  printf("that you found type size_t in, or add a direct definition of type\n");
398
  printf("size_t if that's what you used.  Just add it to the end.\n");
399
#endif
400
401
  return 0;
402
}
(-)a/jpeg/configure.ac (+185 lines)
Line     Link Here 
Line 0    Link Here 
1
#                                               -*- Autoconf -*-
2
# Process this file with autoconf to produce a configure script.
3
4
AC_PREREQ([2.56])
5
AC_INIT([libjpeg-turbo], [1.0.1])
6
BUILD=`date +%Y%m%d`
7
8
AM_INIT_AUTOMAKE([-Wall foreign dist-bzip2])
9
AC_PREFIX_DEFAULT(/opt/libjpeg-turbo)
10
11
# Always build with prototypes
12
AC_DEFINE([HAVE_PROTOTYPES], 1, [Define if your compiler supports prototypes])
13
# Don't use undefined types
14
AC_DEFINE([INCOMPLETE_TYPES_BROKEN], 1, [Define if you want use complete types])
15
16
# Checks for programs.
17
SAVED_CFLAGS=${CFLAGS}
18
SAVED_CXXFLAGS=${CXXFLAGS}
19
AC_PROG_CPP
20
AC_PROG_CC
21
AC_PROG_CXX
22
AC_PROG_INSTALL
23
AC_PROG_LIBTOOL
24
AC_PROG_LN_S
25
26
AC_MSG_CHECKING([whether the linker supports version scripts])
27
VERSION_SCRIPT=no
28
LDVER=`$LD --help </dev/null 2>&1 | grep "\-\-version-script"`
29
if test "$LDVER"; then
30
  VERSION_SCRIPT=yes
31
  VERSION_SCRIPT_FLAG=-Wl,--version-script,
32
  AC_MSG_RESULT(yes)
33
else
34
  LDVER=`$LD --help </dev/null 2>&1 | grep "\-M"`
35
  if test "$LDVER"; then
36
    VERSION_SCRIPT=yes
37
    VERSION_SCRIPT_FLAG=-Wl,-M,
38
    AC_MSG_RESULT(yes)
39
  else
40
    AC_MSG_RESULT(no)
41
  fi
42
fi
43
44
AM_CONDITIONAL(VERSION_SCRIPT, test "x$VERSION_SCRIPT" = "xyes")
45
AC_SUBST(VERSION_SCRIPT_FLAG)
46
47
if test "x${GCC}" = "xyes"; then
48
  if test "x${SAVED_CFLAGS}" = "x"; then
49
    CFLAGS=-O3
50
  fi
51
  if test "x${SAVED_CXXFLAGS}" = "x"; then
52
    CXXFLAGS=-O3
53
  fi
54
fi
55
56
AC_CHECK_DECL([__SUNPRO_C], [SUNCC="yes"], [SUNCC="no"])
57
if test "x${SUNCC}" = "xyes"; then
58
  if test "x${SAVED_CFLAGS}" = "x"; then
59
    CFLAGS=-xO5
60
  fi
61
  if test "x${SAVED_CXXFLAGS}" = "x"; then
62
    CXXFLAGS=-xO5
63
  fi
64
fi
65
66
# Checks for libraries.
67
68
# Checks for header files.
69
AC_HEADER_STDC
70
AC_CHECK_HEADERS([stddef.h stdlib.h string.h])
71
AC_CHECK_HEADER([sys/types.h], AC_DEFINE([NEED_SYS_TYPES_H], 1, [Define if you have sys/types.h]))
72
73
# Checks for typedefs, structures, and compiler characteristics.
74
AC_C_CONST
75
AC_C_CHAR_UNSIGNED
76
AC_C_INLINE
77
AC_TYPE_SIZE_T
78
AC_CHECK_TYPES([unsigned char, unsigned short])
79
80
AC_MSG_CHECKING([if right shift is signed])
81
AC_TRY_RUN(
82
	[#include <stdio.h>
83
	 int is_shifting_signed (long arg) {
84
	 long res = arg >> 4;
85
86
	 if (res == -0x7F7E80CL)
87
		return 1; /* right shift is signed */
88
89
	 /* see if unsigned-shift hack will fix it. */
90
	 /* we can't just test exact value since it depends on width of long... */
91
	 res |= (~0L) << (32-4);
92
	 if (res == -0x7F7E80CL)
93
		return 0; /* right shift is unsigned */
94
95
	 printf("Right shift isn't acting as I expect it to.\n");
96
	 printf("I fear the JPEG software will not work at all.\n\n");
97
	 return 0; /* try it with unsigned anyway */
98
	 }
99
	 int main (void) {
100
		exit(is_shifting_signed(-0x7F7E80B1L));
101
	 }],
102
	[AC_MSG_RESULT(no)
103
	 AC_DEFINE([RIGHT_SHIFT_IS_UNSIGNED], 1, [Define if shift is unsigned])],
104
	[AC_MSG_RESULT(yes)],
105
	[AC_MSG_RESULT(Assuming that right shift is signed on target machine.)])
106
107
# test whether global names are unique to at least 15 chars
108
AC_MSG_CHECKING([for short external names])
109
AC_TRY_LINK(
110
	[int possibly_duplicate_function () { return 0; }
111
	 int possibly_dupli_function () { return 1; }], [ ],
112
	[AC_MSG_RESULT(ok)],
113
	[AC_MSG_RESULT(short)
114
	 AC_DEFINE([NEED_SHORT_EXTERNAL_NAMES], 1, [Define if you need short function names])])
115
116
# Checks for library functions.
117
AC_CHECK_FUNCS([memset memcpy], [],
118
	[AC_DEFINE([NEED_BSD_STRINGS], 1,
119
		   [Define if you have BSD-like bzero and bcopy])])
120
121
# Set flags to indicate platform
122
case "$host_os" in
123
  cygwin* | mingw* | pw32* | interix*)
124
    is_win32=1
125
  ;;
126
esac
127
AM_CONDITIONAL([IS_WIN32], [test "x$is_win32" = "x1"])
128
129
# SIMD is optional
130
AC_ARG_WITH([simd],
131
    AC_HELP_STRING([--without-simd],[Omit accelerated SIMD routines.]))
132
if test "x${with_simd}" != "xno"; then
133
  # Check if we're on a supported CPU
134
  AC_MSG_CHECKING([if we have SIMD optimisations for cpu type])
135
  case "$host_cpu" in
136
    x86_64 | amd64)
137
      AC_MSG_RESULT([yes (x86_64)])
138
      AC_PROG_NASM
139
      simd_arch=x86_64
140
    ;;
141
    i*86 | x86 | ia32)
142
      AC_MSG_RESULT([yes (i386)])
143
      AC_PROG_NASM
144
      simd_arch=i386
145
    ;;
146
    *)
147
      AC_MSG_RESULT([no ("$host_cpu")])
148
      AC_MSG_WARN([SIMD support not available for this CPU.  Performance will suffer.])
149
      with_simd=no;
150
    ;;
151
  esac
152
153
  if test "x${with_simd}" != "xno"; then
154
    AC_DEFINE([WITH_SIMD], [1], [Use accelerated SIMD routines.])
155
  fi
156
fi
157
158
AM_CONDITIONAL([WITH_SIMD], [test "x$with_simd" != "xno"])
159
AM_CONDITIONAL([SIMD_I386], [test "x$simd_arch" = "xi386"])
160
AM_CONDITIONAL([SIMD_X86_64], [test "x$simd_arch" = "xx86_64"])
161
AM_CONDITIONAL([X86_64], [test "x$host_cpu" = "xx86_64" -o "x$host_cpu" = "xamd64"])
162
163
case "$host_cpu" in
164
  x86_64)
165
    RPMARCH=x86_64
166
    DEBARCH=amd64
167
    ;;
168
  i*86 | x86 | ia32)
169
    RPMARCH=i386
170
    DEBARCH=i386
171
    ;;
172
esac
173
174
AC_SUBST(RPMARCH)
175
AC_SUBST(DEBARCH)
176
AC_SUBST(BUILD)
177
178
# jconfig.h is the file we use, but we have another before that to
179
# fool autoheader. the reason is that we include this header in our
180
# API headers, which can screw things up for users of the lib.
181
# jconfig.h is a minimal version that allows this package to be built
182
AC_CONFIG_HEADERS([config.h])
183
AC_CONFIG_HEADERS([jconfig.h])
184
AC_CONFIG_FILES([Makefile simd/Makefile])
185
AC_OUTPUT
(-)a/jpeg/djpeg.1 (+253 lines)
Line     Link Here 
Line 0    Link Here 
1
.TH DJPEG 1 "22 August 1997"
2
.SH NAME
3
djpeg \- decompress a JPEG file to an image file
4
.SH SYNOPSIS
5
.B djpeg
6
[
7
.I options
8
]
9
[
10
.I filename
11
]
12
.LP
13
.SH DESCRIPTION
14
.LP
15
.B djpeg
16
decompresses the named JPEG file, or the standard input if no file is named,
17
and produces an image file on the standard output.  PBMPLUS (PPM/PGM), BMP,
18
GIF, Targa, or RLE (Utah Raster Toolkit) output format can be selected.
19
(RLE is supported only if the URT library is available.)
20
.SH OPTIONS
21
All switch names may be abbreviated; for example,
22
.B \-grayscale
23
may be written
24
.B \-gray
25
or
26
.BR \-gr .
27
Most of the "basic" switches can be abbreviated to as little as one letter.
28
Upper and lower case are equivalent (thus
29
.B \-BMP
30
is the same as
31
.BR \-bmp ).
32
British spellings are also accepted (e.g.,
33
.BR \-greyscale ),
34
though for brevity these are not mentioned below.
35
.PP
36
The basic switches are:
37
.TP
38
.BI \-colors " N"
39
Reduce image to at most N colors.  This reduces the number of colors used in
40
the output image, so that it can be displayed on a colormapped display or
41
stored in a colormapped file format.  For example, if you have an 8-bit
42
display, you'd need to reduce to 256 or fewer colors.
43
.TP
44
.BI \-quantize " N"
45
Same as
46
.BR \-colors .
47
.B \-colors
48
is the recommended name,
49
.B \-quantize
50
is provided only for backwards compatibility.
51
.TP
52
.B \-fast
53
Select recommended processing options for fast, low quality output.  (The
54
default options are chosen for highest quality output.)  Currently, this is
55
equivalent to \fB\-dct fast \-nosmooth \-onepass \-dither ordered\fR.
56
.TP
57
.B \-grayscale
58
Force gray-scale output even if JPEG file is color.  Useful for viewing on
59
monochrome displays; also,
60
.B djpeg
61
runs noticeably faster in this mode.
62
.TP
63
.BI \-scale " M/N"
64
Scale the output image by a factor M/N.  Currently the scale factor must be
65
1/1, 1/2, 1/4, or 1/8.  Scaling is handy if the image is larger than your
66
screen; also,
67
.B djpeg
68
runs much faster when scaling down the output.
69
.TP
70
.B \-bmp
71
Select BMP output format (Windows flavor).  8-bit colormapped format is
72
emitted if
73
.B \-colors
74
or
75
.B \-grayscale
76
is specified, or if the JPEG file is gray-scale; otherwise, 24-bit full-color
77
format is emitted.
78
.TP
79
.B \-gif
80
Select GIF output format.  Since GIF does not support more than 256 colors,
81
.B \-colors 256
82
is assumed (unless you specify a smaller number of colors).
83
.TP
84
.B \-os2
85
Select BMP output format (OS/2 1.x flavor).  8-bit colormapped format is
86
emitted if
87
.B \-colors
88
or
89
.B \-grayscale
90
is specified, or if the JPEG file is gray-scale; otherwise, 24-bit full-color
91
format is emitted.
92
.TP
93
.B \-pnm
94
Select PBMPLUS (PPM/PGM) output format (this is the default format).
95
PGM is emitted if the JPEG file is gray-scale or if
96
.B \-grayscale
97
is specified; otherwise PPM is emitted.
98
.TP
99
.B \-rle
100
Select RLE output format.  (Requires URT library.)
101
.TP
102
.B \-targa
103
Select Targa output format.  Gray-scale format is emitted if the JPEG file is
104
gray-scale or if
105
.B \-grayscale
106
is specified; otherwise, colormapped format is emitted if
107
.B \-colors
108
is specified; otherwise, 24-bit full-color format is emitted.
109
.PP
110
Switches for advanced users:
111
.TP
112
.B \-dct int
113
Use integer DCT method (default).
114
.TP
115
.B \-dct fast
116
Use fast integer DCT (less accurate).
117
.TP
118
.B \-dct float
119
Use floating-point DCT method.
120
The float method is very slightly more accurate than the int method, but is
121
much slower unless your machine has very fast floating-point hardware.  Also
122
note that results of the floating-point method may vary slightly across
123
machines, while the integer methods should give the same results everywhere.
124
The fast integer method is much less accurate than the other two.
125
.TP
126
.B \-dither fs
127
Use Floyd-Steinberg dithering in color quantization.
128
.TP
129
.B \-dither ordered
130
Use ordered dithering in color quantization.
131
.TP
132
.B \-dither none
133
Do not use dithering in color quantization.
134
By default, Floyd-Steinberg dithering is applied when quantizing colors; this
135
is slow but usually produces the best results.  Ordered dither is a compromise
136
between speed and quality; no dithering is fast but usually looks awful.  Note
137
that these switches have no effect unless color quantization is being done.
138
Ordered dither is only available in
139
.B \-onepass
140
mode.
141
.TP
142
.BI \-map " file"
143
Quantize to the colors used in the specified image file.  This is useful for
144
producing multiple files with identical color maps, or for forcing a
145
predefined set of colors to be used.  The
146
.I file
147
must be a GIF or PPM file. This option overrides
148
.B \-colors
149
and
150
.BR \-onepass .
151
.TP
152
.B \-nosmooth
153
Use a faster, lower-quality upsampling routine.
154
.TP
155
.B \-onepass
156
Use one-pass instead of two-pass color quantization.  The one-pass method is
157
faster and needs less memory, but it produces a lower-quality image.
158
.B \-onepass
159
is ignored unless you also say
160
.B \-colors
161
.IR N .
162
Also, the one-pass method is always used for gray-scale output (the two-pass
163
method is no improvement then).
164
.TP
165
.BI \-maxmemory " N"
166
Set limit for amount of memory to use in processing large images.  Value is
167
in thousands of bytes, or millions of bytes if "M" is attached to the
168
number.  For example,
169
.B \-max 4m
170
selects 4000000 bytes.  If more space is needed, temporary files will be used.
171
.TP
172
.BI \-outfile " name"
173
Send output image to the named file, not to standard output.
174
.TP
175
.B \-verbose
176
Enable debug printout.  More
177
.BR \-v 's
178
give more output.  Also, version information is printed at startup.
179
.TP
180
.B \-debug
181
Same as
182
.BR \-verbose .
183
.SH EXAMPLES
184
.LP
185
This example decompresses the JPEG file foo.jpg, quantizes it to
186
256 colors, and saves the output in 8-bit BMP format in foo.bmp:
187
.IP
188
.B djpeg \-colors 256 \-bmp
189
.I foo.jpg
190
.B >
191
.I foo.bmp
192
.SH HINTS
193
To get a quick preview of an image, use the
194
.B \-grayscale
195
and/or
196
.B \-scale
197
switches.
198
.B \-grayscale \-scale 1/8
199
is the fastest case.
200
.PP
201
Several options are available that trade off image quality to gain speed.
202
.B \-fast
203
turns on the recommended settings.
204
.PP
205
.B \-dct fast
206
and/or
207
.B \-nosmooth
208
gain speed at a small sacrifice in quality.
209
When producing a color-quantized image,
210
.B \-onepass \-dither ordered
211
is fast but much lower quality than the default behavior.
212
.B \-dither none
213
may give acceptable results in two-pass mode, but is seldom tolerable in
214
one-pass mode.
215
.PP
216
If you are fortunate enough to have very fast floating point hardware,
217
\fB\-dct float\fR may be even faster than \fB\-dct fast\fR.  But on most
218
machines \fB\-dct float\fR is slower than \fB\-dct int\fR; in this case it is
219
not worth using, because its theoretical accuracy advantage is too small to be
220
significant in practice.
221
.SH ENVIRONMENT
222
.TP
223
.B JPEGMEM
224
If this environment variable is set, its value is the default memory limit.
225
The value is specified as described for the
226
.B \-maxmemory
227
switch.
228
.B JPEGMEM
229
overrides the default value specified when the program was compiled, and
230
itself is overridden by an explicit
231
.BR \-maxmemory .
232
.SH SEE ALSO
233
.BR cjpeg (1),
234
.BR jpegtran (1),
235
.BR rdjpgcom (1),
236
.BR wrjpgcom (1)
237
.br
238
.BR ppm (5),
239
.BR pgm (5)
240
.br
241
Wallace, Gregory K.  "The JPEG Still Picture Compression Standard",
242
Communications of the ACM, April 1991 (vol. 34, no. 4), pp. 30-44.
243
.SH AUTHOR
244
Independent JPEG Group
245
.SH BUGS
246
Arithmetic coding is not supported for legal reasons.
247
.PP
248
To avoid the Unisys LZW patent,
249
.B djpeg
250
produces uncompressed GIF files.  These are larger than they should be, but
251
are readable by standard GIF decoders.
252
.PP
253
Still not as fast as we'd like.
(-)a/jpeg/jccolor.c (-21 / +129 lines)
Line     Link Here 
 Lines 1-21    Link Here 
1
/*
1
/*
2
 * jccolor.c
2
 * jccolor.c
3
 *
3
 *
4
 * Copyright (C) 1991-1996, Thomas G. Lane.
4
 * Copyright (C) 1991-1996, Thomas G. Lane.
5
 * Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
6
 * Copyright 2009 D. R. Commander
5
 * This file is part of the Independent JPEG Group's software.
7
 * This file is part of the Independent JPEG Group's software.
6
 * For conditions of distribution and use, see the accompanying README file.
8
 * For conditions of distribution and use, see the accompanying README file.
7
 *
9
 *
8
 * This file contains input colorspace conversion routines.
10
 * This file contains input colorspace conversion routines.
9
 */
11
 */
10
12
11
#define JPEG_INTERNALS
13
#define JPEG_INTERNALS
12
#include "jinclude.h"
14
#include "jinclude.h"
13
#include "jpeglib.h"
15
#include "jpeglib.h"
16
#include "jsimd.h"
14
17
15
18
16
/* Private subobject */
19
/* Private subobject */
17
20
18
typedef struct {
21
typedef struct {
19
  struct jpeg_color_converter pub; /* public fields */
22
  struct jpeg_color_converter pub; /* public fields */
20
23
21
  /* Private state for RGB->YCC conversion */
24
  /* Private state for RGB->YCC conversion */
 Lines 73-88   typedef my_color_converter * my_cconvert Link Here 
73
#define G_CB_OFF	(4*(MAXJSAMPLE+1))
76
#define G_CB_OFF	(4*(MAXJSAMPLE+1))
74
#define B_CB_OFF	(5*(MAXJSAMPLE+1))
77
#define B_CB_OFF	(5*(MAXJSAMPLE+1))
75
#define R_CR_OFF	B_CB_OFF		/* B=>Cb, R=>Cr are the same */
78
#define R_CR_OFF	B_CB_OFF		/* B=>Cb, R=>Cr are the same */
76
#define G_CR_OFF	(6*(MAXJSAMPLE+1))
79
#define G_CR_OFF	(6*(MAXJSAMPLE+1))
77
#define B_CR_OFF	(7*(MAXJSAMPLE+1))
80
#define B_CR_OFF	(7*(MAXJSAMPLE+1))
78
#define TABLE_SIZE	(8*(MAXJSAMPLE+1))
81
#define TABLE_SIZE	(8*(MAXJSAMPLE+1))
79
82
80
83
84
#if BITS_IN_JSAMPLE == 8
85
86
const unsigned char red_lut[256] = {
87
  0 , 0 , 1 , 1 , 1 , 1 , 2 , 2 , 2 , 3 , 3 , 3 , 4 , 4 , 4 , 4 ,
88
  5 , 5 , 5 , 6 , 6 , 6 , 7 , 7 , 7 , 7 , 8 , 8 , 8 , 9 , 9 , 9 ,
89
  10, 10, 10, 10, 11, 11, 11, 12, 12, 12, 13, 13, 13, 13, 14, 14,
90
  14, 15, 15, 15, 16, 16, 16, 16, 17, 17, 17, 18, 18, 18, 19, 19,
91
  19, 19, 20, 20, 20, 21, 21, 21, 22, 22, 22, 22, 23, 23, 23, 24,
92
  24, 24, 25, 25, 25, 25, 26, 26, 26, 27, 27, 27, 28, 28, 28, 28,
93
  29, 29, 29, 30, 30, 30, 30, 31, 31, 31, 32, 32, 32, 33, 33, 33,
94
  33, 34, 34, 34, 35, 35, 35, 36, 36, 36, 36, 37, 37, 37, 38, 38,
95
  38, 39, 39, 39, 39, 40, 40, 40, 41, 41, 41, 42, 42, 42, 42, 43,
96
  43, 43, 44, 44, 44, 45, 45, 45, 45, 46, 46, 46, 47, 47, 47, 48,
97
  48, 48, 48, 49, 49, 49, 50, 50, 50, 51, 51, 51, 51, 52, 52, 52,
98
  53, 53, 53, 54, 54, 54, 54, 55, 55, 55, 56, 56, 56, 57, 57, 57,
99
  57, 58, 58, 58, 59, 59, 59, 60, 60, 60, 60, 61, 61, 61, 62, 62,
100
  62, 62, 63, 63, 63, 64, 64, 64, 65, 65, 65, 65, 66, 66, 66, 67,
101
  67, 67, 68, 68, 68, 68, 69, 69, 69, 70, 70, 70, 71, 71, 71, 71,
102
  72, 72, 72, 73, 73, 73, 74, 74, 74, 74, 75, 75, 75, 76, 76, 76
103
};
104
105
const unsigned char green_lut[256] = {
106
  0  , 1  , 1  , 2  , 2  , 3  , 4  , 4  , 5  , 5  , 6  , 6  ,
107
  7  , 8  , 8  , 9  , 9  , 10 , 11 , 11 , 12 , 12 , 13 , 14 ,
108
  14 , 15 , 15 , 16 , 16 , 17 , 18 , 18 , 19 , 19 , 20 , 21 ,
109
  21 , 22 , 22 , 23 , 23 , 24 , 25 , 25 , 26 , 26 , 27 , 28 ,
110
  28 , 29 , 29 , 30 , 31 , 31 , 32 , 32 , 33 , 33 , 34 , 35 ,
111
  35 , 36 , 36 , 37 , 38 , 38 , 39 , 39 , 40 , 41 , 41 , 42 ,
112
  42 , 43 , 43 , 44 , 45 , 45 , 46 , 46 , 47 , 48 , 48 , 49 ,
113
  49 , 50 , 50 , 51 , 52 , 52 , 53 , 53 , 54 , 55 , 55 , 56 ,
114
  56 , 57 , 58 , 58 , 59 , 59 , 60 , 60 , 61 , 62 , 62 , 63 ,
115
  63 , 64 , 65 , 65 , 66 , 66 , 67 , 68 , 68 , 69 , 69 , 70 ,
116
  70 , 71 , 72 , 72 , 73 , 73 , 74 , 75 , 75 , 76 , 76 , 77 ,
117
  77 , 78 , 79 , 79 , 80 , 80 , 81 , 82 , 82 , 83 , 83 , 84 ,
118
  85 , 85 , 86 , 86 , 87 , 87 , 88 , 89 , 89 , 90 , 90 , 91 ,
119
  92 , 92 , 93 , 93 , 94 , 95 , 95 , 96 , 96 , 97 , 97 , 98 ,
120
  99 , 99 , 100, 100, 101, 102, 102, 103, 103, 104, 104, 105,
121
  106, 106, 107, 107, 108, 109, 109, 110, 110, 111, 112, 112,
122
  113, 113, 114, 114, 115, 116, 116, 117, 117, 118, 119, 119,
123
  120, 120, 121, 122, 122, 123, 123, 124, 124, 125, 126, 126,
124
  127, 127, 128, 129, 129, 130, 130, 131, 131, 132, 133, 133,
125
  34, 134, 135, 136, 136, 137, 137, 138, 139, 139, 140, 140,
126
  141, 141, 142, 143, 143, 144, 144, 145, 146, 146, 147, 147,
127
  148, 149, 149, 150
128
};
129
130
const unsigned char blue_lut[256] = {
131
  0 , 0 , 0 , 0 , 0 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 2 , 2 ,
132
  2 , 2 , 2 , 2 , 2 , 2 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 4 ,
133
  4 , 4 , 4 , 4 , 4 , 4 , 4 , 4 , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 5 ,
134
  5 , 6 , 6 , 6 , 6 , 6 , 6 , 6 , 6 , 6 , 7 , 7 , 7 , 7 , 7 , 7 ,
135
  7 , 7 , 8 , 8 , 8 , 8 , 8 , 8 , 8 , 8 , 8 , 9 , 9 , 9 , 9 , 9 ,
136
  9 , 9 , 9 , 9 , 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11,
137
  11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13,
138
  13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14,
139
  15, 15, 15, 15, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16,
140
  16, 17, 17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18,
141
  18, 18, 18, 19, 19, 19, 19, 19, 19, 19, 19, 19, 20, 20, 20, 20,
142
  20, 20, 20, 20, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22,
143
  22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, 23, 24,
144
  24, 24, 24, 24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25,
145
  26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27,
146
  27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29
147
};
148
149
#endif
150
151
81
/*
152
/*
82
 * Initialize for RGB->YCC colorspace conversion.
153
 * Initialize for RGB->YCC colorspace conversion.
83
 */
154
 */
84
155
85
METHODDEF(void)
156
METHODDEF(void)
86
rgb_ycc_start (j_compress_ptr cinfo)
157
rgb_ycc_start (j_compress_ptr cinfo)
87
{
158
{
88
  my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
159
  my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
 Lines 141-160   rgb_ycc_convert (j_compress_ptr cinfo, Link Here 
141
212
142
  while (--num_rows >= 0) {
213
  while (--num_rows >= 0) {
143
    inptr = *input_buf++;
214
    inptr = *input_buf++;
144
    outptr0 = output_buf[0][output_row];
215
    outptr0 = output_buf[0][output_row];
145
    outptr1 = output_buf[1][output_row];
216
    outptr1 = output_buf[1][output_row];
146
    outptr2 = output_buf[2][output_row];
217
    outptr2 = output_buf[2][output_row];
147
    output_row++;
218
    output_row++;
148
    for (col = 0; col < num_cols; col++) {
219
    for (col = 0; col < num_cols; col++) {
149
      r = GETJSAMPLE(inptr[RGB_RED]);
220
      r = GETJSAMPLE(inptr[rgb_red[cinfo->in_color_space]]);
150
      g = GETJSAMPLE(inptr[RGB_GREEN]);
221
      g = GETJSAMPLE(inptr[rgb_green[cinfo->in_color_space]]);
151
      b = GETJSAMPLE(inptr[RGB_BLUE]);
222
      b = GETJSAMPLE(inptr[rgb_blue[cinfo->in_color_space]]);
152
      inptr += RGB_PIXELSIZE;
223
      inptr += rgb_pixelsize[cinfo->in_color_space];
153
      /* If the inputs are 0..MAXJSAMPLE, the outputs of these equations
224
      /* If the inputs are 0..MAXJSAMPLE, the outputs of these equations
154
       * must be too; we do not need an explicit range-limiting operation.
225
       * must be too; we do not need an explicit range-limiting operation.
155
       * Hence the value being shifted is never negative, and we don't
226
       * Hence the value being shifted is never negative, and we don't
156
       * need the general RIGHT_SHIFT macro.
227
       * need the general RIGHT_SHIFT macro.
157
       */
228
       */
158
      /* Y */
229
      /* Y */
159
      outptr0[col] = (JSAMPLE)
230
      outptr0[col] = (JSAMPLE)
160
		((ctab[r+R_Y_OFF] + ctab[g+G_Y_OFF] + ctab[b+B_Y_OFF])
231
		((ctab[r+R_Y_OFF] + ctab[g+G_Y_OFF] + ctab[b+B_Y_OFF])
 Lines 183-218   rgb_ycc_convert (j_compress_ptr cinfo, Link Here 
183
 */
254
 */
184
255
185
METHODDEF(void)
256
METHODDEF(void)
186
rgb_gray_convert (j_compress_ptr cinfo,
257
rgb_gray_convert (j_compress_ptr cinfo,
187
		  JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
258
		  JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
188
		  JDIMENSION output_row, int num_rows)
259
		  JDIMENSION output_row, int num_rows)
189
{
260
{
190
  my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
261
  my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
191
  register int r, g, b;
262
  #if BITS_IN_JSAMPLE != 8
192
  register INT32 * ctab = cconvert->rgb_ycc_tab;
263
  register INT32 * ctab = cconvert->rgb_ycc_tab;
264
  #endif
193
  register JSAMPROW inptr;
265
  register JSAMPROW inptr;
194
  register JSAMPROW outptr;
266
  register JSAMPROW outptr;
267
  JSAMPLE *maxoutptr;
195
  register JDIMENSION col;
268
  register JDIMENSION col;
196
  JDIMENSION num_cols = cinfo->image_width;
269
  JDIMENSION num_cols = cinfo->image_width;
270
  int rindex = rgb_red[cinfo->in_color_space];
271
  int gindex = rgb_green[cinfo->in_color_space];
272
  int bindex = rgb_blue[cinfo->in_color_space];
273
  int rgbstride = rgb_pixelsize[cinfo->in_color_space];
197
274
198
  while (--num_rows >= 0) {
275
  while (--num_rows >= 0) {
199
    inptr = *input_buf++;
276
    inptr = *input_buf++;
200
    outptr = output_buf[0][output_row];
277
    outptr = output_buf[0][output_row];
278
    maxoutptr = &outptr[num_cols];
201
    output_row++;
279
    output_row++;
202
    for (col = 0; col < num_cols; col++) {
280
    for (; outptr < maxoutptr; outptr++, inptr += rgbstride) {
203
      r = GETJSAMPLE(inptr[RGB_RED]);
204
      g = GETJSAMPLE(inptr[RGB_GREEN]);
205
      b = GETJSAMPLE(inptr[RGB_BLUE]);
206
      inptr += RGB_PIXELSIZE;
207
      /* Y */
281
      /* Y */
208
      outptr[col] = (JSAMPLE)
282
      #if BITS_IN_JSAMPLE == 8
209
		((ctab[r+R_Y_OFF] + ctab[g+G_Y_OFF] + ctab[b+B_Y_OFF])
283
      *outptr = red_lut[inptr[rindex]] + green_lut[inptr[gindex]]
210
		 >> SCALEBITS);
284
	    + blue_lut[inptr[bindex]];
285
      #else
286
      *outptr = (JSAMPLE)
287
	    ((ctab[GETJSAMPLE(inptr[rindex])+R_Y_OFF]
288
	     + ctab[GETJSAMPLE(inptr[gindex])+G_Y_OFF]
289
	     + ctab[GETJSAMPLE(inptr[bindex])+B_Y_OFF])
290
	     >> SCALEBITS);
291
      #endif
211
    }
292
    }
212
  }
293
  }
213
}
294
}
214
295
215
296
216
/*
297
/*
217
 * Convert some rows of samples to the JPEG colorspace.
298
 * Convert some rows of samples to the JPEG colorspace.
218
 * This version handles Adobe-style CMYK->YCCK conversion,
299
 * This version handles Adobe-style CMYK->YCCK conversion,
 Lines 363-383   jinit_color_converter (j_compress_ptr ci Link Here 
363
  /* Make sure input_components agrees with in_color_space */
444
  /* Make sure input_components agrees with in_color_space */
364
  switch (cinfo->in_color_space) {
445
  switch (cinfo->in_color_space) {
365
  case JCS_GRAYSCALE:
446
  case JCS_GRAYSCALE:
366
    if (cinfo->input_components != 1)
447
    if (cinfo->input_components != 1)
367
      ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE);
448
      ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE);
368
    break;
449
    break;
369
450
370
  case JCS_RGB:
451
  case JCS_RGB:
371
#if RGB_PIXELSIZE != 3
452
  case JCS_EXT_RGB:
372
    if (cinfo->input_components != RGB_PIXELSIZE)
453
  case JCS_EXT_RGBX:
454
  case JCS_EXT_BGR:
455
  case JCS_EXT_BGRX:
456
  case JCS_EXT_XBGR:
457
  case JCS_EXT_XRGB:
458
    if (cinfo->input_components != rgb_pixelsize[cinfo->in_color_space])
373
      ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE);
459
      ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE);
374
    break;
460
    break;
375
#endif /* else share code with YCbCr */
376
461
377
  case JCS_YCbCr:
462
  case JCS_YCbCr:
378
    if (cinfo->input_components != 3)
463
    if (cinfo->input_components != 3)
379
      ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE);
464
      ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE);
380
    break;
465
    break;
381
466
382
  case JCS_CMYK:
467
  case JCS_CMYK:
383
  case JCS_YCCK:
468
  case JCS_YCCK:
 Lines 393-432   jinit_color_converter (j_compress_ptr ci Link Here 
393
478
394
  /* Check num_components, set conversion method based on requested space */
479
  /* Check num_components, set conversion method based on requested space */
395
  switch (cinfo->jpeg_color_space) {
480
  switch (cinfo->jpeg_color_space) {
396
  case JCS_GRAYSCALE:
481
  case JCS_GRAYSCALE:
397
    if (cinfo->num_components != 1)
482
    if (cinfo->num_components != 1)
398
      ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
483
      ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
399
    if (cinfo->in_color_space == JCS_GRAYSCALE)
484
    if (cinfo->in_color_space == JCS_GRAYSCALE)
400
      cconvert->pub.color_convert = grayscale_convert;
485
      cconvert->pub.color_convert = grayscale_convert;
401
    else if (cinfo->in_color_space == JCS_RGB) {
486
    else if (cinfo->in_color_space == JCS_RGB ||
487
             cinfo->in_color_space == JCS_EXT_RGB ||
488
             cinfo->in_color_space == JCS_EXT_RGBX ||
489
             cinfo->in_color_space == JCS_EXT_BGR ||
490
             cinfo->in_color_space == JCS_EXT_BGRX ||
491
             cinfo->in_color_space == JCS_EXT_XBGR ||
492
             cinfo->in_color_space == JCS_EXT_XRGB) {
402
      cconvert->pub.start_pass = rgb_ycc_start;
493
      cconvert->pub.start_pass = rgb_ycc_start;
403
      cconvert->pub.color_convert = rgb_gray_convert;
494
      cconvert->pub.color_convert = rgb_gray_convert;
404
    } else if (cinfo->in_color_space == JCS_YCbCr)
495
    } else if (cinfo->in_color_space == JCS_YCbCr)
405
      cconvert->pub.color_convert = grayscale_convert;
496
      cconvert->pub.color_convert = grayscale_convert;
406
    else
497
    else
407
      ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
498
      ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
408
    break;
499
    break;
409
500
410
  case JCS_RGB:
501
  case JCS_RGB:
502
  case JCS_EXT_RGB:
503
  case JCS_EXT_RGBX:
504
  case JCS_EXT_BGR:
505
  case JCS_EXT_BGRX:
506
  case JCS_EXT_XBGR:
507
  case JCS_EXT_XRGB:
411
    if (cinfo->num_components != 3)
508
    if (cinfo->num_components != 3)
412
      ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
509
      ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
413
    if (cinfo->in_color_space == JCS_RGB && RGB_PIXELSIZE == 3)
510
    if (cinfo->in_color_space == cinfo->jpeg_color_space &&
511
      rgb_pixelsize[cinfo->in_color_space] == 3)
414
      cconvert->pub.color_convert = null_convert;
512
      cconvert->pub.color_convert = null_convert;
415
    else
513
    else
416
      ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
514
      ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
417
    break;
515
    break;
418
516
419
  case JCS_YCbCr:
517
  case JCS_YCbCr:
420
    if (cinfo->num_components != 3)
518
    if (cinfo->num_components != 3)
421
      ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
519
      ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
422
    if (cinfo->in_color_space == JCS_RGB) {
520
    if (cinfo->in_color_space == JCS_RGB ||
423
      cconvert->pub.start_pass = rgb_ycc_start;
521
        cinfo->in_color_space == JCS_EXT_RGB ||
424
      cconvert->pub.color_convert = rgb_ycc_convert;
522
        cinfo->in_color_space == JCS_EXT_RGBX ||
523
        cinfo->in_color_space == JCS_EXT_BGR ||
524
        cinfo->in_color_space == JCS_EXT_BGRX ||
525
        cinfo->in_color_space == JCS_EXT_XBGR ||
526
        cinfo->in_color_space == JCS_EXT_XRGB) {
527
      if (jsimd_can_rgb_ycc())
528
        cconvert->pub.color_convert = jsimd_rgb_ycc_convert;
529
      else {
530
        cconvert->pub.start_pass = rgb_ycc_start;
531
        cconvert->pub.color_convert = rgb_ycc_convert;
532
      }
425
    } else if (cinfo->in_color_space == JCS_YCbCr)
533
    } else if (cinfo->in_color_space == JCS_YCbCr)
426
      cconvert->pub.color_convert = null_convert;
534
      cconvert->pub.color_convert = null_convert;
427
    else
535
    else
428
      ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
536
      ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
429
    break;
537
    break;
430
538
431
  case JCS_CMYK:
539
  case JCS_CMYK:
432
    if (cinfo->num_components != 4)
540
    if (cinfo->num_components != 4)
(-)a/jpeg/jcdctmgr.c (-117 / +362 lines)
Line     Link Here 
 Lines 1-52    Link Here 
1
/*
1
/*
2
 * jcdctmgr.c
2
 * jcdctmgr.c
3
 *
3
 *
4
 * Copyright (C) 1994-1996, Thomas G. Lane.
4
 * Copyright (C) 1994-1996, Thomas G. Lane.
5
 * Copyright (C) 1999-2006, MIYASAKA Masaru.
6
 * Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
5
 * This file is part of the Independent JPEG Group's software.
7
 * This file is part of the Independent JPEG Group's software.
6
 * For conditions of distribution and use, see the accompanying README file.
8
 * For conditions of distribution and use, see the accompanying README file.
7
 *
9
 *
8
 * This file contains the forward-DCT management logic.
10
 * This file contains the forward-DCT management logic.
9
 * This code selects a particular DCT implementation to be used,
11
 * This code selects a particular DCT implementation to be used,
10
 * and it performs related housekeeping chores including coefficient
12
 * and it performs related housekeeping chores including coefficient
11
 * quantization.
13
 * quantization.
12
 */
14
 */
13
15
14
#define JPEG_INTERNALS
16
#define JPEG_INTERNALS
15
#include "jinclude.h"
17
#include "jinclude.h"
16
#include "jpeglib.h"
18
#include "jpeglib.h"
17
#include "jdct.h"		/* Private declarations for DCT subsystem */
19
#include "jdct.h"		/* Private declarations for DCT subsystem */
20
#include "jsimddct.h"
18
21
19
22
20
/* Private subobject for this module */
23
/* Private subobject for this module */
21
24
25
typedef JMETHOD(void, forward_DCT_method_ptr, (DCTELEM * data));
26
typedef JMETHOD(void, float_DCT_method_ptr, (FAST_FLOAT * data));
27
28
typedef JMETHOD(void, convsamp_method_ptr,
29
                (JSAMPARRAY sample_data, JDIMENSION start_col,
30
                 DCTELEM * workspace));
31
typedef JMETHOD(void, float_convsamp_method_ptr,
32
                (JSAMPARRAY sample_data, JDIMENSION start_col,
33
                 FAST_FLOAT *workspace));
34
35
typedef JMETHOD(void, quantize_method_ptr,
36
                (JCOEFPTR coef_block, DCTELEM * divisors,
37
                 DCTELEM * workspace));
38
typedef JMETHOD(void, float_quantize_method_ptr,
39
                (JCOEFPTR coef_block, FAST_FLOAT * divisors,
40
                 FAST_FLOAT * workspace));
41
22
typedef struct {
42
typedef struct {
23
  struct jpeg_forward_dct pub;	/* public fields */
43
  struct jpeg_forward_dct pub;	/* public fields */
24
44
25
  /* Pointer to the DCT routine actually in use */
45
  /* Pointer to the DCT routine actually in use */
26
  forward_DCT_method_ptr do_dct;
46
  forward_DCT_method_ptr dct;
47
  convsamp_method_ptr convsamp;
48
  quantize_method_ptr quantize;
27
49
28
  /* The actual post-DCT divisors --- not identical to the quant table
50
  /* The actual post-DCT divisors --- not identical to the quant table
29
   * entries, because of scaling (especially for an unnormalized DCT).
51
   * entries, because of scaling (especially for an unnormalized DCT).
30
   * Each table is given in normal array order.
52
   * Each table is given in normal array order.
31
   */
53
   */
32
  DCTELEM * divisors[NUM_QUANT_TBLS];
54
  DCTELEM * divisors[NUM_QUANT_TBLS];
33
55
56
  /* work area for FDCT subroutine */
57
  DCTELEM * workspace;
58
34
#ifdef DCT_FLOAT_SUPPORTED
59
#ifdef DCT_FLOAT_SUPPORTED
35
  /* Same as above for the floating-point case. */
60
  /* Same as above for the floating-point case. */
36
  float_DCT_method_ptr do_float_dct;
61
  float_DCT_method_ptr float_dct;
62
  float_convsamp_method_ptr float_convsamp;
63
  float_quantize_method_ptr float_quantize;
37
  FAST_FLOAT * float_divisors[NUM_QUANT_TBLS];
64
  FAST_FLOAT * float_divisors[NUM_QUANT_TBLS];
65
  FAST_FLOAT * float_workspace;
38
#endif
66
#endif
39
} my_fdct_controller;
67
} my_fdct_controller;
40
68
41
typedef my_fdct_controller * my_fdct_ptr;
69
typedef my_fdct_controller * my_fdct_ptr;
42
70
43
71
44
/*
72
/*
73
 * Find the highest bit in an integer through binary search.
74
 */
75
LOCAL(int)
76
flss (UINT16 val)
77
{
78
  int bit;
79
80
  bit = 16;
81
82
  if (!val)
83
    return 0;
84
85
  if (!(val & 0xff00)) {
86
    bit -= 8;
87
    val <<= 8;
88
  }
89
  if (!(val & 0xf000)) {
90
    bit -= 4;
91
    val <<= 4;
92
  }
93
  if (!(val & 0xc000)) {
94
    bit -= 2;
95
    val <<= 2;
96
  }
97
  if (!(val & 0x8000)) {
98
    bit -= 1;
99
    val <<= 1;
100
  }
101
102
  return bit;
103
}
104
105
/*
106
 * Compute values to do a division using reciprocal.
107
 *
108
 * This implementation is based on an algorithm described in
109
 *   "How to optimize for the Pentium family of microprocessors"
110
 *   (http://www.agner.org/assem/).
111
 * More information about the basic algorithm can be found in
112
 * the paper "Integer Division Using Reciprocals" by Robert Alverson.
113
 *
114
 * The basic idea is to replace x/d by x * d^-1. In order to store
115
 * d^-1 with enough precision we shift it left a few places. It turns
116
 * out that this algoright gives just enough precision, and also fits
117
 * into DCTELEM:
118
 *
119
 *   b = (the number of significant bits in divisor) - 1
120
 *   r = (word size) + b
121
 *   f = 2^r / divisor
122
 *
123
 * f will not be an integer for most cases, so we need to compensate
124
 * for the rounding error introduced:
125
 *
126
 *   no fractional part:
127
 *
128
 *       result = input >> r
129
 *
130
 *   fractional part of f < 0.5:
131
 *
132
 *       round f down to nearest integer
133
 *       result = ((input + 1) * f) >> r
134
 *
135
 *   fractional part of f > 0.5:
136
 *
137
 *       round f up to nearest integer
138
 *       result = (input * f) >> r
139
 *
140
 * This is the original algorithm that gives truncated results. But we
141
 * want properly rounded results, so we replace "input" with
142
 * "input + divisor/2".
143
 *
144
 * In order to allow SIMD implementations we also tweak the values to
145
 * allow the same calculation to be made at all times:
146
 * 
147
 *   dctbl[0] = f rounded to nearest integer
148
 *   dctbl[1] = divisor / 2 (+ 1 if fractional part of f < 0.5)
149
 *   dctbl[2] = 1 << ((word size) * 2 - r)
150
 *   dctbl[3] = r - (word size)
151
 *
152
 * dctbl[2] is for stupid instruction sets where the shift operation
153
 * isn't member wise (e.g. MMX).
154
 *
155
 * The reason dctbl[2] and dctbl[3] reduce the shift with (word size)
156
 * is that most SIMD implementations have a "multiply and store top
157
 * half" operation.
158
 *
159
 * Lastly, we store each of the values in their own table instead
160
 * of in a consecutive manner, yet again in order to allow SIMD
161
 * routines.
162
 */
163
LOCAL(void)
164
compute_reciprocal (UINT16 divisor, DCTELEM * dtbl)
165
{
166
  UDCTELEM2 fq, fr;
167
  UDCTELEM c;
168
  int b, r;
169
170
  b = flss(divisor) - 1;
171
  r  = sizeof(DCTELEM) * 8 + b;
172
173
  fq = ((UDCTELEM2)1 << r) / divisor;
174
  fr = ((UDCTELEM2)1 << r) % divisor;
175
176
  c = divisor / 2; /* for rounding */
177
178
  if (fr == 0) { /* divisor is power of two */
179
    /* fq will be one bit too large to fit in DCTELEM, so adjust */
180
    fq >>= 1;
181
    r--;
182
  } else if (fr <= (divisor / 2)) { /* fractional part is < 0.5 */
183
    c++;
184
  } else { /* fractional part is > 0.5 */
185
    fq++;
186
  }
187
188
  dtbl[DCTSIZE2 * 0] = (DCTELEM) fq;      /* reciprocal */
189
  dtbl[DCTSIZE2 * 1] = (DCTELEM) c;       /* correction + roundfactor */
190
  dtbl[DCTSIZE2 * 2] = (DCTELEM) (1 << (sizeof(DCTELEM)*8*2 - r));  /* scale */
191
  dtbl[DCTSIZE2 * 3] = (DCTELEM) r - sizeof(DCTELEM)*8; /* shift */
192
}
193
194
/*
45
 * Initialize for a processing pass.
195
 * Initialize for a processing pass.
46
 * Verify that all referenced Q-tables are present, and set up
196
 * Verify that all referenced Q-tables are present, and set up
47
 * the divisor table for each one.
197
 * the divisor table for each one.
48
 * In the current implementation, DCT of all components is done during
198
 * In the current implementation, DCT of all components is done during
49
 * the first pass, even if only some components will be output in the
199
 * the first pass, even if only some components will be output in the
50
 * first scan.  Hence all components should be examined here.
200
 * first scan.  Hence all components should be examined here.
51
 */
201
 */
52
202
 Lines 73-93   start_pass_fdctmgr (j_compress_ptr cinfo Link Here 
73
#ifdef DCT_ISLOW_SUPPORTED
223
#ifdef DCT_ISLOW_SUPPORTED
74
    case JDCT_ISLOW:
224
    case JDCT_ISLOW:
75
      /* For LL&M IDCT method, divisors are equal to raw quantization
225
      /* For LL&M IDCT method, divisors are equal to raw quantization
76
       * coefficients multiplied by 8 (to counteract scaling).
226
       * coefficients multiplied by 8 (to counteract scaling).
77
       */
227
       */
78
      if (fdct->divisors[qtblno] == NULL) {
228
      if (fdct->divisors[qtblno] == NULL) {
79
	fdct->divisors[qtblno] = (DCTELEM *)
229
	fdct->divisors[qtblno] = (DCTELEM *)
80
	  (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
230
	  (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
81
				      DCTSIZE2 * SIZEOF(DCTELEM));
231
				      (DCTSIZE2 * 4) * SIZEOF(DCTELEM));
82
      }
232
      }
83
      dtbl = fdct->divisors[qtblno];
233
      dtbl = fdct->divisors[qtblno];
84
      for (i = 0; i < DCTSIZE2; i++) {
234
      for (i = 0; i < DCTSIZE2; i++) {
85
	dtbl[i] = ((DCTELEM) qtbl->quantval[i]) << 3;
235
	compute_reciprocal(qtbl->quantval[i] << 3, &dtbl[i]);
86
      }
236
      }
87
      break;
237
      break;
88
#endif
238
#endif
89
#ifdef DCT_IFAST_SUPPORTED
239
#ifdef DCT_IFAST_SUPPORTED
90
    case JDCT_IFAST:
240
    case JDCT_IFAST:
91
      {
241
      {
92
	/* For AA&N IDCT method, divisors are equal to quantization
242
	/* For AA&N IDCT method, divisors are equal to quantization
93
	 * coefficients scaled by scalefactor[row]*scalefactor[col], where
243
	 * coefficients scaled by scalefactor[row]*scalefactor[col], where
 Lines 107-130   start_pass_fdctmgr (j_compress_ptr cinfo Link Here 
107
	   8867, 12299, 11585, 10426,  8867,  6967,  4799,  2446,
257
	   8867, 12299, 11585, 10426,  8867,  6967,  4799,  2446,
108
	   4520,  6270,  5906,  5315,  4520,  3552,  2446,  1247
258
	   4520,  6270,  5906,  5315,  4520,  3552,  2446,  1247
109
	};
259
	};
110
	SHIFT_TEMPS
260
	SHIFT_TEMPS
111
261
112
	if (fdct->divisors[qtblno] == NULL) {
262
	if (fdct->divisors[qtblno] == NULL) {
113
	  fdct->divisors[qtblno] = (DCTELEM *)
263
	  fdct->divisors[qtblno] = (DCTELEM *)
114
	    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
264
	    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
115
					DCTSIZE2 * SIZEOF(DCTELEM));
265
					(DCTSIZE2 * 4) * SIZEOF(DCTELEM));
116
	}
266
	}
117
	dtbl = fdct->divisors[qtblno];
267
	dtbl = fdct->divisors[qtblno];
118
	for (i = 0; i < DCTSIZE2; i++) {
268
	for (i = 0; i < DCTSIZE2; i++) {
119
	  dtbl[i] = (DCTELEM)
269
	  compute_reciprocal(
120
	    DESCALE(MULTIPLY16V16((INT32) qtbl->quantval[i],
270
	    DESCALE(MULTIPLY16V16((INT32) qtbl->quantval[i],
121
				  (INT32) aanscales[i]),
271
				  (INT32) aanscales[i]),
122
		    CONST_BITS-3);
272
		    CONST_BITS-3), &dtbl[i]);
123
	}
273
	}
124
      }
274
      }
125
      break;
275
      break;
126
#endif
276
#endif
127
#ifdef DCT_FLOAT_SUPPORTED
277
#ifdef DCT_FLOAT_SUPPORTED
128
    case JDCT_FLOAT:
278
    case JDCT_FLOAT:
129
      {
279
      {
130
	/* For float AA&N IDCT method, divisors are equal to quantization
280
	/* For float AA&N IDCT method, divisors are equal to quantization
 Lines 164-341   start_pass_fdctmgr (j_compress_ptr cinfo Link Here 
164
      ERREXIT(cinfo, JERR_NOT_COMPILED);
314
      ERREXIT(cinfo, JERR_NOT_COMPILED);
165
      break;
315
      break;
166
    }
316
    }
167
  }
317
  }
168
}
318
}
169
319
170
320
171
/*
321
/*
322
 * Load data into workspace, applying unsigned->signed conversion.
323
 */
324
325
METHODDEF(void)
326
convsamp (JSAMPARRAY sample_data, JDIMENSION start_col, DCTELEM * workspace)
327
{
328
  register DCTELEM *workspaceptr;
329
  register JSAMPROW elemptr;
330
  register int elemr;
331
332
  workspaceptr = workspace;
333
  for (elemr = 0; elemr < DCTSIZE; elemr++) {
334
    elemptr = sample_data[elemr] + start_col;
335
336
#if DCTSIZE == 8		/* unroll the inner loop */
337
    *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
338
    *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
339
    *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
340
    *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
341
    *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
342
    *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
343
    *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
344
    *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
345
#else
346
    {
347
      register int elemc;
348
      for (elemc = DCTSIZE; elemc > 0; elemc--)
349
        *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
350
    }
351
#endif
352
  }
353
}
354
355
356
/*
357
 * Quantize/descale the coefficients, and store into coef_blocks[].
358
 */
359
360
METHODDEF(void)
361
quantize (JCOEFPTR coef_block, DCTELEM * divisors, DCTELEM * workspace)
362
{
363
  int i;
364
  DCTELEM temp;
365
  UDCTELEM recip, corr, shift;
366
  UDCTELEM2 product;
367
  JCOEFPTR output_ptr = coef_block;
368
369
  for (i = 0; i < DCTSIZE2; i++) {
370
    temp = workspace[i];
371
    recip = divisors[i + DCTSIZE2 * 0];
372
    corr =  divisors[i + DCTSIZE2 * 1];
373
    shift = divisors[i + DCTSIZE2 * 3];
374
375
    if (temp < 0) {
376
      temp = -temp;
377
      product = (UDCTELEM2)(temp + corr) * recip;
378
      product >>= shift + sizeof(DCTELEM)*8;
379
      temp = product;
380
      temp = -temp;
381
    } else {
382
      product = (UDCTELEM2)(temp + corr) * recip;
383
      product >>= shift + sizeof(DCTELEM)*8;
384
      temp = product;
385
    }
386
387
    output_ptr[i] = (JCOEF) temp;
388
  }
389
}
390
391
392
/*
172
 * Perform forward DCT on one or more blocks of a component.
393
 * Perform forward DCT on one or more blocks of a component.
173
 *
394
 *
174
 * The input samples are taken from the sample_data[] array starting at
395
 * The input samples are taken from the sample_data[] array starting at
175
 * position start_row/start_col, and moving to the right for any additional
396
 * position start_row/start_col, and moving to the right for any additional
176
 * blocks. The quantized coefficients are returned in coef_blocks[].
397
 * blocks. The quantized coefficients are returned in coef_blocks[].
177
 */
398
 */
178
399
179
METHODDEF(void)
400
METHODDEF(void)
180
forward_DCT (j_compress_ptr cinfo, jpeg_component_info * compptr,
401
forward_DCT (j_compress_ptr cinfo, jpeg_component_info * compptr,
181
	     JSAMPARRAY sample_data, JBLOCKROW coef_blocks,
402
	     JSAMPARRAY sample_data, JBLOCKROW coef_blocks,
182
	     JDIMENSION start_row, JDIMENSION start_col,
403
	     JDIMENSION start_row, JDIMENSION start_col,
183
	     JDIMENSION num_blocks)
404
	     JDIMENSION num_blocks)
184
/* This version is used for integer DCT implementations. */
405
/* This version is used for integer DCT implementations. */
185
{
406
{
186
  /* This routine is heavily used, so it's worth coding it tightly. */
407
  /* This routine is heavily used, so it's worth coding it tightly. */
187
  my_fdct_ptr fdct = (my_fdct_ptr) cinfo->fdct;
408
  my_fdct_ptr fdct = (my_fdct_ptr) cinfo->fdct;
188
  forward_DCT_method_ptr do_dct = fdct->do_dct;
189
  DCTELEM * divisors = fdct->divisors[compptr->quant_tbl_no];
409
  DCTELEM * divisors = fdct->divisors[compptr->quant_tbl_no];
190
  DCTELEM workspace[DCTSIZE2];	/* work area for FDCT subroutine */
410
  DCTELEM * workspace;
191
  JDIMENSION bi;
411
  JDIMENSION bi;
192
412
413
  /* Make sure the compiler doesn't look up these every pass */
414
  forward_DCT_method_ptr do_dct = fdct->dct;
415
  convsamp_method_ptr do_convsamp = fdct->convsamp;
416
  quantize_method_ptr do_quantize = fdct->quantize;
417
  workspace = fdct->workspace;
418
193
  sample_data += start_row;	/* fold in the vertical offset once */
419
  sample_data += start_row;	/* fold in the vertical offset once */
194
420
195
  for (bi = 0; bi < num_blocks; bi++, start_col += DCTSIZE) {
421
  for (bi = 0; bi < num_blocks; bi++, start_col += DCTSIZE) {
196
    /* Load data into workspace, applying unsigned->signed conversion */
422
    /* Load data into workspace, applying unsigned->signed conversion */
197
    { register DCTELEM *workspaceptr;
423
    (*do_convsamp) (sample_data, start_col, workspace);
198
      register JSAMPROW elemptr;
199
      register int elemr;
200
201
      workspaceptr = workspace;
202
      for (elemr = 0; elemr < DCTSIZE; elemr++) {
203
	elemptr = sample_data[elemr] + start_col;
204
#if DCTSIZE == 8		/* unroll the inner loop */
205
	*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
206
	*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
207
	*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
208
	*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
209
	*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
210
	*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
211
	*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
212
	*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
213
#else
214
	{ register int elemc;
215
	  for (elemc = DCTSIZE; elemc > 0; elemc--) {
216
	    *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
217
	  }
218
	}
219
#endif
220
      }
221
    }
222
424
223
    /* Perform the DCT */
425
    /* Perform the DCT */
224
    (*do_dct) (workspace);
426
    (*do_dct) (workspace);
225
427
226
    /* Quantize/descale the coefficients, and store into coef_blocks[] */
428
    /* Quantize/descale the coefficients, and store into coef_blocks[] */
227
    { register DCTELEM temp, qval;
429
    (*do_quantize) (coef_blocks[bi], divisors, workspace);
228
      register int i;
229
      register JCOEFPTR output_ptr = coef_blocks[bi];
230
231
      for (i = 0; i < DCTSIZE2; i++) {
232
	qval = divisors[i];
233
	temp = workspace[i];
234
	/* Divide the coefficient value by qval, ensuring proper rounding.
235
	 * Since C does not specify the direction of rounding for negative
236
	 * quotients, we have to force the dividend positive for portability.
237
	 *
238
	 * In most files, at least half of the output values will be zero
239
	 * (at default quantization settings, more like three-quarters...)
240
	 * so we should ensure that this case is fast.  On many machines,
241
	 * a comparison is enough cheaper than a divide to make a special test
242
	 * a win.  Since both inputs will be nonnegative, we need only test
243
	 * for a < b to discover whether a/b is 0.
244
	 * If your machine's division is fast enough, define FAST_DIVIDE.
245
	 */
246
#ifdef FAST_DIVIDE
247
#define DIVIDE_BY(a,b)	a /= b
248
#else
249
#define DIVIDE_BY(a,b)	if (a >= b) a /= b; else a = 0
250
#endif
251
	if (temp < 0) {
252
	  temp = -temp;
253
	  temp += qval>>1;	/* for rounding */
254
	  DIVIDE_BY(temp, qval);
255
	  temp = -temp;
256
	} else {
257
	  temp += qval>>1;	/* for rounding */
258
	  DIVIDE_BY(temp, qval);
259
	}
260
	output_ptr[i] = (JCOEF) temp;
261
      }
262
    }
263
  }
430
  }
264
}
431
}
265
432
266
433
267
#ifdef DCT_FLOAT_SUPPORTED
434
#ifdef DCT_FLOAT_SUPPORTED
268
435
436
437
METHODDEF(void)
438
convsamp_float (JSAMPARRAY sample_data, JDIMENSION start_col, FAST_FLOAT * workspace)
439
{
440
  register FAST_FLOAT *workspaceptr;
441
  register JSAMPROW elemptr;
442
  register int elemr;
443
444
  workspaceptr = workspace;
445
  for (elemr = 0; elemr < DCTSIZE; elemr++) {
446
    elemptr = sample_data[elemr] + start_col;
447
#if DCTSIZE == 8		/* unroll the inner loop */
448
    *workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
449
    *workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
450
    *workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
451
    *workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
452
    *workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
453
    *workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
454
    *workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
455
    *workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
456
#else
457
    {
458
      register int elemc;
459
      for (elemc = DCTSIZE; elemc > 0; elemc--)
460
        *workspaceptr++ = (FAST_FLOAT)
461
                          (GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
462
    }
463
#endif
464
  }
465
}
466
467
468
METHODDEF(void)
469
quantize_float (JCOEFPTR coef_block, FAST_FLOAT * divisors, FAST_FLOAT * workspace)
470
{
471
  register FAST_FLOAT temp;
472
  register int i;
473
  register JCOEFPTR output_ptr = coef_block;
474
475
  for (i = 0; i < DCTSIZE2; i++) {
476
    /* Apply the quantization and scaling factor */
477
    temp = workspace[i] * divisors[i];
478
479
    /* Round to nearest integer.
480
     * Since C does not specify the direction of rounding for negative
481
     * quotients, we have to force the dividend positive for portability.
482
     * The maximum coefficient size is +-16K (for 12-bit data), so this
483
     * code should work for either 16-bit or 32-bit ints.
484
     */
485
    output_ptr[i] = (JCOEF) ((int) (temp + (FAST_FLOAT) 16384.5) - 16384);
486
  }
487
}
488
489
269
METHODDEF(void)
490
METHODDEF(void)
270
forward_DCT_float (j_compress_ptr cinfo, jpeg_component_info * compptr,
491
forward_DCT_float (j_compress_ptr cinfo, jpeg_component_info * compptr,
271
		   JSAMPARRAY sample_data, JBLOCKROW coef_blocks,
492
		   JSAMPARRAY sample_data, JBLOCKROW coef_blocks,
272
		   JDIMENSION start_row, JDIMENSION start_col,
493
		   JDIMENSION start_row, JDIMENSION start_col,
273
		   JDIMENSION num_blocks)
494
		   JDIMENSION num_blocks)
274
/* This version is used for floating-point DCT implementations. */
495
/* This version is used for floating-point DCT implementations. */
275
{
496
{
276
  /* This routine is heavily used, so it's worth coding it tightly. */
497
  /* This routine is heavily used, so it's worth coding it tightly. */
277
  my_fdct_ptr fdct = (my_fdct_ptr) cinfo->fdct;
498
  my_fdct_ptr fdct = (my_fdct_ptr) cinfo->fdct;
278
  float_DCT_method_ptr do_dct = fdct->do_float_dct;
279
  FAST_FLOAT * divisors = fdct->float_divisors[compptr->quant_tbl_no];
499
  FAST_FLOAT * divisors = fdct->float_divisors[compptr->quant_tbl_no];
280
  FAST_FLOAT workspace[DCTSIZE2]; /* work area for FDCT subroutine */
500
  FAST_FLOAT * workspace;
281
  JDIMENSION bi;
501
  JDIMENSION bi;
282
502
503
504
  /* Make sure the compiler doesn't look up these every pass */
505
  float_DCT_method_ptr do_dct = fdct->float_dct;
506
  float_convsamp_method_ptr do_convsamp = fdct->float_convsamp;
507
  float_quantize_method_ptr do_quantize = fdct->float_quantize;
508
  workspace = fdct->float_workspace;
509
283
  sample_data += start_row;	/* fold in the vertical offset once */
510
  sample_data += start_row;	/* fold in the vertical offset once */
284
511
285
  for (bi = 0; bi < num_blocks; bi++, start_col += DCTSIZE) {
512
  for (bi = 0; bi < num_blocks; bi++, start_col += DCTSIZE) {
286
    /* Load data into workspace, applying unsigned->signed conversion */
513
    /* Load data into workspace, applying unsigned->signed conversion */
287
    { register FAST_FLOAT *workspaceptr;
514
    (*do_convsamp) (sample_data, start_col, workspace);
288
      register JSAMPROW elemptr;
289
      register int elemr;
290
291
      workspaceptr = workspace;
292
      for (elemr = 0; elemr < DCTSIZE; elemr++) {
293
	elemptr = sample_data[elemr] + start_col;
294
#if DCTSIZE == 8		/* unroll the inner loop */
295
	*workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
296
	*workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
297
	*workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
298
	*workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
299
	*workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
300
	*workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
301
	*workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
302
	*workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
303
#else
304
	{ register int elemc;
305
	  for (elemc = DCTSIZE; elemc > 0; elemc--) {
306
	    *workspaceptr++ = (FAST_FLOAT)
307
	      (GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
308
	  }
309
	}
310
#endif
311
      }
312
    }
313
515
314
    /* Perform the DCT */
516
    /* Perform the DCT */
315
    (*do_dct) (workspace);
517
    (*do_dct) (workspace);
316
518
317
    /* Quantize/descale the coefficients, and store into coef_blocks[] */
519
    /* Quantize/descale the coefficients, and store into coef_blocks[] */
318
    { register FAST_FLOAT temp;
520
    (*do_quantize) (coef_blocks[bi], divisors, workspace);
319
      register int i;
320
      register JCOEFPTR output_ptr = coef_blocks[bi];
321
322
      for (i = 0; i < DCTSIZE2; i++) {
323
	/* Apply the quantization and scaling factor */
324
	temp = workspace[i] * divisors[i];
325
	/* Round to nearest integer.
326
	 * Since C does not specify the direction of rounding for negative
327
	 * quotients, we have to force the dividend positive for portability.
328
	 * The maximum coefficient size is +-16K (for 12-bit data), so this
329
	 * code should work for either 16-bit or 32-bit ints.
330
	 */
331
	output_ptr[i] = (JCOEF) ((int) (temp + (FAST_FLOAT) 16384.5) - 16384);
332
      }
333
    }
334
  }
521
  }
335
}
522
}
336
523
337
#endif /* DCT_FLOAT_SUPPORTED */
524
#endif /* DCT_FLOAT_SUPPORTED */
338
525
339
526
340
/*
527
/*
341
 * Initialize FDCT manager.
528
 * Initialize FDCT manager.
 Lines 348-387   jinit_forward_dct (j_compress_ptr cinfo) Link Here 
348
  int i;
535
  int i;
349
536
350
  fdct = (my_fdct_ptr)
537
  fdct = (my_fdct_ptr)
351
    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
538
    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
352
				SIZEOF(my_fdct_controller));
539
				SIZEOF(my_fdct_controller));
353
  cinfo->fdct = (struct jpeg_forward_dct *) fdct;
540
  cinfo->fdct = (struct jpeg_forward_dct *) fdct;
354
  fdct->pub.start_pass = start_pass_fdctmgr;
541
  fdct->pub.start_pass = start_pass_fdctmgr;
355
542
543
  /* First determine the DCT... */
356
  switch (cinfo->dct_method) {
544
  switch (cinfo->dct_method) {
357
#ifdef DCT_ISLOW_SUPPORTED
545
#ifdef DCT_ISLOW_SUPPORTED
358
  case JDCT_ISLOW:
546
  case JDCT_ISLOW:
359
    fdct->pub.forward_DCT = forward_DCT;
547
    fdct->pub.forward_DCT = forward_DCT;
360
    fdct->do_dct = jpeg_fdct_islow;
548
    if (jsimd_can_fdct_islow())
549
      fdct->dct = jsimd_fdct_islow;
550
    else
551
      fdct->dct = jpeg_fdct_islow;
361
    break;
552
    break;
362
#endif
553
#endif
363
#ifdef DCT_IFAST_SUPPORTED
554
#ifdef DCT_IFAST_SUPPORTED
364
  case JDCT_IFAST:
555
  case JDCT_IFAST:
365
    fdct->pub.forward_DCT = forward_DCT;
556
    fdct->pub.forward_DCT = forward_DCT;
366
    fdct->do_dct = jpeg_fdct_ifast;
557
    if (jsimd_can_fdct_ifast())
558
      fdct->dct = jsimd_fdct_ifast;
559
    else
560
      fdct->dct = jpeg_fdct_ifast;
367
    break;
561
    break;
368
#endif
562
#endif
369
#ifdef DCT_FLOAT_SUPPORTED
563
#ifdef DCT_FLOAT_SUPPORTED
370
  case JDCT_FLOAT:
564
  case JDCT_FLOAT:
371
    fdct->pub.forward_DCT = forward_DCT_float;
565
    fdct->pub.forward_DCT = forward_DCT_float;
372
    fdct->do_float_dct = jpeg_fdct_float;
566
    if (jsimd_can_fdct_float())
567
      fdct->float_dct = jsimd_fdct_float;
568
    else
569
      fdct->float_dct = jpeg_fdct_float;
373
    break;
570
    break;
374
#endif
571
#endif
375
  default:
572
  default:
376
    ERREXIT(cinfo, JERR_NOT_COMPILED);
573
    ERREXIT(cinfo, JERR_NOT_COMPILED);
377
    break;
574
    break;
378
  }
575
  }
379
576
577
  /* ...then the supporting stages. */
578
  switch (cinfo->dct_method) {
579
#ifdef DCT_ISLOW_SUPPORTED
580
  case JDCT_ISLOW:
581
#endif
582
#ifdef DCT_IFAST_SUPPORTED
583
  case JDCT_IFAST:
584
#endif
585
#if defined(DCT_ISLOW_SUPPORTED) || defined(DCT_IFAST_SUPPORTED)
586
    if (jsimd_can_convsamp())
587
      fdct->convsamp = jsimd_convsamp;
588
    else
589
      fdct->convsamp = convsamp;
590
    if (jsimd_can_quantize())
591
      fdct->quantize = jsimd_quantize;
592
    else
593
      fdct->quantize = quantize;
594
    break;
595
#endif
596
#ifdef DCT_FLOAT_SUPPORTED
597
  case JDCT_FLOAT:
598
    if (jsimd_can_convsamp_float())
599
      fdct->float_convsamp = jsimd_convsamp_float;
600
    else
601
      fdct->float_convsamp = convsamp_float;
602
    if (jsimd_can_quantize_float())
603
      fdct->float_quantize = jsimd_quantize_float;
604
    else
605
      fdct->float_quantize = quantize_float;
606
    break;
607
#endif
608
  default:
609
    ERREXIT(cinfo, JERR_NOT_COMPILED);
610
    break;
611
  }
612
613
  /* Allocate workspace memory */
614
#ifdef DCT_FLOAT_SUPPORTED
615
  if (cinfo->dct_method == JDCT_FLOAT)
616
    fdct->float_workspace = (FAST_FLOAT *)
617
      (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
618
				  SIZEOF(FAST_FLOAT) * DCTSIZE2);
619
  else
620
#endif
621
    fdct->workspace = (DCTELEM *)
622
      (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
623
				  SIZEOF(DCTELEM) * DCTSIZE2);
624
380
  /* Mark divisor tables unallocated */
625
  /* Mark divisor tables unallocated */
381
  for (i = 0; i < NUM_QUANT_TBLS; i++) {
626
  for (i = 0; i < NUM_QUANT_TBLS; i++) {
382
    fdct->divisors[i] = NULL;
627
    fdct->divisors[i] = NULL;
383
#ifdef DCT_FLOAT_SUPPORTED
628
#ifdef DCT_FLOAT_SUPPORTED
384
    fdct->float_divisors[i] = NULL;
629
    fdct->float_divisors[i] = NULL;
385
#endif
630
#endif
386
  }
631
  }
387
}
632
}
(-)a/jpeg/jchuff.c (+3 lines)
Line     Link Here 
 Lines 14-29    Link Here 
14
 * permanent JPEG objects only upon successful completion of an MCU.
14
 * permanent JPEG objects only upon successful completion of an MCU.
15
 */
15
 */
16
16
17
#define JPEG_INTERNALS
17
#define JPEG_INTERNALS
18
#include "jinclude.h"
18
#include "jinclude.h"
19
#include "jpeglib.h"
19
#include "jpeglib.h"
20
#include "jchuff.h"		/* Declarations shared with jcphuff.c */
20
#include "jchuff.h"		/* Declarations shared with jcphuff.c */
21
21
22
/* MOZILLA CHANGE: libjpeg-turbo doesn't define INLINE in its config file, so
23
 * we define it here. */
24
#define INLINE
22
25
23
/* Expanded entropy encoder object for Huffman encoding.
26
/* Expanded entropy encoder object for Huffman encoding.
24
 *
27
 *
25
 * The savable_state subrecord contains fields that change within an MCU,
28
 * The savable_state subrecord contains fields that change within an MCU,
26
 * but must not be updated permanently until we complete the MCU.
29
 * but must not be updated permanently until we complete the MCU.
27
 */
30
 */
28
31
29
typedef struct {
32
typedef struct {
(-)a/jpeg/jcmarker.c (-25 / +27 lines)
Line     Link Here 
 Lines 70-86   typedef enum { /* JPEG marker codes */ Link Here 
70
  M_APP13 = 0xed,
70
  M_APP13 = 0xed,
71
  M_APP14 = 0xee,
71
  M_APP14 = 0xee,
72
  M_APP15 = 0xef,
72
  M_APP15 = 0xef,
73
  
73
  
74
  M_JPG0  = 0xf0,
74
  M_JPG0  = 0xf0,
75
  M_JPG13 = 0xfd,
75
  M_JPG13 = 0xfd,
76
  M_COM   = 0xfe,
76
  M_COM   = 0xfe,
77
  
77
  
78
  M_TEM   = 0x01
78
  M_TEM   = 0x01,
79
  
80
  M_ERROR = 0x100
79
} JPEG_MARKER;
81
} JPEG_MARKER;
80
82
81
83
82
/* Private state */
84
/* Private state */
83
85
84
typedef struct {
86
typedef struct {
85
  struct jpeg_marker_writer pub; /* public fields */
87
  struct jpeg_marker_writer pub; /* public fields */
86
88
 Lines 98-114   typedef my_marker_writer * my_marker_ptr Link Here 
98
 * enough buffer space for the initial markers (typ. 600-700 bytes) before
100
 * enough buffer space for the initial markers (typ. 600-700 bytes) before
99
 * calling jpeg_start_compress, and enough space to write the trailing EOI
101
 * calling jpeg_start_compress, and enough space to write the trailing EOI
100
 * (a few bytes) before calling jpeg_finish_compress.  Multipass compression
102
 * (a few bytes) before calling jpeg_finish_compress.  Multipass compression
101
 * modes are not supported at all with suspension, so those two are the only
103
 * modes are not supported at all with suspension, so those two are the only
102
 * points where markers will be written.
104
 * points where markers will be written.
103
 */
105
 */
104
106
105
LOCAL(void)
107
LOCAL(void)
106
emit_byte (j_compress_ptr cinfo, int16 val)
108
emit_byte (j_compress_ptr cinfo, int val)
107
/* Emit a byte */
109
/* Emit a byte */
108
{
110
{
109
  struct jpeg_destination_mgr * dest = cinfo->dest;
111
  struct jpeg_destination_mgr * dest = cinfo->dest;
110
112
111
  *(dest->next_output_byte)++ = (JOCTET) val;
113
  *(dest->next_output_byte)++ = (JOCTET) val;
112
  if (--dest->free_in_buffer == 0) {
114
  if (--dest->free_in_buffer == 0) {
113
    if (! (*dest->empty_output_buffer) (cinfo))
115
    if (! (*dest->empty_output_buffer) (cinfo))
114
      ERREXIT(cinfo, JERR_CANT_SUSPEND);
116
      ERREXIT(cinfo, JERR_CANT_SUSPEND);
 Lines 116-156   emit_byte (j_compress_ptr cinfo, int16 v Link Here 
116
}
118
}
117
119
118
120
119
LOCAL(void)
121
LOCAL(void)
120
emit_marker (j_compress_ptr cinfo, JPEG_MARKER mark)
122
emit_marker (j_compress_ptr cinfo, JPEG_MARKER mark)
121
/* Emit a marker code */
123
/* Emit a marker code */
122
{
124
{
123
  emit_byte(cinfo, 0xFF);
125
  emit_byte(cinfo, 0xFF);
124
  emit_byte(cinfo, (int16) mark);
126
  emit_byte(cinfo, (int) mark);
125
}
127
}
126
128
127
129
128
LOCAL(void)
130
LOCAL(void)
129
emit_2bytes (j_compress_ptr cinfo, int16 value)
131
emit_2bytes (j_compress_ptr cinfo, int value)
130
/* Emit a 2-byte integer; these are always MSB first in JPEG files */
132
/* Emit a 2-byte integer; these are always MSB first in JPEG files */
131
{
133
{
132
  emit_byte(cinfo, (value >> 8) & 0xFF);
134
  emit_byte(cinfo, (value >> 8) & 0xFF);
133
  emit_byte(cinfo, value & 0xFF);
135
  emit_byte(cinfo, value & 0xFF);
134
}
136
}
135
137
136
138
137
/*
139
/*
138
 * Routines to write specific marker types.
140
 * Routines to write specific marker types.
139
 */
141
 */
140
142
141
LOCAL(int16)
143
LOCAL(int)
142
emit_dqt (j_compress_ptr cinfo, int16 index)
144
emit_dqt (j_compress_ptr cinfo, int index)
143
/* Emit a DQT marker */
145
/* Emit a DQT marker */
144
/* Returns the precision used (0 = 8bits, 1 = 16bits) for baseline checking */
146
/* Returns the precision used (0 = 8bits, 1 = 16bits) for baseline checking */
145
{
147
{
146
  JQUANT_TBL * qtbl = cinfo->quant_tbl_ptrs[index];
148
  JQUANT_TBL * qtbl = cinfo->quant_tbl_ptrs[index];
147
  int16 prec;
149
  int prec;
148
  int16 i;
150
  int i;
149
151
150
  if (qtbl == NULL)
152
  if (qtbl == NULL)
151
    ERREXIT1(cinfo, JERR_NO_QUANT_TABLE, index);
153
    ERREXIT1(cinfo, JERR_NO_QUANT_TABLE, index);
152
154
153
  prec = 0;
155
  prec = 0;
154
  for (i = 0; i < DCTSIZE2; i++) {
156
  for (i = 0; i < DCTSIZE2; i++) {
155
    if (qtbl->quantval[i] > 255)
157
    if (qtbl->quantval[i] > 255)
156
      prec = 1;
158
      prec = 1;
 Lines 162-194   emit_dqt (j_compress_ptr cinfo, int16 in Link Here 
162
    emit_2bytes(cinfo, prec ? DCTSIZE2*2 + 1 + 2 : DCTSIZE2 + 1 + 2);
164
    emit_2bytes(cinfo, prec ? DCTSIZE2*2 + 1 + 2 : DCTSIZE2 + 1 + 2);
163
165
164
    emit_byte(cinfo, index + (prec<<4));
166
    emit_byte(cinfo, index + (prec<<4));
165
167
166
    for (i = 0; i < DCTSIZE2; i++) {
168
    for (i = 0; i < DCTSIZE2; i++) {
167
      /* The table entries must be emitted in zigzag order. */
169
      /* The table entries must be emitted in zigzag order. */
168
      unsigned int qval = qtbl->quantval[jpeg_natural_order[i]];
170
      unsigned int qval = qtbl->quantval[jpeg_natural_order[i]];
169
      if (prec)
171
      if (prec)
170
	emit_byte(cinfo, (int16) (qval >> 8));
172
	emit_byte(cinfo, (int) (qval >> 8));
171
      emit_byte(cinfo, (int16) (qval & 0xFF));
173
      emit_byte(cinfo, (int) (qval & 0xFF));
172
    }
174
    }
173
175
174
    qtbl->sent_table = TRUE;
176
    qtbl->sent_table = TRUE;
175
  }
177
  }
176
178
177
  return prec;
179
  return prec;
178
}
180
}
179
181
180
182
181
LOCAL(void)
183
LOCAL(void)
182
emit_dht (j_compress_ptr cinfo, int16 index, boolean is_ac)
184
emit_dht (j_compress_ptr cinfo, int index, boolean is_ac)
183
/* Emit a DHT marker */
185
/* Emit a DHT marker */
184
{
186
{
185
  JHUFF_TBL * htbl;
187
  JHUFF_TBL * htbl;
186
  int16 length, i;
188
  int length, i;
187
  
189
  
188
  if (is_ac) {
190
  if (is_ac) {
189
    htbl = cinfo->ac_huff_tbl_ptrs[index];
191
    htbl = cinfo->ac_huff_tbl_ptrs[index];
190
    index += 0x10;		/* output index has AC bit set */
192
    index += 0x10;		/* output index has AC bit set */
191
  } else {
193
  } else {
192
    htbl = cinfo->dc_huff_tbl_ptrs[index];
194
    htbl = cinfo->dc_huff_tbl_ptrs[index];
193
  }
195
  }
194
196
 Lines 220-236   LOCAL(void) Link Here 
220
emit_dac (j_compress_ptr cinfo)
222
emit_dac (j_compress_ptr cinfo)
221
/* Emit a DAC marker */
223
/* Emit a DAC marker */
222
/* Since the useful info is so small, we want to emit all the tables in */
224
/* Since the useful info is so small, we want to emit all the tables in */
223
/* one DAC marker.  Therefore this routine does its own scan of the table. */
225
/* one DAC marker.  Therefore this routine does its own scan of the table. */
224
{
226
{
225
#ifdef C_ARITH_CODING_SUPPORTED
227
#ifdef C_ARITH_CODING_SUPPORTED
226
  char dc_in_use[NUM_ARITH_TBLS];
228
  char dc_in_use[NUM_ARITH_TBLS];
227
  char ac_in_use[NUM_ARITH_TBLS];
229
  char ac_in_use[NUM_ARITH_TBLS];
228
  int16 length, i;
230
  int length, i;
229
  jpeg_component_info *compptr;
231
  jpeg_component_info *compptr;
230
  
232
  
231
  for (i = 0; i < NUM_ARITH_TBLS; i++)
233
  for (i = 0; i < NUM_ARITH_TBLS; i++)
232
    dc_in_use[i] = ac_in_use[i] = 0;
234
    dc_in_use[i] = ac_in_use[i] = 0;
233
  
235
  
234
  for (i = 0; i < cinfo->comps_in_scan; i++) {
236
  for (i = 0; i < cinfo->comps_in_scan; i++) {
235
    compptr = cinfo->cur_comp_info[i];
237
    compptr = cinfo->cur_comp_info[i];
236
    dc_in_use[compptr->dc_tbl_no] = 1;
238
    dc_in_use[compptr->dc_tbl_no] = 1;
 Lines 262-317   emit_dac (j_compress_ptr cinfo) Link Here 
262
LOCAL(void)
264
LOCAL(void)
263
emit_dri (j_compress_ptr cinfo)
265
emit_dri (j_compress_ptr cinfo)
264
/* Emit a DRI marker */
266
/* Emit a DRI marker */
265
{
267
{
266
  emit_marker(cinfo, M_DRI);
268
  emit_marker(cinfo, M_DRI);
267
  
269
  
268
  emit_2bytes(cinfo, 4);	/* fixed length */
270
  emit_2bytes(cinfo, 4);	/* fixed length */
269
271
270
  emit_2bytes(cinfo, (int16) cinfo->restart_interval);
272
  emit_2bytes(cinfo, (int) cinfo->restart_interval);
271
}
273
}
272
274
273
275
274
LOCAL(void)
276
LOCAL(void)
275
emit_sof (j_compress_ptr cinfo, JPEG_MARKER code)
277
emit_sof (j_compress_ptr cinfo, JPEG_MARKER code)
276
/* Emit a SOF marker */
278
/* Emit a SOF marker */
277
{
279
{
278
  int16 ci;
280
  int ci;
279
  jpeg_component_info *compptr;
281
  jpeg_component_info *compptr;
280
  
282
  
281
  emit_marker(cinfo, code);
283
  emit_marker(cinfo, code);
282
  
284
  
283
  emit_2bytes(cinfo, 3 * cinfo->num_components + 2 + 5 + 1); /* length */
285
  emit_2bytes(cinfo, 3 * cinfo->num_components + 2 + 5 + 1); /* length */
284
286
285
  /* Make sure image isn't bigger than SOF field can handle */
287
  /* Make sure image isn't bigger than SOF field can handle */
286
  if ((long) cinfo->image_height > 65535L ||
288
  if ((long) cinfo->image_height > 65535L ||
287
      (long) cinfo->image_width > 65535L)
289
      (long) cinfo->image_width > 65535L)
288
    ERREXIT1(cinfo, JERR_IMAGE_TOO_BIG, (unsigned int) 65535);
290
    ERREXIT1(cinfo, JERR_IMAGE_TOO_BIG, (unsigned int) 65535);
289
291
290
  emit_byte(cinfo, cinfo->data_precision);
292
  emit_byte(cinfo, cinfo->data_precision);
291
  emit_2bytes(cinfo, (int16) cinfo->image_height);
293
  emit_2bytes(cinfo, (int) cinfo->image_height);
292
  emit_2bytes(cinfo, (int16) cinfo->image_width);
294
  emit_2bytes(cinfo, (int) cinfo->image_width);
293
295
294
  emit_byte(cinfo, cinfo->num_components);
296
  emit_byte(cinfo, cinfo->num_components);
295
297
296
  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
298
  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
297
       ci++, compptr++) {
299
       ci++, compptr++) {
298
    emit_byte(cinfo, compptr->component_id);
300
    emit_byte(cinfo, compptr->component_id);
299
    emit_byte(cinfo, (compptr->h_samp_factor << 4) + compptr->v_samp_factor);
301
    emit_byte(cinfo, (compptr->h_samp_factor << 4) + compptr->v_samp_factor);
300
    emit_byte(cinfo, compptr->quant_tbl_no);
302
    emit_byte(cinfo, compptr->quant_tbl_no);
301
  }
303
  }
302
}
304
}
303
305
304
306
305
LOCAL(void)
307
LOCAL(void)
306
emit_sos (j_compress_ptr cinfo)
308
emit_sos (j_compress_ptr cinfo)
307
/* Emit a SOS marker */
309
/* Emit a SOS marker */
308
{
310
{
309
  int16 i, td, ta;
311
  int i, td, ta;
310
  jpeg_component_info *compptr;
312
  jpeg_component_info *compptr;
311
  
313
  
312
  emit_marker(cinfo, M_SOS);
314
  emit_marker(cinfo, M_SOS);
313
  
315
  
314
  emit_2bytes(cinfo, 2 * cinfo->comps_in_scan + 2 + 1 + 3); /* length */
316
  emit_2bytes(cinfo, 2 * cinfo->comps_in_scan + 2 + 1 + 3); /* length */
315
  
317
  
316
  emit_byte(cinfo, cinfo->comps_in_scan);
318
  emit_byte(cinfo, cinfo->comps_in_scan);
317
  
319
  
 Lines 366-383   emit_jfif_app0 (j_compress_ptr cinfo) Link Here 
366
  emit_byte(cinfo, 0x4A);	/* Identifier: ASCII "JFIF" */
368
  emit_byte(cinfo, 0x4A);	/* Identifier: ASCII "JFIF" */
367
  emit_byte(cinfo, 0x46);
369
  emit_byte(cinfo, 0x46);
368
  emit_byte(cinfo, 0x49);
370
  emit_byte(cinfo, 0x49);
369
  emit_byte(cinfo, 0x46);
371
  emit_byte(cinfo, 0x46);
370
  emit_byte(cinfo, 0);
372
  emit_byte(cinfo, 0);
371
  emit_byte(cinfo, cinfo->JFIF_major_version); /* Version fields */
373
  emit_byte(cinfo, cinfo->JFIF_major_version); /* Version fields */
372
  emit_byte(cinfo, cinfo->JFIF_minor_version);
374
  emit_byte(cinfo, cinfo->JFIF_minor_version);
373
  emit_byte(cinfo, cinfo->density_unit); /* Pixel size information */
375
  emit_byte(cinfo, cinfo->density_unit); /* Pixel size information */
374
  emit_2bytes(cinfo, (int16) cinfo->X_density);
376
  emit_2bytes(cinfo, (int) cinfo->X_density);
375
  emit_2bytes(cinfo, (int16) cinfo->Y_density);
377
  emit_2bytes(cinfo, (int) cinfo->Y_density);
376
  emit_byte(cinfo, 0);		/* No thumbnail image */
378
  emit_byte(cinfo, 0);		/* No thumbnail image */
377
  emit_byte(cinfo, 0);
379
  emit_byte(cinfo, 0);
378
}
380
}
379
381
380
382
381
LOCAL(void)
383
LOCAL(void)
382
emit_adobe_app14 (j_compress_ptr cinfo)
384
emit_adobe_app14 (j_compress_ptr cinfo)
383
/* Emit an Adobe APP14 marker */
385
/* Emit an Adobe APP14 marker */
 Lines 436-459   METHODDEF(void) Link Here 
436
write_marker_header (j_compress_ptr cinfo, int marker, unsigned int datalen)
438
write_marker_header (j_compress_ptr cinfo, int marker, unsigned int datalen)
437
/* Emit an arbitrary marker header */
439
/* Emit an arbitrary marker header */
438
{
440
{
439
  if (datalen > (unsigned int) 65533)		/* safety check */
441
  if (datalen > (unsigned int) 65533)		/* safety check */
440
    ERREXIT(cinfo, JERR_BAD_LENGTH);
442
    ERREXIT(cinfo, JERR_BAD_LENGTH);
441
443
442
  emit_marker(cinfo, (JPEG_MARKER) marker);
444
  emit_marker(cinfo, (JPEG_MARKER) marker);
443
445
444
  emit_2bytes(cinfo, (int16) (datalen + 2));	/* total length */
446
  emit_2bytes(cinfo, (int) (datalen + 2));	/* total length */
445
}
447
}
446
448
447
METHODDEF(void)
449
METHODDEF(void)
448
write_marker_byte (j_compress_ptr cinfo, int val)
450
write_marker_byte (j_compress_ptr cinfo, int val)
449
/* Emit one byte of marker parameters following write_marker_header */
451
/* Emit one byte of marker parameters following write_marker_header */
450
{
452
{
451
  emit_byte(cinfo, (int16) val);
453
  emit_byte(cinfo, val);
452
}
454
}
453
455
454
456
455
/*
457
/*
456
 * Write datastream header.
458
 * Write datastream header.
457
 * This consists of an SOI and optional APPn markers.
459
 * This consists of an SOI and optional APPn markers.
458
 * We recommend use of the JFIF marker, but not the Adobe marker,
460
 * We recommend use of the JFIF marker, but not the Adobe marker,
459
 * when using YCbCr or grayscale data.  The JFIF marker should NOT
461
 * when using YCbCr or grayscale data.  The JFIF marker should NOT
 Lines 486-502   write_file_header (j_compress_ptr cinfo) Link Here 
486
 * Note that we do not emit the SOF until we have emitted the DQT(s).
488
 * Note that we do not emit the SOF until we have emitted the DQT(s).
487
 * This avoids compatibility problems with incorrect implementations that
489
 * This avoids compatibility problems with incorrect implementations that
488
 * try to error-check the quant table numbers as soon as they see the SOF.
490
 * try to error-check the quant table numbers as soon as they see the SOF.
489
 */
491
 */
490
492
491
METHODDEF(void)
493
METHODDEF(void)
492
write_frame_header (j_compress_ptr cinfo)
494
write_frame_header (j_compress_ptr cinfo)
493
{
495
{
494
  int16 ci, prec;
496
  int ci, prec;
495
  boolean is_baseline;
497
  boolean is_baseline;
496
  jpeg_component_info *compptr;
498
  jpeg_component_info *compptr;
497
  
499
  
498
  /* Emit DQT for each quantization table.
500
  /* Emit DQT for each quantization table.
499
   * Note that emit_dqt() suppresses any duplicate tables.
501
   * Note that emit_dqt() suppresses any duplicate tables.
500
   */
502
   */
501
  prec = 0;
503
  prec = 0;
502
  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
504
  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
 Lines 544-560   write_frame_header (j_compress_ptr cinfo Link Here 
544
 * This consists of DHT or DAC markers, optional DRI, and SOS.
546
 * This consists of DHT or DAC markers, optional DRI, and SOS.
545
 * Compressed data will be written following the SOS.
547
 * Compressed data will be written following the SOS.
546
 */
548
 */
547
549
548
METHODDEF(void)
550
METHODDEF(void)
549
write_scan_header (j_compress_ptr cinfo)
551
write_scan_header (j_compress_ptr cinfo)
550
{
552
{
551
  my_marker_ptr marker = (my_marker_ptr) cinfo->marker;
553
  my_marker_ptr marker = (my_marker_ptr) cinfo->marker;
552
  int16 i;
554
  int i;
553
  jpeg_component_info *compptr;
555
  jpeg_component_info *compptr;
554
556
555
  if (cinfo->arith_code) {
557
  if (cinfo->arith_code) {
556
    /* Emit arith conditioning info.  We may have some duplication
558
    /* Emit arith conditioning info.  We may have some duplication
557
     * if the file has multiple scans, but it's so small it's hardly
559
     * if the file has multiple scans, but it's so small it's hardly
558
     * worth worrying about.
560
     * worth worrying about.
559
     */
561
     */
560
    emit_dac(cinfo);
562
    emit_dac(cinfo);
 Lines 608-624   write_file_trailer (j_compress_ptr cinfo Link Here 
608
 * This consists of SOI, DQT and DHT tables, and EOI.
610
 * This consists of SOI, DQT and DHT tables, and EOI.
609
 * Any table that is defined and not marked sent_table = TRUE will be
611
 * Any table that is defined and not marked sent_table = TRUE will be
610
 * emitted.  Note that all tables will be marked sent_table = TRUE at exit.
612
 * emitted.  Note that all tables will be marked sent_table = TRUE at exit.
611
 */
613
 */
612
614
613
METHODDEF(void)
615
METHODDEF(void)
614
write_tables_only (j_compress_ptr cinfo)
616
write_tables_only (j_compress_ptr cinfo)
615
{
617
{
616
  int16 i;
618
  int i;
617
619
618
  emit_marker(cinfo, M_SOI);
620
  emit_marker(cinfo, M_SOI);
619
621
620
  for (i = 0; i < NUM_QUANT_TBLS; i++) {
622
  for (i = 0; i < NUM_QUANT_TBLS; i++) {
621
    if (cinfo->quant_tbl_ptrs[i] != NULL)
623
    if (cinfo->quant_tbl_ptrs[i] != NULL)
622
      (void) emit_dqt(cinfo, i);
624
      (void) emit_dqt(cinfo, i);
623
  }
625
  }
624
626
(-)a/jpeg/jconfig-mac-cw.h (-43 lines)
Line     Link Here 
 Lines 1-43    Link Here 
1
/* jconfig.h --- generated by ckconfig.c */
2
/* see jconfig.doc for explanations */
3
4
#define ALIGN_TYPE long /* memory alignment */
5
#define NO_GETENV /* we do have the function, but it's dead */
6
#ifdef __cplusplus
7
#define INLINE inline /* we have them in C++ */
8
#endif
9
10
#define HAVE_PROTOTYPES
11
#define HAVE_UNSIGNED_CHAR
12
#define HAVE_UNSIGNED_SHORT
13
/* #define void char */
14
/* #define const */
15
#undef CHAR_IS_UNSIGNED
16
#define HAVE_STDDEF_H
17
#define HAVE_STDLIB_H
18
#undef NEED_BSD_STRINGS
19
#undef NEED_SYS_TYPES_H
20
#undef NEED_FAR_POINTERS
21
#undef NEED_SHORT_EXTERNAL_NAMES
22
#undef INCOMPLETE_TYPES_BROKEN
23
24
#ifdef JPEG_INTERNALS
25
26
#undef RIGHT_SHIFT_IS_UNSIGNED
27
28
#endif /* JPEG_INTERNALS */
29
30
#ifdef JPEG_CJPEG_DJPEG
31
32
#define BMP_SUPPORTED		/* BMP image file format */
33
#define GIF_SUPPORTED		/* GIF image file format */
34
#define PPM_SUPPORTED		/* PBMPLUS PPM/PGM image file format */
35
#undef RLE_SUPPORTED		/* Utah RLE image file format */
36
#define TARGA_SUPPORTED		/* Targa image file format */
37
38
#undef TWO_FILE_COMMANDLINE	/* You may need this on non-Unix systems */
39
#undef NEED_SIGNAL_CATCHER	/* Define this if you use jmemname.c */
40
#undef DONT_USE_B_MODE
41
/* #define PROGRESS_REPORT */	/* optional */
42
43
#endif /* JPEG_CJPEG_DJPEG */
(-)a/jpeg/jconfig.h (-93 / +36 lines)
Line     Link Here 
 Lines 1-107    Link Here 
1
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
1
/* jconfig.h.  Generated from jconfig.h.in by configure.  */
2
/* ***** BEGIN LICENSE BLOCK *****
2
/* Define if your compiler supports prototypes */
3
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
3
#define HAVE_PROTOTYPES 1
4
 *
5
 * The contents of this file are subject to the Mozilla Public License Version
6
 * 1.1 (the "License"); you may not use this file except in compliance with
7
 * the License. You may obtain a copy of the License at
8
 * http://www.mozilla.org/MPL/
9
 *
10
 * Software distributed under the License is distributed on an "AS IS" basis,
11
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12
 * for the specific language governing rights and limitations under the
13
 * License.
14
 *
15
 * The Original Code is mozilla.org code.
16
 *
17
 * The Initial Developer of the Original Code is
18
 * Netscape Communications Corporation.
19
 * Portions created by the Initial Developer are Copyright (C) 1998
20
 * the Initial Developer. All Rights Reserved.
21
 *
22
 * Contributor(s):
23
 *
24
 * Alternatively, the contents of this file may be used under the terms of
25
 * either the GNU General Public License Version 2 or later (the "GPL"), or
26
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27
 * in which case the provisions of the GPL or the LGPL are applicable instead
28
 * of those above. If you wish to allow use of your version of this file only
29
 * under the terms of either the GPL or the LGPL, and not to allow others to
30
 * use your version of this file under the terms of the MPL, indicate your
31
 * decision by deleting the provisions above and replace them with the notice
32
 * and other provisions required by the GPL or the LGPL. If you do not delete
33
 * the provisions above, a recipient may use your version of this file under
34
 * the terms of any one of the MPL, the GPL or the LGPL.
35
 *
36
 * ***** END LICENSE BLOCK ***** */
37
4
38
/*
5
/* Define to 1 if you have the <stddef.h> header file. */
39
 * jconfig.h to configure the IJG JPEG library for the Mozilla/Netscape
6
#define HAVE_STDDEF_H 1
40
 * environment.  Note that there are also Mozilla mods in jmorecfg.h.
41
 */
42
7
43
/* We assume an ANSI C or C++ compilation environment */
8
/* Define to 1 if you have the <stdlib.h> header file. */
44
#define HAVE_PROTOTYPES 
9
#define HAVE_STDLIB_H 1
45
#define HAVE_UNSIGNED_CHAR 
46
#define HAVE_UNSIGNED_SHORT 
47
/* #define void char */
48
/* #define const */
49
#ifndef HAVE_STDDEF_H 
50
#define HAVE_STDDEF_H 
51
#endif /* HAVE_STDDEF_H */
52
#ifndef HAVE_STDLIB_H
53
#define HAVE_STDLIB_H 
54
#endif /* HAVE_STDLIB_H */
55
#undef NEED_BSD_STRINGS
56
#undef NEED_SYS_TYPES_H
57
#undef NEED_FAR_POINTERS
58
#undef NEED_SHORT_EXTERNAL_NAMES
59
/* Define this if you get warnings about undefined structures. */
60
#undef INCOMPLETE_TYPES_BROKEN
61
10
62
/* With this setting, the IJG code will work regardless of whether
11
/* Define to 1 if the system has the type `unsigned char'. */
63
 * type "char" is signed or unsigned.
12
#define HAVE_UNSIGNED_CHAR 1
64
 */
65
#undef CHAR_IS_UNSIGNED
66
13
14
/* Define to 1 if the system has the type `unsigned short'. */
15
#define HAVE_UNSIGNED_SHORT 1
67
16
68
/* defines that need not be visible to callers of the IJG library */
17
/* Define if you want use complete types */
18
/* #define INCOMPLETE_TYPES_BROKEN 1 */
69
19
70
#ifdef JPEG_INTERNALS
20
/* Define if you have BSD-like bzero and bcopy */
21
/* #undef NEED_BSD_STRINGS */
71
22
72
/* If right shift of "long" quantities is unsigned on your machine,
23
/* Define if you need short function names */
73
 * you'll have to define this.  Fortunately few people should need it.
24
/* #undef NEED_SHORT_EXTERNAL_NAMES */
74
 */
75
#undef RIGHT_SHIFT_IS_UNSIGNED
76
25
77
#endif /* JPEG_INTERNALS */
26
/* Define if you have sys/types.h */
27
#define NEED_SYS_TYPES_H 1
78
28
29
/* Define if shift is unsigned */
30
/* #undef RIGHT_SHIFT_IS_UNSIGNED */
79
31
80
/* these defines are not interesting for building just the IJG library,
32
/* Use accelerated SIMD routines. */
81
 * but we leave 'em here anyway.
33
#define WITH_SIMD 1
82
 */
83
#ifdef JPEG_CJPEG_DJPEG
84
34
85
#define BMP_SUPPORTED		/* BMP image file format */
35
/* Define to 1 if type `char' is unsigned and you are not using gcc.  */
86
#define GIF_SUPPORTED		/* GIF image file format */
36
#ifndef __CHAR_UNSIGNED__
87
#define PPM_SUPPORTED		/* PBMPLUS PPM/PGM image file format */
37
/* # undef __CHAR_UNSIGNED__ */
88
#undef RLE_SUPPORTED		/* Utah RLE image file format */
38
#endif
89
#define TARGA_SUPPORTED		/* Targa image file format */
90
39
91
#undef TWO_FILE_COMMANDLINE
40
/* Define to empty if `const' does not conform to ANSI C. */
92
#undef NEED_SIGNAL_CATCHER
41
/* #undef const */
93
#undef DONT_USE_B_MODE
94
#undef PROGRESS_REPORT
95
42
96
#endif /* JPEG_CJPEG_DJPEG */
43
/* Define to `__inline__' or `__inline' if that's what the C compiler
44
   calls it, or to nothing if 'inline' is not supported under any name.  */
45
#ifndef __cplusplus
46
/* #undef inline */
47
#endif
97
48
98
/* SSE* alignment support - only use on platforms that support declspec and __attribute__ */
49
/* Define to `unsigned int' if <sys/types.h> does not define. */
99
50
/* #undef size_t */
100
#if defined(XP_WIN32) && defined(_M_IX86) && !defined(__GNUC__)
101
#define ALIGN16_const_vector_short(name) __declspec(align(16)) const short name[8]
102
#define ALIGN16_const_vector_uchar(name) __declspec(align(16)) const unsigned char name[16]
103
#else
104
#define ALIGN16_const_vector_short(name) const short name[8] __attribute__ ((aligned (16)))
105
#define ALIGN16_const_vector_uchar(name) const unsigned char name[16] __attribute__ ((aligned (16)))
106
#endif /* ! XP_WIN32 && _M_IX86 && !__GNUC */
107
(-)a/jpeg/jconfig.h.in (+49 lines)
Line     Link Here 
Line 0    Link Here 
1
/* Define if your compiler supports prototypes */
2
#undef HAVE_PROTOTYPES
3
4
/* Define to 1 if you have the <stddef.h> header file. */
5
#undef HAVE_STDDEF_H
6
7
/* Define to 1 if you have the <stdlib.h> header file. */
8
#undef HAVE_STDLIB_H
9
10
/* Define to 1 if the system has the type `unsigned char'. */
11
#undef HAVE_UNSIGNED_CHAR
12
13
/* Define to 1 if the system has the type `unsigned short'. */
14
#undef HAVE_UNSIGNED_SHORT
15
16
/* Define if you want use complete types */
17
#undef INCOMPLETE_TYPES_BROKEN
18
19
/* Define if you have BSD-like bzero and bcopy */
20
#undef NEED_BSD_STRINGS
21
22
/* Define if you need short function names */
23
#undef NEED_SHORT_EXTERNAL_NAMES
24
25
/* Define if you have sys/types.h */
26
#undef NEED_SYS_TYPES_H
27
28
/* Define if shift is unsigned */
29
#undef RIGHT_SHIFT_IS_UNSIGNED
30
31
/* Use accelerated SIMD routines. */
32
#undef WITH_SIMD
33
34
/* Define to 1 if type `char' is unsigned and you are not using gcc.  */
35
#ifndef __CHAR_UNSIGNED__
36
# undef __CHAR_UNSIGNED__
37
#endif
38
39
/* Define to empty if `const' does not conform to ANSI C. */
40
#undef const
41
42
/* Define to `__inline__' or `__inline' if that's what the C compiler
43
   calls it, or to nothing if 'inline' is not supported under any name.  */
44
#ifndef __cplusplus
45
#undef inline
46
#endif
47
48
/* Define to `unsigned int' if <sys/types.h> does not define. */
49
#undef size_t
(-)a/jpeg/jconfig.wat (-38 lines)
Line     Link Here 
 Lines 1-38    Link Here 
1
/* jconfig.wat --- jconfig.h for Watcom C/C++ on MS-DOS or OS/2. */
2
/* see jconfig.doc for explanations */
3
4
#define HAVE_PROTOTYPES
5
#define HAVE_UNSIGNED_CHAR
6
#define HAVE_UNSIGNED_SHORT
7
/* #define void char */
8
/* #define const */
9
#define CHAR_IS_UNSIGNED
10
#define HAVE_STDDEF_H
11
#define HAVE_STDLIB_H
12
#undef NEED_BSD_STRINGS
13
#undef NEED_SYS_TYPES_H
14
#undef NEED_FAR_POINTERS	/* Watcom uses flat 32-bit addressing */
15
#undef NEED_SHORT_EXTERNAL_NAMES
16
#undef INCOMPLETE_TYPES_BROKEN
17
18
#ifdef JPEG_INTERNALS
19
20
#undef RIGHT_SHIFT_IS_UNSIGNED
21
22
#endif /* JPEG_INTERNALS */
23
24
#ifdef JPEG_CJPEG_DJPEG
25
26
#define BMP_SUPPORTED		/* BMP image file format */
27
#define GIF_SUPPORTED		/* GIF image file format */
28
#define PPM_SUPPORTED		/* PBMPLUS PPM/PGM image file format */
29
#undef RLE_SUPPORTED		/* Utah RLE image file format */
30
#define TARGA_SUPPORTED		/* Targa image file format */
31
32
#undef TWO_FILE_COMMANDLINE	/* optional */
33
#define USE_SETMODE		/* Needed to make one-file style work in Watcom */
34
#undef NEED_SIGNAL_CATCHER	/* Define this if you use jmemname.c */
35
#undef DONT_USE_B_MODE
36
#undef PROGRESS_REPORT		/* optional */
37
38
#endif /* JPEG_CJPEG_DJPEG */
(-)a/jpeg/jcparam.c (-2 / +9 lines)
Line     Link Here 
 Lines 1-12    Link Here 
1
/*
1
/*
2
 * jcparam.c
2
 * jcparam.c
3
 *
3
 *
4
 * Copyright (C) 1991-1998, Thomas G. Lane.
4
 * Copyright (C) 1991-1998, Thomas G. Lane.
5
 * Copyright (C) 2009, D. R. Commander.
5
 * This file is part of the Independent JPEG Group's software.
6
 * This file is part of the Independent JPEG Group's software.
6
 * For conditions of distribution and use, see the accompanying README file.
7
 * For conditions of distribution and use, see the accompanying README file.
7
 *
8
 *
8
 * This file contains optional default-setting code for the JPEG compressor.
9
 * This file contains optional default-setting code for the JPEG compressor.
9
 * Applications do not have to use this file, but those that don't use it
10
 * Applications do not have to use this file, but those that don't use it
10
 * must know a lot more about the innards of the JPEG code.
11
 * must know a lot more about the innards of the JPEG code.
11
 */
12
 */
12
13
 Lines 90-108   jpeg_set_linear_quality (j_compress_ptr Link Here 
90
    47,  66,  99,  99,  99,  99,  99,  99,
91
    47,  66,  99,  99,  99,  99,  99,  99,
91
    99,  99,  99,  99,  99,  99,  99,  99,
92
    99,  99,  99,  99,  99,  99,  99,  99,
92
    99,  99,  99,  99,  99,  99,  99,  99,
93
    99,  99,  99,  99,  99,  99,  99,  99,
93
    99,  99,  99,  99,  99,  99,  99,  99,
94
    99,  99,  99,  99,  99,  99,  99,  99,
94
    99,  99,  99,  99,  99,  99,  99,  99
95
    99,  99,  99,  99,  99,  99,  99,  99
95
  };
96
  };
96
97
97
  /* Set up two quantization tables using the specified scaling */
98
  /* Set up two quantization tables using the specified scaling */
98
  jpeg_add_quant_table(cinfo, 0, (const unsigned int *)std_luminance_quant_tbl,
99
  jpeg_add_quant_table(cinfo, 0, std_luminance_quant_tbl,
99
		       scale_factor, force_baseline);
100
		       scale_factor, force_baseline);
100
  jpeg_add_quant_table(cinfo, 1, (const unsigned int *)std_chrominance_quant_tbl,
101
  jpeg_add_quant_table(cinfo, 1, std_chrominance_quant_tbl,
101
		       scale_factor, force_baseline);
102
		       scale_factor, force_baseline);
102
}
103
}
103
104
104
105
105
GLOBAL(int)
106
GLOBAL(int)
106
jpeg_quality_scaling (int quality)
107
jpeg_quality_scaling (int quality)
107
/* Convert a user-specified quality rating to a percentage scaling factor
108
/* Convert a user-specified quality rating to a percentage scaling factor
108
 * for an underlying quantization table, using our recommended scaling curve.
109
 * for an underlying quantization table, using our recommended scaling curve.
 Lines 358-373   jpeg_set_defaults (j_compress_ptr cinfo) Link Here 
358
GLOBAL(void)
359
GLOBAL(void)
359
jpeg_default_colorspace (j_compress_ptr cinfo)
360
jpeg_default_colorspace (j_compress_ptr cinfo)
360
{
361
{
361
  switch (cinfo->in_color_space) {
362
  switch (cinfo->in_color_space) {
362
  case JCS_GRAYSCALE:
363
  case JCS_GRAYSCALE:
363
    jpeg_set_colorspace(cinfo, JCS_GRAYSCALE);
364
    jpeg_set_colorspace(cinfo, JCS_GRAYSCALE);
364
    break;
365
    break;
365
  case JCS_RGB:
366
  case JCS_RGB:
367
  case JCS_EXT_RGB:
368
  case JCS_EXT_RGBX:
369
  case JCS_EXT_BGR:
370
  case JCS_EXT_BGRX:
371
  case JCS_EXT_XBGR:
372
  case JCS_EXT_XRGB:
366
    jpeg_set_colorspace(cinfo, JCS_YCbCr);
373
    jpeg_set_colorspace(cinfo, JCS_YCbCr);
367
    break;
374
    break;
368
  case JCS_YCbCr:
375
  case JCS_YCbCr:
369
    jpeg_set_colorspace(cinfo, JCS_YCbCr);
376
    jpeg_set_colorspace(cinfo, JCS_YCbCr);
370
    break;
377
    break;
371
  case JCS_CMYK:
378
  case JCS_CMYK:
372
    jpeg_set_colorspace(cinfo, JCS_CMYK); /* By default, no translation */
379
    jpeg_set_colorspace(cinfo, JCS_CMYK); /* By default, no translation */
373
    break;
380
    break;
(-)a/jpeg/jcphuff.c (-2 lines)
Line     Link Here 
 Lines 218-234   dump_buffer (phuff_entropy_ptr entropy) Link Here 
218
/* Outputting bits to the file */
218
/* Outputting bits to the file */
219
219
220
/* Only the right 24 bits of put_buffer are used; the valid bits are
220
/* Only the right 24 bits of put_buffer are used; the valid bits are
221
 * left-justified in this part.  At most 16 bits can be passed to emit_bits
221
 * left-justified in this part.  At most 16 bits can be passed to emit_bits
222
 * in one call, and we never retain more than 7 bits in put_buffer
222
 * in one call, and we never retain more than 7 bits in put_buffer
223
 * between calls, so 24 bits are sufficient.
223
 * between calls, so 24 bits are sufficient.
224
 */
224
 */
225
225
226
INLINE
227
LOCAL(void)
226
LOCAL(void)
228
emit_bits (phuff_entropy_ptr entropy, unsigned int code, int size)
227
emit_bits (phuff_entropy_ptr entropy, unsigned int code, int size)
229
/* Emit some bits, unless we are in gather mode */
228
/* Emit some bits, unless we are in gather mode */
230
{
229
{
231
  /* This routine is heavily used, so it's worth coding tightly. */
230
  /* This routine is heavily used, so it's worth coding tightly. */
232
  register INT32 put_buffer = (INT32) code;
231
  register INT32 put_buffer = (INT32) code;
233
  register int put_bits = entropy->put_bits;
232
  register int put_bits = entropy->put_bits;
234
233
 Lines 271-287   flush_bits (phuff_entropy_ptr entropy) Link Here 
271
  entropy->put_bits = 0;
270
  entropy->put_bits = 0;
272
}
271
}
273
272
274
273
275
/*
274
/*
276
 * Emit (or just count) a Huffman symbol.
275
 * Emit (or just count) a Huffman symbol.
277
 */
276
 */
278
277
279
INLINE
280
LOCAL(void)
278
LOCAL(void)
281
emit_symbol (phuff_entropy_ptr entropy, int tbl_no, int symbol)
279
emit_symbol (phuff_entropy_ptr entropy, int tbl_no, int symbol)
282
{
280
{
283
  if (entropy->gather_statistics)
281
  if (entropy->gather_statistics)
284
    entropy->count_ptrs[tbl_no][symbol]++;
282
    entropy->count_ptrs[tbl_no][symbol]++;
285
  else {
283
  else {
286
    c_derived_tbl * tbl = entropy->derived_tbls[tbl_no];
284
    c_derived_tbl * tbl = entropy->derived_tbls[tbl_no];
287
    emit_bits(entropy, tbl->ehufco[symbol], tbl->ehufsi[symbol]);
285
    emit_bits(entropy, tbl->ehufco[symbol], tbl->ehufsi[symbol]);
(-)a/jpeg/jcsample.c (-2 / +10 lines)
Line     Link Here 
 Lines 1-12    Link Here 
1
/*
1
/*
2
 * jcsample.c
2
 * jcsample.c
3
 *
3
 *
4
 * Copyright (C) 1991-1996, Thomas G. Lane.
4
 * Copyright (C) 1991-1996, Thomas G. Lane.
5
 * Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
5
 * This file is part of the Independent JPEG Group's software.
6
 * This file is part of the Independent JPEG Group's software.
6
 * For conditions of distribution and use, see the accompanying README file.
7
 * For conditions of distribution and use, see the accompanying README file.
7
 *
8
 *
8
 * This file contains downsampling routines.
9
 * This file contains downsampling routines.
9
 *
10
 *
10
 * Downsampling input data is counted in "row groups".  A row group
11
 * Downsampling input data is counted in "row groups".  A row group
11
 * is defined to be max_v_samp_factor pixel rows of each component,
12
 * is defined to be max_v_samp_factor pixel rows of each component,
12
 * from which the downsampler produces v_samp_factor sample rows.
13
 * from which the downsampler produces v_samp_factor sample rows.
 Lines 43-58    Link Here 
43
 * eight neighbors.  P's weight is 1-8*SF and each neighbor's weight is SF,
44
 * eight neighbors.  P's weight is 1-8*SF and each neighbor's weight is SF,
44
 * where SF = (smoothing_factor / 1024).
45
 * where SF = (smoothing_factor / 1024).
45
 * Currently, smoothing is only supported for 2h2v sampling factors.
46
 * Currently, smoothing is only supported for 2h2v sampling factors.
46
 */
47
 */
47
48
48
#define JPEG_INTERNALS
49
#define JPEG_INTERNALS
49
#include "jinclude.h"
50
#include "jinclude.h"
50
#include "jpeglib.h"
51
#include "jpeglib.h"
52
#include "jsimd.h"
51
53
52
54
53
/* Pointer to routine to downsample a single component */
55
/* Pointer to routine to downsample a single component */
54
typedef JMETHOD(void, downsample1_ptr,
56
typedef JMETHOD(void, downsample1_ptr,
55
		(j_compress_ptr cinfo, jpeg_component_info * compptr,
57
		(j_compress_ptr cinfo, jpeg_component_info * compptr,
56
		 JSAMPARRAY input_data, JSAMPARRAY output_data));
58
		 JSAMPARRAY input_data, JSAMPARRAY output_data));
57
59
58
/* Private subobject */
60
/* Private subobject */
 Lines 489-514   jinit_downsampler (j_compress_ptr cinfo) Link Here 
489
	downsample->methods[ci] = fullsize_smooth_downsample;
491
	downsample->methods[ci] = fullsize_smooth_downsample;
490
	downsample->pub.need_context_rows = TRUE;
492
	downsample->pub.need_context_rows = TRUE;
491
      } else
493
      } else
492
#endif
494
#endif
493
	downsample->methods[ci] = fullsize_downsample;
495
	downsample->methods[ci] = fullsize_downsample;
494
    } else if (compptr->h_samp_factor * 2 == cinfo->max_h_samp_factor &&
496
    } else if (compptr->h_samp_factor * 2 == cinfo->max_h_samp_factor &&
495
	       compptr->v_samp_factor == cinfo->max_v_samp_factor) {
497
	       compptr->v_samp_factor == cinfo->max_v_samp_factor) {
496
      smoothok = FALSE;
498
      smoothok = FALSE;
497
      downsample->methods[ci] = h2v1_downsample;
499
      if (jsimd_can_h2v1_downsample())
500
        downsample->methods[ci] = jsimd_h2v1_downsample;
501
      else
502
        downsample->methods[ci] = h2v1_downsample;
498
    } else if (compptr->h_samp_factor * 2 == cinfo->max_h_samp_factor &&
503
    } else if (compptr->h_samp_factor * 2 == cinfo->max_h_samp_factor &&
499
	       compptr->v_samp_factor * 2 == cinfo->max_v_samp_factor) {
504
	       compptr->v_samp_factor * 2 == cinfo->max_v_samp_factor) {
500
#ifdef INPUT_SMOOTHING_SUPPORTED
505
#ifdef INPUT_SMOOTHING_SUPPORTED
501
      if (cinfo->smoothing_factor) {
506
      if (cinfo->smoothing_factor) {
502
	downsample->methods[ci] = h2v2_smooth_downsample;
507
	downsample->methods[ci] = h2v2_smooth_downsample;
503
	downsample->pub.need_context_rows = TRUE;
508
	downsample->pub.need_context_rows = TRUE;
504
      } else
509
      } else
505
#endif
510
#endif
506
	downsample->methods[ci] = h2v2_downsample;
511
	if (jsimd_can_h2v2_downsample())
512
	  downsample->methods[ci] = jsimd_h2v2_downsample;
513
	else
514
	  downsample->methods[ci] = h2v2_downsample;
507
    } else if ((cinfo->max_h_samp_factor % compptr->h_samp_factor) == 0 &&
515
    } else if ((cinfo->max_h_samp_factor % compptr->h_samp_factor) == 0 &&
508
	       (cinfo->max_v_samp_factor % compptr->v_samp_factor) == 0) {
516
	       (cinfo->max_v_samp_factor % compptr->v_samp_factor) == 0) {
509
      smoothok = FALSE;
517
      smoothok = FALSE;
510
      downsample->methods[ci] = int_downsample;
518
      downsample->methods[ci] = int_downsample;
511
    } else
519
    } else
512
      ERREXIT(cinfo, JERR_FRACT_SAMPLE_NOTIMPL);
520
      ERREXIT(cinfo, JERR_FRACT_SAMPLE_NOTIMPL);
513
  }
521
  }
514
522
(-)a/jpeg/jctrans.c (+388 lines)
Line     Link Here 
Line 0    Link Here 
1
/*
2
 * jctrans.c
3
 *
4
 * Copyright (C) 1995-1998, Thomas G. Lane.
5
 * This file is part of the Independent JPEG Group's software.
6
 * For conditions of distribution and use, see the accompanying README file.
7
 *
8
 * This file contains library routines for transcoding compression,
9
 * that is, writing raw DCT coefficient arrays to an output JPEG file.
10
 * The routines in jcapimin.c will also be needed by a transcoder.
11
 */
12
13
#define JPEG_INTERNALS
14
#include "jinclude.h"
15
#include "jpeglib.h"
16
17
18
/* Forward declarations */
19
LOCAL(void) transencode_master_selection
20
	JPP((j_compress_ptr cinfo, jvirt_barray_ptr * coef_arrays));
21
LOCAL(void) transencode_coef_controller
22
	JPP((j_compress_ptr cinfo, jvirt_barray_ptr * coef_arrays));
23
24
25
/*
26
 * Compression initialization for writing raw-coefficient data.
27
 * Before calling this, all parameters and a data destination must be set up.
28
 * Call jpeg_finish_compress() to actually write the data.
29
 *
30
 * The number of passed virtual arrays must match cinfo->num_components.
31
 * Note that the virtual arrays need not be filled or even realized at
32
 * the time write_coefficients is called; indeed, if the virtual arrays
33
 * were requested from this compression object's memory manager, they
34
 * typically will be realized during this routine and filled afterwards.
35
 */
36
37
GLOBAL(void)
38
jpeg_write_coefficients (j_compress_ptr cinfo, jvirt_barray_ptr * coef_arrays)
39
{
40
  if (cinfo->global_state != CSTATE_START)
41
    ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
42
  /* Mark all tables to be written */
43
  jpeg_suppress_tables(cinfo, FALSE);
44
  /* (Re)initialize error mgr and destination modules */
45
  (*cinfo->err->reset_error_mgr) ((j_common_ptr) cinfo);
46
  (*cinfo->dest->init_destination) (cinfo);
47
  /* Perform master selection of active modules */
48
  transencode_master_selection(cinfo, coef_arrays);
49
  /* Wait for jpeg_finish_compress() call */
50
  cinfo->next_scanline = 0;	/* so jpeg_write_marker works */
51
  cinfo->global_state = CSTATE_WRCOEFS;
52
}
53
54
55
/*
56
 * Initialize the compression object with default parameters,
57
 * then copy from the source object all parameters needed for lossless
58
 * transcoding.  Parameters that can be varied without loss (such as
59
 * scan script and Huffman optimization) are left in their default states.
60
 */
61
62
GLOBAL(void)
63
jpeg_copy_critical_parameters (j_decompress_ptr srcinfo,
64
			       j_compress_ptr dstinfo)
65
{
66
  JQUANT_TBL ** qtblptr;
67
  jpeg_component_info *incomp, *outcomp;
68
  JQUANT_TBL *c_quant, *slot_quant;
69
  int tblno, ci, coefi;
70
71
  /* Safety check to ensure start_compress not called yet. */
72
  if (dstinfo->global_state != CSTATE_START)
73
    ERREXIT1(dstinfo, JERR_BAD_STATE, dstinfo->global_state);
74
  /* Copy fundamental image dimensions */
75
  dstinfo->image_width = srcinfo->image_width;
76
  dstinfo->image_height = srcinfo->image_height;
77
  dstinfo->input_components = srcinfo->num_components;
78
  dstinfo->in_color_space = srcinfo->jpeg_color_space;
79
  /* Initialize all parameters to default values */
80
  jpeg_set_defaults(dstinfo);
81
  /* jpeg_set_defaults may choose wrong colorspace, eg YCbCr if input is RGB.
82
   * Fix it to get the right header markers for the image colorspace.
83
   */
84
  jpeg_set_colorspace(dstinfo, srcinfo->jpeg_color_space);
85
  dstinfo->data_precision = srcinfo->data_precision;
86
  dstinfo->CCIR601_sampling = srcinfo->CCIR601_sampling;
87
  /* Copy the source's quantization tables. */
88
  for (tblno = 0; tblno < NUM_QUANT_TBLS; tblno++) {
89
    if (srcinfo->quant_tbl_ptrs[tblno] != NULL) {
90
      qtblptr = & dstinfo->quant_tbl_ptrs[tblno];
91
      if (*qtblptr == NULL)
92
	*qtblptr = jpeg_alloc_quant_table((j_common_ptr) dstinfo);
93
      MEMCOPY((*qtblptr)->quantval,
94
	      srcinfo->quant_tbl_ptrs[tblno]->quantval,
95
	      SIZEOF((*qtblptr)->quantval));
96
      (*qtblptr)->sent_table = FALSE;
97
    }
98
  }
99
  /* Copy the source's per-component info.
100
   * Note we assume jpeg_set_defaults has allocated the dest comp_info array.
101
   */
102
  dstinfo->num_components = srcinfo->num_components;
103
  if (dstinfo->num_components < 1 || dstinfo->num_components > MAX_COMPONENTS)
104
    ERREXIT2(dstinfo, JERR_COMPONENT_COUNT, dstinfo->num_components,
105
	     MAX_COMPONENTS);
106
  for (ci = 0, incomp = srcinfo->comp_info, outcomp = dstinfo->comp_info;
107
       ci < dstinfo->num_components; ci++, incomp++, outcomp++) {
108
    outcomp->component_id = incomp->component_id;
109
    outcomp->h_samp_factor = incomp->h_samp_factor;
110
    outcomp->v_samp_factor = incomp->v_samp_factor;
111
    outcomp->quant_tbl_no = incomp->quant_tbl_no;
112
    /* Make sure saved quantization table for component matches the qtable
113
     * slot.  If not, the input file re-used this qtable slot.
114
     * IJG encoder currently cannot duplicate this.
115
     */
116
    tblno = outcomp->quant_tbl_no;
117
    if (tblno < 0 || tblno >= NUM_QUANT_TBLS ||
118
	srcinfo->quant_tbl_ptrs[tblno] == NULL)
119
      ERREXIT1(dstinfo, JERR_NO_QUANT_TABLE, tblno);
120
    slot_quant = srcinfo->quant_tbl_ptrs[tblno];
121
    c_quant = incomp->quant_table;
122
    if (c_quant != NULL) {
123
      for (coefi = 0; coefi < DCTSIZE2; coefi++) {
124
	if (c_quant->quantval[coefi] != slot_quant->quantval[coefi])
125
	  ERREXIT1(dstinfo, JERR_MISMATCHED_QUANT_TABLE, tblno);
126
      }
127
    }
128
    /* Note: we do not copy the source's Huffman table assignments;
129
     * instead we rely on jpeg_set_colorspace to have made a suitable choice.
130
     */
131
  }
132
  /* Also copy JFIF version and resolution information, if available.
133
   * Strictly speaking this isn't "critical" info, but it's nearly
134
   * always appropriate to copy it if available.  In particular,
135
   * if the application chooses to copy JFIF 1.02 extension markers from
136
   * the source file, we need to copy the version to make sure we don't
137
   * emit a file that has 1.02 extensions but a claimed version of 1.01.
138
   * We will *not*, however, copy version info from mislabeled "2.01" files.
139
   */
140
  if (srcinfo->saw_JFIF_marker) {
141
    if (srcinfo->JFIF_major_version == 1) {
142
      dstinfo->JFIF_major_version = srcinfo->JFIF_major_version;
143
      dstinfo->JFIF_minor_version = srcinfo->JFIF_minor_version;
144
    }
145
    dstinfo->density_unit = srcinfo->density_unit;
146
    dstinfo->X_density = srcinfo->X_density;
147
    dstinfo->Y_density = srcinfo->Y_density;
148
  }
149
}
150
151
152
/*
153
 * Master selection of compression modules for transcoding.
154
 * This substitutes for jcinit.c's initialization of the full compressor.
155
 */
156
157
LOCAL(void)
158
transencode_master_selection (j_compress_ptr cinfo,
159
			      jvirt_barray_ptr * coef_arrays)
160
{
161
  /* Although we don't actually use input_components for transcoding,
162
   * jcmaster.c's initial_setup will complain if input_components is 0.
163
   */
164
  cinfo->input_components = 1;
165
  /* Initialize master control (includes parameter checking/processing) */
166
  jinit_c_master_control(cinfo, TRUE /* transcode only */);
167
168
  /* Entropy encoding: either Huffman or arithmetic coding. */
169
  if (cinfo->arith_code) {
170
    ERREXIT(cinfo, JERR_ARITH_NOTIMPL);
171
  } else {
172
    if (cinfo->progressive_mode) {
173
#ifdef C_PROGRESSIVE_SUPPORTED
174
      jinit_phuff_encoder(cinfo);
175
#else
176
      ERREXIT(cinfo, JERR_NOT_COMPILED);
177
#endif
178
    } else
179
      jinit_huff_encoder(cinfo);
180
  }
181
182
  /* We need a special coefficient buffer controller. */
183
  transencode_coef_controller(cinfo, coef_arrays);
184
185
  jinit_marker_writer(cinfo);
186
187
  /* We can now tell the memory manager to allocate virtual arrays. */
188
  (*cinfo->mem->realize_virt_arrays) ((j_common_ptr) cinfo);
189
190
  /* Write the datastream header (SOI, JFIF) immediately.
191
   * Frame and scan headers are postponed till later.
192
   * This lets application insert special markers after the SOI.
193
   */
194
  (*cinfo->marker->write_file_header) (cinfo);
195
}
196
197
198
/*
199
 * The rest of this file is a special implementation of the coefficient
200
 * buffer controller.  This is similar to jccoefct.c, but it handles only
201
 * output from presupplied virtual arrays.  Furthermore, we generate any
202
 * dummy padding blocks on-the-fly rather than expecting them to be present
203
 * in the arrays.
204
 */
205
206
/* Private buffer controller object */
207
208
typedef struct {
209
  struct jpeg_c_coef_controller pub; /* public fields */
210
211
  JDIMENSION iMCU_row_num;	/* iMCU row # within image */
212
  JDIMENSION mcu_ctr;		/* counts MCUs processed in current row */
213
  int MCU_vert_offset;		/* counts MCU rows within iMCU row */
214
  int MCU_rows_per_iMCU_row;	/* number of such rows needed */
215
216
  /* Virtual block array for each component. */
217
  jvirt_barray_ptr * whole_image;
218
219
  /* Workspace for constructing dummy blocks at right/bottom edges. */
220
  JBLOCKROW dummy_buffer[C_MAX_BLOCKS_IN_MCU];
221
} my_coef_controller;
222
223
typedef my_coef_controller * my_coef_ptr;
224
225
226
LOCAL(void)
227
start_iMCU_row (j_compress_ptr cinfo)
228
/* Reset within-iMCU-row counters for a new row */
229
{
230
  my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
231
232
  /* In an interleaved scan, an MCU row is the same as an iMCU row.
233
   * In a noninterleaved scan, an iMCU row has v_samp_factor MCU rows.
234
   * But at the bottom of the image, process only what's left.
235
   */
236
  if (cinfo->comps_in_scan > 1) {
237
    coef->MCU_rows_per_iMCU_row = 1;
238
  } else {
239
    if (coef->iMCU_row_num < (cinfo->total_iMCU_rows-1))
240
      coef->MCU_rows_per_iMCU_row = cinfo->cur_comp_info[0]->v_samp_factor;
241
    else
242
      coef->MCU_rows_per_iMCU_row = cinfo->cur_comp_info[0]->last_row_height;
243
  }
244
245
  coef->mcu_ctr = 0;
246
  coef->MCU_vert_offset = 0;
247
}
248
249
250
/*
251
 * Initialize for a processing pass.
252
 */
253
254
METHODDEF(void)
255
start_pass_coef (j_compress_ptr cinfo, J_BUF_MODE pass_mode)
256
{
257
  my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
258
259
  if (pass_mode != JBUF_CRANK_DEST)
260
    ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
261
262
  coef->iMCU_row_num = 0;
263
  start_iMCU_row(cinfo);
264
}
265
266
267
/*
268
 * Process some data.
269
 * We process the equivalent of one fully interleaved MCU row ("iMCU" row)
270
 * per call, ie, v_samp_factor block rows for each component in the scan.
271
 * The data is obtained from the virtual arrays and fed to the entropy coder.
272
 * Returns TRUE if the iMCU row is completed, FALSE if suspended.
273
 *
274
 * NB: input_buf is ignored; it is likely to be a NULL pointer.
275
 */
276
277
METHODDEF(boolean)
278
compress_output (j_compress_ptr cinfo, JSAMPIMAGE input_buf)
279
{
280
  my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
281
  JDIMENSION MCU_col_num;	/* index of current MCU within row */
282
  JDIMENSION last_MCU_col = cinfo->MCUs_per_row - 1;
283
  JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1;
284
  int blkn, ci, xindex, yindex, yoffset, blockcnt;
285
  JDIMENSION start_col;
286
  JBLOCKARRAY buffer[MAX_COMPS_IN_SCAN];
287
  JBLOCKROW MCU_buffer[C_MAX_BLOCKS_IN_MCU];
288
  JBLOCKROW buffer_ptr;
289
  jpeg_component_info *compptr;
290
291
  /* Align the virtual buffers for the components used in this scan. */
292
  for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
293
    compptr = cinfo->cur_comp_info[ci];
294
    buffer[ci] = (*cinfo->mem->access_virt_barray)
295
      ((j_common_ptr) cinfo, coef->whole_image[compptr->component_index],
296
       coef->iMCU_row_num * compptr->v_samp_factor,
297
       (JDIMENSION) compptr->v_samp_factor, FALSE);
298
  }
299
300
  /* Loop to process one whole iMCU row */
301
  for (yoffset = coef->MCU_vert_offset; yoffset < coef->MCU_rows_per_iMCU_row;
302
       yoffset++) {
303
    for (MCU_col_num = coef->mcu_ctr; MCU_col_num < cinfo->MCUs_per_row;
304
	 MCU_col_num++) {
305
      /* Construct list of pointers to DCT blocks belonging to this MCU */
306
      blkn = 0;			/* index of current DCT block within MCU */
307
      for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
308
	compptr = cinfo->cur_comp_info[ci];
309
	start_col = MCU_col_num * compptr->MCU_width;
310
	blockcnt = (MCU_col_num < last_MCU_col) ? compptr->MCU_width
311
						: compptr->last_col_width;
312
	for (yindex = 0; yindex < compptr->MCU_height; yindex++) {
313
	  if (coef->iMCU_row_num < last_iMCU_row ||
314
	      yindex+yoffset < compptr->last_row_height) {
315
	    /* Fill in pointers to real blocks in this row */
316
	    buffer_ptr = buffer[ci][yindex+yoffset] + start_col;
317
	    for (xindex = 0; xindex < blockcnt; xindex++)
318
	      MCU_buffer[blkn++] = buffer_ptr++;
319
	  } else {
320
	    /* At bottom of image, need a whole row of dummy blocks */
321
	    xindex = 0;
322
	  }
323
	  /* Fill in any dummy blocks needed in this row.
324
	   * Dummy blocks are filled in the same way as in jccoefct.c:
325
	   * all zeroes in the AC entries, DC entries equal to previous
326
	   * block's DC value.  The init routine has already zeroed the
327
	   * AC entries, so we need only set the DC entries correctly.
328
	   */
329
	  for (; xindex < compptr->MCU_width; xindex++) {
330
	    MCU_buffer[blkn] = coef->dummy_buffer[blkn];
331
	    MCU_buffer[blkn][0][0] = MCU_buffer[blkn-1][0][0];
332
	    blkn++;
333
	  }
334
	}
335
      }
336
      /* Try to write the MCU. */
337
      if (! (*cinfo->entropy->encode_mcu) (cinfo, MCU_buffer)) {
338
	/* Suspension forced; update state counters and exit */
339
	coef->MCU_vert_offset = yoffset;
340
	coef->mcu_ctr = MCU_col_num;
341
	return FALSE;
342
      }
343
    }
344
    /* Completed an MCU row, but perhaps not an iMCU row */
345
    coef->mcu_ctr = 0;
346
  }
347
  /* Completed the iMCU row, advance counters for next one */
348
  coef->iMCU_row_num++;
349
  start_iMCU_row(cinfo);
350
  return TRUE;
351
}
352
353
354
/*
355
 * Initialize coefficient buffer controller.
356
 *
357
 * Each passed coefficient array must be the right size for that
358
 * coefficient: width_in_blocks wide and height_in_blocks high,
359
 * with unitheight at least v_samp_factor.
360
 */
361
362
LOCAL(void)
363
transencode_coef_controller (j_compress_ptr cinfo,
364
			     jvirt_barray_ptr * coef_arrays)
365
{
366
  my_coef_ptr coef;
367
  JBLOCKROW buffer;
368
  int i;
369
370
  coef = (my_coef_ptr)
371
    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
372
				SIZEOF(my_coef_controller));
373
  cinfo->coef = (struct jpeg_c_coef_controller *) coef;
374
  coef->pub.start_pass = start_pass_coef;
375
  coef->pub.compress_data = compress_output;
376
377
  /* Save pointer to virtual arrays */
378
  coef->whole_image = coef_arrays;
379
380
  /* Allocate and pre-zero space for dummy DCT blocks. */
381
  buffer = (JBLOCKROW)
382
    (*cinfo->mem->alloc_large) ((j_common_ptr) cinfo, JPOOL_IMAGE,
383
				C_MAX_BLOCKS_IN_MCU * SIZEOF(JBLOCK));
384
  jzero_far((void FAR *) buffer, C_MAX_BLOCKS_IN_MCU * SIZEOF(JBLOCK));
385
  for (i = 0; i < C_MAX_BLOCKS_IN_MCU; i++) {
386
    coef->dummy_buffer[i] = buffer + i;
387
  }
388
}
(-)a/jpeg/jdapimin.c (-136 / +1 lines)
Line     Link Here 
 Lines 15-129    Link Here 
15
 * shared by compression and decompression, and jdtrans.c for the transcoding
15
 * shared by compression and decompression, and jdtrans.c for the transcoding
16
 * case.
16
 * case.
17
 */
17
 */
18
18
19
#define JPEG_INTERNALS
19
#define JPEG_INTERNALS
20
#include "jinclude.h"
20
#include "jinclude.h"
21
#include "jpeglib.h"
21
#include "jpeglib.h"
22
22
23
#ifdef HAVE_MMX_INTEL_MNEMONICS
24
#if _MSC_VER >= 1400
25
#include "intrin.h"
26
#else
27
/* no __cpuid intrinsic, use a manually rewritten replacement */
28
void __stdcall __cpuid( int CPUInfo[4], int InfoType )
29
{
30
  int my_eax = 0, my_ebx = 0, my_ecx = 0, my_edx = 0;
31
  __asm {
32
    /* check eflags bit 21 to see if cpuid is supported */
33
    pushfd             /* save eflags to stack */
34
    pop eax            /* and put it in eax */
35
    mov ecx, eax       /* save a copy in ecx to compare against */
36
    xor eax, 0x200000  /* toggle ID bit (bit 21) in eflags */
37
    push eax           /* save modified eflags to stack */
38
    popfd              /* set eflags register with modified value */
39
    pushfd             /* read eflags back out */
40
    pop eax
41
    xor eax, ecx       /* check for modified eflags */
42
    jz NOT_SUPPORTED   /* cpuid not supported */
43
44
    /* check to see if the requested cpuid type is supported */
45
    xor eax, eax       /* set eax to zero */
46
    cpuid
47
    cmp eax, InfoType
48
    jl NOT_SUPPORTED   /* the requested cpuid type is not supported */
49
50
    /* actually make the cpuid call */
51
    mov eax, InfoType
52
    cpuid
53
    mov my_eax, eax
54
    mov my_ebx, ebx
55
    mov my_ecx, ecx
56
    mov my_edx, edx
57
NOT_SUPPORTED:
58
  }
59
  CPUInfo[0] = my_eax;
60
  CPUInfo[1] = my_ebx;
61
  CPUInfo[2] = my_ecx;
62
  CPUInfo[3] = my_edx;
63
}
64
#endif /* _MSC_VER >= 1400 */
65
66
int MMXAvailable;
67
static int mmxsupport();
68
#endif
69
70
#ifdef HAVE_SSE2_INTRINSICS
71
int SSE2Available = 0;
72
#ifdef HAVE_SSE2_INTEL_MNEMONICS
73
static int sse2support();
74
#else
75
static int sse2supportGCC();
76
#endif /* HAVE_SSE2_INTEL_MNEMONICS */
77
#endif /* HAVE_SSE2_INTRINSICS */
78
79
23
80
/*
24
/*
81
 * Initialization of a JPEG decompression object.
25
 * Initialization of a JPEG decompression object.
82
 * The error manager must already be set up (in case memory manager fails).
26
 * The error manager must already be set up (in case memory manager fails).
83
 */
27
 */
84
28
85
GLOBAL(void)
29
GLOBAL(void)
86
jpeg_CreateDecompress (j_decompress_ptr cinfo, int version, size_t structsize)
30
jpeg_CreateDecompress (j_decompress_ptr cinfo, int version, size_t structsize)
87
{
31
{
88
  int i;
32
  int i;
89
33
90
#ifdef HAVE_MMX_INTEL_MNEMONICS
91
  static int cpuidDetected = 0;
92
93
  if(!cpuidDetected)
94
  {
95
	MMXAvailable = mmxsupport();
96
97
#ifdef HAVE_SSE2_INTEL_MNEMONICS
98
	/* only do the sse2 support check if mmx is supported (so
99
	   we know the processor supports cpuid) */
100
	if (MMXAvailable)
101
	    SSE2Available = sse2support();
102
#endif
103
104
	cpuidDetected = 1;
105
  }
106
#else
107
#ifdef HAVE_SSE2_INTRINSICS
108
  static int cpuidDetected = 0;
109
110
  if(!cpuidDetected) {
111
    SSE2Available = sse2supportGCC();
112
    cpuidDetected = 1;
113
  }
114
115
#endif /* HAVE_SSE2_INTRINSICS */
116
#endif /* HAVE_MMX_INTEL_MNEMONICS */
117
118
  /* For debugging purposes, zero the whole master structure.
119
   * But error manager pointer is already there, so save and restore it.
120
   */
121
122
  /* Guard against version mismatches between library and caller. */
34
  /* Guard against version mismatches between library and caller. */
123
  cinfo->mem = NULL;		/* so jpeg_destroy knows mem mgr not called */
35
  cinfo->mem = NULL;		/* so jpeg_destroy knows mem mgr not called */
124
  if (version != JPEG_LIB_VERSION)
36
  if (version != JPEG_LIB_VERSION)
125
    ERREXIT2(cinfo, JERR_BAD_LIB_VERSION, JPEG_LIB_VERSION, version);
37
    ERREXIT2(cinfo, JERR_BAD_LIB_VERSION, JPEG_LIB_VERSION, version);
126
  if (structsize != SIZEOF(struct jpeg_decompress_struct))
38
  if (structsize != SIZEOF(struct jpeg_decompress_struct))
127
    ERREXIT2(cinfo, JERR_BAD_STRUCT_SIZE, 
39
    ERREXIT2(cinfo, JERR_BAD_STRUCT_SIZE, 
128
	     (int) SIZEOF(struct jpeg_decompress_struct), (int) structsize);
40
	     (int) SIZEOF(struct jpeg_decompress_struct), (int) structsize);
129
41
 Lines 188-203   jpeg_destroy_decompress (j_decompress_pt Link Here 
188
 */
100
 */
189
101
190
GLOBAL(void)
102
GLOBAL(void)
191
jpeg_abort_decompress (j_decompress_ptr cinfo)
103
jpeg_abort_decompress (j_decompress_ptr cinfo)
192
{
104
{
193
  jpeg_abort((j_common_ptr) cinfo); /* use common routine */
105
  jpeg_abort((j_common_ptr) cinfo); /* use common routine */
194
}
106
}
195
107
108
196
/*
109
/*
197
 * Set default decompression parameters.
110
 * Set default decompression parameters.
198
 */
111
 */
199
112
200
LOCAL(void)
113
LOCAL(void)
201
default_decompress_parms (j_decompress_ptr cinfo)
114
default_decompress_parms (j_decompress_ptr cinfo)
202
{
115
{
203
  /* Guess the input colorspace, and set output colorspace accordingly. */
116
  /* Guess the input colorspace, and set output colorspace accordingly. */
 Lines 475-530   jpeg_finish_decompress (j_decompress_ptr Link Here 
475
      return FALSE;		/* Suspend, come back later */
388
      return FALSE;		/* Suspend, come back later */
476
  }
389
  }
477
  /* Do final cleanup */
390
  /* Do final cleanup */
478
  (*cinfo->src->term_source) (cinfo);
391
  (*cinfo->src->term_source) (cinfo);
479
  /* We can use jpeg_abort to release memory and reset global_state */
392
  /* We can use jpeg_abort to release memory and reset global_state */
480
  jpeg_abort((j_common_ptr) cinfo);
393
  jpeg_abort((j_common_ptr) cinfo);
481
  return TRUE;
394
  return TRUE;
482
}
395
}
483
484
485
#ifdef HAVE_MMX_INTEL_MNEMONICS
486
static int mmxsupport()
487
{
488
  int CPUInfo[4];
489
490
  __cpuid(CPUInfo, 1);
491
  if (CPUInfo[3] & (0x1 << 23))
492
    return 1;
493
  else
494
    return 0;
495
}
496
#endif
497
498
#ifdef HAVE_SSE2_INTEL_MNEMONICS
499
static int sse2support()
500
{
501
  int CPUInfo[4];
502
503
  __cpuid(CPUInfo, 1);
504
  if (CPUInfo[3] & (0x1 << 26))
505
    return 1;
506
  else
507
    return 2;
508
}
509
#else
510
#ifdef HAVE_SSE2_INTRINSICS
511
static int sse2supportGCC()
512
{
513
514
  /* Mac Intel started with Core Duo chips which have SSE2 Support */
515
516
#if defined(__GNUC__) && defined(__i386__)
517
#if defined(XP_MACOSX)
518
  return 1;
519
#endif /* XP_MACOSX */
520
#endif /* GNUC && i386 */
521
522
  /* Add checking for SSE2 support for other platforms here */
523
524
  /* We don't have SSE2 intrinsics support */
525
526
  return 2;
527
}
528
#endif /* HAVE_SSE2_INTRINSICS */
529
#endif /* HAVE_SSE2_INTEL_MNEMONICS */
530
(-)a/jpeg/jdatadst.c (-63 lines)
Line     Link Here 
 Lines 144-214   jpeg_stdio_dest (j_compress_ptr cinfo, F Link Here 
144
  }
144
  }
145
145
146
  dest = (my_dest_ptr) cinfo->dest;
146
  dest = (my_dest_ptr) cinfo->dest;
147
  dest->pub.init_destination = init_destination;
147
  dest->pub.init_destination = init_destination;
148
  dest->pub.empty_output_buffer = empty_output_buffer;
148
  dest->pub.empty_output_buffer = empty_output_buffer;
149
  dest->pub.term_destination = term_destination;
149
  dest->pub.term_destination = term_destination;
150
  dest->outfile = outfile;
150
  dest->outfile = outfile;
151
}
151
}
152
153
/*
154
 * term_destination_file_close --- called by jpeg_finish_compress
155
 * after all data has been written.  Usually needs to flush buffer.
156
 * also will need to close file
157
 * NB: *not* called by jpeg_abort or jpeg_destroy; surrounding
158
 * application must deal with any cleanup that should happen even
159
 * for error exit.
160
 */
161
162
METHODDEF(void)
163
term_destination_file_close(j_compress_ptr cinfo)
164
{
165
  my_dest_ptr dest = (my_dest_ptr) cinfo->dest;
166
  size_t datacount = OUTPUT_BUF_SIZE - dest->pub.free_in_buffer;
167
168
  /* Write any data remaining in the buffer */
169
  if (datacount > 0) {
170
    if (JFWRITE(dest->outfile, dest->buffer, datacount) != datacount)
171
      ERREXIT(cinfo, JERR_FILE_WRITE);
172
  }
173
  fflush(dest->outfile);
174
  
175
  /* Make sure we wrote the output file OK */
176
  if (ferror(dest->outfile))
177
    ERREXIT(cinfo, JERR_FILE_WRITE);
178
  else
179
      fclose(dest->outfile);
180
}
181
182
183
184
185
186
/*
187
 * Prepare for output to a file from a char *
188
 * The caller is responsible
189
 * for closing it after finishing compression.
190
 */
191
192
GLOBAL(void)
193
jpeg_file_dest (j_compress_ptr cinfo, char * outfile)
194
{
195
  my_dest_ptr dest;
196
197
  /* The destination object is made permanent so that multiple JPEG images
198
   * can be written to the same file without re-executing jpeg_stdio_dest.
199
   * This makes it dangerous to use this manager and a different destination
200
   * manager serially with the same JPEG object, because their private object
201
   * sizes may be different.  Caveat programmer.
202
   */
203
  if (cinfo->dest == NULL) {	/* first time for this JPEG object? */
204
    cinfo->dest = (struct jpeg_destination_mgr *)
205
      (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
206
				  SIZEOF(my_destination_mgr));
207
  }
208
209
  dest = (my_dest_ptr) cinfo->dest;
210
  dest->pub.init_destination = init_destination;
211
  dest->pub.empty_output_buffer = empty_output_buffer;
212
  dest->pub.term_destination = term_destination_file_close;
213
  dest->outfile = fopen(outfile,"wb");
214
}
(-)a/jpeg/jdcoefct.c (-1 / +12 lines)
Line     Link Here 
 Lines 42-57   typedef struct { Link Here 
42
   * (On 80x86, the workspace is FAR even though it's not really very big;
42
   * (On 80x86, the workspace is FAR even though it's not really very big;
43
   * this is to keep the module interfaces unchanged when a large coefficient
43
   * this is to keep the module interfaces unchanged when a large coefficient
44
   * buffer is necessary.)
44
   * buffer is necessary.)
45
   * In multi-pass modes, this array points to the current MCU's blocks
45
   * In multi-pass modes, this array points to the current MCU's blocks
46
   * within the virtual arrays; it is used only by the input side.
46
   * within the virtual arrays; it is used only by the input side.
47
   */
47
   */
48
  JBLOCKROW MCU_buffer[D_MAX_BLOCKS_IN_MCU];
48
  JBLOCKROW MCU_buffer[D_MAX_BLOCKS_IN_MCU];
49
49
50
  /* Temporary workspace for one MCU */
51
  JCOEF * workspace;
52
50
#ifdef D_MULTISCAN_FILES_SUPPORTED
53
#ifdef D_MULTISCAN_FILES_SUPPORTED
51
  /* In multi-pass modes, we need a virtual block array for each component. */
54
  /* In multi-pass modes, we need a virtual block array for each component. */
52
  jvirt_barray_ptr whole_image[MAX_COMPONENTS];
55
  jvirt_barray_ptr whole_image[MAX_COMPONENTS];
53
#endif
56
#endif
54
57
55
#ifdef BLOCK_SMOOTHING_SUPPORTED
58
#ifdef BLOCK_SMOOTHING_SUPPORTED
56
  /* When doing block smoothing, we latch coefficient Al values here */
59
  /* When doing block smoothing, we latch coefficient Al values here */
57
  int * coef_bits_latch;
60
  int * coef_bits_latch;
 Lines 466-488   decompress_smooth_data (j_decompress_ptr Link Here 
466
  int ci, block_row, block_rows, access_rows;
469
  int ci, block_row, block_rows, access_rows;
467
  JBLOCKARRAY buffer;
470
  JBLOCKARRAY buffer;
468
  JBLOCKROW buffer_ptr, prev_block_row, next_block_row;
471
  JBLOCKROW buffer_ptr, prev_block_row, next_block_row;
469
  JSAMPARRAY output_ptr;
472
  JSAMPARRAY output_ptr;
470
  JDIMENSION output_col;
473
  JDIMENSION output_col;
471
  jpeg_component_info *compptr;
474
  jpeg_component_info *compptr;
472
  inverse_DCT_method_ptr inverse_DCT;
475
  inverse_DCT_method_ptr inverse_DCT;
473
  boolean first_row, last_row;
476
  boolean first_row, last_row;
474
  JBLOCK workspace;
477
  JCOEF * workspace;
475
  int *coef_bits;
478
  int *coef_bits;
476
  JQUANT_TBL *quanttbl;
479
  JQUANT_TBL *quanttbl;
477
  INT32 Q00,Q01,Q02,Q10,Q11,Q20, num;
480
  INT32 Q00,Q01,Q02,Q10,Q11,Q20, num;
478
  int DC1,DC2,DC3,DC4,DC5,DC6,DC7,DC8,DC9;
481
  int DC1,DC2,DC3,DC4,DC5,DC6,DC7,DC8,DC9;
479
  int Al, pred;
482
  int Al, pred;
480
483
484
  /* Keep a local variable to avoid looking it up more than once */
485
  workspace = coef->workspace;
486
481
  /* Force some input to be done if we are getting ahead of the input. */
487
  /* Force some input to be done if we are getting ahead of the input. */
482
  while (cinfo->input_scan_number <= cinfo->output_scan_number &&
488
  while (cinfo->input_scan_number <= cinfo->output_scan_number &&
483
	 ! cinfo->inputctl->eoi_reached) {
489
	 ! cinfo->inputctl->eoi_reached) {
484
    if (cinfo->input_scan_number == cinfo->output_scan_number) {
490
    if (cinfo->input_scan_number == cinfo->output_scan_number) {
485
      /* If input is working on current scan, we ordinarily want it to
491
      /* If input is working on current scan, we ordinarily want it to
486
       * have completed the current row.  But if input scan is DC,
492
       * have completed the current row.  But if input scan is DC,
487
       * we want it to keep one row ahead so that next block row's DC
493
       * we want it to keep one row ahead so that next block row's DC
488
       * values are up to date.
494
       * values are up to date.
 Lines 728-736   jinit_d_coef_controller (j_decompress_pt Link Here 
728
				  D_MAX_BLOCKS_IN_MCU * SIZEOF(JBLOCK));
734
				  D_MAX_BLOCKS_IN_MCU * SIZEOF(JBLOCK));
729
    for (i = 0; i < D_MAX_BLOCKS_IN_MCU; i++) {
735
    for (i = 0; i < D_MAX_BLOCKS_IN_MCU; i++) {
730
      coef->MCU_buffer[i] = buffer + i;
736
      coef->MCU_buffer[i] = buffer + i;
731
    }
737
    }
732
    coef->pub.consume_data = dummy_consume_data;
738
    coef->pub.consume_data = dummy_consume_data;
733
    coef->pub.decompress_data = decompress_onepass;
739
    coef->pub.decompress_data = decompress_onepass;
734
    coef->pub.coef_arrays = NULL; /* flag for no virtual arrays */
740
    coef->pub.coef_arrays = NULL; /* flag for no virtual arrays */
735
  }
741
  }
742
743
  /* Allocate the workspace buffer */
744
  coef->workspace = (JCOEF *)
745
    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
746
                                SIZEOF(JCOEF) * DCTSIZE2);
736
}
747
}
(-)a/jpeg/jdcolor.c (-218 / +50 lines)
Line     Link Here 
 Lines 1-38    Link Here 
1
/*
1
/*
2
 * jdcolor.c
2
 * jdcolor.c
3
 *
3
 *
4
 * Copyright (C) 1991-1997, Thomas G. Lane.
4
 * Copyright (C) 1991-1997, Thomas G. Lane.
5
 * Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
6
 * Copyright (C) 2009, D. R. Commander.
5
 * This file is part of the Independent JPEG Group's software.
7
 * This file is part of the Independent JPEG Group's software.
6
 * For conditions of distribution and use, see the accompanying README file.
8
 * For conditions of distribution and use, see the accompanying README file.
7
 *
9
 *
8
 * This file contains output colorspace conversion routines.
10
 * This file contains output colorspace conversion routines.
9
 */
11
 */
10
12
11
#define JPEG_INTERNALS
13
#define JPEG_INTERNALS
12
#include "jinclude.h"
14
#include "jinclude.h"
13
#include "jpeglib.h"
15
#include "jpeglib.h"
14
#include "jconfig.h"
16
#include "jsimd.h"
15
17
16
18
17
/* Private subobject */
19
/* Private subobject */
18
20
19
typedef struct {
21
typedef struct {
20
  struct jpeg_color_deconverter pub; /* public fields */
22
  struct jpeg_color_deconverter pub; /* public fields */
21
23
22
  /* These fields are not needed anymore as these are now static tables */
23
24
#if 0
25
  /* Private state for YCC->RGB conversion */
24
  /* Private state for YCC->RGB conversion */
26
  int * Cr_r_tab;		/* => table for Cr to R conversion */
25
  int * Cr_r_tab;		/* => table for Cr to R conversion */
27
  int * Cb_b_tab;		/* => table for Cb to B conversion */
26
  int * Cb_b_tab;		/* => table for Cb to B conversion */
28
  INT32 * Cr_g_tab;		/* => table for Cr to G conversion */
27
  INT32 * Cr_g_tab;		/* => table for Cr to G conversion */
29
  INT32 * Cb_g_tab;		/* => table for Cb to G conversion */
28
  INT32 * Cb_g_tab;		/* => table for Cb to G conversion */
30
#endif
31
} my_color_deconverter;
29
} my_color_deconverter;
32
30
33
typedef my_color_deconverter * my_cconvert_ptr;
31
typedef my_color_deconverter * my_cconvert_ptr;
34
32
35
33
36
/**************** YCbCr -> RGB conversion: most common case **************/
34
/**************** YCbCr -> RGB conversion: most common case **************/
37
35
38
/*
36
/*
 Lines 61-273   typedef my_color_deconverter * my_cconve Link Here 
61
 * values for the G calculation are left scaled up, since we must add them
59
 * values for the G calculation are left scaled up, since we must add them
62
 * together before rounding.
60
 * together before rounding.
63
 */
61
 */
64
62
65
#define SCALEBITS	16	/* speediest right-shift on some machines */
63
#define SCALEBITS	16	/* speediest right-shift on some machines */
66
#define ONE_HALF	((INT32) 1 << (SCALEBITS-1))
64
#define ONE_HALF	((INT32) 1 << (SCALEBITS-1))
67
#define FIX(x)		((INT32) ((x) * (1L<<SCALEBITS) + 0.5))
65
#define FIX(x)		((INT32) ((x) * (1L<<SCALEBITS) + 0.5))
68
66
69
/* Use static tables for color processing. */
70
71
const int Cr_r_tab[(MAXJSAMPLE+1) * SIZEOF(int)] ={
72
  0xffffff4dUL, 0xffffff4eUL, 0xffffff4fUL, 0xffffff51UL, 0xffffff52UL, 0xffffff54UL, 
73
  0xffffff55UL, 0xffffff56UL, 0xffffff58UL, 0xffffff59UL, 0xffffff5bUL, 0xffffff5cUL, 
74
  0xffffff5dUL, 0xffffff5fUL, 0xffffff60UL, 0xffffff62UL, 0xffffff63UL, 0xffffff64UL, 
75
  0xffffff66UL, 0xffffff67UL, 0xffffff69UL, 0xffffff6aUL, 0xffffff6bUL, 0xffffff6dUL, 
76
  0xffffff6eUL, 0xffffff70UL, 0xffffff71UL, 0xffffff72UL, 0xffffff74UL, 0xffffff75UL, 
77
  0xffffff77UL, 0xffffff78UL, 0xffffff79UL, 0xffffff7bUL, 0xffffff7cUL, 0xffffff7eUL, 
78
  0xffffff7fUL, 0xffffff80UL, 0xffffff82UL, 0xffffff83UL, 0xffffff85UL, 0xffffff86UL, 
79
  0xffffff87UL, 0xffffff89UL, 0xffffff8aUL, 0xffffff8cUL, 0xffffff8dUL, 0xffffff8eUL, 
80
  0xffffff90UL, 0xffffff91UL, 0xffffff93UL, 0xffffff94UL, 0xffffff95UL, 0xffffff97UL, 
81
  0xffffff98UL, 0xffffff9aUL, 0xffffff9bUL, 0xffffff9cUL, 0xffffff9eUL, 0xffffff9fUL, 
82
  0xffffffa1UL, 0xffffffa2UL, 0xffffffa3UL, 0xffffffa5UL, 0xffffffa6UL, 0xffffffa8UL, 
83
  0xffffffa9UL, 0xffffffaaUL, 0xffffffacUL, 0xffffffadUL, 0xffffffafUL, 0xffffffb0UL, 
84
  0xffffffb1UL, 0xffffffb3UL, 0xffffffb4UL, 0xffffffb6UL, 0xffffffb7UL, 0xffffffb8UL, 
85
  0xffffffbaUL, 0xffffffbbUL, 0xffffffbdUL, 0xffffffbeUL, 0xffffffc0UL, 0xffffffc1UL, 
86
  0xffffffc2UL, 0xffffffc4UL, 0xffffffc5UL, 0xffffffc7UL, 0xffffffc8UL, 0xffffffc9UL, 
87
  0xffffffcbUL, 0xffffffccUL, 0xffffffceUL, 0xffffffcfUL, 0xffffffd0UL, 0xffffffd2UL, 
88
  0xffffffd3UL, 0xffffffd5UL, 0xffffffd6UL, 0xffffffd7UL, 0xffffffd9UL, 0xffffffdaUL, 
89
  0xffffffdcUL, 0xffffffddUL, 0xffffffdeUL, 0xffffffe0UL, 0xffffffe1UL, 0xffffffe3UL, 
90
  0xffffffe4UL, 0xffffffe5UL, 0xffffffe7UL, 0xffffffe8UL, 0xffffffeaUL, 0xffffffebUL, 
91
  0xffffffecUL, 0xffffffeeUL, 0xffffffefUL, 0xfffffff1UL, 0xfffffff2UL, 0xfffffff3UL, 
92
  0xfffffff5UL, 0xfffffff6UL, 0xfffffff8UL, 0xfffffff9UL, 0xfffffffaUL, 0xfffffffcUL, 
93
  0xfffffffdUL, 0xffffffffUL,       0x00UL,       0x01UL,       0x03UL,       0x04UL, 
94
        0x06UL,       0x07UL,       0x08UL,       0x0aUL,       0x0bUL,       0x0dUL, 
95
        0x0eUL,       0x0fUL,       0x11UL,       0x12UL,       0x14UL,       0x15UL, 
96
        0x16UL,       0x18UL,       0x19UL,       0x1bUL,       0x1cUL,       0x1dUL, 
97
        0x1fUL,       0x20UL,       0x22UL,       0x23UL,       0x24UL,       0x26UL, 
98
        0x27UL,       0x29UL,       0x2aUL,       0x2bUL,       0x2dUL,       0x2eUL, 
99
        0x30UL,       0x31UL,       0x32UL,       0x34UL,       0x35UL,       0x37UL, 
100
        0x38UL,       0x39UL,       0x3bUL,       0x3cUL,       0x3eUL,       0x3fUL, 
101
        0x40UL,       0x42UL,       0x43UL,       0x45UL,       0x46UL,       0x48UL, 
102
        0x49UL,       0x4aUL,       0x4cUL,       0x4dUL,       0x4fUL,       0x50UL, 
103
        0x51UL,       0x53UL,       0x54UL,       0x56UL,       0x57UL,       0x58UL, 
104
        0x5aUL,       0x5bUL,       0x5dUL,       0x5eUL,       0x5fUL,       0x61UL, 
105
        0x62UL,       0x64UL,       0x65UL,       0x66UL,       0x68UL,       0x69UL, 
106
        0x6bUL,       0x6cUL,       0x6dUL,       0x6fUL,       0x70UL,       0x72UL, 
107
        0x73UL,       0x74UL,       0x76UL,       0x77UL,       0x79UL,       0x7aUL, 
108
        0x7bUL,       0x7dUL,       0x7eUL,       0x80UL,       0x81UL,       0x82UL, 
109
        0x84UL,       0x85UL,       0x87UL,       0x88UL,       0x89UL,       0x8bUL, 
110
        0x8cUL,       0x8eUL,       0x8fUL,       0x90UL,       0x92UL,       0x93UL, 
111
        0x95UL,       0x96UL,       0x97UL,       0x99UL,       0x9aUL,       0x9cUL, 
112
        0x9dUL,       0x9eUL,       0xa0UL,       0xa1UL,       0xa3UL,       0xa4UL, 
113
        0xa5UL,       0xa7UL,       0xa8UL,       0xaaUL,       0xabUL,       0xacUL, 
114
        0xaeUL,       0xafUL,       0xb1UL,       0xb2UL
115
  };
116
117
const int Cb_b_tab[(MAXJSAMPLE+1) * SIZEOF(int)] ={
118
  0xffffff1dUL, 0xffffff1fUL, 0xffffff21UL, 0xffffff22UL, 0xffffff24UL, 0xffffff26UL, 
119
  0xffffff28UL, 0xffffff2aUL, 0xffffff2bUL, 0xffffff2dUL, 0xffffff2fUL, 0xffffff31UL, 
120
  0xffffff32UL, 0xffffff34UL, 0xffffff36UL, 0xffffff38UL, 0xffffff3aUL, 0xffffff3bUL, 
121
  0xffffff3dUL, 0xffffff3fUL, 0xffffff41UL, 0xffffff42UL, 0xffffff44UL, 0xffffff46UL, 
122
  0xffffff48UL, 0xffffff49UL, 0xffffff4bUL, 0xffffff4dUL, 0xffffff4fUL, 0xffffff51UL, 
123
  0xffffff52UL, 0xffffff54UL, 0xffffff56UL, 0xffffff58UL, 0xffffff59UL, 0xffffff5bUL, 
124
  0xffffff5dUL, 0xffffff5fUL, 0xffffff61UL, 0xffffff62UL, 0xffffff64UL, 0xffffff66UL, 
125
  0xffffff68UL, 0xffffff69UL, 0xffffff6bUL, 0xffffff6dUL, 0xffffff6fUL, 0xffffff70UL, 
126
  0xffffff72UL, 0xffffff74UL, 0xffffff76UL, 0xffffff78UL, 0xffffff79UL, 0xffffff7bUL, 
127
  0xffffff7dUL, 0xffffff7fUL, 0xffffff80UL, 0xffffff82UL, 0xffffff84UL, 0xffffff86UL, 
128
  0xffffff88UL, 0xffffff89UL, 0xffffff8bUL, 0xffffff8dUL, 0xffffff8fUL, 0xffffff90UL, 
129
  0xffffff92UL, 0xffffff94UL, 0xffffff96UL, 0xffffff97UL, 0xffffff99UL, 0xffffff9bUL, 
130
  0xffffff9dUL, 0xffffff9fUL, 0xffffffa0UL, 0xffffffa2UL, 0xffffffa4UL, 0xffffffa6UL, 
131
  0xffffffa7UL, 0xffffffa9UL, 0xffffffabUL, 0xffffffadUL, 0xffffffaeUL, 0xffffffb0UL, 
132
  0xffffffb2UL, 0xffffffb4UL, 0xffffffb6UL, 0xffffffb7UL, 0xffffffb9UL, 0xffffffbbUL, 
133
  0xffffffbdUL, 0xffffffbeUL, 0xffffffc0UL, 0xffffffc2UL, 0xffffffc4UL, 0xffffffc6UL, 
134
  0xffffffc7UL, 0xffffffc9UL, 0xffffffcbUL, 0xffffffcdUL, 0xffffffceUL, 0xffffffd0UL, 
135
  0xffffffd2UL, 0xffffffd4UL, 0xffffffd5UL, 0xffffffd7UL, 0xffffffd9UL, 0xffffffdbUL, 
136
  0xffffffddUL, 0xffffffdeUL, 0xffffffe0UL, 0xffffffe2UL, 0xffffffe4UL, 0xffffffe5UL, 
137
  0xffffffe7UL, 0xffffffe9UL, 0xffffffebUL, 0xffffffedUL, 0xffffffeeUL, 0xfffffff0UL, 
138
  0xfffffff2UL, 0xfffffff4UL, 0xfffffff5UL, 0xfffffff7UL, 0xfffffff9UL, 0xfffffffbUL, 
139
  0xfffffffcUL, 0xfffffffeUL,       0x00UL,       0x02UL,       0x04UL,       0x05UL, 
140
        0x07UL,       0x09UL,       0x0bUL,       0x0cUL,       0x0eUL,       0x10UL, 
141
        0x12UL,       0x13UL,       0x15UL,       0x17UL,       0x19UL,       0x1bUL, 
142
        0x1cUL,       0x1eUL,       0x20UL,       0x22UL,       0x23UL,       0x25UL, 
143
        0x27UL,       0x29UL,       0x2bUL,       0x2cUL,       0x2eUL,       0x30UL, 
144
        0x32UL,       0x33UL,       0x35UL,       0x37UL,       0x39UL,       0x3aUL, 
145
        0x3cUL,       0x3eUL,       0x40UL,       0x42UL,       0x43UL,       0x45UL, 
146
        0x47UL,       0x49UL,       0x4aUL,       0x4cUL,       0x4eUL,       0x50UL, 
147
        0x52UL,       0x53UL,       0x55UL,       0x57UL,       0x59UL,       0x5aUL, 
148
        0x5cUL,       0x5eUL,       0x60UL,       0x61UL,       0x63UL,       0x65UL, 
149
        0x67UL,       0x69UL,       0x6aUL,       0x6cUL,       0x6eUL,       0x70UL, 
150
        0x71UL,       0x73UL,       0x75UL,       0x77UL,       0x78UL,       0x7aUL, 
151
        0x7cUL,       0x7eUL,       0x80UL,       0x81UL,       0x83UL,       0x85UL, 
152
        0x87UL,       0x88UL,       0x8aUL,       0x8cUL,       0x8eUL,       0x90UL, 
153
        0x91UL,       0x93UL,       0x95UL,       0x97UL,       0x98UL,       0x9aUL, 
154
        0x9cUL,       0x9eUL,       0x9fUL,       0xa1UL,       0xa3UL,       0xa5UL, 
155
        0xa7UL,       0xa8UL,       0xaaUL,       0xacUL,       0xaeUL,       0xafUL, 
156
        0xb1UL,       0xb3UL,       0xb5UL,       0xb7UL,       0xb8UL,       0xbaUL, 
157
        0xbcUL,       0xbeUL,       0xbfUL,       0xc1UL,       0xc3UL,       0xc5UL, 
158
        0xc6UL,       0xc8UL,       0xcaUL,       0xccUL,       0xceUL,       0xcfUL, 
159
        0xd1UL,       0xd3UL,       0xd5UL,       0xd6UL,       0xd8UL,       0xdaUL, 
160
        0xdcUL,       0xdeUL,       0xdfUL,       0xe1UL
161
  };
162
163
const int Cr_g_tab[(MAXJSAMPLE+1) * SIZEOF(int)] ={
164
    0x5b6900UL,   0x5ab22eUL,   0x59fb5cUL,   0x59448aUL,   0x588db8UL,   0x57d6e6UL, 
165
    0x572014UL,   0x566942UL,   0x55b270UL,   0x54fb9eUL,   0x5444ccUL,   0x538dfaUL, 
166
    0x52d728UL,   0x522056UL,   0x516984UL,   0x50b2b2UL,   0x4ffbe0UL,   0x4f450eUL, 
167
    0x4e8e3cUL,   0x4dd76aUL,   0x4d2098UL,   0x4c69c6UL,   0x4bb2f4UL,   0x4afc22UL, 
168
    0x4a4550UL,   0x498e7eUL,   0x48d7acUL,   0x4820daUL,   0x476a08UL,   0x46b336UL, 
169
    0x45fc64UL,   0x454592UL,   0x448ec0UL,   0x43d7eeUL,   0x43211cUL,   0x426a4aUL, 
170
    0x41b378UL,   0x40fca6UL,   0x4045d4UL,   0x3f8f02UL,   0x3ed830UL,   0x3e215eUL, 
171
    0x3d6a8cUL,   0x3cb3baUL,   0x3bfce8UL,   0x3b4616UL,   0x3a8f44UL,   0x39d872UL, 
172
    0x3921a0UL,   0x386aceUL,   0x37b3fcUL,   0x36fd2aUL,   0x364658UL,   0x358f86UL, 
173
    0x34d8b4UL,   0x3421e2UL,   0x336b10UL,   0x32b43eUL,   0x31fd6cUL,   0x31469aUL, 
174
    0x308fc8UL,   0x2fd8f6UL,   0x2f2224UL,   0x2e6b52UL,   0x2db480UL,   0x2cfdaeUL, 
175
    0x2c46dcUL,   0x2b900aUL,   0x2ad938UL,   0x2a2266UL,   0x296b94UL,   0x28b4c2UL, 
176
    0x27fdf0UL,   0x27471eUL,   0x26904cUL,   0x25d97aUL,   0x2522a8UL,   0x246bd6UL, 
177
    0x23b504UL,   0x22fe32UL,   0x224760UL,   0x21908eUL,   0x20d9bcUL,   0x2022eaUL, 
178
    0x1f6c18UL,   0x1eb546UL,   0x1dfe74UL,   0x1d47a2UL,   0x1c90d0UL,   0x1bd9feUL, 
179
    0x1b232cUL,   0x1a6c5aUL,   0x19b588UL,   0x18feb6UL,   0x1847e4UL,   0x179112UL, 
180
    0x16da40UL,   0x16236eUL,   0x156c9cUL,   0x14b5caUL,   0x13fef8UL,   0x134826UL, 
181
    0x129154UL,   0x11da82UL,   0x1123b0UL,   0x106cdeUL,    0xfb60cUL,    0xeff3aUL, 
182
     0xe4868UL,    0xd9196UL,    0xcdac4UL,    0xc23f2UL,    0xb6d20UL,    0xab64eUL, 
183
     0x9ff7cUL,    0x948aaUL,    0x891d8UL,    0x7db06UL,    0x72434UL,    0x66d62UL, 
184
     0x5b690UL,    0x4ffbeUL,    0x448ecUL,    0x3921aUL,    0x2db48UL,    0x22476UL, 
185
     0x16da4UL,     0xb6d2UL,        0x0UL, 0xffff492eUL, 0xfffe925cUL, 0xfffddb8aUL, 
186
  0xfffd24b8UL, 0xfffc6de6UL, 0xfffbb714UL, 0xfffb0042UL, 0xfffa4970UL, 0xfff9929eUL, 
187
  0xfff8dbccUL, 0xfff824faUL, 0xfff76e28UL, 0xfff6b756UL, 0xfff60084UL, 0xfff549b2UL, 
188
  0xfff492e0UL, 0xfff3dc0eUL, 0xfff3253cUL, 0xfff26e6aUL, 0xfff1b798UL, 0xfff100c6UL, 
189
  0xfff049f4UL, 0xffef9322UL, 0xffeedc50UL, 0xffee257eUL, 0xffed6eacUL, 0xffecb7daUL, 
190
  0xffec0108UL, 0xffeb4a36UL, 0xffea9364UL, 0xffe9dc92UL, 0xffe925c0UL, 0xffe86eeeUL, 
191
  0xffe7b81cUL, 0xffe7014aUL, 0xffe64a78UL, 0xffe593a6UL, 0xffe4dcd4UL, 0xffe42602UL, 
192
  0xffe36f30UL, 0xffe2b85eUL, 0xffe2018cUL, 0xffe14abaUL, 0xffe093e8UL, 0xffdfdd16UL, 
193
  0xffdf2644UL, 0xffde6f72UL, 0xffddb8a0UL, 0xffdd01ceUL, 0xffdc4afcUL, 0xffdb942aUL, 
194
  0xffdadd58UL, 0xffda2686UL, 0xffd96fb4UL, 0xffd8b8e2UL, 0xffd80210UL, 0xffd74b3eUL, 
195
  0xffd6946cUL, 0xffd5dd9aUL, 0xffd526c8UL, 0xffd46ff6UL, 0xffd3b924UL, 0xffd30252UL, 
196
  0xffd24b80UL, 0xffd194aeUL, 0xffd0dddcUL, 0xffd0270aUL, 0xffcf7038UL, 0xffceb966UL, 
197
  0xffce0294UL, 0xffcd4bc2UL, 0xffcc94f0UL, 0xffcbde1eUL, 0xffcb274cUL, 0xffca707aUL, 
198
  0xffc9b9a8UL, 0xffc902d6UL, 0xffc84c04UL, 0xffc79532UL, 0xffc6de60UL, 0xffc6278eUL, 
199
  0xffc570bcUL, 0xffc4b9eaUL, 0xffc40318UL, 0xffc34c46UL, 0xffc29574UL, 0xffc1dea2UL, 
200
  0xffc127d0UL, 0xffc070feUL, 0xffbfba2cUL, 0xffbf035aUL, 0xffbe4c88UL, 0xffbd95b6UL, 
201
  0xffbcdee4UL, 0xffbc2812UL, 0xffbb7140UL, 0xffbaba6eUL, 0xffba039cUL, 0xffb94ccaUL, 
202
  0xffb895f8UL, 0xffb7df26UL, 0xffb72854UL, 0xffb67182UL, 0xffb5bab0UL, 0xffb503deUL, 
203
  0xffb44d0cUL, 0xffb3963aUL, 0xffb2df68UL, 0xffb22896UL, 0xffb171c4UL, 0xffb0baf2UL, 
204
  0xffb00420UL, 0xffaf4d4eUL, 0xffae967cUL, 0xffaddfaaUL, 0xffad28d8UL, 0xffac7206UL, 
205
  0xffabbb34UL, 0xffab0462UL, 0xffaa4d90UL, 0xffa996beUL, 0xffa8dfecUL, 0xffa8291aUL, 
206
  0xffa77248UL, 0xffa6bb76UL, 0xffa604a4UL, 0xffa54dd2UL
207
 };
208
209
const int Cb_g_tab[(MAXJSAMPLE+1) * SIZEOF(int)] ={
210
    0x2c8d00UL,   0x2c34e6UL,   0x2bdcccUL,   0x2b84b2UL,   0x2b2c98UL,   0x2ad47eUL, 
211
    0x2a7c64UL,   0x2a244aUL,   0x29cc30UL,   0x297416UL,   0x291bfcUL,   0x28c3e2UL, 
212
    0x286bc8UL,   0x2813aeUL,   0x27bb94UL,   0x27637aUL,   0x270b60UL,   0x26b346UL, 
213
    0x265b2cUL,   0x260312UL,   0x25aaf8UL,   0x2552deUL,   0x24fac4UL,   0x24a2aaUL, 
214
    0x244a90UL,   0x23f276UL,   0x239a5cUL,   0x234242UL,   0x22ea28UL,   0x22920eUL, 
215
    0x2239f4UL,   0x21e1daUL,   0x2189c0UL,   0x2131a6UL,   0x20d98cUL,   0x208172UL, 
216
    0x202958UL,   0x1fd13eUL,   0x1f7924UL,   0x1f210aUL,   0x1ec8f0UL,   0x1e70d6UL, 
217
    0x1e18bcUL,   0x1dc0a2UL,   0x1d6888UL,   0x1d106eUL,   0x1cb854UL,   0x1c603aUL, 
218
    0x1c0820UL,   0x1bb006UL,   0x1b57ecUL,   0x1affd2UL,   0x1aa7b8UL,   0x1a4f9eUL, 
219
    0x19f784UL,   0x199f6aUL,   0x194750UL,   0x18ef36UL,   0x18971cUL,   0x183f02UL, 
220
    0x17e6e8UL,   0x178eceUL,   0x1736b4UL,   0x16de9aUL,   0x168680UL,   0x162e66UL, 
221
    0x15d64cUL,   0x157e32UL,   0x152618UL,   0x14cdfeUL,   0x1475e4UL,   0x141dcaUL, 
222
    0x13c5b0UL,   0x136d96UL,   0x13157cUL,   0x12bd62UL,   0x126548UL,   0x120d2eUL, 
223
    0x11b514UL,   0x115cfaUL,   0x1104e0UL,   0x10acc6UL,   0x1054acUL,    0xffc92UL, 
224
     0xfa478UL,    0xf4c5eUL,    0xef444UL,    0xe9c2aUL,    0xe4410UL,    0xdebf6UL, 
225
     0xd93dcUL,    0xd3bc2UL,    0xce3a8UL,    0xc8b8eUL,    0xc3374UL,    0xbdb5aUL, 
226
     0xb8340UL,    0xb2b26UL,    0xad30cUL,    0xa7af2UL,    0xa22d8UL,    0x9cabeUL, 
227
     0x972a4UL,    0x91a8aUL,    0x8c270UL,    0x86a56UL,    0x8123cUL,    0x7ba22UL, 
228
     0x76208UL,    0x709eeUL,    0x6b1d4UL,    0x659baUL,    0x601a0UL,    0x5a986UL, 
229
     0x5516cUL,    0x4f952UL,    0x4a138UL,    0x4491eUL,    0x3f104UL,    0x398eaUL, 
230
     0x340d0UL,    0x2e8b6UL,    0x2909cUL,    0x23882UL,    0x1e068UL,    0x1884eUL, 
231
     0x13034UL,     0xd81aUL,     0x8000UL,     0x27e6UL, 0xffffcfccUL, 0xffff77b2UL,
232
  0xffff1f98UL, 0xfffec77eUL, 0xfffe6f64UL, 0xfffe174aUL, 0xfffdbf30UL, 0xfffd6716UL,
233
  0xfffd0efcUL, 0xfffcb6e2UL, 0xfffc5ec8UL, 0xfffc06aeUL, 0xfffbae94UL, 0xfffb567aUL,
234
  0xfffafe60UL, 0xfffaa646UL, 0xfffa4e2cUL, 0xfff9f612UL, 0xfff99df8UL, 0xfff945deUL,
235
  0xfff8edc4UL, 0xfff895aaUL, 0xfff83d90UL, 0xfff7e576UL, 0xfff78d5cUL, 0xfff73542UL,
236
  0xfff6dd28UL, 0xfff6850eUL, 0xfff62cf4UL, 0xfff5d4daUL, 0xfff57cc0UL, 0xfff524a6UL,
237
  0xfff4cc8cUL, 0xfff47472UL, 0xfff41c58UL, 0xfff3c43eUL, 0xfff36c24UL, 0xfff3140aUL,
238
  0xfff2bbf0UL, 0xfff263d6UL, 0xfff20bbcUL, 0xfff1b3a2UL, 0xfff15b88UL, 0xfff1036eUL,
239
  0xfff0ab54UL, 0xfff0533aUL, 0xffeffb20UL, 0xffefa306UL, 0xffef4aecUL, 0xffeef2d2UL,
240
  0xffee9ab8UL, 0xffee429eUL, 0xffedea84UL, 0xffed926aUL, 0xffed3a50UL, 0xffece236UL,
241
  0xffec8a1cUL, 0xffec3202UL, 0xffebd9e8UL, 0xffeb81ceUL, 0xffeb29b4UL, 0xffead19aUL,
242
  0xffea7980UL, 0xffea2166UL, 0xffe9c94cUL, 0xffe97132UL, 0xffe91918UL, 0xffe8c0feUL,
243
  0xffe868e4UL, 0xffe810caUL, 0xffe7b8b0UL, 0xffe76096UL, 0xffe7087cUL, 0xffe6b062UL,
244
  0xffe65848UL, 0xffe6002eUL, 0xffe5a814UL, 0xffe54ffaUL, 0xffe4f7e0UL, 0xffe49fc6UL,
245
  0xffe447acUL, 0xffe3ef92UL, 0xffe39778UL, 0xffe33f5eUL, 0xffe2e744UL, 0xffe28f2aUL,
246
  0xffe23710UL, 0xffe1def6UL, 0xffe186dcUL, 0xffe12ec2UL, 0xffe0d6a8UL, 0xffe07e8eUL,
247
  0xffe02674UL, 0xffdfce5aUL, 0xffdf7640UL, 0xffdf1e26UL, 0xffdec60cUL, 0xffde6df2UL,
248
  0xffde15d8UL, 0xffddbdbeUL, 0xffdd65a4UL, 0xffdd0d8aUL, 0xffdcb570UL, 0xffdc5d56UL,
249
  0xffdc053cUL, 0xffdbad22UL, 0xffdb5508UL, 0xffdafceeUL, 0xffdaa4d4UL, 0xffda4cbaUL,
250
  0xffd9f4a0UL, 0xffd99c86UL, 0xffd9446cUL, 0xffd8ec52UL, 0xffd89438UL, 0xffd83c1eUL,
251
  0xffd7e404UL, 0xffd78beaUL, 0xffd733d0UL, 0xffd6dbb6UL, 0xffd6839cUL, 0xffd62b82UL,
252
  0xffd5d368UL, 0xffd57b4eUL, 0xffd52334UL, 0xffd4cb1aUL
253
 };
254
67
255
/*
68
/*
256
 * Initialize tables for YCC->RGB colorspace conversion.
69
 * Initialize tables for YCC->RGB colorspace conversion.
257
 */
70
 */
258
71
259
LOCAL(void)
72
LOCAL(void)
260
build_ycc_rgb_table (j_decompress_ptr cinfo)
73
build_ycc_rgb_table (j_decompress_ptr cinfo)
261
{
74
{
262
263
  /* The code below was used to generate the static tables above */
264
265
#if 0
266
  my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
75
  my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
267
  int i;
76
  int i;
268
  INT32 x;
77
  INT32 x;
269
  SHIFT_TEMPS
78
  SHIFT_TEMPS
270
79
271
  cconvert->Cr_r_tab = (int *)
80
  cconvert->Cr_r_tab = (int *)
272
    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
81
    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
273
				(MAXJSAMPLE+1) * SIZEOF(int));
82
				(MAXJSAMPLE+1) * SIZEOF(int));
 Lines 291-307   build_ycc_rgb_table (j_decompress_ptr ci Link Here 
291
    cconvert->Cb_b_tab[i] = (int)
100
    cconvert->Cb_b_tab[i] = (int)
292
		    RIGHT_SHIFT(FIX(1.77200) * x + ONE_HALF, SCALEBITS);
101
		    RIGHT_SHIFT(FIX(1.77200) * x + ONE_HALF, SCALEBITS);
293
    /* Cr=>G value is scaled-up -0.71414 * x */
102
    /* Cr=>G value is scaled-up -0.71414 * x */
294
    cconvert->Cr_g_tab[i] = (- FIX(0.71414)) * x;
103
    cconvert->Cr_g_tab[i] = (- FIX(0.71414)) * x;
295
    /* Cb=>G value is scaled-up -0.34414 * x */
104
    /* Cb=>G value is scaled-up -0.34414 * x */
296
    /* We also add in ONE_HALF so that need not do it in inner loop */
105
    /* We also add in ONE_HALF so that need not do it in inner loop */
297
    cconvert->Cb_g_tab[i] = (- FIX(0.34414)) * x + ONE_HALF;
106
    cconvert->Cb_g_tab[i] = (- FIX(0.34414)) * x + ONE_HALF;
298
  }
107
  }
299
#endif /* 0 */
300
}
108
}
301
109
302
110
303
/*
111
/*
304
 * Convert some rows of samples to the output colorspace.
112
 * Convert some rows of samples to the output colorspace.
305
 *
113
 *
306
 * Note that we change from noninterleaved, one-plane-per-component format
114
 * Note that we change from noninterleaved, one-plane-per-component format
307
 * to interleaved-pixel format.  The output buffer is therefore three times
115
 * to interleaved-pixel format.  The output buffer is therefore three times
 Lines 313-354   build_ycc_rgb_table (j_decompress_ptr ci Link Here 
313
121
314
METHODDEF(void)
122
METHODDEF(void)
315
ycc_rgb_convert (j_decompress_ptr cinfo,
123
ycc_rgb_convert (j_decompress_ptr cinfo,
316
		 JSAMPIMAGE input_buf, JDIMENSION input_row,
124
		 JSAMPIMAGE input_buf, JDIMENSION input_row,
317
		 JSAMPARRAY output_buf, int num_rows)
125
		 JSAMPARRAY output_buf, int num_rows)
318
{
126
{
319
  my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
127
  my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
320
  register int y, cb, cr;
128
  register int y, cb, cr;
321
  JSAMPLE * range_limit_y;
129
  register JSAMPROW outptr;
322
  JSAMPROW outptr;
130
  register JSAMPROW inptr0, inptr1, inptr2;
323
  JSAMPROW inptr0, inptr1, inptr2;
131
  register JDIMENSION col;
324
  JDIMENSION col;
325
  JDIMENSION num_cols = cinfo->output_width;
132
  JDIMENSION num_cols = cinfo->output_width;
326
  JSAMPLE * range_limit = cinfo->sample_range_limit;
133
  /* copy these pointers into registers if possible */
134
  register JSAMPLE * range_limit = cinfo->sample_range_limit;
135
  register int * Crrtab = cconvert->Cr_r_tab;
136
  register int * Cbbtab = cconvert->Cb_b_tab;
137
  register INT32 * Crgtab = cconvert->Cr_g_tab;
138
  register INT32 * Cbgtab = cconvert->Cb_g_tab;
327
  SHIFT_TEMPS
139
  SHIFT_TEMPS
328
140
329
  while (--num_rows >= 0) {
141
  while (--num_rows >= 0) {
330
    inptr0 = input_buf[0][input_row];
142
    inptr0 = input_buf[0][input_row];
331
    inptr1 = input_buf[1][input_row];
143
    inptr1 = input_buf[1][input_row];
332
    inptr2 = input_buf[2][input_row];
144
    inptr2 = input_buf[2][input_row];
333
    input_row++;
145
    input_row++;
334
    outptr = *output_buf++;
146
    outptr = *output_buf++;
335
    for (col = 0; col < num_cols; col++) {
147
    for (col = 0; col < num_cols; col++) {
336
      y  = GETJSAMPLE(inptr0[col]);
148
      y  = GETJSAMPLE(inptr0[col]);
337
      cb = GETJSAMPLE(inptr1[col]);
149
      cb = GETJSAMPLE(inptr1[col]);
338
      cr = GETJSAMPLE(inptr2[col]);
150
      cr = GETJSAMPLE(inptr2[col]);
339
      range_limit_y = range_limit + y;
340
      /* Range-limiting is essential due to noise introduced by DCT losses. */
151
      /* Range-limiting is essential due to noise introduced by DCT losses. */
341
      outptr[RGB_RED] =   range_limit_y[Cr_r_tab[cr]];
152
      outptr[rgb_red[cinfo->out_color_space]] =   range_limit[y + Crrtab[cr]];
342
      outptr[RGB_GREEN] = range_limit_y[
153
      outptr[rgb_green[cinfo->out_color_space]] = range_limit[y +
343
			      ((int) RIGHT_SHIFT(Cb_g_tab[cb] + Cr_g_tab[cr],
154
			      ((int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr],
344
						 SCALEBITS))];
155
						 SCALEBITS))];
345
      outptr[RGB_BLUE] =  range_limit_y[Cb_b_tab[cb]];
156
      outptr[rgb_blue[cinfo->out_color_space]] =  range_limit[y + Cbbtab[cb]];
346
      outptr += RGB_PIXELSIZE;
157
      outptr += rgb_pixelsize[cinfo->out_color_space];
347
    }
158
    }
348
  }
159
  }
349
}
160
}
350
161
351
162
352
/**************** Cases other than YCbCr -> RGB **************/
163
/**************** Cases other than YCbCr -> RGB **************/
353
164
354
165
 Lines 406-474   grayscale_convert (j_decompress_ptr cinf Link Here 
406
 */
217
 */
407
218
408
METHODDEF(void)
219
METHODDEF(void)
409
gray_rgb_convert (j_decompress_ptr cinfo,
220
gray_rgb_convert (j_decompress_ptr cinfo,
410
		  JSAMPIMAGE input_buf, JDIMENSION input_row,
221
		  JSAMPIMAGE input_buf, JDIMENSION input_row,
411
		  JSAMPARRAY output_buf, int num_rows)
222
		  JSAMPARRAY output_buf, int num_rows)
412
{
223
{
413
  register JSAMPROW inptr, outptr;
224
  register JSAMPROW inptr, outptr;
225
  JSAMPLE *maxinptr;
414
  register JDIMENSION col;
226
  register JDIMENSION col;
415
  JDIMENSION num_cols = cinfo->output_width;
227
  JDIMENSION num_cols = cinfo->output_width;
228
  int rindex = rgb_red[cinfo->out_color_space];
229
  int gindex = rgb_green[cinfo->out_color_space];
230
  int bindex = rgb_blue[cinfo->out_color_space];
231
  int rgbstride = rgb_pixelsize[cinfo->out_color_space];
416
232
417
  while (--num_rows >= 0) {
233
  while (--num_rows >= 0) {
418
    inptr = input_buf[0][input_row++];
234
    inptr = input_buf[0][input_row++];
235
    maxinptr = &inptr[num_cols];
419
    outptr = *output_buf++;
236
    outptr = *output_buf++;
420
    for (col = 0; col < num_cols; col++) {
237
    for (; inptr < maxinptr; inptr++, outptr += rgbstride) {
421
      /* We can dispense with GETJSAMPLE() here */
238
      /* We can dispense with GETJSAMPLE() here */
422
      outptr[RGB_RED] = outptr[RGB_GREEN] = outptr[RGB_BLUE] = inptr[col];
239
      outptr[rindex] = outptr[gindex] = outptr[bindex] = *inptr;
423
      outptr += RGB_PIXELSIZE;
424
    }
240
    }
425
  }
241
  }
426
}
242
}
427
243
428
244
429
/*
245
/*
430
 * Adobe-style YCCK->CMYK conversion.
246
 * Adobe-style YCCK->CMYK conversion.
431
 * We convert YCbCr to R=1-C, G=1-M, and B=1-Y using the same
247
 * We convert YCbCr to R=1-C, G=1-M, and B=1-Y using the same
432
 * conversion as above, while passing K (black) unchanged.
248
 * conversion as above, while passing K (black) unchanged.
249
 * We assume build_ycc_rgb_table has been called.
433
 */
250
 */
434
251
435
METHODDEF(void)
252
METHODDEF(void)
436
ycck_cmyk_convert (j_decompress_ptr cinfo,
253
ycck_cmyk_convert (j_decompress_ptr cinfo,
437
		   JSAMPIMAGE input_buf, JDIMENSION input_row,
254
		   JSAMPIMAGE input_buf, JDIMENSION input_row,
438
		   JSAMPARRAY output_buf, int num_rows)
255
		   JSAMPARRAY output_buf, int num_rows)
439
{
256
{
440
  my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
257
  my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
441
  register int y, cb, cr;
258
  register int y, cb, cr;
442
  register JSAMPROW outptr;
259
  register JSAMPROW outptr;
443
  register JSAMPROW inptr0, inptr1, inptr2, inptr3;
260
  register JSAMPROW inptr0, inptr1, inptr2, inptr3;
444
  register JDIMENSION col;
261
  register JDIMENSION col;
445
  JDIMENSION num_cols = cinfo->output_width;
262
  JDIMENSION num_cols = cinfo->output_width;
446
  /* copy these pointers into registers if possible */
263
  /* copy these pointers into registers if possible */
447
  register JSAMPLE * range_limit = cinfo->sample_range_limit;
264
  register JSAMPLE * range_limit = cinfo->sample_range_limit;
265
  register int * Crrtab = cconvert->Cr_r_tab;
266
  register int * Cbbtab = cconvert->Cb_b_tab;
267
  register INT32 * Crgtab = cconvert->Cr_g_tab;
268
  register INT32 * Cbgtab = cconvert->Cb_g_tab;
448
  SHIFT_TEMPS
269
  SHIFT_TEMPS
449
270
450
  while (--num_rows >= 0) {
271
  while (--num_rows >= 0) {
451
    inptr0 = input_buf[0][input_row];
272
    inptr0 = input_buf[0][input_row];
452
    inptr1 = input_buf[1][input_row];
273
    inptr1 = input_buf[1][input_row];
453
    inptr2 = input_buf[2][input_row];
274
    inptr2 = input_buf[2][input_row];
454
    inptr3 = input_buf[3][input_row];
275
    inptr3 = input_buf[3][input_row];
455
    input_row++;
276
    input_row++;
456
    outptr = *output_buf++;
277
    outptr = *output_buf++;
457
    for (col = 0; col < num_cols; col++) {
278
    for (col = 0; col < num_cols; col++) {
458
      y  = GETJSAMPLE(inptr0[col]);
279
      y  = GETJSAMPLE(inptr0[col]);
459
      cb = GETJSAMPLE(inptr1[col]);
280
      cb = GETJSAMPLE(inptr1[col]);
460
      cr = GETJSAMPLE(inptr2[col]);
281
      cr = GETJSAMPLE(inptr2[col]);
461
      /* Range-limiting is essential due to noise introduced by DCT losses. */
282
      /* Range-limiting is essential due to noise introduced by DCT losses. */
462
      outptr[0] = range_limit[MAXJSAMPLE - (y + Cr_r_tab[cr])];   /* red */
283
      outptr[0] = range_limit[MAXJSAMPLE - (y + Crrtab[cr])];	/* red */
463
      outptr[1] = range_limit[MAXJSAMPLE - (y +                   /* green */
284
      outptr[1] = range_limit[MAXJSAMPLE - (y +			/* green */
464
				  ((int) RIGHT_SHIFT(Cb_g_tab[cb] + Cr_g_tab[cr],
285
			      ((int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr],
465
                         SCALEBITS)))];
286
						 SCALEBITS)))];
466
      outptr[2] = range_limit[MAXJSAMPLE - (y + Cb_b_tab[cb])];   /* blue */
287
      outptr[2] = range_limit[MAXJSAMPLE - (y + Cbbtab[cb])];	/* blue */
467
      /* K passes through unchanged */
288
      /* K passes through unchanged */
468
      outptr[3] = inptr3[col];	/* don't need GETJSAMPLE here */
289
      outptr[3] = inptr3[col];	/* don't need GETJSAMPLE here */
469
      outptr += 4;
290
      outptr += 4;
470
    }
291
    }
471
  }
292
  }
472
}
293
}
473
294
474
295
 Lines 538-560   jinit_color_deconverter (j_decompress_pt Link Here 
538
      /* For color->grayscale conversion, only the Y (0) component is needed */
359
      /* For color->grayscale conversion, only the Y (0) component is needed */
539
      for (ci = 1; ci < cinfo->num_components; ci++)
360
      for (ci = 1; ci < cinfo->num_components; ci++)
540
	cinfo->comp_info[ci].component_needed = FALSE;
361
	cinfo->comp_info[ci].component_needed = FALSE;
541
    } else
362
    } else
542
      ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
363
      ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
543
    break;
364
    break;
544
365
545
  case JCS_RGB:
366
  case JCS_RGB:
546
    cinfo->out_color_components = RGB_PIXELSIZE;
367
  case JCS_EXT_RGB:
368
  case JCS_EXT_RGBX:
369
  case JCS_EXT_BGR:
370
  case JCS_EXT_BGRX:
371
  case JCS_EXT_XBGR:
372
  case JCS_EXT_XRGB:
373
    cinfo->out_color_components = rgb_pixelsize[cinfo->out_color_space];
547
    if (cinfo->jpeg_color_space == JCS_YCbCr) {
374
    if (cinfo->jpeg_color_space == JCS_YCbCr) {
548
      cconvert->pub.color_convert = ycc_rgb_convert;
375
      if (jsimd_can_ycc_rgb())
549
      build_ycc_rgb_table(cinfo);
376
        cconvert->pub.color_convert = jsimd_ycc_rgb_convert;
377
      else {
378
        cconvert->pub.color_convert = ycc_rgb_convert;
379
        build_ycc_rgb_table(cinfo);
380
      }
550
    } else if (cinfo->jpeg_color_space == JCS_GRAYSCALE) {
381
    } else if (cinfo->jpeg_color_space == JCS_GRAYSCALE) {
551
      cconvert->pub.color_convert = gray_rgb_convert;
382
      cconvert->pub.color_convert = gray_rgb_convert;
552
    } else if (cinfo->jpeg_color_space == JCS_RGB && RGB_PIXELSIZE == 3) {
383
    } else if (cinfo->jpeg_color_space == cinfo->out_color_space &&
384
      rgb_pixelsize[cinfo->out_color_space] == 3) {
553
      cconvert->pub.color_convert = null_convert;
385
      cconvert->pub.color_convert = null_convert;
554
    } else
386
    } else
555
      ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
387
      ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
556
    break;
388
    break;
557
389
558
  case JCS_CMYK:
390
  case JCS_CMYK:
559
    cinfo->out_color_components = 4;
391
    cinfo->out_color_components = 4;
560
    if (cinfo->jpeg_color_space == JCS_YCCK) {
392
    if (cinfo->jpeg_color_space == JCS_YCCK) {
(-)a/jpeg/jdct.h (-4 / +12 lines)
Line     Link Here 
 Lines 18-45    Link Here 
18
 * the DCT is to be performed in-place in that buffer.  Type DCTELEM is int
18
 * the DCT is to be performed in-place in that buffer.  Type DCTELEM is int
19
 * for 8-bit samples, INT32 for 12-bit samples.  (NOTE: Floating-point DCT
19
 * for 8-bit samples, INT32 for 12-bit samples.  (NOTE: Floating-point DCT
20
 * implementations use an array of type FAST_FLOAT, instead.)
20
 * implementations use an array of type FAST_FLOAT, instead.)
21
 * The DCT inputs are expected to be signed (range +-CENTERJSAMPLE).
21
 * The DCT inputs are expected to be signed (range +-CENTERJSAMPLE).
22
 * The DCT outputs are returned scaled up by a factor of 8; they therefore
22
 * The DCT outputs are returned scaled up by a factor of 8; they therefore
23
 * have a range of +-8K for 8-bit data, +-128K for 12-bit data.  This
23
 * have a range of +-8K for 8-bit data, +-128K for 12-bit data.  This
24
 * convention improves accuracy in integer implementations and saves some
24
 * convention improves accuracy in integer implementations and saves some
25
 * work in floating-point ones.
25
 * work in floating-point ones.
26
 * Quantization of the output coefficients is done by jcdctmgr.c.
26
 * Quantization of the output coefficients is done by jcdctmgr.c. This
27
 * step requires an unsigned type and also one with twice the bits.
27
 */
28
 */
28
29
29
#if BITS_IN_JSAMPLE == 8
30
#if BITS_IN_JSAMPLE == 8
31
#ifndef WITH_SIMD
30
typedef int DCTELEM;		/* 16 or 32 bits is fine */
32
typedef int DCTELEM;		/* 16 or 32 bits is fine */
33
typedef unsigned int UDCTELEM;
34
typedef unsigned long long UDCTELEM2;
35
#else
36
typedef short DCTELEM;  /* prefer 16 bit with SIMD for parellelism */
37
typedef unsigned short UDCTELEM;
38
typedef unsigned int UDCTELEM2;
39
#endif
31
#else
40
#else
32
typedef INT32 DCTELEM;		/* must have 32 bits */
41
typedef INT32 DCTELEM;		/* must have 32 bits */
42
typedef UINT32 UDCTELEM;
43
typedef unsigned long long UDCTELEM2;
33
#endif
44
#endif
34
45
35
typedef JMETHOD(void, forward_DCT_method_ptr, (DCTELEM * data));
36
typedef JMETHOD(void, float_DCT_method_ptr, (FAST_FLOAT * data));
37
38
46
39
/*
47
/*
40
 * An inverse DCT routine is given a pointer to the input JBLOCK and a pointer
48
 * An inverse DCT routine is given a pointer to the input JBLOCK and a pointer
41
 * to an output sample array.  The routine must dequantize the input data as
49
 * to an output sample array.  The routine must dequantize the input data as
42
 * well as perform the IDCT; for dequantization, it uses the multiplier table
50
 * well as perform the IDCT; for dequantization, it uses the multiplier table
43
 * pointed to by compptr->dct_table.  The output data is to be placed into the
51
 * pointed to by compptr->dct_table.  The output data is to be placed into the
44
 * sample array starting at a specified column.  (Any row offset needed will
52
 * sample array starting at a specified column.  (Any row offset needed will
45
 * be applied to the array pointer before it is passed to the IDCT code.)
53
 * be applied to the array pointer before it is passed to the IDCT code.)
(-)a/jpeg/jddctmgr.c (-46 / +25 lines)
Line     Link Here 
 Lines 1-12    Link Here 
1
/*
1
/*
2
 * jddctmgr.c
2
 * jddctmgr.c
3
 *
3
 *
4
 * Copyright (C) 1994-1996, Thomas G. Lane.
4
 * Copyright (C) 1994-1996, Thomas G. Lane.
5
 * Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
5
 * This file is part of the Independent JPEG Group's software.
6
 * This file is part of the Independent JPEG Group's software.
6
 * For conditions of distribution and use, see the accompanying README file.
7
 * For conditions of distribution and use, see the accompanying README file.
7
 *
8
 *
8
 * This file contains the inverse-DCT management logic.
9
 * This file contains the inverse-DCT management logic.
9
 * This code selects a particular IDCT implementation to be used,
10
 * This code selects a particular IDCT implementation to be used,
10
 * and it performs related housekeeping chores.  No code in this file
11
 * and it performs related housekeeping chores.  No code in this file
11
 * is executed per IDCT step, only during output pass setup.
12
 * is executed per IDCT step, only during output pass setup.
12
 *
13
 *
 Lines 14-32    Link Here 
14
 * dequantization as well as the IDCT proper.  This module sets up the
15
 * dequantization as well as the IDCT proper.  This module sets up the
15
 * dequantization multiplier table needed by the IDCT routine.
16
 * dequantization multiplier table needed by the IDCT routine.
16
 */
17
 */
17
18
18
#define JPEG_INTERNALS
19
#define JPEG_INTERNALS
19
#include "jinclude.h"
20
#include "jinclude.h"
20
#include "jpeglib.h"
21
#include "jpeglib.h"
21
#include "jdct.h"		/* Private declarations for DCT subsystem */
22
#include "jdct.h"		/* Private declarations for DCT subsystem */
22
#ifdef HAVE_SSE2_INTRINSICS
23
#include "jsimddct.h"
23
extern int SSE2Available;
24
24
#endif
25
25
26
/*
26
/*
27
 * The decompressor input side (jdinput.c) saves away the appropriate
27
 * The decompressor input side (jdinput.c) saves away the appropriate
28
 * quantization table for each component at the start of the first scan
28
 * quantization table for each component at the start of the first scan
29
 * involving that component.  (This is necessary in order to correctly
29
 * involving that component.  (This is necessary in order to correctly
30
 * decode files that reuse Q-table slots.)
30
 * decode files that reuse Q-table slots.)
31
 * When we are ready to make an output pass, the saved Q-table is converted
31
 * When we are ready to make an output pass, the saved Q-table is converted
32
 * to a multiplier table that will actually be used by the IDCT routine.
32
 * to a multiplier table that will actually be used by the IDCT routine.
 Lines 75-98   typedef union { Link Here 
75
#ifdef DCT_ISLOW_SUPPORTED
75
#ifdef DCT_ISLOW_SUPPORTED
76
#define PROVIDE_ISLOW_TABLES
76
#define PROVIDE_ISLOW_TABLES
77
#else
77
#else
78
#ifdef IDCT_SCALING_SUPPORTED
78
#ifdef IDCT_SCALING_SUPPORTED
79
#define PROVIDE_ISLOW_TABLES
79
#define PROVIDE_ISLOW_TABLES
80
#endif
80
#endif
81
#endif
81
#endif
82
82
83
GLOBAL(void)
84
jpeg_idct_islow_sse2 (
85
	j_decompress_ptr cinfo, 
86
	jpeg_component_info * compptr,
87
	JCOEFPTR coef_block,
88
	JSAMPARRAY output_buf, 
89
	JDIMENSION output_col);
90
91
83
92
/*
84
/*
93
 * Prepare for an output pass.
85
 * Prepare for an output pass.
94
 * Here we select the proper IDCT routine for each component and build
86
 * Here we select the proper IDCT routine for each component and build
95
 * a matching multiplier table.
87
 * a matching multiplier table.
96
 */
88
 */
97
89
98
METHODDEF(void)
90
METHODDEF(void)
 Lines 110-178   start_pass (j_decompress_ptr cinfo) Link Here 
110
    /* Select the proper IDCT routine for this component's scaling */
102
    /* Select the proper IDCT routine for this component's scaling */
111
    switch (compptr->DCT_scaled_size) {
103
    switch (compptr->DCT_scaled_size) {
112
#ifdef IDCT_SCALING_SUPPORTED
104
#ifdef IDCT_SCALING_SUPPORTED
113
    case 1:
105
    case 1:
114
      method_ptr = jpeg_idct_1x1;
106
      method_ptr = jpeg_idct_1x1;
115
      method = JDCT_ISLOW;	/* jidctred uses islow-style table */
107
      method = JDCT_ISLOW;	/* jidctred uses islow-style table */
116
      break;
108
      break;
117
    case 2:
109
    case 2:
118
      method_ptr = jpeg_idct_2x2;
110
      if (jsimd_can_idct_2x2())
111
        method_ptr = jsimd_idct_2x2;
112
      else
113
        method_ptr = jpeg_idct_2x2;
119
      method = JDCT_ISLOW;	/* jidctred uses islow-style table */
114
      method = JDCT_ISLOW;	/* jidctred uses islow-style table */
120
      break;
115
      break;
121
    case 4:
116
    case 4:
122
      method_ptr = jpeg_idct_4x4;
117
      if (jsimd_can_idct_4x4())
118
        method_ptr = jsimd_idct_4x4;
119
      else
120
        method_ptr = jpeg_idct_4x4;
123
      method = JDCT_ISLOW;	/* jidctred uses islow-style table */
121
      method = JDCT_ISLOW;	/* jidctred uses islow-style table */
124
      break;
122
      break;
125
#endif
123
#endif
126
    case DCTSIZE:
124
    case DCTSIZE:
127
      switch (cinfo->dct_method) {
125
      switch (cinfo->dct_method) {
128
#ifdef DCT_ISLOW_SUPPORTED
126
#ifdef DCT_ISLOW_SUPPORTED
129
      case JDCT_ISLOW:
127
      case JDCT_ISLOW:
130
#ifdef HAVE_SSE2_INTEL_MNEMONICS
128
	if (jsimd_can_idct_islow())
131
		if(SSE2Available == 1)
129
	  method_ptr = jsimd_idct_islow;
132
		{
130
	else
133
			method_ptr = jpeg_idct_islow_sse2;
131
	  method_ptr = jpeg_idct_islow;
134
			method = JDCT_ISLOW;
132
	method = JDCT_ISLOW;
135
		}
136
		else
137
		{
138
			method_ptr = jpeg_idct_islow;
139
			method = JDCT_ISLOW;
140
		}
141
#else
142
		method_ptr = jpeg_idct_islow;
143
		method = JDCT_ISLOW;
144
		  
145
#endif /* HAVE_SSE2_INTEL_MNEMONICS */
146
	break;
133
	break;
147
#endif
134
#endif
148
#ifdef DCT_IFAST_SUPPORTED
135
#ifdef DCT_IFAST_SUPPORTED
149
      case JDCT_IFAST:
136
      case JDCT_IFAST:
150
#ifdef HAVE_SSE2_INTEL_MNEMONICS
137
	if (jsimd_can_idct_ifast())
151
		if (SSE2Available==1) 
138
	  method_ptr = jsimd_idct_ifast;
152
		{
139
	else
153
			method_ptr = jpeg_idct_islow_sse2;
140
	  method_ptr = jpeg_idct_ifast;
154
			method = JDCT_ISLOW;
141
	method = JDCT_IFAST;
155
		}
156
		else
157
		{
158
			method_ptr = jpeg_idct_ifast;
159
			method = JDCT_IFAST;
160
		}
161
#else
162
		method_ptr = jpeg_idct_ifast;
163
		method = JDCT_IFAST;
164
#endif /* HAVE_SSE2_INTEL_MNEMONICS */
165
	break;
142
	break;
166
167
#endif
143
#endif
168
#ifdef DCT_FLOAT_SUPPORTED
144
#ifdef DCT_FLOAT_SUPPORTED
169
      case JDCT_FLOAT:
145
      case JDCT_FLOAT:
170
	method_ptr = jpeg_idct_float;
146
	if (jsimd_can_idct_float())
147
	  method_ptr = jsimd_idct_float;
148
	else
149
	  method_ptr = jpeg_idct_float;
171
	method = JDCT_FLOAT;
150
	method = JDCT_FLOAT;
172
	break;
151
	break;
173
#endif
152
#endif
174
      default:
153
      default:
175
	ERREXIT(cinfo, JERR_NOT_COMPILED);
154
	ERREXIT(cinfo, JERR_NOT_COMPILED);
176
	break;
155
	break;
177
      }
156
      }
178
      break;
157
      break;
(-)a/jpeg/jdmarker.c (-1 / +3 lines)
Line     Link Here 
 Lines 74-90   typedef enum { /* JPEG marker codes */ Link Here 
74
  M_APP13 = 0xed,
74
  M_APP13 = 0xed,
75
  M_APP14 = 0xee,
75
  M_APP14 = 0xee,
76
  M_APP15 = 0xef,
76
  M_APP15 = 0xef,
77
  
77
  
78
  M_JPG0  = 0xf0,
78
  M_JPG0  = 0xf0,
79
  M_JPG13 = 0xfd,
79
  M_JPG13 = 0xfd,
80
  M_COM   = 0xfe,
80
  M_COM   = 0xfe,
81
  
81
  
82
  M_TEM   = 0x01
82
  M_TEM   = 0x01,
83
  
84
  M_ERROR = 0x100
83
} JPEG_MARKER;
85
} JPEG_MARKER;
84
86
85
87
86
/* Private state */
88
/* Private state */
87
89
88
typedef struct {
90
typedef struct {
89
  struct jpeg_marker_reader pub; /* public fields */
91
  struct jpeg_marker_reader pub; /* public fields */
90
92
(-)a/jpeg/jdmaster.c (-113 / +16 lines)
Line     Link Here 
 Lines 1-123    Link Here 
1
/*
1
/*
2
 * jdmaster.c
2
 * jdmaster.c
3
 *
3
 *
4
 * Copyright (C) 1991-1997, Thomas G. Lane.
4
 * Copyright (C) 1991-1997, Thomas G. Lane.
5
 * Copyright (C) 2009, D. R. Commander.
5
 * This file is part of the Independent JPEG Group's software.
6
 * This file is part of the Independent JPEG Group's software.
6
 * For conditions of distribution and use, see the accompanying README file.
7
 * For conditions of distribution and use, see the accompanying README file.
7
 *
8
 *
8
 * This file contains master control logic for the JPEG decompressor.
9
 * This file contains master control logic for the JPEG decompressor.
9
 * These routines are concerned with selecting the modules to be executed
10
 * These routines are concerned with selecting the modules to be executed
10
 * and with determining the number of passes and the work to be done in each
11
 * and with determining the number of passes and the work to be done in each
11
 * pass.
12
 * pass.
12
 */
13
 */
13
14
14
#define JPEG_INTERNALS
15
#define JPEG_INTERNALS
15
#include "jinclude.h"
16
#include "jinclude.h"
16
#include "jpeglib.h"
17
#include "jpeglib.h"
17
18
18
/* Use static array */
19
20
const JSAMPLE static_range_table[ (5 * (MAXJSAMPLE+1) + CENTERJSAMPLE) * SIZEOF(JSAMPLE) ]={
21
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
22
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
23
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
24
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
25
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
26
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
27
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
28
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
29
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
30
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
31
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
32
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
33
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
34
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
35
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
36
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
37
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
38
 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 
39
 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 
40
 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 
41
 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 
42
 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 
43
 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 
44
 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 
45
 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 
46
 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 
47
 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, 0x94, 
48
 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 
49
 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 
50
 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, 0xc0, 0xc1, 
51
 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0, 
52
 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 
53
 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 
54
 0xef, 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 
55
 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
56
 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
57
 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
58
 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
59
 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
60
 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
61
 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
62
 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
63
 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
64
 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
65
 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
66
 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
67
 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
68
 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
69
 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
70
 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
71
 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
72
 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
73
 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
74
 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
75
 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
76
 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
77
 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
78
 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
79
 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
80
 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 
81
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
82
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
83
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
84
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
85
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
86
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
87
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
88
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
89
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
90
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
91
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
92
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
93
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
94
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
95
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
96
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
97
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
98
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
99
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
100
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
101
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
102
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
103
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
104
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
105
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
106
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 
107
 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 
108
 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 
109
 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 
110
 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 
111
 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, 0x54, 
112
 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x60, 0x61, 0x62, 0x63, 
113
 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 
114
 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f
115
};
116
19
117
/* Private state */
20
/* Private state */
118
21
119
typedef struct {
22
typedef struct {
120
  struct jpeg_decomp_master pub; /* public fields */
23
  struct jpeg_decomp_master pub; /* public fields */
121
24
122
  int pass_number;		/* # of passes completed */
25
  int pass_number;		/* # of passes completed */
123
26
 Lines 142-159   LOCAL(boolean) Link Here 
142
use_merged_upsample (j_decompress_ptr cinfo)
45
use_merged_upsample (j_decompress_ptr cinfo)
143
{
46
{
144
#ifdef UPSAMPLE_MERGING_SUPPORTED
47
#ifdef UPSAMPLE_MERGING_SUPPORTED
145
  /* Merging is the equivalent of plain box-filter upsampling */
48
  /* Merging is the equivalent of plain box-filter upsampling */
146
  if (cinfo->do_fancy_upsampling || cinfo->CCIR601_sampling)
49
  if (cinfo->do_fancy_upsampling || cinfo->CCIR601_sampling)
147
    return FALSE;
50
    return FALSE;
148
  /* jdmerge.c only supports YCC=>RGB color conversion */
51
  /* jdmerge.c only supports YCC=>RGB color conversion */
149
  if (cinfo->jpeg_color_space != JCS_YCbCr || cinfo->num_components != 3 ||
52
  if (cinfo->jpeg_color_space != JCS_YCbCr || cinfo->num_components != 3 ||
150
      cinfo->out_color_space != JCS_RGB ||
53
      (cinfo->out_color_space != JCS_RGB &&
151
      cinfo->out_color_components != RGB_PIXELSIZE)
54
      cinfo->out_color_space != JCS_EXT_RGB &&
55
      cinfo->out_color_space != JCS_EXT_RGBX &&
56
      cinfo->out_color_space != JCS_EXT_BGR &&
57
      cinfo->out_color_space != JCS_EXT_BGRX &&
58
      cinfo->out_color_space != JCS_EXT_XBGR &&
59
      cinfo->out_color_space != JCS_EXT_XRGB) ||
60
      cinfo->out_color_components != rgb_pixelsize[cinfo->out_color_space])
152
    return FALSE;
61
    return FALSE;
153
  /* and it only handles 2h1v or 2h2v sampling ratios */
62
  /* and it only handles 2h1v or 2h2v sampling ratios */
154
  if (cinfo->comp_info[0].h_samp_factor != 2 ||
63
  if (cinfo->comp_info[0].h_samp_factor != 2 ||
155
      cinfo->comp_info[1].h_samp_factor != 1 ||
64
      cinfo->comp_info[1].h_samp_factor != 1 ||
156
      cinfo->comp_info[2].h_samp_factor != 1 ||
65
      cinfo->comp_info[2].h_samp_factor != 1 ||
157
      cinfo->comp_info[0].v_samp_factor >  2 ||
66
      cinfo->comp_info[0].v_samp_factor >  2 ||
158
      cinfo->comp_info[1].v_samp_factor != 1 ||
67
      cinfo->comp_info[1].v_samp_factor != 1 ||
159
      cinfo->comp_info[2].v_samp_factor != 1)
68
      cinfo->comp_info[2].v_samp_factor != 1)
 Lines 268-287   jpeg_calc_output_dimensions (j_decompres Link Here 
268
177
269
  /* Report number of components in selected colorspace. */
178
  /* Report number of components in selected colorspace. */
270
  /* Probably this should be in the color conversion module... */
179
  /* Probably this should be in the color conversion module... */
271
  switch (cinfo->out_color_space) {
180
  switch (cinfo->out_color_space) {
272
  case JCS_GRAYSCALE:
181
  case JCS_GRAYSCALE:
273
    cinfo->out_color_components = 1;
182
    cinfo->out_color_components = 1;
274
    break;
183
    break;
275
  case JCS_RGB:
184
  case JCS_RGB:
276
#if RGB_PIXELSIZE != 3
185
  case JCS_EXT_RGB:
277
    cinfo->out_color_components = RGB_PIXELSIZE;
186
  case JCS_EXT_RGBX:
187
  case JCS_EXT_BGR:
188
  case JCS_EXT_BGRX:
189
  case JCS_EXT_XBGR:
190
  case JCS_EXT_XRGB:
191
    cinfo->out_color_components = rgb_pixelsize[cinfo->out_color_space];
278
    break;
192
    break;
279
#endif /* else share code with YCbCr */
280
  case JCS_YCbCr:
193
  case JCS_YCbCr:
281
    cinfo->out_color_components = 3;
194
    cinfo->out_color_components = 3;
282
    break;
195
    break;
283
  case JCS_CMYK:
196
  case JCS_CMYK:
284
  case JCS_YCCK:
197
  case JCS_YCCK:
285
    cinfo->out_color_components = 4;
198
    cinfo->out_color_components = 4;
286
    break;
199
    break;
287
  default:			/* else must be same colorspace as in file */
200
  default:			/* else must be same colorspace as in file */
 Lines 341-364   jpeg_calc_output_dimensions (j_decompres Link Here 
341
 * Note that the table is allocated in near data space on PCs; it's small
254
 * Note that the table is allocated in near data space on PCs; it's small
342
 * enough and used often enough to justify this.
255
 * enough and used often enough to justify this.
343
 */
256
 */
344
257
345
LOCAL(void)
258
LOCAL(void)
346
prepare_range_limit_table (j_decompress_ptr cinfo)
259
prepare_range_limit_table (j_decompress_ptr cinfo)
347
/* Allocate and fill in the sample_range_limit table */
260
/* Allocate and fill in the sample_range_limit table */
348
{
261
{
349
  /* Use a static table and allow negative subscripts of simple table */
350
351
  cinfo->sample_range_limit = (JSAMPLE *) static_range_table + (MAXJSAMPLE+1);
352
353
  /* This code is used to create the values for the static table used above */
354
355
#if 0
356
357
  JSAMPLE * table;
262
  JSAMPLE * table;
358
  int i;
263
  int i;
359
264
360
  table = (JSAMPLE *)
265
  table = (JSAMPLE *)
361
    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
266
    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
362
		(5 * (MAXJSAMPLE+1) + CENTERJSAMPLE) * SIZEOF(JSAMPLE));
267
		(5 * (MAXJSAMPLE+1) + CENTERJSAMPLE) * SIZEOF(JSAMPLE));
363
  table += (MAXJSAMPLE+1);	/* allow negative subscripts of simple table */
268
  table += (MAXJSAMPLE+1);	/* allow negative subscripts of simple table */
364
  cinfo->sample_range_limit = table;
269
  cinfo->sample_range_limit = table;
 Lines 371-388   prepare_range_limit_table (j_decompress_ Link Here 
371
  /* End of simple table, rest of first half of post-IDCT table */
276
  /* End of simple table, rest of first half of post-IDCT table */
372
  for (i = CENTERJSAMPLE; i < 2*(MAXJSAMPLE+1); i++)
277
  for (i = CENTERJSAMPLE; i < 2*(MAXJSAMPLE+1); i++)
373
    table[i] = MAXJSAMPLE;
278
    table[i] = MAXJSAMPLE;
374
  /* Second half of post-IDCT table */
279
  /* Second half of post-IDCT table */
375
  MEMZERO(table + (2 * (MAXJSAMPLE+1)),
280
  MEMZERO(table + (2 * (MAXJSAMPLE+1)),
376
	  (2 * (MAXJSAMPLE+1) - CENTERJSAMPLE) * SIZEOF(JSAMPLE));
281
	  (2 * (MAXJSAMPLE+1) - CENTERJSAMPLE) * SIZEOF(JSAMPLE));
377
  MEMCOPY(table + (4 * (MAXJSAMPLE+1) - CENTERJSAMPLE),
282
  MEMCOPY(table + (4 * (MAXJSAMPLE+1) - CENTERJSAMPLE),
378
	  cinfo->sample_range_limit, CENTERJSAMPLE * SIZEOF(JSAMPLE));
283
	  cinfo->sample_range_limit, CENTERJSAMPLE * SIZEOF(JSAMPLE));
379
380
#endif /* 0 */
381
}
284
}
382
285
383
286
384
/*
287
/*
385
 * Master selection of decompression modules.
288
 * Master selection of decompression modules.
386
 * This is done once at jpeg_start_decompress time.  We determine
289
 * This is done once at jpeg_start_decompress time.  We determine
387
 * which modules will be used and give them appropriate initialization calls.
290
 * which modules will be used and give them appropriate initialization calls.
388
 * We also initialize the decompressor input side to begin consuming data.
291
 * We also initialize the decompressor input side to begin consuming data.
(-)a/jpeg/jdmerge.c (-656 / +41 lines)
Line     Link Here 
 Lines 1-12    Link Here 
1
/*
1
/*
2
 * jdmerge.c
2
 * jdmerge.c
3
 *
3
 *
4
 * Copyright (C) 1994-1996, Thomas G. Lane.
4
 * Copyright (C) 1994-1996, Thomas G. Lane.
5
 * Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
6
 * Copyright (C) 2009, D. R. Commander.
5
 * This file is part of the Independent JPEG Group's software.
7
 * This file is part of the Independent JPEG Group's software.
6
 * For conditions of distribution and use, see the accompanying README file.
8
 * For conditions of distribution and use, see the accompanying README file.
7
 *
9
 *
8
 * This file contains code for merged upsampling/color conversion.
10
 * This file contains code for merged upsampling/color conversion.
9
 *
11
 *
10
 * This file combines functions from jdsample.c and jdcolor.c;
12
 * This file combines functions from jdsample.c and jdcolor.c;
11
 * read those files first to understand what's going on.
13
 * read those files first to understand what's going on.
12
 *
14
 *
 Lines 30-61    Link Here 
30
 * Other special cases could be added, but in most applications these are
32
 * Other special cases could be added, but in most applications these are
31
 * the only common cases.  (For uncommon cases we fall back on the more
33
 * the only common cases.  (For uncommon cases we fall back on the more
32
 * general code in jdsample.c and jdcolor.c.)
34
 * general code in jdsample.c and jdcolor.c.)
33
 */
35
 */
34
36
35
#define JPEG_INTERNALS
37
#define JPEG_INTERNALS
36
#include "jinclude.h"
38
#include "jinclude.h"
37
#include "jpeglib.h"
39
#include "jpeglib.h"
40
#include "jsimd.h"
38
41
39
#ifdef UPSAMPLE_MERGING_SUPPORTED
42
#ifdef UPSAMPLE_MERGING_SUPPORTED
40
43
41
#ifdef HAVE_MMX_INTEL_MNEMONICS
42
  __int64 const1 = 0x59BA0000D24B59BA;       // Cr_r Cr_b Cr_g Cr_r
43
  __int64 const2 = 0x00007168E9FA0000;		 // Cb-r Cb_b Cb_g Cb_r
44
  __int64 const5 = 0x0000D24B59BA0000;		 // Cr_b Cr_g Cr_r Cr_b
45
  __int64 const6 = 0x7168E9FA00007168;		 // Cb_b Cb_g Cb_r Cb_b
46
47
  // constants for factors (One_Half/fix(x)) << 2
48
49
  __int64 const05 = 0x0001000000000001;	// Cr_r Cr_b Cr_g Cr_r
50
  __int64 const15 = 0x00000001FFFA0000;	// Cb-r Cb_b Cb_g Cb_r
51
  __int64 const45 = 0x0000000000010000;	// Cr_b Cr_g Cr_r Cr_b
52
  __int64 const55 = 0x0001FFFA00000001;	// Cb_b Cb_g Cb_r Cb_b
53
#endif
54
44
55
/* Private subobject */
45
/* Private subobject */
56
46
57
typedef struct {
47
typedef struct {
58
  struct jpeg_upsampler pub;	/* public fields */
48
  struct jpeg_upsampler pub;	/* public fields */
59
49
60
  /* Pointer to routine to do actual upsampling/conversion of one row group */
50
  /* Pointer to routine to do actual upsampling/conversion of one row group */
61
  JMETHOD(void, upmethod, (j_decompress_ptr cinfo,
51
  JMETHOD(void, upmethod, (j_decompress_ptr cinfo,
 Lines 235-253   merged_1v_upsample (j_decompress_ptr cin Link Here 
235
 * Upsample and color convert for the case of 2:1 horizontal and 1:1 vertical.
225
 * Upsample and color convert for the case of 2:1 horizontal and 1:1 vertical.
236
 */
226
 */
237
227
238
METHODDEF(void)
228
METHODDEF(void)
239
h2v1_merged_upsample (j_decompress_ptr cinfo,
229
h2v1_merged_upsample (j_decompress_ptr cinfo,
240
		      JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
230
		      JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
241
		      JSAMPARRAY output_buf)
231
		      JSAMPARRAY output_buf)
242
{
232
{
243
 
233
  my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
244
245
 my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
246
  register int y, cred, cgreen, cblue;
234
  register int y, cred, cgreen, cblue;
247
  int cb, cr;
235
  int cb, cr;
248
  register JSAMPROW outptr;
236
  register JSAMPROW outptr;
249
  JSAMPROW inptr0, inptr1, inptr2;
237
  JSAMPROW inptr0, inptr1, inptr2;
250
  JDIMENSION col;
238
  JDIMENSION col;
251
  /* copy these pointers into registers if possible */
239
  /* copy these pointers into registers if possible */
252
  register JSAMPLE * range_limit = cinfo->sample_range_limit;
240
  register JSAMPLE * range_limit = cinfo->sample_range_limit;
253
  int * Crrtab = upsample->Cr_r_tab;
241
  int * Crrtab = upsample->Cr_r_tab;
 Lines 265-917   h2v1_merged_upsample (j_decompress_ptr c Link Here 
265
    /* Do the chroma part of the calculation */
253
    /* Do the chroma part of the calculation */
266
    cb = GETJSAMPLE(*inptr1++);
254
    cb = GETJSAMPLE(*inptr1++);
267
    cr = GETJSAMPLE(*inptr2++);
255
    cr = GETJSAMPLE(*inptr2++);
268
    cred = Crrtab[cr];
256
    cred = Crrtab[cr];
269
    cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
257
    cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
270
    cblue = Cbbtab[cb];
258
    cblue = Cbbtab[cb];
271
    /* Fetch 2 Y values and emit 2 pixels */
259
    /* Fetch 2 Y values and emit 2 pixels */
272
    y  = GETJSAMPLE(*inptr0++);
260
    y  = GETJSAMPLE(*inptr0++);
273
    outptr[RGB_RED] =   range_limit[y + cred];
261
    outptr[rgb_red[cinfo->out_color_space]] =   range_limit[y + cred];
274
    outptr[RGB_GREEN] = range_limit[y + cgreen];
262
    outptr[rgb_green[cinfo->out_color_space]] = range_limit[y + cgreen];
275
    outptr[RGB_BLUE] =  range_limit[y + cblue];
263
    outptr[rgb_blue[cinfo->out_color_space]] =  range_limit[y + cblue];
276
    outptr += RGB_PIXELSIZE;
264
    outptr += rgb_pixelsize[cinfo->out_color_space];
277
    y  = GETJSAMPLE(*inptr0++);
265
    y  = GETJSAMPLE(*inptr0++);
278
    outptr[RGB_RED] =   range_limit[y + cred];
266
    outptr[rgb_red[cinfo->out_color_space]] =   range_limit[y + cred];
279
    outptr[RGB_GREEN] = range_limit[y + cgreen];
267
    outptr[rgb_green[cinfo->out_color_space]] = range_limit[y + cgreen];
280
    outptr[RGB_BLUE] =  range_limit[y + cblue];
268
    outptr[rgb_blue[cinfo->out_color_space]] =  range_limit[y + cblue];
281
    outptr += RGB_PIXELSIZE;
269
    outptr += rgb_pixelsize[cinfo->out_color_space];
282
  }
270
  }
283
  /* If image width is odd, do the last output column separately */
271
  /* If image width is odd, do the last output column separately */
284
  if (cinfo->output_width & 1) {
272
  if (cinfo->output_width & 1) {
285
    cb = GETJSAMPLE(*inptr1);
273
    cb = GETJSAMPLE(*inptr1);
286
    cr = GETJSAMPLE(*inptr2);
274
    cr = GETJSAMPLE(*inptr2);
287
    cred = Crrtab[cr];
275
    cred = Crrtab[cr];
288
    cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
276
    cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
289
    cblue = Cbbtab[cb];
277
    cblue = Cbbtab[cb];
290
    y  = GETJSAMPLE(*inptr0);
278
    y  = GETJSAMPLE(*inptr0);
291
    outptr[RGB_RED] =   range_limit[y + cred];
279
    outptr[rgb_red[cinfo->out_color_space]] =   range_limit[y + cred];
292
    outptr[RGB_GREEN] = range_limit[y + cgreen];
280
    outptr[rgb_green[cinfo->out_color_space]] = range_limit[y + cgreen];
293
    outptr[RGB_BLUE] =  range_limit[y + cblue];
281
    outptr[rgb_blue[cinfo->out_color_space]] =  range_limit[y + cblue];
294
  }
282
  }
295
}
283
}
296
284
297
285
298
/*
286
/*
299
 * Upsample and color convert for the case of 2:1 horizontal and 2:1 vertical.
287
 * Upsample and color convert for the case of 2:1 horizontal and 2:1 vertical.
300
 */
288
 */
301
289
302
#ifdef HAVE_MMX_INTEL_MNEMONICS
303
__inline METHODDEF(void)
304
h2v2_merged_upsample_orig (j_decompress_ptr cinfo,
305
		      JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
306
		      JSAMPARRAY output_buf);
307
__inline METHODDEF(void)
308
h2v2_merged_upsample_mmx (j_decompress_ptr cinfo,
309
		      JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
310
		      JSAMPARRAY output_buf);
311
#endif
312
 
313
METHODDEF(void)
314
h2v2_merged_upsample (j_decompress_ptr cinfo,
315
		      JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
316
		      JSAMPARRAY output_buf);
317
318
#ifdef HAVE_MMX_INTEL_MNEMONICS
319
METHODDEF(void)
320
h2v2_merged_upsample (j_decompress_ptr cinfo,
321
		      JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
322
		      JSAMPARRAY output_buf)
323
{
324
if (MMXAvailable && (cinfo->image_width >= 8))
325
	h2v2_merged_upsample_mmx (cinfo, input_buf, in_row_group_ctr, output_buf);
326
else
327
	h2v2_merged_upsample_orig (cinfo, input_buf, in_row_group_ctr, output_buf);
328
329
}
330
331
__inline METHODDEF(void)
332
h2v2_merged_upsample_orig (j_decompress_ptr cinfo,
333
		      JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
334
		      JSAMPARRAY output_buf)
335
{
336
337
  my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
338
  register int y, cred, cgreen, cblue;
339
  int cb, cr;
340
  register JSAMPROW outptr0, outptr1;
341
  JSAMPROW inptr00, inptr01, inptr1, inptr2;
342
  JDIMENSION col;
343
  /* copy these pointers into registers if possible */
344
  register JSAMPLE * range_limit = cinfo->sample_range_limit;
345
  int * Crrtab = upsample->Cr_r_tab;
346
  int * Cbbtab = upsample->Cb_b_tab;
347
  INT32 * Crgtab = upsample->Cr_g_tab;
348
  INT32 * Cbgtab = upsample->Cb_g_tab;
349
  SHIFT_TEMPS
350
351
  inptr00 = input_buf[0][in_row_group_ctr*2];
352
  inptr01 = input_buf[0][in_row_group_ctr*2 + 1];
353
  inptr1 = input_buf[1][in_row_group_ctr];
354
  inptr2 = input_buf[2][in_row_group_ctr];
355
  outptr0 = output_buf[0];
356
  outptr1 = output_buf[1];
357
  /* Loop for each group of output pixels */
358
  for (col = cinfo->output_width >> 1; col > 0; col--) {
359
    /* Do the chroma part of the calculation */
360
    cb = GETJSAMPLE(*inptr1++);
361
    cr = GETJSAMPLE(*inptr2++);
362
    cred = Crrtab[cr];
363
    cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
364
    cblue = Cbbtab[cb];
365
    /* Fetch 4 Y values and emit 4 pixels */
366
    y  = GETJSAMPLE(*inptr00++);
367
    outptr0[RGB_RED] =   range_limit[y + cred];
368
    outptr0[RGB_GREEN] = range_limit[y + cgreen];
369
    outptr0[RGB_BLUE] =  range_limit[y + cblue];
370
    outptr0 += RGB_PIXELSIZE;
371
    y  = GETJSAMPLE(*inptr00++);
372
    outptr0[RGB_RED] =   range_limit[y + cred];
373
    outptr0[RGB_GREEN] = range_limit[y + cgreen];
374
    outptr0[RGB_BLUE] =  range_limit[y + cblue];
375
    outptr0 += RGB_PIXELSIZE;
376
    y  = GETJSAMPLE(*inptr01++);
377
    outptr1[RGB_RED] =   range_limit[y + cred];
378
    outptr1[RGB_GREEN] = range_limit[y + cgreen];
379
    outptr1[RGB_BLUE] =  range_limit[y + cblue];
380
    outptr1 += RGB_PIXELSIZE;
381
    y  = GETJSAMPLE(*inptr01++);
382
    outptr1[RGB_RED] =   range_limit[y + cred];
383
    outptr1[RGB_GREEN] = range_limit[y + cgreen];
384
    outptr1[RGB_BLUE] =  range_limit[y + cblue];
385
    outptr1 += RGB_PIXELSIZE;
386
  }
387
  /* If image width is odd, do the last output column separately */
388
  if (cinfo->output_width & 1) {
389
    cb = GETJSAMPLE(*inptr1);
390
    cr = GETJSAMPLE(*inptr2);
391
    cred = Crrtab[cr];
392
    cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
393
    cblue = Cbbtab[cb];
394
    y  = GETJSAMPLE(*inptr00);
395
    outptr0[RGB_RED] =   range_limit[y + cred];
396
    outptr0[RGB_GREEN] = range_limit[y + cgreen];
397
    outptr0[RGB_BLUE] =  range_limit[y + cblue];
398
    y  = GETJSAMPLE(*inptr01);
399
    outptr1[RGB_RED] =   range_limit[y + cred];
400
    outptr1[RGB_GREEN] = range_limit[y + cgreen];
401
    outptr1[RGB_BLUE] =  range_limit[y + cblue];
402
  }
403
}
404
405
/*
406
 * Upsample and color convert for the case of 2:1 horizontal and 2:1 vertical.
407
 */
408
__inline METHODDEF(void)
409
h2v2_merged_upsample_mmx (j_decompress_ptr cinfo,
410
		      JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
411
		      JSAMPARRAY output_buf)
412
{
413
	// added for MMX
414
  __int64 const128 = 0x0080008000800080;
415
  __int64 empty = 0x0000000000000000;
416
  __int64 davemask = 0x0000FFFFFFFF0000;
417
  ////////////////////////////////
418
419
  my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
420
  register int y, cred, cgreen, cblue;
421
  int cb, cr;
422
  register JSAMPROW outptr0, outptr1;
423
  JSAMPROW inptr00, inptr01, inptr1, inptr2;
424
  JDIMENSION col;
425
  /* copy these pointers into registers if possible */
426
  register JSAMPLE * range_limit = cinfo->sample_range_limit;
427
  int * Crrtab = upsample->Cr_r_tab;
428
  int * Cbbtab = upsample->Cb_b_tab;
429
  INT32 * Crgtab = upsample->Cr_g_tab;
430
  INT32 * Cbgtab = upsample->Cb_g_tab;
431
  SHIFT_TEMPS
432
  
433
434
  // Added for MMX	  
435
  register int width = cinfo->image_width;
436
  int cols = cinfo->output_width;
437
  int cols_asm = (cols >> 3);
438
  int diff = cols - (cols_asm<<3);
439
  int cols_asm_copy = cols_asm;
440
441
 ///////////////////////////////////////
442
443
  inptr00 = input_buf[0][in_row_group_ctr*2];
444
  inptr01 = input_buf[0][in_row_group_ctr*2 + 1];
445
  inptr1 = input_buf[1][in_row_group_ctr];
446
  inptr2 = input_buf[2][in_row_group_ctr];
447
  outptr0 = output_buf[0];
448
  outptr1 = output_buf[1];
449
  /* Loop for each group of output pixels */
450
451
	   
452
  _asm
453
  {
454
	  mov esi, inptr00
455
456
	  mov eax, inptr01
457
	  
458
	  mov ebx, inptr2
459
460
	  mov ecx, inptr1
461
462
	  mov edi, outptr0
463
464
	  mov edx, outptr1
465
466
do_next16:
467
	  
468
	  movd mm0, [ebx]			; Cr7 Cr6.....Cr1 Cr0
469
470
	  pxor mm6, mm6
471
472
	  punpcklbw mm0, mm0		; Cr3 Cr3 Cr2 Cr2 Cr1 Cr1 Cr0 Cr0
473
474
	  movq mm7, const128
475
476
	  punpcklwd mm0, mm0		; Cr1 Cr1 Cr1 Cr1 Cr0 Cr0 Cr0 Cr0
477
478
	  movq mm4, mm0
479
480
	  punpcklbw mm0, mm6		; Cr0 Cr0 Cr0 Cr0
481
482
	  psubsw mm0, mm7			; Cr0 - 128:Cr0-128:Cr0-128:Cr0 -128
483
	  
484
	  movd mm1, [ecx]			; Cb7 Cb6...... Cb1 Cb0
485
	  	   
486
	  psllw mm0, 2				; left shift by 2 bits
487
488
	  punpcklbw mm1, mm1		; Cb3 Cb3 Cb2 Cb2 Cb1 Cb1 Cb0 Cb0
489
	  
490
	  paddsw mm0, const05		; add (one_half/fix(x)) << 2
491
492
	  punpcklwd mm1, mm1		; Cb1 Cb1 Cb1 Cb1 Cb0 Cb0 Cb0 Cb0
493
494
	  movq mm5, mm1
495
496
	  pmulhw mm0, const1		; multiply by (fix(x) >> 1) 
497
498
	  punpcklbw mm1, mm6		; Cb0 Cb0 Cb0 Cb0
499
500
	  punpckhbw mm4, mm6		; Cr1 Cr1 Cr1 Cr1
501
502
	  psubsw mm1, mm7			; Cb0 - 128:Cb0-128:Cb0-128:Cb0 -128
503
504
	  punpckhbw mm5, mm6		; Cb1 Cb1 Cb1 Cb1
505
506
	  psllw mm1, 2				; left shift by 2 bits
507
 
508
	  paddsw mm1, const15		; add (one_half/fix(x)) << 2
509
510
	  psubsw mm4, mm7			; Cr1 - 128:Cr1-128:Cr1-128:Cr1 -128
511
						
512
	  psubsw mm5, mm7			; Cb1 - 128:Cb1-128:Cb1-128:Cb1 -128
513
514
	  pmulhw mm1, const2		; multiply by (fix(x) >> 1) 
515
516
	  psllw mm4, 2				; left shift by 2 bits
517
518
	  psllw mm5, 2				; left shift by 2 bits
519
520
	  paddsw mm4, const45		; add (one_half/fix(x)) << 2
521
522
	  movd mm7, [esi]			;  Y13 Y12 Y9 Y8 Y5 Y4 Y1 Y0
523
524
	  pmulhw mm4, const5		; multiply by (fix(x) >> 1) 
525
526
	  movq mm6, mm7
527
528
	  punpcklbw mm7, mm7		; Y5 Y5 Y4 Y4 Y1 Y1 Y0 Y0
529
530
	  paddsw mm5, const55		; add (one_half/fix(x)) << 2
531
532
	  paddsw  mm0, mm1			; cred0 cbl0 cgr0 cred0
533
534
	  movq mm1, mm7
535
536
	  pmulhw mm5, const6		; multiply by (fix(x) >> 1) 
537
538
	  movq	mm2, mm0			; cred0 cbl0 cgr0 cred0
539
540
	  punpcklwd mm7, mm6		; Y5 Y4 Y1 Y1 Y1 Y0 Y0 Y0
541
542
	  pand mm2, davemask		; 0 cbl0 cgr0 0
543
544
	  psrlq mm1, 16				; 0 0 Y5 Y5 Y4 Y4 Y1 Y1
545
546
	  psrlq	mm2, 16				; 0 0 cbl0 cgr0
547
548
	  punpcklbw mm7, empty		; Y1 Y0 Y0 Y0
549
550
	  paddsw mm4, mm5			; cbl1 cgr1 cred1 cbl1
551
552
	  movq	mm3, mm4			; cbl1 cgr1 cred1 cbl1
553
554
	  pand	mm3, davemask		; 0 cgr1 cred1 0
555
556
	  paddsw mm7, mm0			; r1 b0 g0 r0
557
558
	  psllq	mm3, 16				; cgr1 cred1 0 0
559
560
	  movq mm6, mm1				; 0 0 Y5 Y5 Y4 Y4 Y1 Y1
561
	
562
	  por	mm2, mm3			; cgr1 cred1 cbl0 cgr0
563
564
	  punpcklbw mm6, empty		; Y4 Y4 Y1 Y1
565
566
	  movd mm3, [eax]			; Y15 Y14 Y11 Y10 Y7 Y6 Y3 Y2
567
	  
568
	  paddsw mm6, mm2			; g4 r4 b1 g1
569
570
	  packuswb mm7, mm6			; g4 r4 b1 g1 r1 b0 g0 r0
571
572
	  movq mm6, mm3				; Y15 Y14 Y11 Y10 Y7 Y6 Y3 Y2
573
574
	  punpcklbw mm3, mm3		; Y7 Y7 Y6 Y6 Y3 Y3 Y2 Y2
575
576
	  movq [edi], mm7			; move to memory g4 r4 b1 g1 r1 b0 g0 r0
577
578
	  movq mm5, mm3				; Y7 Y7 Y6 Y6 Y3 Y3 Y2 Y2
579
580
	  punpcklwd mm3, mm6		; X X X X Y3 Y2 Y2 Y2
581
582
	  punpcklbw mm3, empty		; Y3 Y2 Y2 Y2
583
584
	  psrlq mm5, 16				; 0 0 Y7 Y7 Y6 Y6 Y3 Y3
585
586
	  paddsw mm3, mm0			; r3 b2 g2 r2
587
588
	  movq mm6, mm5				; 0 0 Y7 Y7 Y6 Y6 Y3 Y3
589
590
	  movq mm0, mm1				; 0 0 Y5 Y5 Y4 Y4 Y1 Y1
591
592
	  punpckldq mm6, mm6		; X X X X Y6 Y6 Y3 Y3
593
594
	  punpcklbw mm6, empty		; Y6 Y6 Y3 Y3
595
596
	  psrlq mm1, 24				; 0 0 0 0 0 Y5 Y5 Y4
597
	  
598
	  paddsw mm6, mm2			; g6 r6 b3 g3
599
600
	  packuswb mm3, mm6			; g6 r6 b3 g3 r3 b2 g2 r2
601
602
	  movq mm2, mm5				; 0 0 Y7 Y7 Y6 Y6 Y3 Y3
603
604
	  psrlq mm0, 32				; 0 0 0 0 0 0 Y5 Y5
605
606
	  movq [edx], mm3			; move to memory g6 r6 b3 g3 r3 b2 g2 r2
607
	  
608
	  punpcklwd mm1, mm0		; X X X X Y5 Y5 Y5 Y4
609
610
	  psrlq mm5, 24				; 0 0 0 0 0 Y7 Y7 Y6 
611
612
	  movd mm0, [ebx]			; Cr9 Cr8.....Cr3 Cr2
613
614
	  psrlq mm2, 32	   			; 0 0 0 0 0 0 Y7 Y7	 
615
	  
616
	  psrlq	mm0, 16		
617
618
	  punpcklbw mm1, empty		; Y5 Y5 Y5 Y4
619
620
	  punpcklwd mm5, mm2		; X X X X Y7 Y7 Y7 Y6
621
622
	  paddsw mm1, mm4			; b5 g5 r5 b4
623
	 
624
	  punpcklbw mm5, empty		; Y7 Y7 Y7 Y6	    
625
626
	  pxor mm6, mm6				; clear mm6 registr
627
	  
628
	  punpcklbw mm0, mm0		; X X X X Cr3 Cr3 Cr2 Cr2
629
  
630
	  paddsw mm5, mm4			; b7 g7 r7 b6
631
	  
632
	  punpcklwd mm0, mm0		; Cr3 Cr3 Cr3 Cr3 Cr2 Cr2 Cr2 Cr2
633
634
	  movq mm4, mm0
635
636
	  movd mm3, [ecx]			; Cb9 Cb8...... Cb3 Cb2
637
	  
638
	  punpcklbw mm0, mm6		; Cr2 Cr2 Cr2 Cr2
639
640
	  psrlq	mm3, 16
641
642
	  psubsw mm0, const128		; Cr2 - 128:Cr2-128:Cr2-128:Cr2 -128
643
644
	  punpcklbw mm3, mm3		; X X X X Cb3 Cb3 Cb2 Cb2
645
646
	  psllw mm0, 2				; left shift by 2 bits
647
648
	  paddsw mm0, const05		; add (one_half/fix(x)) << 2
649
650
	  punpcklwd mm3, mm3		; Cb3 Cb3 Cb3 Cb3 Cb2 Cb2 Cb2 Cb2
651
652
	  movq mm7, mm3
653
	  
654
	  pmulhw mm0, const1		; multiply by (fix(x) >> 1) 	  	  
655
656
	  punpcklbw mm3, mm6		; Cb2 Cb2 Cb2 Cb2
657
658
	  psubsw mm3, const128		; Cb0 - 128:Cb0-128:Cb0-128:Cb0 -128
659
660
	  punpckhbw mm4, mm6		; Cr3 Cr3 Cr3 Cr3
661
	  
662
	  psllw mm3, 2				; left shift by 2 bits
663
664
	  paddsw mm3, const15		; add (one_half/fix(x)) << 2
665
666
	  punpckhbw mm7, mm6		; Cb3 Cb3 Cb3 Cb3
667
668
	  pmulhw mm3, const2		; multiply by (fix(x) >> 1) 
669
	  
670
	  psubsw mm7, const128		; Cb3 - 128:Cb3-128:Cb3-128:Cb3 -128
671
672
	  paddsw  mm0, mm3			; cred2 cbl2 cgr2 cred2
673
	    
674
	  psllw mm7, 2				; left shift by 2 bits
675
676
	  psubsw mm4, const128		; Cr3 - 128:Cr3-128:Cr3-128:Cr3 -128
677
	  
678
	  movd mm3, [esi+4]			;  Y21 Y20 Y17 Y16 Y13 Y12 Y9 Y8
679
	  
680
	  psllw mm4, 2				; left shift by 2 bits
681
682
	  paddsw mm7, const55		; add (one_half/fix(x)) << 2
683
	  	  
684
	  movq mm6, mm3				;  Y21 Y20 Y17 Y16 Y13 Y12 Y9 Y8
685
686
	  movq	mm2, mm0
687
	  	  
688
	  pand mm2, davemask
689
690
	  punpcklbw mm3, mm3		; Y13 Y13 Y12 Y12 Y9 Y9 Y8 Y8
691
692
	  psrlq	mm2, 16
693
	    	  
694
	  paddsw mm4, const45		; add (one_half/fix(x)) << 2
695
696
	  punpcklwd mm3, mm6		; X X X X Y9 Y8 Y8 Y8
697
	  
698
	  pmulhw mm4, const5		; multiply by (fix(x) >> 1) 
699
700
	  pmulhw mm7, const6		; multiply by (fix(x) >> 1) 
701
702
	  punpcklbw mm3, empty		; Y9 Y8 Y8 Y8
703
	  
704
	  paddsw mm4, mm7			; cbl3 cgr3 cred3 cbl3
705
706
	  paddsw mm3, mm0			; r9 b8 g8 r8
707
708
	  movq	mm7, mm4
709
710
	  packuswb mm1, mm3			; r9 b8 g8 r8 b5 g5 r5 b4
711
712
	  movd mm3, [eax+4]			; Y23 Y22 Y19 Y18 Y15 Y14 Y11 Y10
713
 	  
714
	  pand	mm7, davemask
715
716
	  psrlq mm6, 8				; 0 Y21 Y20 Y17 Y16 Y13 Y12 Y9
717
718
	  psllq	mm7, 16
719
						   
720
	  movq [edi+8], mm1			; move to memory r9 b8 g8 r8 b5 g5 r5 b4
721
722
	  por	mm2, mm7
723
724
	  movq mm7, mm3				; Y23 Y22 Y19 Y18 Y15 Y14 Y11 Y10
725
726
	  punpcklbw mm3, mm3		; X X X X Y11 Y11 Y10 Y10
727
728
	  pxor mm1, mm1
729
730
	  punpcklwd mm3, mm7		; X X X X Y11 Y10 Y10 Y10
731
732
	  punpcklbw mm3, mm1		; Y11 Y10 Y10 Y10
733
734
	  psrlq mm7, 8				; 0 Y23 Y22 Y19 Y18 Y15 Y14 Y11
735
	  
736
	  paddsw mm3, mm0			; r11 b10 g10 r10
737
738
	  movq mm0, mm7				; 0 Y23 Y22 Y19 Y18 Y15 Y14 Y11
739
740
	  packuswb mm5, mm3			; r11 b10 g10 r10 b7 g7 r7 b6
741
742
	  punpcklbw mm7, mm7		; X X X X Y14 Y14 Y11 Y11
743
744
	  movq [edx+8], mm5			; move to memory r11 b10 g10 r10 b7 g7 r7 b6
745
746
	  movq mm3, mm6				; 0 Y21 Y20 Y17 Y16 Y13 Y12 Y9
747
748
	  punpcklbw mm6, mm6		; X X X X Y12 Y12 Y9 Y9
749
750
	  punpcklbw mm7, mm1		; Y14 Y14 Y11 Y11
751
752
	  punpcklbw mm6, mm1		; Y12 Y12 Y9 Y9
753
754
	  paddsw mm7, mm2			; g14 r14 b11 g11
755
756
	  paddsw mm6, mm2			; g12 r12 b9 g9
757
758
	  psrlq mm3, 8				; 0 0 Y21 Y20 Y17 Y16 Y13 Y12
759
760
	  movq mm1, mm3				; 0 0 Y21 Y20 Y17 Y16 Y13 Y12
761
762
	  punpcklbw mm3, mm3		; X X X X Y13 Y13 Y12 Y12
763
764
	  add esi, 8
765
766
	  psrlq mm3, 16				; X X X X X X Y13 Y13 modified on 09/24
767
768
	  punpcklwd mm1, mm3		; X X X X Y13 Y13 Y13 Y12
769
770
	  add eax, 8
771
772
	  psrlq mm0, 8				; 0 0 Y23 Y22 Y19 Y18 Y15 Y14	
773
774
	  punpcklbw mm1, empty		; Y13 Y13 Y13 Y12
775
776
	  movq mm5, mm0				; 0 0 Y23 Y22 Y19 Y18 Y15 Y14	
777
778
	  punpcklbw mm0, mm0		; X X X X Y15 Y15 Y14 Y14
779
780
	  paddsw mm1, mm4			; b13 g13 r13 b12
781
782
	  psrlq mm0, 16				; X X X X X X Y15 Y15
783
784
	  add edi, 24
785
	  
786
	  punpcklwd mm5, mm0		; X X X X Y15 Y15 Y15 Y14
787
788
	  packuswb mm6, mm1			; b13 g13 r13 b12 g12 r12 b9 g9
789
790
	  add edx, 24
791
	  
792
	  punpcklbw mm5, empty		; Y15 Y15 Y15 Y14
793
794
	  add ebx, 4
795
	  	  
796
	  paddsw mm5, mm4			; b15 g15 r15 b14
797
798
	  movq [edi-8], mm6		; move to memory b13 g13 r13 b12 g12 r12 b9 g9
799
800
	  packuswb mm7, mm5			; b15 g15 r15 b14 g14 r14 b11 g11
801
802
	  add ecx, 4
803
  
804
	  movq [edx-8], mm7		; move to memory b15 g15 r15 b14 g14 r14 b11 g11
805
806
	  dec cols_asm
807
	  
808
	  jnz do_next16
809
810
	  EMMS
811
	  	  
812
	  }
813
814
	  
815
  inptr1 += (cols_asm_copy<<2);
816
817
  inptr2 += (cols_asm_copy<<2);
818
819
  inptr00 += (cols_asm_copy<<3);
820
821
  inptr01 += (cols_asm_copy<<3);
822
823
  outptr0 += cols_asm_copy*24;
824
825
  outptr1 += cols_asm_copy*24;
826
  		  
827
  //for (col = cinfo->output_width >> 1; col > 0; col--) {
828
      /* Do the chroma part of the calculation */
829
    /*cb = GETJSAMPLE(*inptr1++);
830
    cr = GETJSAMPLE(*inptr2++);
831
    cred = Crrtab[cr];
832
    cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
833
    cblue = Cbbtab[cb];*/
834
    /* Fetch 4 Y values and emit 4 pixels */
835
    /*y  = GETJSAMPLE(*inptr00++);
836
    outptr0[RGB_RED] =   range_limit[y + cred];
837
    outptr0[RGB_GREEN] = range_limit[y + cgreen];
838
    outptr0[RGB_BLUE] =  range_limit[y + cblue];
839
    outptr0 += RGB_PIXELSIZE;
840
    y  = GETJSAMPLE(*inptr00++);
841
    outptr0[RGB_RED] =   range_limit[y + cred];
842
    outptr0[RGB_GREEN] = range_limit[y + cgreen];
843
    outptr0[RGB_BLUE] =  range_limit[y + cblue];
844
    outptr0 += RGB_PIXELSIZE;
845
    y  = GETJSAMPLE(*inptr01++);
846
    outptr1[RGB_RED] =   range_limit[y + cred];
847
    outptr1[RGB_GREEN] = range_limit[y + cgreen];
848
    outptr1[RGB_BLUE] =  range_limit[y + cblue];
849
    outptr1 += RGB_PIXELSIZE;
850
    y  = GETJSAMPLE(*inptr01++);
851
    outptr1[RGB_RED] =   range_limit[y + cred];
852
    outptr1[RGB_GREEN] = range_limit[y + cgreen];
853
    outptr1[RGB_BLUE] =  range_limit[y + cblue];
854
    outptr1 += RGB_PIXELSIZE;
855
  }	  */
856
857
858
  for (col = diff >> 1; col > 0; col--) {
859
      /* Do the chroma part of the calculation */
860
    cb = GETJSAMPLE(*inptr1++);
861
    cr = GETJSAMPLE(*inptr2++);
862
    cred = Crrtab[cr];
863
    cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
864
    cblue = Cbbtab[cb];
865
    /* Fetch 4 Y values and emit 4 pixels */
866
    y  = GETJSAMPLE(*inptr00++);
867
    outptr0[RGB_RED] =   range_limit[y + cred];
868
    outptr0[RGB_GREEN] = range_limit[y + cgreen];
869
    outptr0[RGB_BLUE] =  range_limit[y + cblue];
870
    outptr0 += RGB_PIXELSIZE;
871
    y  = GETJSAMPLE(*inptr00++);
872
    outptr0[RGB_RED] =   range_limit[y + cred];
873
    outptr0[RGB_GREEN] = range_limit[y + cgreen];
874
    outptr0[RGB_BLUE] =  range_limit[y + cblue];
875
    outptr0 += RGB_PIXELSIZE;
876
    y  = GETJSAMPLE(*inptr01++);
877
    outptr1[RGB_RED] =   range_limit[y + cred];
878
    outptr1[RGB_GREEN] = range_limit[y + cgreen];
879
    outptr1[RGB_BLUE] =  range_limit[y + cblue];
880
    outptr1 += RGB_PIXELSIZE;
881
    y  = GETJSAMPLE(*inptr01++);
882
    outptr1[RGB_RED] =   range_limit[y + cred];
883
    outptr1[RGB_GREEN] = range_limit[y + cgreen];
884
    outptr1[RGB_BLUE] =  range_limit[y + cblue];
885
    outptr1 += RGB_PIXELSIZE;
886
  }	  
887
888
					  
889
  /* If image width is odd, do the last output column separately */
890
  //if (cinfo->output_width & 1) {
891
  if (diff & 1) {
892
    cb = GETJSAMPLE(*inptr1);
893
    cr = GETJSAMPLE(*inptr2);
894
    cred = Crrtab[cr];
895
    cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
896
    cblue = Cbbtab[cb];
897
    y  = GETJSAMPLE(*inptr00);
898
    outptr0[RGB_RED] =   range_limit[y + cred];
899
    outptr0[RGB_GREEN] = range_limit[y + cgreen];
900
    outptr0[RGB_BLUE] =  range_limit[y + cblue];
901
    y  = GETJSAMPLE(*inptr01);
902
    outptr1[RGB_RED] =   range_limit[y + cred];
903
    outptr1[RGB_GREEN] = range_limit[y + cgreen];
904
    outptr1[RGB_BLUE] =  range_limit[y + cblue];
905
  }    
906
}
907
#else
908
909
910
METHODDEF(void)
290
METHODDEF(void)
911
h2v2_merged_upsample (j_decompress_ptr cinfo,
291
h2v2_merged_upsample (j_decompress_ptr cinfo,
912
		      JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
292
		      JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
913
		      JSAMPARRAY output_buf)
293
		      JSAMPARRAY output_buf)
914
{
294
{
915
  my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
295
  my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
916
  register int y, cred, cgreen, cblue;
296
  register int y, cred, cgreen, cblue;
917
  int cb, cr;
297
  int cb, cr;
 Lines 937-990   h2v2_merged_upsample (j_decompress_ptr c Link Here 
937
    /* Do the chroma part of the calculation */
317
    /* Do the chroma part of the calculation */
938
    cb = GETJSAMPLE(*inptr1++);
318
    cb = GETJSAMPLE(*inptr1++);
939
    cr = GETJSAMPLE(*inptr2++);
319
    cr = GETJSAMPLE(*inptr2++);
940
    cred = Crrtab[cr];
320
    cred = Crrtab[cr];
941
    cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
321
    cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
942
    cblue = Cbbtab[cb];
322
    cblue = Cbbtab[cb];
943
    /* Fetch 4 Y values and emit 4 pixels */
323
    /* Fetch 4 Y values and emit 4 pixels */
944
    y  = GETJSAMPLE(*inptr00++);
324
    y  = GETJSAMPLE(*inptr00++);
945
    outptr0[RGB_RED] =   range_limit[y + cred];
325
    outptr0[rgb_red[cinfo->out_color_space]] =   range_limit[y + cred];
946
    outptr0[RGB_GREEN] = range_limit[y + cgreen];
326
    outptr0[rgb_green[cinfo->out_color_space]] = range_limit[y + cgreen];
947
    outptr0[RGB_BLUE] =  range_limit[y + cblue];
327
    outptr0[rgb_blue[cinfo->out_color_space]] =  range_limit[y + cblue];
948
    outptr0 += RGB_PIXELSIZE;
328
    outptr0 += RGB_PIXELSIZE;
949
    y  = GETJSAMPLE(*inptr00++);
329
    y  = GETJSAMPLE(*inptr00++);
950
    outptr0[RGB_RED] =   range_limit[y + cred];
330
    outptr0[rgb_red[cinfo->out_color_space]] =   range_limit[y + cred];
951
    outptr0[RGB_GREEN] = range_limit[y + cgreen];
331
    outptr0[rgb_green[cinfo->out_color_space]] = range_limit[y + cgreen];
952
    outptr0[RGB_BLUE] =  range_limit[y + cblue];
332
    outptr0[rgb_blue[cinfo->out_color_space]] =  range_limit[y + cblue];
953
    outptr0 += RGB_PIXELSIZE;
333
    outptr0 += RGB_PIXELSIZE;
954
    y  = GETJSAMPLE(*inptr01++);
334
    y  = GETJSAMPLE(*inptr01++);
955
    outptr1[RGB_RED] =   range_limit[y + cred];
335
    outptr1[rgb_red[cinfo->out_color_space]] =   range_limit[y + cred];
956
    outptr1[RGB_GREEN] = range_limit[y + cgreen];
336
    outptr1[rgb_green[cinfo->out_color_space]] = range_limit[y + cgreen];
957
    outptr1[RGB_BLUE] =  range_limit[y + cblue];
337
    outptr1[rgb_blue[cinfo->out_color_space]] =  range_limit[y + cblue];
958
    outptr1 += RGB_PIXELSIZE;
338
    outptr1 += RGB_PIXELSIZE;
959
    y  = GETJSAMPLE(*inptr01++);
339
    y  = GETJSAMPLE(*inptr01++);
960
    outptr1[RGB_RED] =   range_limit[y + cred];
340
    outptr1[rgb_red[cinfo->out_color_space]] =   range_limit[y + cred];
961
    outptr1[RGB_GREEN] = range_limit[y + cgreen];
341
    outptr1[rgb_green[cinfo->out_color_space]] = range_limit[y + cgreen];
962
    outptr1[RGB_BLUE] =  range_limit[y + cblue];
342
    outptr1[rgb_blue[cinfo->out_color_space]] =  range_limit[y + cblue];
963
    outptr1 += RGB_PIXELSIZE;
343
    outptr1 += RGB_PIXELSIZE;
964
  }
344
  }
965
  /* If image width is odd, do the last output column separately */
345
  /* If image width is odd, do the last output column separately */
966
  if (cinfo->output_width & 1) {
346
  if (cinfo->output_width & 1) {
967
    cb = GETJSAMPLE(*inptr1);
347
    cb = GETJSAMPLE(*inptr1);
968
    cr = GETJSAMPLE(*inptr2);
348
    cr = GETJSAMPLE(*inptr2);
969
    cred = Crrtab[cr];
349
    cred = Crrtab[cr];
970
    cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
350
    cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
971
    cblue = Cbbtab[cb];
351
    cblue = Cbbtab[cb];
972
    y  = GETJSAMPLE(*inptr00);
352
    y  = GETJSAMPLE(*inptr00);
973
    outptr0[RGB_RED] =   range_limit[y + cred];
353
    outptr0[rgb_red[cinfo->out_color_space]] =   range_limit[y + cred];
974
    outptr0[RGB_GREEN] = range_limit[y + cgreen];
354
    outptr0[rgb_green[cinfo->out_color_space]] = range_limit[y + cgreen];
975
    outptr0[RGB_BLUE] =  range_limit[y + cblue];
355
    outptr0[rgb_blue[cinfo->out_color_space]] =  range_limit[y + cblue];
976
    y  = GETJSAMPLE(*inptr01);
356
    y  = GETJSAMPLE(*inptr01);
977
    outptr1[RGB_RED] =   range_limit[y + cred];
357
    outptr1[rgb_red[cinfo->out_color_space]] =   range_limit[y + cred];
978
    outptr1[RGB_GREEN] = range_limit[y + cgreen];
358
    outptr1[rgb_green[cinfo->out_color_space]] = range_limit[y + cgreen];
979
    outptr1[RGB_BLUE] =  range_limit[y + cblue];
359
    outptr1[rgb_blue[cinfo->out_color_space]] =  range_limit[y + cblue];
980
  }
360
  }
981
}
361
}
982
#endif
983
362
984
363
985
/*
364
/*
986
 * Module initialization routine for merged upsampling/color conversion.
365
 * Module initialization routine for merged upsampling/color conversion.
987
 *
366
 *
988
 * NB: this is called under the conditions determined by use_merged_upsample()
367
 * NB: this is called under the conditions determined by use_merged_upsample()
989
 * in jdmaster.c.  That routine MUST correspond to the actual capabilities
368
 * in jdmaster.c.  That routine MUST correspond to the actual capabilities
990
 * of this module; no safety checks are made here.
369
 * of this module; no safety checks are made here.
 Lines 1001-1024   jinit_merged_upsampler (j_decompress_ptr Link Here 
1001
  cinfo->upsample = (struct jpeg_upsampler *) upsample;
380
  cinfo->upsample = (struct jpeg_upsampler *) upsample;
1002
  upsample->pub.start_pass = start_pass_merged_upsample;
381
  upsample->pub.start_pass = start_pass_merged_upsample;
1003
  upsample->pub.need_context_rows = FALSE;
382
  upsample->pub.need_context_rows = FALSE;
1004
383
1005
  upsample->out_row_width = cinfo->output_width * cinfo->out_color_components;
384
  upsample->out_row_width = cinfo->output_width * cinfo->out_color_components;
1006
385
1007
  if (cinfo->max_v_samp_factor == 2) {
386
  if (cinfo->max_v_samp_factor == 2) {
1008
    upsample->pub.upsample = merged_2v_upsample;
387
    upsample->pub.upsample = merged_2v_upsample;
1009
    upsample->upmethod = h2v2_merged_upsample;
388
    if (jsimd_can_h2v2_merged_upsample())
389
      upsample->upmethod = jsimd_h2v2_merged_upsample;
390
    else
391
      upsample->upmethod = h2v2_merged_upsample;
1010
    /* Allocate a spare row buffer */
392
    /* Allocate a spare row buffer */
1011
    upsample->spare_row = (JSAMPROW)
393
    upsample->spare_row = (JSAMPROW)
1012
      (*cinfo->mem->alloc_large) ((j_common_ptr) cinfo, JPOOL_IMAGE,
394
      (*cinfo->mem->alloc_large) ((j_common_ptr) cinfo, JPOOL_IMAGE,
1013
		(size_t) (upsample->out_row_width * SIZEOF(JSAMPLE)));
395
		(size_t) (upsample->out_row_width * SIZEOF(JSAMPLE)));
1014
  } else {
396
  } else {
1015
    upsample->pub.upsample = merged_1v_upsample;
397
    upsample->pub.upsample = merged_1v_upsample;
1016
    upsample->upmethod = h2v1_merged_upsample;
398
    if (jsimd_can_h2v1_merged_upsample())
399
      upsample->upmethod = jsimd_h2v1_merged_upsample;
400
    else
401
      upsample->upmethod = h2v1_merged_upsample;
1017
    /* No spare row needed */
402
    /* No spare row needed */
1018
    upsample->spare_row = NULL;
403
    upsample->spare_row = NULL;
1019
  }
404
  }
1020
405
1021
  build_ycc_rgb_table(cinfo);
406
  build_ycc_rgb_table(cinfo);
1022
}
407
}
1023
408
1024
#endif /* UPSAMPLE_MERGING_SUPPORTED */
409
#endif /* UPSAMPLE_MERGING_SUPPORTED */
(-)a/jpeg/jdsample.c (-7 / +23 lines)
Line     Link Here 
 Lines 1-12    Link Here 
1
/*
1
/*
2
 * jdsample.c
2
 * jdsample.c
3
 *
3
 *
4
 * Copyright (C) 1991-1996, Thomas G. Lane.
4
 * Copyright (C) 1991-1996, Thomas G. Lane.
5
 * Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
5
 * This file is part of the Independent JPEG Group's software.
6
 * This file is part of the Independent JPEG Group's software.
6
 * For conditions of distribution and use, see the accompanying README file.
7
 * For conditions of distribution and use, see the accompanying README file.
7
 *
8
 *
8
 * This file contains upsampling routines.
9
 * This file contains upsampling routines.
9
 *
10
 *
10
 * Upsampling input data is counted in "row groups".  A row group
11
 * Upsampling input data is counted in "row groups".  A row group
11
 * is defined to be (v_samp_factor * DCT_scaled_size / min_DCT_scaled_size)
12
 * is defined to be (v_samp_factor * DCT_scaled_size / min_DCT_scaled_size)
12
 * sample rows of each component.  Upsampling will normally produce
13
 * sample rows of each component.  Upsampling will normally produce
 Lines 16-31    Link Here 
16
 * An excellent reference for image resampling is
17
 * An excellent reference for image resampling is
17
 *   Digital Image Warping, George Wolberg, 1990.
18
 *   Digital Image Warping, George Wolberg, 1990.
18
 *   Pub. by IEEE Computer Society Press, Los Alamitos, CA. ISBN 0-8186-8944-7.
19
 *   Pub. by IEEE Computer Society Press, Los Alamitos, CA. ISBN 0-8186-8944-7.
19
 */
20
 */
20
21
21
#define JPEG_INTERNALS
22
#define JPEG_INTERNALS
22
#include "jinclude.h"
23
#include "jinclude.h"
23
#include "jpeglib.h"
24
#include "jpeglib.h"
25
#include "jsimd.h"
24
26
25
27
26
/* Pointer to routine to upsample a single component */
28
/* Pointer to routine to upsample a single component */
27
typedef JMETHOD(void, upsample1_ptr,
29
typedef JMETHOD(void, upsample1_ptr,
28
		(j_decompress_ptr cinfo, jpeg_component_info * compptr,
30
		(j_decompress_ptr cinfo, jpeg_component_info * compptr,
29
		 JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr));
31
		 JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr));
30
32
31
/* Private subobject */
33
/* Private subobject */
 Lines 442-469   jinit_upsampler (j_decompress_ptr cinfo) Link Here 
442
      need_buffer = FALSE;
444
      need_buffer = FALSE;
443
    } else if (h_in_group == h_out_group && v_in_group == v_out_group) {
445
    } else if (h_in_group == h_out_group && v_in_group == v_out_group) {
444
      /* Fullsize components can be processed without any work. */
446
      /* Fullsize components can be processed without any work. */
445
      upsample->methods[ci] = fullsize_upsample;
447
      upsample->methods[ci] = fullsize_upsample;
446
      need_buffer = FALSE;
448
      need_buffer = FALSE;
447
    } else if (h_in_group * 2 == h_out_group &&
449
    } else if (h_in_group * 2 == h_out_group &&
448
	       v_in_group == v_out_group) {
450
	       v_in_group == v_out_group) {
449
      /* Special cases for 2h1v upsampling */
451
      /* Special cases for 2h1v upsampling */
450
      if (do_fancy && compptr->downsampled_width > 2)
452
      if (do_fancy && compptr->downsampled_width > 2) {
451
	upsample->methods[ci] = h2v1_fancy_upsample;
453
	if (jsimd_can_h2v1_fancy_upsample())
452
      else
454
	  upsample->methods[ci] = jsimd_h2v1_fancy_upsample;
453
	upsample->methods[ci] = h2v1_upsample;
455
	else
456
	  upsample->methods[ci] = h2v1_fancy_upsample;
457
      } else {
458
	if (jsimd_can_h2v1_upsample())
459
	  upsample->methods[ci] = jsimd_h2v1_upsample;
460
	else
461
	  upsample->methods[ci] = h2v1_upsample;
462
      }
454
    } else if (h_in_group * 2 == h_out_group &&
463
    } else if (h_in_group * 2 == h_out_group &&
455
	       v_in_group * 2 == v_out_group) {
464
	       v_in_group * 2 == v_out_group) {
456
      /* Special cases for 2h2v upsampling */
465
      /* Special cases for 2h2v upsampling */
457
      if (do_fancy && compptr->downsampled_width > 2) {
466
      if (do_fancy && compptr->downsampled_width > 2) {
458
	upsample->methods[ci] = h2v2_fancy_upsample;
467
	if (jsimd_can_h2v2_fancy_upsample())
468
	  upsample->methods[ci] = jsimd_h2v2_fancy_upsample;
469
	else
470
	  upsample->methods[ci] = h2v2_fancy_upsample;
459
	upsample->pub.need_context_rows = TRUE;
471
	upsample->pub.need_context_rows = TRUE;
460
      } else
472
      } else {
461
	upsample->methods[ci] = h2v2_upsample;
473
	if (jsimd_can_h2v2_upsample())
474
	  upsample->methods[ci] = jsimd_h2v2_upsample;
475
	else
476
	  upsample->methods[ci] = h2v2_upsample;
477
      }
462
    } else if ((h_out_group % h_in_group) == 0 &&
478
    } else if ((h_out_group % h_in_group) == 0 &&
463
	       (v_out_group % v_in_group) == 0) {
479
	       (v_out_group % v_in_group) == 0) {
464
      /* Generic integral-factors upsampling method */
480
      /* Generic integral-factors upsampling method */
465
      upsample->methods[ci] = int_upsample;
481
      upsample->methods[ci] = int_upsample;
466
      upsample->h_expand[ci] = (UINT8) (h_out_group / h_in_group);
482
      upsample->h_expand[ci] = (UINT8) (h_out_group / h_in_group);
467
      upsample->v_expand[ci] = (UINT8) (v_out_group / v_in_group);
483
      upsample->v_expand[ci] = (UINT8) (v_out_group / v_in_group);
468
    } else
484
    } else
469
      ERREXIT(cinfo, JERR_FRACT_SAMPLE_NOTIMPL);
485
      ERREXIT(cinfo, JERR_FRACT_SAMPLE_NOTIMPL);
(-)a/jpeg/jdtrans.c (+143 lines)
Line     Link Here 
Line 0    Link Here 
1
/*
2
 * jdtrans.c
3
 *
4
 * Copyright (C) 1995-1997, Thomas G. Lane.
5
 * This file is part of the Independent JPEG Group's software.
6
 * For conditions of distribution and use, see the accompanying README file.
7
 *
8
 * This file contains library routines for transcoding decompression,
9
 * that is, reading raw DCT coefficient arrays from an input JPEG file.
10
 * The routines in jdapimin.c will also be needed by a transcoder.
11
 */
12
13
#define JPEG_INTERNALS
14
#include "jinclude.h"
15
#include "jpeglib.h"
16
17
18
/* Forward declarations */
19
LOCAL(void) transdecode_master_selection JPP((j_decompress_ptr cinfo));
20
21
22
/*
23
 * Read the coefficient arrays from a JPEG file.
24
 * jpeg_read_header must be completed before calling this.
25
 *
26
 * The entire image is read into a set of virtual coefficient-block arrays,
27
 * one per component.  The return value is a pointer to the array of
28
 * virtual-array descriptors.  These can be manipulated directly via the
29
 * JPEG memory manager, or handed off to jpeg_write_coefficients().
30
 * To release the memory occupied by the virtual arrays, call
31
 * jpeg_finish_decompress() when done with the data.
32
 *
33
 * An alternative usage is to simply obtain access to the coefficient arrays
34
 * during a buffered-image-mode decompression operation.  This is allowed
35
 * after any jpeg_finish_output() call.  The arrays can be accessed until
36
 * jpeg_finish_decompress() is called.  (Note that any call to the library
37
 * may reposition the arrays, so don't rely on access_virt_barray() results
38
 * to stay valid across library calls.)
39
 *
40
 * Returns NULL if suspended.  This case need be checked only if
41
 * a suspending data source is used.
42
 */
43
44
GLOBAL(jvirt_barray_ptr *)
45
jpeg_read_coefficients (j_decompress_ptr cinfo)
46
{
47
  if (cinfo->global_state == DSTATE_READY) {
48
    /* First call: initialize active modules */
49
    transdecode_master_selection(cinfo);
50
    cinfo->global_state = DSTATE_RDCOEFS;
51
  }
52
  if (cinfo->global_state == DSTATE_RDCOEFS) {
53
    /* Absorb whole file into the coef buffer */
54
    for (;;) {
55
      int retcode;
56
      /* Call progress monitor hook if present */
57
      if (cinfo->progress != NULL)
58
	(*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo);
59
      /* Absorb some more input */
60
      retcode = (*cinfo->inputctl->consume_input) (cinfo);
61
      if (retcode == JPEG_SUSPENDED)
62
	return NULL;
63
      if (retcode == JPEG_REACHED_EOI)
64
	break;
65
      /* Advance progress counter if appropriate */
66
      if (cinfo->progress != NULL &&
67
	  (retcode == JPEG_ROW_COMPLETED || retcode == JPEG_REACHED_SOS)) {
68
	if (++cinfo->progress->pass_counter >= cinfo->progress->pass_limit) {
69
	  /* startup underestimated number of scans; ratchet up one scan */
70
	  cinfo->progress->pass_limit += (long) cinfo->total_iMCU_rows;
71
	}
72
      }
73
    }
74
    /* Set state so that jpeg_finish_decompress does the right thing */
75
    cinfo->global_state = DSTATE_STOPPING;
76
  }
77
  /* At this point we should be in state DSTATE_STOPPING if being used
78
   * standalone, or in state DSTATE_BUFIMAGE if being invoked to get access
79
   * to the coefficients during a full buffered-image-mode decompression.
80
   */
81
  if ((cinfo->global_state == DSTATE_STOPPING ||
82
       cinfo->global_state == DSTATE_BUFIMAGE) && cinfo->buffered_image) {
83
    return cinfo->coef->coef_arrays;
84
  }
85
  /* Oops, improper usage */
86
  ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
87
  return NULL;			/* keep compiler happy */
88
}
89
90
91
/*
92
 * Master selection of decompression modules for transcoding.
93
 * This substitutes for jdmaster.c's initialization of the full decompressor.
94
 */
95
96
LOCAL(void)
97
transdecode_master_selection (j_decompress_ptr cinfo)
98
{
99
  /* This is effectively a buffered-image operation. */
100
  cinfo->buffered_image = TRUE;
101
102
  /* Entropy decoding: either Huffman or arithmetic coding. */
103
  if (cinfo->arith_code) {
104
    ERREXIT(cinfo, JERR_ARITH_NOTIMPL);
105
  } else {
106
    if (cinfo->progressive_mode) {
107
#ifdef D_PROGRESSIVE_SUPPORTED
108
      jinit_phuff_decoder(cinfo);
109
#else
110
      ERREXIT(cinfo, JERR_NOT_COMPILED);
111
#endif
112
    } else
113
      jinit_huff_decoder(cinfo);
114
  }
115
116
  /* Always get a full-image coefficient buffer. */
117
  jinit_d_coef_controller(cinfo, TRUE);
118
119
  /* We can now tell the memory manager to allocate virtual arrays. */
120
  (*cinfo->mem->realize_virt_arrays) ((j_common_ptr) cinfo);
121
122
  /* Initialize input side of decompressor to consume first scan. */
123
  (*cinfo->inputctl->start_input_pass) (cinfo);
124
125
  /* Initialize progress monitoring. */
126
  if (cinfo->progress != NULL) {
127
    int nscans;
128
    /* Estimate number of scans to set pass_limit. */
129
    if (cinfo->progressive_mode) {
130
      /* Arbitrarily estimate 2 interleaved DC scans + 3 AC scans/component. */
131
      nscans = 2 + 3 * cinfo->num_components;
132
    } else if (cinfo->inputctl->has_multiple_scans) {
133
      /* For a nonprogressive multiscan file, estimate 1 scan per component. */
134
      nscans = cinfo->num_components;
135
    } else {
136
      nscans = 1;
137
    }
138
    cinfo->progress->pass_counter = 0L;
139
    cinfo->progress->pass_limit = (long) cinfo->total_iMCU_rows * nscans;
140
    cinfo->progress->completed_passes = 0;
141
    cinfo->progress->total_passes = 1;
142
  }
143
}
(-)a/jpeg/jerror.c (-15 / +9 lines)
Line     Link Here 
 Lines 13-35    Link Here 
13
 * If you define USE_WINDOWS_MESSAGEBOX in jconfig.h or in the makefile,
13
 * If you define USE_WINDOWS_MESSAGEBOX in jconfig.h or in the makefile,
14
 * you get a Windows-specific hack to display error messages in a dialog box.
14
 * you get a Windows-specific hack to display error messages in a dialog box.
15
 * It ain't much, but it beats dropping error messages into the bit bucket,
15
 * It ain't much, but it beats dropping error messages into the bit bucket,
16
 * which is what happens to output to stderr under most Windows C compilers.
16
 * which is what happens to output to stderr under most Windows C compilers.
17
 *
17
 *
18
 * These routines are used by both the compression and decompression code.
18
 * These routines are used by both the compression and decompression code.
19
 */
19
 */
20
20
21
/*
22
 * This file has been modified for the Mozilla/Netscape environment.
23
 * Modifications are distributed under the mozilla.org tri-license and are
24
 * Copyright (C) 1998 Netscape Communications Corporation.  All Rights
25
 * Reserved. See http://www.mozilla.org/MPL/
26
 */
27
28
/* this is not a core library module, so it doesn't define JPEG_INTERNALS */
21
/* this is not a core library module, so it doesn't define JPEG_INTERNALS */
29
#include "jinclude.h"
22
#include "jinclude.h"
30
#include "jpeglib.h"
23
#include "jpeglib.h"
31
#include "jversion.h"
24
#include "jversion.h"
32
#include "jerror.h"
25
#include "jerror.h"
33
26
34
#ifdef USE_WINDOWS_MESSAGEBOX
27
#ifdef USE_WINDOWS_MESSAGEBOX
35
#include <windows.h>
28
#include <windows.h>
 Lines 77-101   METHODDEF(void) Link Here 
77
error_exit (j_common_ptr cinfo)
70
error_exit (j_common_ptr cinfo)
78
{
71
{
79
  /* Always display the message */
72
  /* Always display the message */
80
  (*cinfo->err->output_message) (cinfo);
73
  (*cinfo->err->output_message) (cinfo);
81
74
82
  /* Let the memory manager delete any temp files before we die */
75
  /* Let the memory manager delete any temp files before we die */
83
  jpeg_destroy(cinfo);
76
  jpeg_destroy(cinfo);
84
77
85
/* Mozilla mod: in some Windows environments, the exit() function doesn't
86
 * even exist, so don't compile a reference to it.  Heaven help you if
87
 * you fail to provide a replacement error_exit function, because the
88
 * IJG library will NOT handle control returning from error_exit!
89
 */
90
91
#ifndef XP_WIN
92
  exit(EXIT_FAILURE);
78
  exit(EXIT_FAILURE);
93
#endif
94
}
79
}
95
80
96
81
97
/*
82
/*
98
 * Actual output of an error or trace message.
83
 * Actual output of an error or trace message.
99
 * Applications may override this method to send JPEG messages somewhere
84
 * Applications may override this method to send JPEG messages somewhere
100
 * other than stderr.
85
 * other than stderr.
101
 *
86
 *
 Lines 111-126   error_exit (j_common_ptr cinfo) Link Here 
111
96
112
METHODDEF(void)
97
METHODDEF(void)
113
output_message (j_common_ptr cinfo)
98
output_message (j_common_ptr cinfo)
114
{
99
{
115
  char buffer[JMSG_LENGTH_MAX];
100
  char buffer[JMSG_LENGTH_MAX];
116
101
117
  /* Create the message */
102
  /* Create the message */
118
  (*cinfo->err->format_message) (cinfo, buffer);
103
  (*cinfo->err->format_message) (cinfo, buffer);
104
105
#ifdef USE_WINDOWS_MESSAGEBOX
106
  /* Display it in a message dialog box */
107
  MessageBox(GetActiveWindow(), buffer, "JPEG Library Error",
108
	     MB_OK | MB_ICONERROR);
109
#else
110
  /* Send it to stderr, adding a newline */
111
  fprintf(stderr, "%s\n", buffer);
112
#endif
119
}
113
}
120
114
121
115
122
/*
116
/*
123
 * Decide whether to emit a trace or warning message.
117
 * Decide whether to emit a trace or warning message.
124
 * msg_level is one of:
118
 * msg_level is one of:
125
 *   -1: recoverable corrupt-data warning, may want to abort.
119
 *   -1: recoverable corrupt-data warning, may want to abort.
126
 *    0: important advisory messages (always display to user).
120
 *    0: important advisory messages (always display to user).
(-)a/jpeg/jidctfst.c (-1283 / +1 lines)
Line     Link Here 
 Lines 32-48    Link Here 
32
 * quality-setting files than with low-quality ones.
32
 * quality-setting files than with low-quality ones.
33
 */
33
 */
34
34
35
#define JPEG_INTERNALS
35
#define JPEG_INTERNALS
36
#include "jinclude.h"
36
#include "jinclude.h"
37
#include "jpeglib.h"
37
#include "jpeglib.h"
38
#include "jdct.h"		/* Private declarations for DCT subsystem */
38
#include "jdct.h"		/* Private declarations for DCT subsystem */
39
39
40
41
#ifdef DCT_IFAST_SUPPORTED
40
#ifdef DCT_IFAST_SUPPORTED
42
41
43
42
44
/*
43
/*
45
 * This module is specialized to the case DCTSIZE = 8.
44
 * This module is specialized to the case DCTSIZE = 8.
46
 */
45
 */
47
46
48
#if DCTSIZE != 8
47
#if DCTSIZE != 8
 Lines 155-205    Link Here 
155
#endif
154
#endif
156
155
157
#ifdef USE_ACCURATE_ROUNDING
156
#ifdef USE_ACCURATE_ROUNDING
158
#define IDESCALE(x,n)  ((int) IRIGHT_SHIFT((x) + (1 << ((n)-1)), n))
157
#define IDESCALE(x,n)  ((int) IRIGHT_SHIFT((x) + (1 << ((n)-1)), n))
159
#else
158
#else
160
#define IDESCALE(x,n)  ((int) IRIGHT_SHIFT(x, n))
159
#define IDESCALE(x,n)  ((int) IRIGHT_SHIFT(x, n))
161
#endif
160
#endif
162
161
163
#ifdef HAVE_MMX_INTEL_MNEMONICS
164
__inline GLOBAL(void)
165
jpeg_idct_ifast_mmx (j_decompress_ptr cinfo, jpeg_component_info * compptr,
166
		 JCOEFPTR coef_block,
167
		 JSAMPARRAY output_buf, JDIMENSION output_col);
168
__inline GLOBAL(void)
169
jpeg_idct_ifast_orig (j_decompress_ptr cinfo, jpeg_component_info * compptr,
170
		 JCOEFPTR coef_block,
171
		 JSAMPARRAY output_buf, JDIMENSION output_col);
172
#endif
173
174
GLOBAL(void)
175
jpeg_idct_ifast(j_decompress_ptr cinfo, jpeg_component_info * compptr,
176
		 JCOEFPTR coef_block,
177
		 JSAMPARRAY output_buf, JDIMENSION output_col);
178
179
180
#ifdef HAVE_MMX_INTEL_MNEMONICS
181
GLOBAL(void)
182
jpeg_idct_ifast (j_decompress_ptr cinfo, jpeg_component_info * compptr,
183
		 JCOEFPTR coef_block,
184
		 JSAMPARRAY output_buf, JDIMENSION output_col)
185
{
186
if (MMXAvailable)
187
	jpeg_idct_ifast_mmx(cinfo, compptr, coef_block, output_buf, output_col);
188
else
189
	jpeg_idct_ifast_orig(cinfo, compptr, coef_block, output_buf, output_col);
190
}
191
#else
192
162
193
/*
163
/*
194
 * Perform dequantization and inverse DCT on one block of coefficients.
164
 * Perform dequantization and inverse DCT on one block of coefficients.
195
 */
165
 */
196
166
197
GLOBAL (void)
167
GLOBAL(void)
198
jpeg_idct_ifast (j_decompress_ptr cinfo, jpeg_component_info * compptr,
168
jpeg_idct_ifast (j_decompress_ptr cinfo, jpeg_component_info * compptr,
199
		 JCOEFPTR coef_block,
169
		 JCOEFPTR coef_block,
200
		 JSAMPARRAY output_buf, JDIMENSION output_col)
170
		 JSAMPARRAY output_buf, JDIMENSION output_col)
201
{
171
{
202
  DCTELEM tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
172
  DCTELEM tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
203
  DCTELEM tmp10, tmp11, tmp12, tmp13;
173
  DCTELEM tmp10, tmp11, tmp12, tmp13;
204
  DCTELEM z5, z10, z11, z12, z13;
174
  DCTELEM z5, z10, z11, z12, z13;
205
  JCOEFPTR inptr;
175
  JCOEFPTR inptr;
 Lines 390-1650   jpeg_idct_ifast (j_decompress_ptr cinfo, Link Here 
390
			    & RANGE_MASK];
360
			    & RANGE_MASK];
391
    outptr[3] = range_limit[IDESCALE(tmp3 - tmp4, PASS1_BITS+3)
361
    outptr[3] = range_limit[IDESCALE(tmp3 - tmp4, PASS1_BITS+3)
392
			    & RANGE_MASK];
362
			    & RANGE_MASK];
393
363
394
    wsptr += DCTSIZE;		/* advance pointer to next row */
364
    wsptr += DCTSIZE;		/* advance pointer to next row */
395
  }
365
  }
396
}
366
}
397
367
398
#endif
399
400
#ifdef HAVE_MMX_INTEL_MNEMONICS
401
402
403
_inline GLOBAL(void)
404
jpeg_idct_ifast_orig (j_decompress_ptr cinfo, jpeg_component_info * compptr,
405
		 JCOEFPTR coef_block,
406
		 JSAMPARRAY output_buf, JDIMENSION output_col)
407
{
408
  DCTELEM tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
409
  DCTELEM tmp10, tmp11, tmp12, tmp13;
410
  DCTELEM z5, z10, z11, z12, z13;
411
  JCOEFPTR inptr;
412
  IFAST_MULT_TYPE * quantptr;
413
  int * wsptr;
414
  JSAMPROW outptr;
415
  JSAMPLE *range_limit = IDCT_range_limit(cinfo);
416
  int ctr;
417
  int workspace[DCTSIZE2];	/* buffers data between passes */
418
  SHIFT_TEMPS			/* for DESCALE */
419
  ISHIFT_TEMPS			/* for IDESCALE */
420
421
  /* Pass 1: process columns from input, store into work array. */
422
423
  inptr = coef_block;
424
  quantptr = (IFAST_MULT_TYPE *) compptr->dct_table;
425
  wsptr = workspace;
426
  for (ctr = DCTSIZE; ctr > 0; ctr--) {
427
    /* Due to quantization, we will usually find that many of the input
428
     * coefficients are zero, especially the AC terms.  We can exploit this
429
     * by short-circuiting the IDCT calculation for any column in which all
430
     * the AC terms are zero.  In that case each output is equal to the
431
     * DC coefficient (with scale factor as needed).
432
     * With typical images and quantization tables, half or more of the
433
     * column DCT calculations can be simplified this way.
434
     */
435
    
436
    if ((inptr[DCTSIZE*1] | inptr[DCTSIZE*2] | inptr[DCTSIZE*3] |
437
	 inptr[DCTSIZE*4] | inptr[DCTSIZE*5] | inptr[DCTSIZE*6] |
438
	 inptr[DCTSIZE*7]) == 0) {
439
      /* AC terms all zero */
440
      int dcval = (int) DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]);
441
442
      wsptr[DCTSIZE*0] = dcval;
443
      wsptr[DCTSIZE*1] = dcval;
444
      wsptr[DCTSIZE*2] = dcval;
445
      wsptr[DCTSIZE*3] = dcval;
446
      wsptr[DCTSIZE*4] = dcval;
447
      wsptr[DCTSIZE*5] = dcval;
448
      wsptr[DCTSIZE*6] = dcval;
449
      wsptr[DCTSIZE*7] = dcval;
450
      
451
      inptr++;			/* advance pointers to next column */
452
      quantptr++;
453
      wsptr++;
454
      continue;
455
    }
456
    
457
    /* Even part */
458
459
    tmp0 = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]);
460
    tmp1 = DEQUANTIZE(inptr[DCTSIZE*2], quantptr[DCTSIZE*2]);
461
    tmp2 = DEQUANTIZE(inptr[DCTSIZE*4], quantptr[DCTSIZE*4]);
462
    tmp3 = DEQUANTIZE(inptr[DCTSIZE*6], quantptr[DCTSIZE*6]);
463
464
    tmp10 = tmp0 + tmp2;	/* phase 3 */
465
    tmp11 = tmp0 - tmp2;
466
467
    tmp13 = tmp1 + tmp3;	/* phases 5-3 */
468
    tmp12 = MULTIPLY(tmp1 - tmp3, FIX_1_414213562) - tmp13; /* 2*c4 */
469
470
    tmp0 = tmp10 + tmp13;	/* phase 2 */
471
    tmp3 = tmp10 - tmp13;
472
    tmp1 = tmp11 + tmp12;
473
    tmp2 = tmp11 - tmp12;
474
    
475
    /* Odd part */
476
477
    tmp4 = DEQUANTIZE(inptr[DCTSIZE*1], quantptr[DCTSIZE*1]);
478
    tmp5 = DEQUANTIZE(inptr[DCTSIZE*3], quantptr[DCTSIZE*3]);
479
    tmp6 = DEQUANTIZE(inptr[DCTSIZE*5], quantptr[DCTSIZE*5]);
480
    tmp7 = DEQUANTIZE(inptr[DCTSIZE*7], quantptr[DCTSIZE*7]);
481
482
    z13 = tmp6 + tmp5;		/* phase 6 */
483
    z10 = tmp6 - tmp5;
484
    z11 = tmp4 + tmp7;
485
    z12 = tmp4 - tmp7;
486
487
    tmp7 = z11 + z13;		/* phase 5 */
488
    tmp11 = MULTIPLY(z11 - z13, FIX_1_414213562); /* 2*c4 */
489
490
    z5 = MULTIPLY(z10 + z12, FIX_1_847759065); /* 2*c2 */
491
    tmp10 = MULTIPLY(z12, FIX_1_082392200) - z5; /* 2*(c2-c6) */
492
    tmp12 = MULTIPLY(z10, - FIX_2_613125930) + z5; /* -2*(c2+c6) */
493
494
    tmp6 = tmp12 - tmp7;	/* phase 2 */
495
    tmp5 = tmp11 - tmp6;
496
    tmp4 = tmp10 + tmp5;
497
498
    wsptr[DCTSIZE*0] = (int) (tmp0 + tmp7);
499
    wsptr[DCTSIZE*7] = (int) (tmp0 - tmp7);
500
    wsptr[DCTSIZE*1] = (int) (tmp1 + tmp6);
501
    wsptr[DCTSIZE*6] = (int) (tmp1 - tmp6);
502
    wsptr[DCTSIZE*2] = (int) (tmp2 + tmp5);
503
    wsptr[DCTSIZE*5] = (int) (tmp2 - tmp5);
504
    wsptr[DCTSIZE*4] = (int) (tmp3 + tmp4);
505
    wsptr[DCTSIZE*3] = (int) (tmp3 - tmp4);
506
507
    inptr++;			/* advance pointers to next column */
508
    quantptr++;
509
    wsptr++;
510
  }
511
  
512
  /* Pass 2: process rows from work array, store into output array. */
513
  /* Note that we must descale the results by a factor of 8 == 2**3, */
514
  /* and also undo the PASS1_BITS scaling. */
515
516
  wsptr = workspace;
517
  for (ctr = 0; ctr < DCTSIZE; ctr++) {
518
    outptr = output_buf[ctr] + output_col;
519
    /* Rows of zeroes can be exploited in the same way as we did with columns.
520
     * However, the column calculation has created many nonzero AC terms, so
521
     * the simplification applies less often (typically 5% to 10% of the time).
522
     * On machines with very fast multiplication, it's possible that the
523
     * test takes more time than it's worth.  In that case this section
524
     * may be commented out.
525
     */
526
    
527
#ifndef NO_ZERO_ROW_TEST
528
    if ((wsptr[1] | wsptr[2] | wsptr[3] | wsptr[4] | wsptr[5] | wsptr[6] |
529
	 wsptr[7]) == 0) {
530
      /* AC terms all zero */
531
      JSAMPLE dcval = range_limit[IDESCALE(wsptr[0], PASS1_BITS+3)
532
				  & RANGE_MASK];
533
      
534
      outptr[0] = dcval;
535
      outptr[1] = dcval;
536
      outptr[2] = dcval;
537
      outptr[3] = dcval;
538
      outptr[4] = dcval;
539
      outptr[5] = dcval;
540
      outptr[6] = dcval;
541
      outptr[7] = dcval;
542
543
      wsptr += DCTSIZE;		/* advance pointer to next row */
544
      continue;
545
    }
546
#endif
547
    
548
    /* Even part */
549
550
    tmp10 = ((DCTELEM) wsptr[0] + (DCTELEM) wsptr[4]);
551
    tmp11 = ((DCTELEM) wsptr[0] - (DCTELEM) wsptr[4]);
552
553
    tmp13 = ((DCTELEM) wsptr[2] + (DCTELEM) wsptr[6]);
554
    tmp12 = MULTIPLY((DCTELEM) wsptr[2] - (DCTELEM) wsptr[6], FIX_1_414213562)
555
	    - tmp13;
556
557
    tmp0 = tmp10 + tmp13;
558
    tmp3 = tmp10 - tmp13;
559
    tmp1 = tmp11 + tmp12;
560
    tmp2 = tmp11 - tmp12;
561
562
    /* Odd part */
563
564
    z13 = (DCTELEM) wsptr[5] + (DCTELEM) wsptr[3];
565
    z10 = (DCTELEM) wsptr[5] - (DCTELEM) wsptr[3];
566
    z11 = (DCTELEM) wsptr[1] + (DCTELEM) wsptr[7];
567
    z12 = (DCTELEM) wsptr[1] - (DCTELEM) wsptr[7];
568
569
    tmp7 = z11 + z13;		/* phase 5 */
570
    tmp11 = MULTIPLY(z11 - z13, FIX_1_414213562); /* 2*c4 */
571
572
    z5 = MULTIPLY(z10 + z12, FIX_1_847759065); /* 2*c2 */
573
    tmp10 = MULTIPLY(z12, FIX_1_082392200) - z5; /* 2*(c2-c6) */
574
    tmp12 = MULTIPLY(z10, - FIX_2_613125930) + z5; /* -2*(c2+c6) */
575
576
    tmp6 = tmp12 - tmp7;	/* phase 2 */
577
    tmp5 = tmp11 - tmp6;
578
    tmp4 = tmp10 + tmp5;
579
580
    /* Final output stage: scale down by a factor of 8 and range-limit */
581
582
    outptr[0] = range_limit[IDESCALE(tmp0 + tmp7, PASS1_BITS+3)
583
			    & RANGE_MASK];
584
    outptr[7] = range_limit[IDESCALE(tmp0 - tmp7, PASS1_BITS+3)
585
			    & RANGE_MASK];
586
    outptr[1] = range_limit[IDESCALE(tmp1 + tmp6, PASS1_BITS+3)
587
			    & RANGE_MASK];
588
    outptr[6] = range_limit[IDESCALE(tmp1 - tmp6, PASS1_BITS+3)
589
			    & RANGE_MASK];
590
    outptr[2] = range_limit[IDESCALE(tmp2 + tmp5, PASS1_BITS+3)
591
			    & RANGE_MASK];
592
    outptr[5] = range_limit[IDESCALE(tmp2 - tmp5, PASS1_BITS+3)
593
			    & RANGE_MASK];
594
    outptr[4] = range_limit[IDESCALE(tmp3 + tmp4, PASS1_BITS+3)
595
			    & RANGE_MASK];
596
    outptr[3] = range_limit[IDESCALE(tmp3 - tmp4, PASS1_BITS+3)
597
			    & RANGE_MASK];
598
599
    wsptr += DCTSIZE;		/* advance pointer to next row */
600
  }
601
}
602
603
604
	static	  __int64 fix_141		= 0x5a825a825a825a82;
605
	static	  __int64 fix_184n261	= 0xcf04cf04cf04cf04;
606
	static	  __int64 fix_184		= 0x7641764176417641;
607
	static	  __int64 fix_n184		= 0x896f896f896f896f;
608
	static	  __int64 fix_108n184	= 0xcf04cf04cf04cf04;
609
	static	  __int64 const_0x0080	= 0x0080008000800080;
610
611
612
__inline GLOBAL(void)
613
jpeg_idct_ifast_mmx (j_decompress_ptr cinfo, jpeg_component_info * compptr,
614
		 JCOEFPTR inptr,
615
		 JSAMPARRAY outptr, JDIMENSION output_col)
616
{
617
618
  int16 workspace[DCTSIZE2 + 4];	/* buffers data between passes */
619
  int16 *wsptr=workspace;
620
  int16 *quantptr=compptr->dct_table;
621
622
  __asm{ 
623
    
624
	mov		edi, quantptr
625
	mov		ebx, inptr
626
	mov		esi, wsptr
627
	add		esi, 0x07		;align wsptr to qword
628
	and		esi, 0xfffffff8	;align wsptr to qword
629
630
	mov		eax, esi
631
632
    /* Odd part */
633
634
635
	movq		mm1, [ebx + 8*10]		;load inptr[DCTSIZE*5]
636
637
	pmullw		mm1, [edi + 8*10]		;tmp6 = DEQUANTIZE(inptr[DCTSIZE*5], quantptr[DCTSIZE*5]);
638
639
	movq		mm0, [ebx + 8*6]		;load inptr[DCTSIZE*3]
640
641
	pmullw		mm0, [edi + 8*6]		;tmp5 = DEQUANTIZE(inptr[DCTSIZE*3], quantptr[DCTSIZE*3]);
642
643
	movq		mm3, [ebx + 8*2]		;load inptr[DCTSIZE*1]
644
	movq	mm2, mm1					;copy tmp6	/* phase 6 */
645
646
	pmullw		mm3, [edi + 8*2]		;tmp4 = DEQUANTIZE(inptr[DCTSIZE*1], quantptr[DCTSIZE*1]);
647
648
	movq		mm4, [ebx + 8*14]		;load inptr[DCTSIZE*1]
649
	paddw	mm1, mm0					;z13 = tmp6 + tmp5;
650
651
	pmullw		mm4, [edi + 8*14]	    ;tmp7 = DEQUANTIZE(inptr[DCTSIZE*7], quantptr[DCTSIZE*7]);
652
	psubw	mm2, mm0					;z10 = tmp6 - tmp5   
653
654
	psllw		mm2, 2				;shift z10
655
	movq		mm0, mm2			;copy z10
656
657
	pmulhw		mm2, fix_184n261	;MULTIPLY( z12, FIX_1_847759065); /* 2*c2 */
658
	movq		mm5, mm3				;copy tmp4
659
660
	pmulhw		mm0, fix_n184		;MULTIPLY(z10, -FIX_1_847759065); /* 2*c2 */
661
	paddw		mm3, mm4				;z11 = tmp4 + tmp7;
662
663
	movq		mm6, mm3				;copy z11			/* phase 5 */
664
	psubw		mm5, mm4				;z12 = tmp4 - tmp7;
665
666
	psubw		mm6, mm1				;z11-z13
667
	psllw		mm5, 2				;shift z12
668
669
	movq		mm4, [ebx + 8*12]		;load inptr[DCTSIZE*6], even part
670
 	movq		mm7, mm5			;copy z12
671
672
	pmulhw		mm5, fix_108n184	;MULT(z12, (FIX_1_08-FIX_1_84)) //- z5; /* 2*(c2-c6) */ even part
673
	paddw		mm3, mm1				;tmp7 = z11 + z13;	
674
675
676
    /* Even part */
677
	pmulhw		mm7, fix_184		;MULTIPLY(z10,(FIX_1_847759065 - FIX_2_613125930)) //+ z5; /* -2*(c2+c6) */
678
	psllw		mm6, 2
679
680
	movq		mm1, [ebx + 8*4]		;load inptr[DCTSIZE*2]
681
682
	pmullw		mm1, [edi + 8*4]		;tmp1 = DEQUANTIZE(inptr[DCTSIZE*2], quantptr[DCTSIZE*2]);
683
	paddw		mm0, mm5			;tmp10
684
685
	pmullw		mm4, [edi + 8*12]		;tmp3 = DEQUANTIZE(inptr[DCTSIZE*6], quantptr[DCTSIZE*6]);
686
	paddw		mm2, mm7			;tmp12
687
688
	pmulhw		mm6, fix_141			;tmp11 = MULTIPLY(z11 - z13, FIX_1_414213562); /* 2*c4 */
689
	psubw		mm2, mm3		;tmp6 = tmp12 - tmp7
690
691
	movq		mm5, mm1				;copy tmp1
692
	paddw		mm1, mm4				;tmp13= tmp1 + tmp3;	/* phases 5-3 */
693
694
	psubw		mm5, mm4				;tmp1-tmp3
695
	psubw		mm6, mm2		;tmp5 = tmp11 - tmp6;
696
697
	movq		[esi+8*0], mm1			;save tmp13 in workspace
698
	psllw		mm5, 2					;shift tmp1-tmp3
699
    
700
	movq		mm7, [ebx + 8*0]		;load inptr[DCTSIZE*0]
701
702
	pmulhw		mm5, fix_141			;MULTIPLY(tmp1 - tmp3, FIX_1_414213562)
703
	paddw		mm0, mm6		;tmp4 = tmp10 + tmp5;
704
705
	pmullw		mm7, [edi + 8*0]		;tmp0 = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]);
706
707
	movq		mm4, [ebx + 8*8]		;load inptr[DCTSIZE*4]
708
	
709
	pmullw		mm4, [edi + 8*8]		;tmp2 = DEQUANTIZE(inptr[DCTSIZE*4], quantptr[DCTSIZE*4]);
710
	psubw		mm5, mm1				;tmp12 = MULTIPLY(tmp1 - tmp3, FIX_1_414213562) - tmp13; /* 2*c4 */
711
712
	movq		[esi+8*4], mm0		;save tmp4 in workspace
713
	movq		mm1, mm7			;copy tmp0	/* phase 3 */
714
715
	movq		[esi+8*2], mm5		;save tmp12 in workspace
716
	psubw		mm1, mm4			;tmp11 = tmp0 - tmp2; 
717
718
	paddw		mm7, mm4			;tmp10 = tmp0 + tmp2;
719
    movq		mm5, mm1		;copy tmp11
720
	
721
	paddw		mm1, [esi+8*2]	;tmp1 = tmp11 + tmp12;
722
	movq		mm4, mm7		;copy tmp10		/* phase 2 */
723
724
	paddw		mm7, [esi+8*0]	;tmp0 = tmp10 + tmp13;	
725
726
	psubw		mm4, [esi+8*0]	;tmp3 = tmp10 - tmp13;
727
	movq		mm0, mm7		;copy tmp0
728
729
	psubw		mm5, [esi+8*2]	;tmp2 = tmp11 - tmp12;
730
	paddw		mm7, mm3		;wsptr[DCTSIZE*0] = (int) (tmp0 + tmp7);
731
	
732
	psubw		mm0, mm3			;wsptr[DCTSIZE*7] = (int) (tmp0 - tmp7);
733
734
	movq		[esi + 8*0], mm7	;wsptr[DCTSIZE*0]
735
	movq		mm3, mm1			;copy tmp1
736
737
	movq		[esi + 8*14], mm0	;wsptr[DCTSIZE*7]
738
	paddw		mm1, mm2			;wsptr[DCTSIZE*1] = (int) (tmp1 + tmp6);
739
740
	psubw		mm3, mm2			;wsptr[DCTSIZE*6] = (int) (tmp1 - tmp6);
741
742
	movq		[esi + 8*2], mm1	;wsptr[DCTSIZE*1]
743
	movq		mm1, mm4			;copy tmp3
744
745
	movq		[esi + 8*12], mm3	;wsptr[DCTSIZE*6]
746
747
	paddw		mm4, [esi+8*4]		;wsptr[DCTSIZE*4] = (int) (tmp3 + tmp4);
748
749
	psubw		mm1, [esi+8*4]		;wsptr[DCTSIZE*3] = (int) (tmp3 - tmp4);
750
751
	movq		[esi + 8*8], mm4
752
	movq		mm7, mm5			;copy tmp2
753
754
	paddw		mm5, mm6			;wsptr[DCTSIZE*2] = (int) (tmp2 + tmp5)
755
756
	movq		[esi+8*6], mm1		;
757
	psubw		mm7, mm6			;wsptr[DCTSIZE*5] = (int) (tmp2 - tmp5);
758
759
	movq		[esi + 8*4], mm5
760
761
	movq		[esi + 8*10], mm7
762
763
764
765
/*****************************************************************/
766
	add		edi, 8
767
	add		ebx, 8
768
	add		esi, 8
769
770
/*****************************************************************/
771
772
773
774
775
	movq		mm1, [ebx + 8*10]		;load inptr[DCTSIZE*5]
776
777
	pmullw		mm1, [edi + 8*10]		;tmp6 = DEQUANTIZE(inptr[DCTSIZE*5], quantptr[DCTSIZE*5]);
778
779
	movq		mm0, [ebx + 8*6]		;load inptr[DCTSIZE*3]
780
781
	pmullw		mm0, [edi + 8*6]		;tmp5 = DEQUANTIZE(inptr[DCTSIZE*3], quantptr[DCTSIZE*3]);
782
783
	movq		mm3, [ebx + 8*2]		;load inptr[DCTSIZE*1]
784
	movq	mm2, mm1					;copy tmp6	/* phase 6 */
785
786
	pmullw		mm3, [edi + 8*2]		;tmp4 = DEQUANTIZE(inptr[DCTSIZE*1], quantptr[DCTSIZE*1]);
787
788
	movq		mm4, [ebx + 8*14]		;load inptr[DCTSIZE*1]
789
	paddw	mm1, mm0					;z13 = tmp6 + tmp5;
790
791
	pmullw		mm4, [edi + 8*14]	    ;tmp7 = DEQUANTIZE(inptr[DCTSIZE*7], quantptr[DCTSIZE*7]);
792
	psubw	mm2, mm0					;z10 = tmp6 - tmp5   
793
794
	psllw		mm2, 2				;shift z10
795
	movq		mm0, mm2			;copy z10
796
797
	pmulhw		mm2, fix_184n261	;MULTIPLY( z12, FIX_1_847759065); /* 2*c2 */
798
	movq		mm5, mm3				;copy tmp4
799
800
	pmulhw		mm0, fix_n184		;MULTIPLY(z10, -FIX_1_847759065); /* 2*c2 */
801
	paddw		mm3, mm4				;z11 = tmp4 + tmp7;
802
803
	movq		mm6, mm3				;copy z11			/* phase 5 */
804
	psubw		mm5, mm4				;z12 = tmp4 - tmp7;
805
806
	psubw		mm6, mm1				;z11-z13
807
	psllw		mm5, 2				;shift z12
808
809
	movq		mm4, [ebx + 8*12]		;load inptr[DCTSIZE*6], even part
810
 	movq		mm7, mm5			;copy z12
811
812
	pmulhw		mm5, fix_108n184	;MULT(z12, (FIX_1_08-FIX_1_84)) //- z5; /* 2*(c2-c6) */ even part
813
	paddw		mm3, mm1				;tmp7 = z11 + z13;	
814
815
816
    /* Even part */
817
	pmulhw		mm7, fix_184		;MULTIPLY(z10,(FIX_1_847759065 - FIX_2_613125930)) //+ z5; /* -2*(c2+c6) */
818
	psllw		mm6, 2
819
820
	movq		mm1, [ebx + 8*4]		;load inptr[DCTSIZE*2]
821
822
	pmullw		mm1, [edi + 8*4]		;tmp1 = DEQUANTIZE(inptr[DCTSIZE*2], quantptr[DCTSIZE*2]);
823
	paddw		mm0, mm5			;tmp10
824
825
	pmullw		mm4, [edi + 8*12]		;tmp3 = DEQUANTIZE(inptr[DCTSIZE*6], quantptr[DCTSIZE*6]);
826
	paddw		mm2, mm7			;tmp12
827
828
	pmulhw		mm6, fix_141			;tmp11 = MULTIPLY(z11 - z13, FIX_1_414213562); /* 2*c4 */
829
	psubw		mm2, mm3		;tmp6 = tmp12 - tmp7
830
831
	movq		mm5, mm1				;copy tmp1
832
	paddw		mm1, mm4				;tmp13= tmp1 + tmp3;	/* phases 5-3 */
833
834
	psubw		mm5, mm4				;tmp1-tmp3
835
	psubw		mm6, mm2		;tmp5 = tmp11 - tmp6;
836
837
	movq		[esi+8*0], mm1			;save tmp13 in workspace
838
	psllw		mm5, 2					;shift tmp1-tmp3
839
    
840
	movq		mm7, [ebx + 8*0]		;load inptr[DCTSIZE*0]
841
	paddw		mm0, mm6		;tmp4 = tmp10 + tmp5;
842
843
	pmulhw		mm5, fix_141			;MULTIPLY(tmp1 - tmp3, FIX_1_414213562)
844
845
	pmullw		mm7, [edi + 8*0]		;tmp0 = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]);
846
847
	movq		mm4, [ebx + 8*8]		;load inptr[DCTSIZE*4]
848
	
849
	pmullw		mm4, [edi + 8*8]		;tmp2 = DEQUANTIZE(inptr[DCTSIZE*4], quantptr[DCTSIZE*4]);
850
	psubw		mm5, mm1				;tmp12 = MULTIPLY(tmp1 - tmp3, FIX_1_414213562) - tmp13; /* 2*c4 */
851
852
	movq		[esi+8*4], mm0		;save tmp4 in workspace
853
	movq		mm1, mm7			;copy tmp0	/* phase 3 */
854
855
	movq		[esi+8*2], mm5		;save tmp12 in workspace
856
	psubw		mm1, mm4			;tmp11 = tmp0 - tmp2; 
857
858
	paddw		mm7, mm4			;tmp10 = tmp0 + tmp2;
859
    movq		mm5, mm1		;copy tmp11
860
	
861
	paddw		mm1, [esi+8*2]	;tmp1 = tmp11 + tmp12;
862
	movq		mm4, mm7		;copy tmp10		/* phase 2 */
863
864
	paddw		mm7, [esi+8*0]	;tmp0 = tmp10 + tmp13;	
865
866
	psubw		mm4, [esi+8*0]	;tmp3 = tmp10 - tmp13;
867
	movq		mm0, mm7		;copy tmp0
868
869
	psubw		mm5, [esi+8*2]	;tmp2 = tmp11 - tmp12;
870
	paddw		mm7, mm3		;wsptr[DCTSIZE*0] = (int) (tmp0 + tmp7);
871
	
872
	psubw		mm0, mm3			;wsptr[DCTSIZE*7] = (int) (tmp0 - tmp7);
873
874
	movq		[esi + 8*0], mm7	;wsptr[DCTSIZE*0]
875
	movq		mm3, mm1			;copy tmp1
876
877
	movq		[esi + 8*14], mm0	;wsptr[DCTSIZE*7]
878
	paddw		mm1, mm2			;wsptr[DCTSIZE*1] = (int) (tmp1 + tmp6);
879
880
	psubw		mm3, mm2			;wsptr[DCTSIZE*6] = (int) (tmp1 - tmp6);
881
882
	movq		[esi + 8*2], mm1	;wsptr[DCTSIZE*1]
883
	movq		mm1, mm4			;copy tmp3
884
885
	movq		[esi + 8*12], mm3	;wsptr[DCTSIZE*6]
886
887
	paddw		mm4, [esi+8*4]		;wsptr[DCTSIZE*4] = (int) (tmp3 + tmp4);
888
889
	psubw		mm1, [esi+8*4]		;wsptr[DCTSIZE*3] = (int) (tmp3 - tmp4);
890
891
	movq		[esi + 8*8], mm4
892
	movq		mm7, mm5			;copy tmp2
893
894
	paddw		mm5, mm6			;wsptr[DCTSIZE*2] = (int) (tmp2 + tmp5)
895
896
	movq		[esi+8*6], mm1		;
897
	psubw		mm7, mm6			;wsptr[DCTSIZE*5] = (int) (tmp2 - tmp5);
898
899
	movq		[esi + 8*4], mm5
900
901
	movq		[esi + 8*10], mm7
902
903
904
905
906
/*****************************************************************/
907
908
  /* Pass 2: process rows from work array, store into output array. */
909
  /* Note that we must descale the results by a factor of 8 == 2**3, */
910
  /* and also undo the PASS1_BITS scaling. */
911
912
/*****************************************************************/
913
    /* Even part */
914
915
	mov			esi, eax
916
	mov			eax, outptr
917
918
//    tmp10 = ((DCTELEM) wsptr[0] + (DCTELEM) wsptr[4]);
919
//    tmp13 = ((DCTELEM) wsptr[2] + (DCTELEM) wsptr[6]);
920
//    tmp11 = ((DCTELEM) wsptr[0] - (DCTELEM) wsptr[4]);
921
//    tmp14 = ((DCTELEM) wsptr[2] - (DCTELEM) wsptr[6]);
922
	movq		mm0, [esi+8*0]		;wsptr[0,0],[0,1],[0,2],[0,3]
923
924
	movq		mm1, [esi+8*1]		;wsptr[0,4],[0,5],[0,6],[0,7]
925
	movq		mm2, mm0
926
	
927
	movq		mm3, [esi+8*2]		;wsptr[1,0],[1,1],[1,2],[1,3]
928
	paddw		mm0, mm1			;wsptr[0,tmp10],[xxx],[0,tmp13],[xxx]
929
930
	movq		mm4, [esi+8*3]		;wsptr[1,4],[1,5],[1,6],[1,7]
931
	psubw		mm2, mm1			;wsptr[0,tmp11],[xxx],[0,tmp14],[xxx]
932
933
	movq		mm6, mm0
934
	movq		mm5, mm3
935
	
936
	paddw		mm3, mm4			;wsptr[1,tmp10],[xxx],[1,tmp13],[xxx]
937
	movq		mm1, mm2
938
939
	psubw		mm5, mm4			;wsptr[1,tmp11],[xxx],[1,tmp14],[xxx]
940
	punpcklwd	mm0, mm3			;wsptr[0,tmp10],[1,tmp10],[xxx],[xxx]
941
942
	movq		mm7, [esi+8*7]		;wsptr[3,4],[3,5],[3,6],[3,7]
943
	punpckhwd	mm6, mm3			;wsptr[0,tmp13],[1,tmp13],[xxx],[xxx]
944
945
	movq		mm3, [esi+8*4]		;wsptr[2,0],[2,1],[2,2],[2,3]
946
	punpckldq	mm0, mm6	;wsptr[0,tmp10],[1,tmp10],[0,tmp13],[1,tmp13]
947
948
	punpcklwd	mm1, mm5			;wsptr[0,tmp11],[1,tmp11],[xxx],[xxx]
949
	movq		mm4, mm3
950
951
	movq		mm6, [esi+8*6]		;wsptr[3,0],[3,1],[3,2],[3,3]
952
	punpckhwd	mm2, mm5			;wsptr[0,tmp14],[1,tmp14],[xxx],[xxx]
953
954
	movq		mm5, [esi+8*5]		;wsptr[2,4],[2,5],[2,6],[2,7]
955
	punpckldq	mm1, mm2	;wsptr[0,tmp11],[1,tmp11],[0,tmp14],[1,tmp14]
956
957
	
958
	paddw		mm3, mm5			;wsptr[2,tmp10],[xxx],[2,tmp13],[xxx]
959
	movq		mm2, mm6
960
961
	psubw		mm4, mm5			;wsptr[2,tmp11],[xxx],[2,tmp14],[xxx]
962
	paddw		mm6, mm7			;wsptr[3,tmp10],[xxx],[3,tmp13],[xxx]
963
964
	movq		mm5, mm3
965
	punpcklwd	mm3, mm6			;wsptr[2,tmp10],[3,tmp10],[xxx],[xxx]
966
	
967
	psubw		mm2, mm7			;wsptr[3,tmp11],[xxx],[3,tmp14],[xxx]
968
	punpckhwd	mm5, mm6			;wsptr[2,tmp13],[3,tmp13],[xxx],[xxx]
969
970
	movq		mm7, mm4
971
	punpckldq	mm3, mm5	;wsptr[2,tmp10],[3,tmp10],[2,tmp13],[3,tmp13]
972
973
	punpcklwd	mm4, mm2			;wsptr[2,tmp11],[3,tmp11],[xxx],[xxx]
974
975
	punpckhwd	mm7, mm2			;wsptr[2,tmp14],[3,tmp14],[xxx],[xxx]
976
977
	punpckldq	mm4, mm7	;wsptr[2,tmp11],[3,tmp11],[2,tmp14],[3,tmp14]
978
	movq		mm6, mm1
979
980
//	mm0 = 	;wsptr[0,tmp10],[1,tmp10],[0,tmp13],[1,tmp13]
981
//	mm1 =	;wsptr[0,tmp11],[1,tmp11],[0,tmp14],[1,tmp14]
982
983
984
	movq		mm2, mm0
985
	punpckhdq	mm6, mm4	;wsptr[0,tmp14],[1,tmp14],[2,tmp14],[3,tmp14]
986
987
	punpckldq	mm1, mm4	;wsptr[0,tmp11],[1,tmp11],[2,tmp11],[3,tmp11]
988
	psllw		mm6, 2
989
990
	pmulhw		mm6, fix_141
991
	punpckldq	mm0, mm3	;wsptr[0,tmp10],[1,tmp10],[2,tmp10],[3,tmp10]
992
993
	punpckhdq	mm2, mm3	;wsptr[0,tmp13],[1,tmp13],[2,tmp13],[3,tmp13]
994
	movq		mm7, mm0
995
996
//    tmp0 = tmp10 + tmp13;
997
//    tmp3 = tmp10 - tmp13;
998
	paddw		mm0, mm2	;[0,tmp0],[1,tmp0],[2,tmp0],[3,tmp0]
999
	psubw		mm7, mm2	;[0,tmp3],[1,tmp3],[2,tmp3],[3,tmp3]
1000
1001
//    tmp12 = MULTIPLY(tmp14, FIX_1_414213562) - tmp13;
1002
	psubw		mm6, mm2	;wsptr[0,tmp12],[1,tmp12],[2,tmp12],[3,tmp12]
1003
//    tmp1 = tmp11 + tmp12;
1004
//    tmp2 = tmp11 - tmp12;
1005
	movq		mm5, mm1
1006
1007
1008
1009
    /* Odd part */
1010
1011
//    z13 = (DCTELEM) wsptr[5] + (DCTELEM) wsptr[3];
1012
//    z10 = (DCTELEM) wsptr[5] - (DCTELEM) wsptr[3];
1013
//    z11 = (DCTELEM) wsptr[1] + (DCTELEM) wsptr[7];
1014
//    z12 = (DCTELEM) wsptr[1] - (DCTELEM) wsptr[7];
1015
	movq		mm3, [esi+8*0]		;wsptr[0,0],[0,1],[0,2],[0,3]
1016
	paddw		mm1, mm6	;[0,tmp1],[1,tmp1],[2,tmp1],[3,tmp1]
1017
1018
	movq		mm4, [esi+8*1]		;wsptr[0,4],[0,5],[0,6],[0,7]
1019
	psubw		mm5, mm6	;[0,tmp2],[1,tmp2],[2,tmp2],[3,tmp2]
1020
1021
	movq		mm6, mm3
1022
	punpckldq	mm3, mm4			;wsptr[0,0],[0,1],[0,4],[0,5]
1023
1024
	punpckhdq	mm4, mm6			;wsptr[0,6],[0,7],[0,2],[0,3]
1025
	movq		mm2, mm3
1026
1027
//Save tmp0 and tmp1 in wsptr
1028
	movq		[esi+8*0], mm0		;save tmp0
1029
	paddw		mm2, mm4			;wsptr[xxx],[0,z11],[xxx],[0,z13]
1030
1031
	
1032
//Continue with z10 --- z13
1033
	movq		mm6, [esi+8*2]		;wsptr[1,0],[1,1],[1,2],[1,3]
1034
	psubw		mm3, mm4			;wsptr[xxx],[0,z12],[xxx],[0,z10]
1035
1036
	movq		mm0, [esi+8*3]		;wsptr[1,4],[1,5],[1,6],[1,7]
1037
	movq		mm4, mm6
1038
1039
	movq		[esi+8*1], mm1		;save tmp1
1040
	punpckldq	mm6, mm0			;wsptr[1,0],[1,1],[1,4],[1,5]
1041
1042
	punpckhdq	mm0, mm4			;wsptr[1,6],[1,7],[1,2],[1,3]
1043
	movq		mm1, mm6
1044
	
1045
//Save tmp2 and tmp3 in wsptr
1046
	paddw		mm6, mm0		;wsptr[xxx],[1,z11],[xxx],[1,z13]
1047
	movq		mm4, mm2
1048
	
1049
//Continue with z10 --- z13
1050
	movq		[esi+8*2], mm5		;save tmp2
1051
	punpcklwd	mm2, mm6		;wsptr[xxx],[xxx],[0,z11],[1,z11]
1052
1053
	psubw		mm1, mm0		;wsptr[xxx],[1,z12],[xxx],[1,z10]
1054
	punpckhwd	mm4, mm6		;wsptr[xxx],[xxx],[0,z13],[1,z13]
1055
1056
	movq		mm0, mm3
1057
	punpcklwd	mm3, mm1		;wsptr[xxx],[xxx],[0,z12],[1,z12]
1058
1059
	movq		[esi+8*3], mm7		;save tmp3
1060
	punpckhwd	mm0, mm1		;wsptr[xxx],[xxx],[0,z10],[1,z10]
1061
1062
	movq		mm6, [esi+8*4]		;wsptr[2,0],[2,1],[2,2],[2,3]
1063
	punpckhdq	mm0, mm2		;wsptr[0,z10],[1,z10],[0,z11],[1,z11]
1064
1065
	movq		mm7, [esi+8*5]		;wsptr[2,4],[2,5],[2,6],[2,7]
1066
	punpckhdq	mm3, mm4		;wsptr[0,z12],[1,z12],[0,z13],[1,z13]
1067
1068
	movq		mm1, [esi+8*6]		;wsptr[3,0],[3,1],[3,2],[3,3]
1069
	movq		mm4, mm6
1070
1071
	punpckldq	mm6, mm7			;wsptr[2,0],[2,1],[2,4],[2,5]
1072
	movq		mm5, mm1
1073
1074
	punpckhdq	mm7, mm4			;wsptr[2,6],[2,7],[2,2],[2,3]
1075
	movq		mm2, mm6
1076
	
1077
	movq		mm4, [esi+8*7]		;wsptr[3,4],[3,5],[3,6],[3,7]
1078
	paddw		mm6, mm7		;wsptr[xxx],[2,z11],[xxx],[2,z13]
1079
1080
	psubw		mm2, mm7		;wsptr[xxx],[2,z12],[xxx],[2,z10]
1081
	punpckldq	mm1, mm4			;wsptr[3,0],[3,1],[3,4],[3,5]
1082
1083
	punpckhdq	mm4, mm5			;wsptr[3,6],[3,7],[3,2],[3,3]
1084
	movq		mm7, mm1
1085
1086
	paddw		mm1, mm4		;wsptr[xxx],[3,z11],[xxx],[3,z13]
1087
	psubw		mm7, mm4		;wsptr[xxx],[3,z12],[xxx],[3,z10]
1088
1089
	movq		mm5, mm6
1090
	punpcklwd	mm6, mm1		;wsptr[xxx],[xxx],[2,z11],[3,z11]
1091
1092
	punpckhwd	mm5, mm1		;wsptr[xxx],[xxx],[2,z13],[3,z13]
1093
	movq		mm4, mm2
1094
1095
	punpcklwd	mm2, mm7		;wsptr[xxx],[xxx],[2,z12],[3,z12]
1096
1097
	punpckhwd	mm4, mm7		;wsptr[xxx],[xxx],[2,z10],[3,z10]
1098
1099
	punpckhdq	mm4, mm6		;wsptr[2,z10],[3,z10],[2,z11],[3,z11]
1100
1101
	punpckhdq	mm2, mm5		;wsptr[2,z12],[3,z12],[2,z13],[3,z13]
1102
	movq		mm5, mm0
1103
1104
	punpckldq	mm0, mm4		;wsptr[0,z10],[1,z10],[2,z10],[3,z10]
1105
1106
	punpckhdq	mm5, mm4		;wsptr[0,z11],[1,z11],[2,z11],[3,z11]
1107
	movq		mm4, mm3
1108
1109
	punpckhdq	mm4, mm2		;wsptr[0,z13],[1,z13],[2,z13],[3,z13]
1110
	movq		mm1, mm5
1111
1112
	punpckldq	mm3, mm2		;wsptr[0,z12],[1,z12],[2,z12],[3,z12]
1113
//    tmp7 = z11 + z13;		/* phase 5 */
1114
//    tmp8 = z11 - z13;		/* phase 5 */
1115
	psubw		mm1, mm4		;tmp8
1116
1117
	paddw		mm5, mm4		;tmp7
1118
//    tmp21 = MULTIPLY(tmp8, FIX_1_414213562); /* 2*c4 */
1119
	psllw		mm1, 2
1120
1121
	psllw		mm0, 2
1122
1123
	pmulhw		mm1, fix_141	;tmp21
1124
//    tmp20 = MULTIPLY(z12, (FIX_1_082392200- FIX_1_847759065))  /* 2*(c2-c6) */
1125
//			+ MULTIPLY(z10, - FIX_1_847759065); /* 2*c2 */
1126
	psllw		mm3, 2
1127
	movq		mm7, mm0
1128
1129
	pmulhw		mm7, fix_n184
1130
	movq		mm6, mm3
1131
1132
	movq		mm2, [esi+8*0]	;tmp0,final1
1133
1134
	pmulhw		mm6, fix_108n184
1135
//	 tmp22 = MULTIPLY(z10,(FIX_1_847759065 - FIX_2_613125930)) /* -2*(c2+c6) */
1136
//			+ MULTIPLY(z12, FIX_1_847759065); /* 2*c2 */
1137
	movq		mm4, mm2		;final1
1138
  
1139
	pmulhw		mm0, fix_184n261
1140
	paddw		mm2, mm5		;tmp0+tmp7,final1
1141
1142
	pmulhw		mm3, fix_184
1143
	psubw		mm4, mm5		;tmp0-tmp7,final1
1144
1145
//    tmp6 = tmp22 - tmp7;	/* phase 2 */
1146
	psraw		mm2, 5			;outptr[0,0],[1,0],[2,0],[3,0],final1
1147
1148
	paddsw		mm2, const_0x0080	;final1
1149
	paddw		mm7, mm6			;tmp20
1150
	psraw		mm4, 5			;outptr[0,7],[1,7],[2,7],[3,7],final1
1151
1152
	paddsw		mm4, const_0x0080	;final1
1153
	paddw		mm3, mm0			;tmp22
1154
1155
//    tmp5 = tmp21 - tmp6;
1156
	psubw		mm3, mm5		;tmp6
1157
1158
//    tmp4 = tmp20 + tmp5;
1159
	movq		mm0, [esi+8*1]		;tmp1,final2
1160
	psubw		mm1, mm3		;tmp5
1161
1162
	movq		mm6, mm0			;final2
1163
	paddw		mm0, mm3		;tmp1+tmp6,final2
1164
1165
    /* Final output stage: scale down by a factor of 8 and range-limit */
1166
1167
1168
//    outptr[0] = range_limit[IDESCALE(tmp0 + tmp7, PASS1_BITS+3)
1169
//			    & RANGE_MASK];
1170
//    outptr[7] = range_limit[IDESCALE(tmp0 - tmp7, PASS1_BITS+3)
1171
//			    & RANGE_MASK];	final1
1172
1173
1174
//    outptr[1] = range_limit[IDESCALE(tmp1 + tmp6, PASS1_BITS+3)
1175
//			    & RANGE_MASK];
1176
//    outptr[6] = range_limit[IDESCALE(tmp1 - tmp6, PASS1_BITS+3)
1177
//			    & RANGE_MASK];	final2
1178
	psubw		mm6, mm3		;tmp1-tmp6,final2
1179
	psraw		mm0, 5			;outptr[0,1],[1,1],[2,1],[3,1]
1180
1181
	paddsw		mm0, const_0x0080
1182
	psraw		mm6, 5			;outptr[0,6],[1,6],[2,6],[3,6]
1183
	
1184
	paddsw		mm6, const_0x0080		;need to check this value
1185
	packuswb	mm0, mm4	;out[0,1],[1,1],[2,1],[3,1],[0,7],[1,7],[2,7],[3,7]
1186
	
1187
	movq		mm5, [esi+8*2]		;tmp2,final3
1188
	packuswb	mm2, mm6	;out[0,0],[1,0],[2,0],[3,0],[0,6],[1,6],[2,6],[3,6]
1189
1190
//    outptr[2] = range_limit[IDESCALE(tmp2 + tmp5, PASS1_BITS+3)
1191
//			    & RANGE_MASK];
1192
//    outptr[5] = range_limit[IDESCALE(tmp2 - tmp5, PASS1_BITS+3)
1193
//			    & RANGE_MASK];	final3
1194
	paddw		mm7, mm1		;tmp4
1195
	movq		mm3, mm5
1196
1197
	paddw		mm5, mm1		;tmp2+tmp5
1198
	psubw		mm3, mm1		;tmp2-tmp5
1199
1200
	psraw		mm5, 5			;outptr[0,2],[1,2],[2,2],[3,2]
1201
1202
	paddsw		mm5, const_0x0080
1203
	movq		mm4, [esi+8*3]		;tmp3,final4
1204
	psraw		mm3, 5			;outptr[0,5],[1,5],[2,5],[3,5]
1205
1206
	paddsw		mm3, const_0x0080
1207
1208
1209
//    outptr[4] = range_limit[IDESCALE(tmp3 + tmp4, PASS1_BITS+3)
1210
//			    & RANGE_MASK];
1211
//    outptr[3] = range_limit[IDESCALE(tmp3 - tmp4, PASS1_BITS+3)
1212
//			    & RANGE_MASK];	final4
1213
	movq		mm6, mm4
1214
	paddw		mm4, mm7		;tmp3+tmp4
1215
1216
	psubw		mm6, mm7		;tmp3-tmp4
1217
	psraw		mm4, 5			;outptr[0,4],[1,4],[2,4],[3,4]
1218
	mov			ecx, [eax]
1219
1220
	paddsw		mm4, const_0x0080
1221
	psraw		mm6, 5			;outptr[0,3],[1,3],[2,3],[3,3]
1222
1223
	paddsw		mm6, const_0x0080
1224
	packuswb	mm5, mm4	;out[0,2],[1,2],[2,2],[3,2],[0,4],[1,4],[2,4],[3,4]
1225
1226
	packuswb	mm6, mm3	;out[0,3],[1,3],[2,3],[3,3],[0,5],[1,5],[2,5],[3,5]
1227
	movq		mm4, mm2
1228
1229
	movq		mm7, mm5
1230
	punpcklbw	mm2, mm0	;out[0,0],[0,1],[1,0],[1,1],[2,0],[2,1],[3,0],[3,1]
1231
1232
	punpckhbw	mm4, mm0	;out[0,6],[0,7],[1,6],[1,7],[2,6],[2,7],[3,6],[3,7]
1233
	movq		mm1, mm2
1234
1235
	punpcklbw	mm5, mm6	;out[0,2],[0,3],[1,2],[1,3],[2,2],[2,3],[3,2],[3,3]
1236
	add		 	eax, 4
1237
1238
	punpckhbw	mm7, mm6	;out[0,4],[0,5],[1,4],[1,5],[2,4],[2,5],[3,4],[3,5]
1239
1240
	punpcklwd	mm2, mm5	;out[0,0],[0,1],[0,2],[0,3],[1,0],[1,1],[1,2],[1,3]
1241
	add			ecx, output_col
1242
1243
	movq		mm6, mm7
1244
	punpckhwd	mm1, mm5	;out[2,0],[2,1],[2,2],[2,3],[3,0],[3,1],[3,2],[3,3]
1245
1246
	movq		mm0, mm2
1247
	punpcklwd	mm6, mm4	;out[0,4],[0,5],[0,6],[0,7],[1,4],[1,5],[1,6],[1,7]
1248
1249
	mov			ebx, [eax]
1250
	punpckldq	mm2, mm6	;out[0,0],[0,1],[0,2],[0,3],[0,4],[0,5],[0,6],[0,7]
1251
1252
	add		 	eax, 4
1253
	movq		mm3, mm1
1254
1255
	add			ebx, output_col 
1256
	punpckhwd	mm7, mm4	;out[2,4],[2,5],[2,6],[2,7],[3,4],[3,5],[3,6],[3,7]
1257
	
1258
	movq		[ecx], mm2
1259
	punpckhdq	mm0, mm6	;out[1,0],[1,1],[1,2],[1,3],[1,4],[1,5],[1,6],[1,7]
1260
1261
	mov			ecx, [eax]
1262
	add		 	eax, 4
1263
	add			ecx, output_col
1264
1265
	movq		[ebx], mm0
1266
	punpckldq	mm1, mm7	;out[2,0],[2,1],[2,2],[2,3],[2,4],[2,5],[2,6],[2,7]
1267
1268
	mov			ebx, [eax]
1269
1270
	add			ebx, output_col
1271
	punpckhdq	mm3, mm7	;out[3,0],[3,1],[3,2],[3,3],[3,4],[3,5],[3,6],[3,7]
1272
	movq		[ecx], mm1
1273
1274
1275
	movq		[ebx], mm3
1276
1277
1278
		
1279
/*******************************************************************/
1280
	
1281
1282
	add			esi, 64
1283
	add			eax, 4
1284
1285
/*******************************************************************/
1286
1287
//    tmp10 = ((DCTELEM) wsptr[0] + (DCTELEM) wsptr[4]);
1288
//    tmp13 = ((DCTELEM) wsptr[2] + (DCTELEM) wsptr[6]);
1289
//    tmp11 = ((DCTELEM) wsptr[0] - (DCTELEM) wsptr[4]);
1290
//    tmp14 = ((DCTELEM) wsptr[2] - (DCTELEM) wsptr[6]);
1291
	movq		mm0, [esi+8*0]		;wsptr[0,0],[0,1],[0,2],[0,3]
1292
1293
	movq		mm1, [esi+8*1]		;wsptr[0,4],[0,5],[0,6],[0,7]
1294
	movq		mm2, mm0
1295
	
1296
	movq		mm3, [esi+8*2]		;wsptr[1,0],[1,1],[1,2],[1,3]
1297
	paddw		mm0, mm1			;wsptr[0,tmp10],[xxx],[0,tmp13],[xxx]
1298
1299
	movq		mm4, [esi+8*3]		;wsptr[1,4],[1,5],[1,6],[1,7]
1300
	psubw		mm2, mm1			;wsptr[0,tmp11],[xxx],[0,tmp14],[xxx]
1301
1302
	movq		mm6, mm0
1303
	movq		mm5, mm3
1304
	
1305
	paddw		mm3, mm4			;wsptr[1,tmp10],[xxx],[1,tmp13],[xxx]
1306
	movq		mm1, mm2
1307
1308
	psubw		mm5, mm4			;wsptr[1,tmp11],[xxx],[1,tmp14],[xxx]
1309
	punpcklwd	mm0, mm3			;wsptr[0,tmp10],[1,tmp10],[xxx],[xxx]
1310
1311
	movq		mm7, [esi+8*7]		;wsptr[3,4],[3,5],[3,6],[3,7]
1312
	punpckhwd	mm6, mm3			;wsptr[0,tmp13],[1,tmp13],[xxx],[xxx]
1313
1314
	movq		mm3, [esi+8*4]		;wsptr[2,0],[2,1],[2,2],[2,3]
1315
	punpckldq	mm0, mm6	;wsptr[0,tmp10],[1,tmp10],[0,tmp13],[1,tmp13]
1316
1317
	punpcklwd	mm1, mm5			;wsptr[0,tmp11],[1,tmp11],[xxx],[xxx]
1318
	movq		mm4, mm3
1319
1320
	movq		mm6, [esi+8*6]		;wsptr[3,0],[3,1],[3,2],[3,3]
1321
	punpckhwd	mm2, mm5			;wsptr[0,tmp14],[1,tmp14],[xxx],[xxx]
1322
1323
	movq		mm5, [esi+8*5]		;wsptr[2,4],[2,5],[2,6],[2,7]
1324
	punpckldq	mm1, mm2	;wsptr[0,tmp11],[1,tmp11],[0,tmp14],[1,tmp14]
1325
1326
	
1327
	paddw		mm3, mm5			;wsptr[2,tmp10],[xxx],[2,tmp13],[xxx]
1328
	movq		mm2, mm6
1329
1330
	psubw		mm4, mm5			;wsptr[2,tmp11],[xxx],[2,tmp14],[xxx]
1331
	paddw		mm6, mm7			;wsptr[3,tmp10],[xxx],[3,tmp13],[xxx]
1332
1333
	movq		mm5, mm3
1334
	punpcklwd	mm3, mm6			;wsptr[2,tmp10],[3,tmp10],[xxx],[xxx]
1335
	
1336
	psubw		mm2, mm7			;wsptr[3,tmp11],[xxx],[3,tmp14],[xxx]
1337
	punpckhwd	mm5, mm6			;wsptr[2,tmp13],[3,tmp13],[xxx],[xxx]
1338
1339
	movq		mm7, mm4
1340
	punpckldq	mm3, mm5	;wsptr[2,tmp10],[3,tmp10],[2,tmp13],[3,tmp13]
1341
1342
	punpcklwd	mm4, mm2			;wsptr[2,tmp11],[3,tmp11],[xxx],[xxx]
1343
1344
	punpckhwd	mm7, mm2			;wsptr[2,tmp14],[3,tmp14],[xxx],[xxx]
1345
1346
	punpckldq	mm4, mm7	;wsptr[2,tmp11],[3,tmp11],[2,tmp14],[3,tmp14]
1347
	movq		mm6, mm1
1348
1349
//	mm0 = 	;wsptr[0,tmp10],[1,tmp10],[0,tmp13],[1,tmp13]
1350
//	mm1 =	;wsptr[0,tmp11],[1,tmp11],[0,tmp14],[1,tmp14]
1351
1352
1353
	movq		mm2, mm0
1354
	punpckhdq	mm6, mm4	;wsptr[0,tmp14],[1,tmp14],[2,tmp14],[3,tmp14]
1355
1356
	punpckldq	mm1, mm4	;wsptr[0,tmp11],[1,tmp11],[2,tmp11],[3,tmp11]
1357
	psllw		mm6, 2
1358
1359
	pmulhw		mm6, fix_141
1360
	punpckldq	mm0, mm3	;wsptr[0,tmp10],[1,tmp10],[2,tmp10],[3,tmp10]
1361
1362
	punpckhdq	mm2, mm3	;wsptr[0,tmp13],[1,tmp13],[2,tmp13],[3,tmp13]
1363
	movq		mm7, mm0
1364
1365
//    tmp0 = tmp10 + tmp13;
1366
//    tmp3 = tmp10 - tmp13;
1367
	paddw		mm0, mm2	;[0,tmp0],[1,tmp0],[2,tmp0],[3,tmp0]
1368
	psubw		mm7, mm2	;[0,tmp3],[1,tmp3],[2,tmp3],[3,tmp3]
1369
1370
//    tmp12 = MULTIPLY(tmp14, FIX_1_414213562) - tmp13;
1371
	psubw		mm6, mm2	;wsptr[0,tmp12],[1,tmp12],[2,tmp12],[3,tmp12]
1372
//    tmp1 = tmp11 + tmp12;
1373
//    tmp2 = tmp11 - tmp12;
1374
	movq		mm5, mm1
1375
1376
1377
1378
    /* Odd part */
1379
1380
//    z13 = (DCTELEM) wsptr[5] + (DCTELEM) wsptr[3];
1381
//    z10 = (DCTELEM) wsptr[5] - (DCTELEM) wsptr[3];
1382
//    z11 = (DCTELEM) wsptr[1] + (DCTELEM) wsptr[7];
1383
//    z12 = (DCTELEM) wsptr[1] - (DCTELEM) wsptr[7];
1384
	movq		mm3, [esi+8*0]		;wsptr[0,0],[0,1],[0,2],[0,3]
1385
	paddw		mm1, mm6	;[0,tmp1],[1,tmp1],[2,tmp1],[3,tmp1]
1386
1387
	movq		mm4, [esi+8*1]		;wsptr[0,4],[0,5],[0,6],[0,7]
1388
	psubw		mm5, mm6	;[0,tmp2],[1,tmp2],[2,tmp2],[3,tmp2]
1389
1390
	movq		mm6, mm3
1391
	punpckldq	mm3, mm4			;wsptr[0,0],[0,1],[0,4],[0,5]
1392
1393
	punpckhdq	mm4, mm6			;wsptr[0,6],[0,7],[0,2],[0,3]
1394
	movq		mm2, mm3
1395
1396
//Save tmp0 and tmp1 in wsptr
1397
	movq		[esi+8*0], mm0		;save tmp0
1398
	paddw		mm2, mm4			;wsptr[xxx],[0,z11],[xxx],[0,z13]
1399
1400
	
1401
//Continue with z10 --- z13
1402
	movq		mm6, [esi+8*2]		;wsptr[1,0],[1,1],[1,2],[1,3]
1403
	psubw		mm3, mm4			;wsptr[xxx],[0,z12],[xxx],[0,z10]
1404
1405
	movq		mm0, [esi+8*3]		;wsptr[1,4],[1,5],[1,6],[1,7]
1406
	movq		mm4, mm6
1407
1408
	movq		[esi+8*1], mm1		;save tmp1
1409
	punpckldq	mm6, mm0			;wsptr[1,0],[1,1],[1,4],[1,5]
1410
1411
	punpckhdq	mm0, mm4			;wsptr[1,6],[1,7],[1,2],[1,3]
1412
	movq		mm1, mm6
1413
	
1414
//Save tmp2 and tmp3 in wsptr
1415
	paddw		mm6, mm0		;wsptr[xxx],[1,z11],[xxx],[1,z13]
1416
	movq		mm4, mm2
1417
	
1418
//Continue with z10 --- z13
1419
	movq		[esi+8*2], mm5		;save tmp2
1420
	punpcklwd	mm2, mm6		;wsptr[xxx],[xxx],[0,z11],[1,z11]
1421
1422
	psubw		mm1, mm0		;wsptr[xxx],[1,z12],[xxx],[1,z10]
1423
	punpckhwd	mm4, mm6		;wsptr[xxx],[xxx],[0,z13],[1,z13]
1424
1425
	movq		mm0, mm3
1426
	punpcklwd	mm3, mm1		;wsptr[xxx],[xxx],[0,z12],[1,z12]
1427
1428
	movq		[esi+8*3], mm7		;save tmp3
1429
	punpckhwd	mm0, mm1		;wsptr[xxx],[xxx],[0,z10],[1,z10]
1430
1431
	movq		mm6, [esi+8*4]		;wsptr[2,0],[2,1],[2,2],[2,3]
1432
	punpckhdq	mm0, mm2		;wsptr[0,z10],[1,z10],[0,z11],[1,z11]
1433
1434
	movq		mm7, [esi+8*5]		;wsptr[2,4],[2,5],[2,6],[2,7]
1435
	punpckhdq	mm3, mm4		;wsptr[0,z12],[1,z12],[0,z13],[1,z13]
1436
1437
	movq		mm1, [esi+8*6]		;wsptr[3,0],[3,1],[3,2],[3,3]
1438
	movq		mm4, mm6
1439
1440
	punpckldq	mm6, mm7			;wsptr[2,0],[2,1],[2,4],[2,5]
1441
	movq		mm5, mm1
1442
1443
	punpckhdq	mm7, mm4			;wsptr[2,6],[2,7],[2,2],[2,3]
1444
	movq		mm2, mm6
1445
	
1446
	movq		mm4, [esi+8*7]		;wsptr[3,4],[3,5],[3,6],[3,7]
1447
	paddw		mm6, mm7		;wsptr[xxx],[2,z11],[xxx],[2,z13]
1448
1449
	psubw		mm2, mm7		;wsptr[xxx],[2,z12],[xxx],[2,z10]
1450
	punpckldq	mm1, mm4			;wsptr[3,0],[3,1],[3,4],[3,5]
1451
1452
	punpckhdq	mm4, mm5			;wsptr[3,6],[3,7],[3,2],[3,3]
1453
	movq		mm7, mm1
1454
1455
	paddw		mm1, mm4		;wsptr[xxx],[3,z11],[xxx],[3,z13]
1456
	psubw		mm7, mm4		;wsptr[xxx],[3,z12],[xxx],[3,z10]
1457
1458
	movq		mm5, mm6
1459
	punpcklwd	mm6, mm1		;wsptr[xxx],[xxx],[2,z11],[3,z11]
1460
1461
	punpckhwd	mm5, mm1		;wsptr[xxx],[xxx],[2,z13],[3,z13]
1462
	movq		mm4, mm2
1463
1464
	punpcklwd	mm2, mm7		;wsptr[xxx],[xxx],[2,z12],[3,z12]
1465
1466
	punpckhwd	mm4, mm7		;wsptr[xxx],[xxx],[2,z10],[3,z10]
1467
1468
	punpckhdq	mm4, mm6		;wsptr[2,z10],[3,z10],[2,z11],[3,z11]
1469
1470
	punpckhdq	mm2, mm5		;wsptr[2,z12],[3,z12],[2,z13],[3,z13]
1471
	movq		mm5, mm0
1472
1473
	punpckldq	mm0, mm4		;wsptr[0,z10],[1,z10],[2,z10],[3,z10]
1474
1475
	punpckhdq	mm5, mm4		;wsptr[0,z11],[1,z11],[2,z11],[3,z11]
1476
	movq		mm4, mm3
1477
1478
	punpckhdq	mm4, mm2		;wsptr[0,z13],[1,z13],[2,z13],[3,z13]
1479
	movq		mm1, mm5
1480
1481
	punpckldq	mm3, mm2		;wsptr[0,z12],[1,z12],[2,z12],[3,z12]
1482
//    tmp7 = z11 + z13;		/* phase 5 */
1483
//    tmp8 = z11 - z13;		/* phase 5 */
1484
	psubw		mm1, mm4		;tmp8
1485
1486
	paddw		mm5, mm4		;tmp7
1487
//    tmp21 = MULTIPLY(tmp8, FIX_1_414213562); /* 2*c4 */
1488
	psllw		mm1, 2
1489
1490
	psllw		mm0, 2
1491
1492
	pmulhw		mm1, fix_141	;tmp21
1493
//    tmp20 = MULTIPLY(z12, (FIX_1_082392200- FIX_1_847759065))  /* 2*(c2-c6) */
1494
//			+ MULTIPLY(z10, - FIX_1_847759065); /* 2*c2 */
1495
	psllw		mm3, 2
1496
	movq		mm7, mm0
1497
1498
	pmulhw		mm7, fix_n184
1499
	movq		mm6, mm3
1500
1501
	movq		mm2, [esi+8*0]	;tmp0,final1
1502
1503
	pmulhw		mm6, fix_108n184
1504
//	 tmp22 = MULTIPLY(z10,(FIX_1_847759065 - FIX_2_613125930)) /* -2*(c2+c6) */
1505
//			+ MULTIPLY(z12, FIX_1_847759065); /* 2*c2 */
1506
	movq		mm4, mm2		;final1
1507
  
1508
	pmulhw		mm0, fix_184n261
1509
	paddw		mm2, mm5		;tmp0+tmp7,final1
1510
1511
	pmulhw		mm3, fix_184
1512
	psubw		mm4, mm5		;tmp0-tmp7,final1
1513
1514
//    tmp6 = tmp22 - tmp7;	/* phase 2 */
1515
	psraw		mm2, 5			;outptr[0,0],[1,0],[2,0],[3,0],final1
1516
1517
	paddsw		mm2, const_0x0080	;final1
1518
	paddw		mm7, mm6			;tmp20
1519
	psraw		mm4, 5			;outptr[0,7],[1,7],[2,7],[3,7],final1
1520
1521
	paddsw		mm4, const_0x0080	;final1
1522
	paddw		mm3, mm0			;tmp22
1523
1524
//    tmp5 = tmp21 - tmp6;
1525
	psubw		mm3, mm5		;tmp6
1526
1527
//    tmp4 = tmp20 + tmp5;
1528
	movq		mm0, [esi+8*1]		;tmp1,final2
1529
	psubw		mm1, mm3		;tmp5
1530
1531
	movq		mm6, mm0			;final2
1532
	paddw		mm0, mm3		;tmp1+tmp6,final2
1533
1534
    /* Final output stage: scale down by a factor of 8 and range-limit */
1535
1536
1537
//    outptr[0] = range_limit[IDESCALE(tmp0 + tmp7, PASS1_BITS+3)
1538
//			    & RANGE_MASK];
1539
//    outptr[7] = range_limit[IDESCALE(tmp0 - tmp7, PASS1_BITS+3)
1540
//			    & RANGE_MASK];	final1
1541
1542
1543
//    outptr[1] = range_limit[IDESCALE(tmp1 + tmp6, PASS1_BITS+3)
1544
//			    & RANGE_MASK];
1545
//    outptr[6] = range_limit[IDESCALE(tmp1 - tmp6, PASS1_BITS+3)
1546
//			    & RANGE_MASK];	final2
1547
	psubw		mm6, mm3		;tmp1-tmp6,final2
1548
	psraw		mm0, 5			;outptr[0,1],[1,1],[2,1],[3,1]
1549
1550
	paddsw		mm0, const_0x0080
1551
	psraw		mm6, 5			;outptr[0,6],[1,6],[2,6],[3,6]
1552
	
1553
	paddsw		mm6, const_0x0080		;need to check this value
1554
	packuswb	mm0, mm4	;out[0,1],[1,1],[2,1],[3,1],[0,7],[1,7],[2,7],[3,7]
1555
	
1556
	movq		mm5, [esi+8*2]		;tmp2,final3
1557
	packuswb	mm2, mm6	;out[0,0],[1,0],[2,0],[3,0],[0,6],[1,6],[2,6],[3,6]
1558
1559
//    outptr[2] = range_limit[IDESCALE(tmp2 + tmp5, PASS1_BITS+3)
1560
//			    & RANGE_MASK];
1561
//    outptr[5] = range_limit[IDESCALE(tmp2 - tmp5, PASS1_BITS+3)
1562
//			    & RANGE_MASK];	final3
1563
	paddw		mm7, mm1		;tmp4
1564
	movq		mm3, mm5
1565
1566
	paddw		mm5, mm1		;tmp2+tmp5
1567
	psubw		mm3, mm1		;tmp2-tmp5
1568
1569
	psraw		mm5, 5			;outptr[0,2],[1,2],[2,2],[3,2]
1570
1571
	paddsw		mm5, const_0x0080
1572
	movq		mm4, [esi+8*3]		;tmp3,final4
1573
	psraw		mm3, 5			;outptr[0,5],[1,5],[2,5],[3,5]
1574
1575
	paddsw		mm3, const_0x0080
1576
1577
1578
//    outptr[4] = range_limit[IDESCALE(tmp3 + tmp4, PASS1_BITS+3)
1579
//			    & RANGE_MASK];
1580
//    outptr[3] = range_limit[IDESCALE(tmp3 - tmp4, PASS1_BITS+3)
1581
//			    & RANGE_MASK];	final4
1582
	movq		mm6, mm4
1583
	paddw		mm4, mm7		;tmp3+tmp4
1584
1585
	psubw		mm6, mm7		;tmp3-tmp4
1586
	psraw		mm4, 5			;outptr[0,4],[1,4],[2,4],[3,4]
1587
	mov			ecx, [eax]
1588
1589
	paddsw		mm4, const_0x0080
1590
	psraw		mm6, 5			;outptr[0,3],[1,3],[2,3],[3,3]
1591
1592
	paddsw		mm6, const_0x0080
1593
	packuswb	mm5, mm4	;out[0,2],[1,2],[2,2],[3,2],[0,4],[1,4],[2,4],[3,4]
1594
1595
	packuswb	mm6, mm3	;out[0,3],[1,3],[2,3],[3,3],[0,5],[1,5],[2,5],[3,5]
1596
	movq		mm4, mm2
1597
1598
	movq		mm7, mm5
1599
	punpcklbw	mm2, mm0	;out[0,0],[0,1],[1,0],[1,1],[2,0],[2,1],[3,0],[3,1]
1600
1601
	punpckhbw	mm4, mm0	;out[0,6],[0,7],[1,6],[1,7],[2,6],[2,7],[3,6],[3,7]
1602
	movq		mm1, mm2
1603
1604
	punpcklbw	mm5, mm6	;out[0,2],[0,3],[1,2],[1,3],[2,2],[2,3],[3,2],[3,3]
1605
	add		 	eax, 4
1606
1607
	punpckhbw	mm7, mm6	;out[0,4],[0,5],[1,4],[1,5],[2,4],[2,5],[3,4],[3,5]
1608
1609
	punpcklwd	mm2, mm5	;out[0,0],[0,1],[0,2],[0,3],[1,0],[1,1],[1,2],[1,3]
1610
	add			ecx, output_col
1611
1612
	movq		mm6, mm7
1613
	punpckhwd	mm1, mm5	;out[2,0],[2,1],[2,2],[2,3],[3,0],[3,1],[3,2],[3,3]
1614
1615
	movq		mm0, mm2
1616
	punpcklwd	mm6, mm4	;out[0,4],[0,5],[0,6],[0,7],[1,4],[1,5],[1,6],[1,7]
1617
1618
	mov			ebx, [eax]
1619
	punpckldq	mm2, mm6	;out[0,0],[0,1],[0,2],[0,3],[0,4],[0,5],[0,6],[0,7]
1620
1621
	add		 	eax, 4
1622
	movq		mm3, mm1
1623
1624
	add			ebx, output_col 
1625
	punpckhwd	mm7, mm4	;out[2,4],[2,5],[2,6],[2,7],[3,4],[3,5],[3,6],[3,7]
1626
	
1627
	movq		[ecx], mm2
1628
	punpckhdq	mm0, mm6	;out[1,0],[1,1],[1,2],[1,3],[1,4],[1,5],[1,6],[1,7]
1629
1630
	mov			ecx, [eax]
1631
	add		 	eax, 4
1632
	add			ecx, output_col
1633
1634
	movq		[ebx], mm0
1635
	punpckldq	mm1, mm7	;out[2,0],[2,1],[2,2],[2,3],[2,4],[2,5],[2,6],[2,7]
1636
1637
	mov			ebx, [eax]
1638
1639
	add			ebx, output_col
1640
	punpckhdq	mm3, mm7	;out[3,0],[3,1],[3,2],[3,3],[3,4],[3,5],[3,6],[3,7]
1641
	movq		[ecx], mm1
1642
1643
	movq		[ebx], mm3
1644
1645
	emms
1646
	}
1647
}
1648
#endif
1649
1650
#endif /* DCT_IFAST_SUPPORTED */
368
#endif /* DCT_IFAST_SUPPORTED */
(-)a/jpeg/jidctint.c (-574 lines)
Line     Link Here 
 Lines 381-963   jpeg_idct_islow (j_decompress_ptr cinfo, Link Here 
381
    outptr[4] = range_limit[(int) DESCALE(tmp13 - tmp0,
381
    outptr[4] = range_limit[(int) DESCALE(tmp13 - tmp0,
382
					  CONST_BITS+PASS1_BITS+3)
382
					  CONST_BITS+PASS1_BITS+3)
383
			    & RANGE_MASK];
383
			    & RANGE_MASK];
384
    
384
    
385
    wsptr += DCTSIZE;		/* advance pointer to next row */
385
    wsptr += DCTSIZE;		/* advance pointer to next row */
386
  }
386
  }
387
}
387
}
388
388
389
390
#ifdef HAVE_SSE2_INTEL_MNEMONICS
391
392
/*
393
* Intel SSE2 optimized Inverse Discrete Cosine Transform
394
*
395
*
396
* Copyright (c) 2001-2002 Intel Corporation
397
* All Rights Reserved
398
*
399
*
400
*  Authors:
401
*      Danilov G.
402
*
403
*
404
*-----------------------------------------------------------------------------
405
*
406
* References:
407
*    K.R. Rao and P. Yip
408
*       Discrete Cosine Transform.
409
*       Algorithms, Advantages, Applications.
410
*       Academic Press, Inc, London, 1990.
411
*    JPEG Group's software.
412
*       This implementation is based on Appendix A.2 of the book (R&Y) ...
413
*
414
*-----------------------------------------------------------------------------
415
*/
416
417
typedef unsigned char   Ipp8u;
418
typedef unsigned short  Ipp16u;
419
typedef unsigned int    Ipp32u;
420
421
typedef signed char    Ipp8s;
422
typedef signed short   Ipp16s;
423
typedef signed int     Ipp32s;
424
425
#define BITS_INV_ACC  4			
426
#define SHIFT_INV_ROW  16 - BITS_INV_ACC
427
#define SHIFT_INV_COL 1 + BITS_INV_ACC
428
429
#define RND_INV_ROW  1024 * (6 - BITS_INV_ACC)	/* 1 << (SHIFT_INV_ROW-1)		*/
430
#define RND_INV_COL = 16 * (BITS_INV_ACC - 3)   /* 1 << (SHIFT_INV_COL-1)		*/
431
#define RND_INV_CORR = RND_INV_COL - 1          /* correction -1.0 and round	*/
432
433
#define c_inv_corr_0 -1024 * (6 - BITS_INV_ACC) + 65536		/* -0.5 + (16.0 or 32.0)	*/
434
#define c_inv_corr_1 1877 * (6 - BITS_INV_ACC)				/* 0.9167	*/	
435
#define c_inv_corr_2 1236 * (6 - BITS_INV_ACC)				/* 0.6035	*/					
436
#define c_inv_corr_3 680  * (6 - BITS_INV_ACC)				/* 0.3322	*/
437
#define c_inv_corr_4 0    * (6 - BITS_INV_ACC)				/* 0.0		*/	
438
#define c_inv_corr_5 -569  * (6 - BITS_INV_ACC)				/* -0.278	*/
439
#define c_inv_corr_6 -512  * (6 - BITS_INV_ACC)				/* -0.25	*/	
440
#define c_inv_corr_7 -651  * (6 - BITS_INV_ACC)				/* -0.3176	*/	
441
442
#define RND_INV_ROW_0 RND_INV_ROW + c_inv_corr_0
443
#define RND_INV_ROW_1 RND_INV_ROW + c_inv_corr_1
444
#define RND_INV_ROW_2 RND_INV_ROW + c_inv_corr_2
445
#define RND_INV_ROW_3 RND_INV_ROW + c_inv_corr_3
446
#define RND_INV_ROW_4 RND_INV_ROW + c_inv_corr_4
447
#define RND_INV_ROW_5 RND_INV_ROW + c_inv_corr_5
448
#define RND_INV_ROW_6 RND_INV_ROW + c_inv_corr_6
449
#define RND_INV_ROW_7 RND_INV_ROW + c_inv_corr_7
450
451
/* Table for rows 0,4 - constants are multiplied on cos_4_16 */
452
453
__declspec(align(16)) short tab_i_04[] = { 
454
	16384, 21407, 16384, 8867,		
455
	-16384, 21407, 16384, -8867,	
456
	16384,  -8867,  16384, -21407,  
457
    16384,   8867, -16384, -21407,  
458
    22725,  19266,  19266,  -4520,  
459
    4520,  19266,  19266, -22725,   
460
    12873, -22725,   4520, -12873,  
461
    12873,   4520, -22725, -12873}; 
462
463
/* Table for rows 1,7 - constants are multiplied on cos_1_16 */
464
465
__declspec(align(16)) short tab_i_17[] = {
466
	22725,  29692,  22725,  12299,   
467
    -22725,  29692,  22725, -12299,  
468
    22725, -12299,  22725, -29692,   
469
    22725,  12299, -22725, -29692,   
470
    31521,  26722,  26722,  -6270,   
471
    6270,  26722,  26722, -31521,    
472
    17855, -31521,   6270, -17855,   
473
    17855,   6270, -31521, -17855};  
474
475
/* Table for rows 2,6 - constants are multiplied on cos_2_16 */
476
477
__declspec(align(16)) short tab_i_26[] = {
478
	21407,  27969,  21407,  11585,	
479
    -21407,  27969,  21407, -11585,	
480
    21407, -11585,  21407, -27969,	
481
    21407,  11585, -21407, -27969,	
482
    29692,  25172,  25172,  -5906,	
483
    5906,  25172,  25172, -29692,	
484
    16819, -29692,   5906, -16819,	
485
    16819,   5906, -29692, -16819};	
486
487
/* Table for rows 3,5 - constants are multiplied on cos_3_16 */
488
489
__declspec(align(16)) short tab_i_35[] = {
490
	19266,  25172,  19266,  10426,	
491
    -19266,  25172,  19266, -10426,	
492
    19266, -10426,  19266, -25172,	
493
    19266,  10426, -19266, -25172,	
494
    26722,  22654,  22654,  -5315,	
495
    5315,  22654,  22654, -26722,	
496
    15137, -26722,   5315, -15137,	
497
    15137,   5315, -26722, -15137};	
498
	
499
__declspec(align(16)) long round_i_0[] = {RND_INV_ROW_0,RND_INV_ROW_0,
500
	RND_INV_ROW_0,RND_INV_ROW_0};
501
__declspec(align(16)) long round_i_1[] = {RND_INV_ROW_1,RND_INV_ROW_1,
502
	RND_INV_ROW_1,RND_INV_ROW_1};
503
__declspec(align(16)) long round_i_2[] = {RND_INV_ROW_2,RND_INV_ROW_2,
504
	RND_INV_ROW_2,RND_INV_ROW_2};
505
__declspec(align(16)) long round_i_3[] = {RND_INV_ROW_3,RND_INV_ROW_3,
506
	RND_INV_ROW_3,RND_INV_ROW_3};
507
__declspec(align(16)) long round_i_4[] = {RND_INV_ROW_4,RND_INV_ROW_4,
508
	RND_INV_ROW_4,RND_INV_ROW_4};
509
__declspec(align(16)) long round_i_5[] = {RND_INV_ROW_5,RND_INV_ROW_5,
510
	RND_INV_ROW_5,RND_INV_ROW_5};
511
__declspec(align(16)) long round_i_6[] = {RND_INV_ROW_6,RND_INV_ROW_6,
512
	RND_INV_ROW_6,RND_INV_ROW_6};
513
__declspec(align(16)) long round_i_7[] = {RND_INV_ROW_7,RND_INV_ROW_7,
514
	RND_INV_ROW_7,RND_INV_ROW_7};
515
516
__declspec(align(16)) short tg_1_16[] = {
517
	13036,  13036,  13036,  13036,	/* tg * (2<<16) + 0.5 */
518
	13036,  13036,  13036,  13036};
519
__declspec(align(16)) short tg_2_16[] = {
520
	27146,  27146,  27146,  27146,	/* tg * (2<<16) + 0.5 */
521
	27146,  27146,  27146,  27146};
522
__declspec(align(16)) short tg_3_16[] = {
523
	-21746, -21746, -21746, -21746,	/* tg * (2<<16) + 0.5 */
524
	-21746, -21746, -21746, -21746};
525
__declspec(align(16)) short cos_4_16[] = {
526
	-19195, -19195, -19195, -19195,	/* cos * (2<<16) + 0.5 */
527
	-19195, -19195, -19195, -19195};
528
529
/*
530
* In this implementation the outputs of the iDCT-1D are multiplied
531
*    for rows 0,4 - on cos_4_16,
532
*    for rows 1,7 - on cos_1_16,
533
*    for rows 2,6 - on cos_2_16,
534
*    for rows 3,5 - on cos_3_16
535
* and are shifted to the left for rise of accuracy
536
*
537
* For used constants
538
*    FIX(float_const) = (short) (float_const * (1<<15) + 0.5)
539
*
540
*-----------------------------------------------------------------------------
541
*
542
* On the first stage the calculation is executed at once for two rows.
543
* The permutation for each output row is done on second stage
544
*    t7 t6 t5 t4 t3 t2 t1 t0 -> t4 t5 t6 t7 t3 t2 t1 t0
545
*
546
*-----------------------------------------------------------------------------
547
*/
548
	
549
#define DCT_8_INV_ROW_2R(TABLE, ROUND1, ROUND2) __asm {	\
550
	__asm pshuflw  xmm1, xmm0, 10001000b				\
551
    __asm pshuflw  xmm0, xmm0, 11011101b    			\
552
    __asm pshufhw  xmm1, xmm1, 10001000b    			\
553
	__asm pshufhw  xmm0, xmm0, 11011101b				\
554
	__asm movdqa   xmm2, XMMWORD PTR [TABLE]			\
555
	__asm pmaddwd  xmm2, xmm1							\
556
	__asm movdqa   xmm3, XMMWORD PTR [TABLE + 32]		\
557
	__asm pmaddwd  xmm3, xmm0               			\
558
	__asm pmaddwd  xmm1, XMMWORD PTR [TABLE + 16]		\
559
	__asm pmaddwd  xmm0, XMMWORD PTR [TABLE + 48]		\
560
	__asm pshuflw  xmm5, xmm4, 10001000b				\
561
	__asm pshuflw  xmm4, xmm4, 11011101b    			\
562
	__asm pshufhw  xmm5, xmm5, 10001000b    			\
563
	__asm pshufhw  xmm4, xmm4, 11011101b    			\
564
	__asm movdqa   xmm6, XMMWORD PTR [TABLE]			\
565
	__asm pmaddwd  xmm6, xmm5               			\
566
	__asm movdqa   xmm7, XMMWORD PTR [TABLE + 32]		\
567
	__asm pmaddwd  xmm7, xmm4               			\
568
	__asm pmaddwd  xmm5, XMMWORD PTR [TABLE + 16]		\
569
	__asm pmaddwd  xmm4, XMMWORD PTR [TABLE + 48]		\
570
	__asm pshufd   xmm1, xmm1, 01001110b    			\
571
	__asm pshufd   xmm0, xmm0, 01001110b    			\
572
	__asm paddd    xmm2, XMMWORD PTR [ROUND1]			\
573
	__asm paddd    xmm3, xmm0							\
574
	__asm paddd    xmm1, xmm2							\
575
	__asm pshufd   xmm5, xmm5, 01001110b    			\
576
	__asm pshufd   xmm4, xmm4, 01001110b    			\
577
	__asm movdqa   xmm2, xmm1             				\
578
	__asm psubd    xmm2, xmm3             				\
579
	__asm psrad    xmm2, SHIFT_INV_ROW    				\
580
	__asm paddd    xmm1, xmm3							\
581
	__asm psrad    xmm1, SHIFT_INV_ROW      			\
582
	__asm packssdw xmm1, xmm2							\
583
	__asm paddd    xmm6, XMMWORD PTR [ROUND2]			\
584
	__asm paddd    xmm7, xmm4							\
585
	__asm paddd    xmm5, xmm6							\
586
	__asm movdqa   xmm6, xmm5	            			\
587
	__asm psubd    xmm6, xmm7               			\
588
	__asm psrad    xmm6, SHIFT_INV_ROW      			\
589
	__asm paddd    xmm5, xmm7							\
590
	__asm psrad    xmm5, SHIFT_INV_ROW      			\
591
	__asm packssdw xmm5, xmm6							\
592
	}
593
594
/*
595
*
596
* The second stage - inverse DCTs of columns
597
*
598
* The inputs are multiplied
599
*    for rows 0,4 - on cos_4_16,
600
*    for rows 1,7 - on cos_1_16,
601
*    for rows 2,6 - on cos_2_16,
602
*    for rows 3,5 - on cos_3_16
603
* and are shifted to the left for rise of accuracy
604
*/
605
606
#define DCT_8_INV_COL_8R(INP, OUTP) __asm {		\
607
	__asm movdqa   xmm0, [INP + 5*16]			\
608
    __asm movdqa   xmm1, XMMWORD PTR tg_3_16	\
609
    __asm movdqa   xmm2, xmm0            		\
610
    __asm movdqa   xmm3, [INP + 3*16]   		\
611
    __asm pmulhw   xmm0, xmm1           		\
612
    __asm movdqa   xmm4, [INP + 7*16]   		\
613
    __asm pmulhw   xmm1, xmm3           		\
614
    __asm movdqa   xmm5, XMMWORD PTR tg_1_16   	\
615
    __asm movdqa   xmm6, xmm4            		\
616
    __asm pmulhw   xmm4, xmm5           		\
617
    __asm paddsw   xmm0, xmm2           		\
618
    __asm pmulhw   xmm5, [INP + 1*16]   		\
619
    __asm paddsw   xmm1, xmm3           		\
620
    __asm movdqa   xmm7, [INP + 6*16]    		\
621
    __asm paddsw   xmm0, xmm3					\
622
    __asm movdqa   xmm3, XMMWORD PTR tg_2_16	\
623
    __asm psubsw   xmm2, xmm1					\
624
    __asm pmulhw   xmm7, xmm3            		\
625
    __asm movdqa   xmm1, xmm0            		\
626
    __asm pmulhw   xmm3, [INP + 2*16]   		\
627
    __asm psubsw   xmm5, xmm6					\
628
    __asm paddsw   xmm4, [INP + 1*16]    		\
629
    __asm paddsw   xmm0, xmm4            		\
630
    __asm psubsw   xmm4, xmm1					\
631
    __asm pshufhw  xmm0, xmm0, 00011011b		\
632
    __asm paddsw   xmm7, [INP + 2*16]    		\
633
    __asm movdqa   xmm6, xmm5					\
634
    __asm psubsw   xmm3, [INP + 6*16]    		\
635
    __asm psubsw   xmm5, xmm2            		\
636
    __asm paddsw   xmm6, xmm2					\
637
	__asm movdqa   [OUTP + 7*16], xmm0    		\
638
    __asm movdqa   xmm1, xmm4            		\
639
    __asm movdqa   xmm2, XMMWORD PTR cos_4_16  	\
640
    __asm paddsw   xmm4, xmm5            		\
641
    __asm movdqa   xmm0, XMMWORD PTR cos_4_16  	\
642
    __asm pmulhw   xmm2, xmm4					\
643
    __asm pshufhw  xmm6, xmm6, 00011011b		\
644
    __asm movdqa   [OUTP + 3*16], xmm6    		\
645
    __asm psubsw   xmm1, xmm5            		\
646
    __asm movdqa   xmm6, [INP + 0*16]   		\
647
    __asm pmulhw   xmm0, xmm1					\
648
    __asm movdqa   xmm5, [INP + 4*16]    		\
649
    __asm paddsw   xmm4, xmm2					\
650
    __asm paddsw   xmm5, xmm6       			\
651
    __asm psubsw   xmm6, [INP + 4*16]   		\
652
    __asm paddsw   xmm0, xmm1					\
653
    __asm pshufhw  xmm4, xmm4, 00011011b		\
654
    __asm movdqa   xmm2, xmm5            		\
655
    __asm paddsw   xmm5, xmm7            		\
656
    __asm movdqa   xmm1, xmm6					\
657
    __asm psubsw   xmm2, xmm7					\
658
    __asm movdqa   xmm7, [OUTP + 7*16]    		\
659
    __asm paddsw   xmm6, xmm3            		\
660
    __asm pshufhw  xmm5, xmm5, 00011011b		\
661
	__asm paddsw   xmm7, xmm5					\
662
    __asm psubsw   xmm1, xmm3					\
663
    __asm pshufhw  xmm6, xmm6, 00011011b		\
664
	__asm movdqa   xmm3, xmm6					\
665
    __asm paddsw   xmm6, xmm4            		\
666
    __asm pshufhw  xmm2, xmm2, 00011011b		\
667
    __asm psraw    xmm7, SHIFT_INV_COL   		\
668
    __asm movdqa   [OUTP + 0*16], xmm7    		\
669
    __asm movdqa   xmm7, xmm1            		\
670
    __asm paddsw   xmm1, xmm0					\
671
    __asm psraw    xmm6, SHIFT_INV_COL			\
672
    __asm movdqa   [OUTP + 1*16], xmm6    		\
673
    __asm pshufhw  xmm1, xmm1, 00011011b		\
674
	__asm movdqa   xmm6, [OUTP + 3*16]			\
675
    __asm psubsw   xmm7, xmm0            		\
676
    __asm psraw    xmm1, SHIFT_INV_COL   		\
677
    __asm movdqa   [OUTP + 2*16], xmm1    		\
678
    __asm psubsw   xmm5, [OUTP + 7*16]			\
679
    __asm paddsw   xmm6, xmm2            		\
680
    __asm psubsw   xmm2, [OUTP + 3*16]			\
681
    __asm psubsw   xmm3, xmm4            		\
682
    __asm psraw    xmm7, SHIFT_INV_COL  		\
683
    __asm pshufhw  xmm7, xmm7, 00011011b		\
684
    __asm movdqa   [OUTP + 5*16], xmm7    		\
685
    __asm psraw    xmm5, SHIFT_INV_COL			\
686
    __asm movdqa   [OUTP + 7*16], xmm5    		\
687
    __asm psraw    xmm6, SHIFT_INV_COL			\
688
    __asm movdqa   [OUTP + 3*16], xmm6    		\
689
    __asm psraw    xmm2, SHIFT_INV_COL			\
690
    __asm movdqa   [OUTP + 4*16], xmm2    		\
691
    __asm psraw    xmm3, SHIFT_INV_COL			\
692
    __asm movdqa   [OUTP + 6*16], xmm3    		\
693
	}
694
695
/*
696
*
697
*  Name:      dct_8x8_inv_16s
698
*  Purpose:   Inverse Discrete Cosine Transform 8x8 with
699
*             2D buffer of short int data
700
*  Context:
701
*      void dct_8x8_inv_16s ( short *src, short *dst )
702
*  Parameters:
703
*      src  - Pointer to the source buffer
704
*      dst  - Pointer to the destination buffer
705
*
706
*/
707
708
GLOBAL(void)
709
dct_8x8_inv_16s ( short *src, short *dst ) {
710
	
711
	__asm {
712
713
		mov     ecx,  src
714
		mov     edx,  dst
715
716
		movdqa  xmm0, [ecx+0*16]
717
		movdqa  xmm4, [ecx+4*16]
718
		DCT_8_INV_ROW_2R(tab_i_04, round_i_0, round_i_4)
719
		movdqa     [edx+0*16], xmm1 
720
		movdqa     [edx+4*16], xmm5 
721
722
		movdqa  xmm0, [ecx+1*16]
723
		movdqa  xmm4, [ecx+7*16]
724
		DCT_8_INV_ROW_2R(tab_i_17, round_i_1, round_i_7)
725
		movdqa     [edx+1*16], xmm1 
726
		movdqa     [edx+7*16], xmm5 
727
728
		movdqa  xmm0, [ecx+3*16]
729
		movdqa  xmm4, [ecx+5*16]
730
		DCT_8_INV_ROW_2R(tab_i_35, round_i_3, round_i_5);
731
		movdqa     [edx+3*16], xmm1 
732
		movdqa     [edx+5*16], xmm5 
733
734
		movdqa  xmm0, [ecx+2*16]
735
		movdqa  xmm4, [ecx+6*16]
736
		DCT_8_INV_ROW_2R(tab_i_26, round_i_2, round_i_6);
737
		movdqa     [edx+2*16], xmm1
738
		movdqa     [edx+6*16], xmm5    
739
740
		DCT_8_INV_COL_8R(edx+0, edx+0);
741
	}
742
}
743
744
745
/*
746
*  Name:
747
*    ownpj_QuantInv_8x8_16s
748
*
749
*  Purpose:
750
*    Dequantize 8x8 block of DCT coefficients
751
*
752
*  Context:
753
*    void ownpj_QuantInv_8x8_16s
754
*            Ipp16s*  pSrc,
755
*            Ipp16s*  pDst,
756
*      const Ipp16u*  pQTbl)*
757
*
758
*/
759
760
GLOBAL(void)
761
ownpj_QuantInv_8x8_16s(short * pSrc, short * pDst, const unsigned short * pQTbl)
762
{
763
	__asm {
764
765
		push        ebx
766
		push        ecx
767
		push        edx
768
		push        esi
769
		push        edi
770
771
		mov         esi, pSrc
772
		mov         edi, pDst
773
		mov         edx, pQTbl
774
		mov         ecx, 4
775
		mov         ebx, 32
776
777
	again:
778
779
		movq        mm0, QWORD PTR [esi+0]
780
		movq        mm1, QWORD PTR [esi+8]
781
		movq        mm2, QWORD PTR [esi+16]
782
		movq        mm3, QWORD PTR [esi+24]
783
784
		prefetcht0  [esi+ebx] ; fetch next cache line
785
786
		pmullw      mm0, QWORD PTR [edx+0]
787
		pmullw      mm1, QWORD PTR [edx+8]
788
		pmullw      mm2, QWORD PTR [edx+16]
789
		pmullw      mm3, QWORD PTR [edx+24]
790
791
		movq        QWORD PTR [edi+0], mm0
792
		movq        QWORD PTR [edi+8], mm1
793
		movq        QWORD PTR [edi+16], mm2
794
		movq        QWORD PTR [edi+24], mm3
795
796
		add         esi, ebx
797
		add         edi, ebx
798
		add         edx, ebx
799
		dec         ecx
800
		jnz         again
801
802
		emms
803
804
		pop         edi
805
		pop         esi
806
		pop         edx
807
		pop         ecx
808
		pop         ebx
809
	}
810
}
811
812
813
/*
814
*  Name:
815
*    ownpj_Add128_8x8_16s8u
816
*
817
*  Purpose:
818
*    signed to unsigned conversion (level shift)
819
*    for 8x8 block of DCT coefficients
820
*
821
*  Context:
822
*    void ownpj_Add128_8x8_16s8u
823
*      const Ipp16s* pSrc,
824
*            Ipp8u*  pDst,
825
*            int     DstStep);
826
*
827
*/
828
829
__declspec(align(16)) long const_128[]= {0x00800080, 0x00800080, 0x00800080, 0x00800080};
830
831
GLOBAL(void)
832
ownpj_Add128_8x8_16s8u(const short * pSrc, unsigned char * pDst, int DstStep)
833
{
834
	__asm {
835
		push        eax
836
		push        ebx
837
		push        ecx
838
		push        edx
839
		push        esi
840
		push        edi
841
842
		mov         esi, pSrc
843
		mov         edi, pDst
844
		mov         edx, DstStep
845
		mov         ecx, 2
846
		mov         ebx, edx
847
		mov         eax, edx
848
		sal         ebx, 1
849
		add         eax, ebx
850
		movdqa      xmm7, XMMWORD PTR const_128
851
852
	again:
853
854
		movdqa      xmm0, XMMWORD PTR [esi+0]  ; line 0
855
		movdqa      xmm1, XMMWORD PTR [esi+16] ; line 1
856
		movdqa      xmm2, XMMWORD PTR [esi+32] ; line 2
857
		movdqa      xmm3, XMMWORD PTR [esi+48] ; line 3
858
859
		paddw     xmm0, xmm7
860
		paddw     xmm1, xmm7
861
		paddw     xmm2, xmm7
862
		paddw     xmm3, xmm7
863
864
		packuswb  xmm0, xmm1
865
		packuswb  xmm2, xmm3
866
867
		movq      QWORD PTR [edi], xmm0      ;0*DstStep
868
		movq      QWORD PTR [edi+ebx], xmm2  ;2*DstStep
869
870
		psrldq      xmm0, 8
871
		psrldq      xmm2, 8
872
873
		movq      QWORD PTR [edi+edx], xmm0  ;1*DstStep
874
		movq      QWORD PTR [edi+eax], xmm2  ;3*DstStep
875
876
		add         edi, ebx
877
		add         esi, 64
878
		add         edi, ebx
879
		dec         ecx
880
		jnz         again
881
882
		pop         edi
883
		pop         esi
884
		pop         edx
885
		pop         ecx
886
		pop         ebx
887
		pop         eax
888
	}
889
}
890
891
892
/* 
893
*  Name:
894
*    ippiDCTQuantInv8x8LS_JPEG_16s8u_C1R
895
*
896
*  Purpose:
897
*    Inverse DCT transform, de-quantization and level shift
898
*
899
*  Parameters:
900
*    pSrc               - pointer to source
901
*    pDst               - pointer to output array
902
*    DstStep            - line offset for output data
903
*    pEncoderQuantTable - pointer to Quantization table
904
*
905
*/
906
907
GLOBAL(void)
908
ippiDCTQuantInv8x8LS_JPEG_16s8u_C1R(
909
  short * pSrc,
910
  unsigned char *  pDst,
911
  int     DstStep,
912
  const unsigned short * pQuantInvTable)
913
{
914
915
	__declspec(align(16)) Ipp8u buf[DCTSIZE2*sizeof(Ipp16s)];
916
	Ipp16s * workbuf = (Ipp16s *)buf;	
917
918
	ownpj_QuantInv_8x8_16s(pSrc,workbuf,pQuantInvTable);
919
	dct_8x8_inv_16s(workbuf,workbuf);
920
	ownpj_Add128_8x8_16s8u(workbuf,pDst,DstStep);
921
  
922
} 
923
924
GLOBAL(void)
925
jpeg_idct_islow_sse2 (
926
	j_decompress_ptr cinfo, 
927
	jpeg_component_info * compptr,
928
	JCOEFPTR coef_block,
929
	JSAMPARRAY output_buf, 
930
	JDIMENSION output_col)
931
{
932
	int			ctr;
933
	JCOEFPTR	inptr;
934
	Ipp16u*		quantptr;
935
	Ipp8u*		wsptr;
936
	__declspec(align(16)) Ipp8u workspace[DCTSIZE2];  	
937
	JSAMPROW	outptr;
938
939
	inptr = coef_block;
940
	quantptr = (Ipp16u*)compptr->dct_table;
941
	wsptr = workspace;
942
	
943
	ippiDCTQuantInv8x8LS_JPEG_16s8u_C1R(inptr, workspace, 8, quantptr);
944
945
	for(ctr = 0; ctr < DCTSIZE; ctr++)
946
	{
947
		outptr = output_buf[ctr] + output_col;
948
949
		outptr[0] = wsptr[0];
950
		outptr[1] = wsptr[1];
951
		outptr[2] = wsptr[2];
952
		outptr[3] = wsptr[3];
953
		outptr[4] = wsptr[4];
954
		outptr[5] = wsptr[5];
955
		outptr[6] = wsptr[6];
956
		outptr[7] = wsptr[7];
957
958
		wsptr += DCTSIZE;
959
	}
960
}
961
#endif /* HAVE_SSE2_INTEL_MNEMONICS */
962
963
#endif /* DCT_ISLOW_SUPPORTED */
389
#endif /* DCT_ISLOW_SUPPORTED */
(-)a/jpeg/jmemansi.c (-167 lines)
Line     Link Here 
 Lines 1-167    Link Here 
1
/*
2
 * jmemansi.c
3
 *
4
 * Copyright (C) 1992-1996, Thomas G. Lane.
5
 * This file is part of the Independent JPEG Group's software.
6
 * For conditions of distribution and use, see the accompanying README file.
7
 *
8
 * This file provides a simple generic implementation of the system-
9
 * dependent portion of the JPEG memory manager.  This implementation
10
 * assumes that you have the ANSI-standard library routine tmpfile().
11
 * Also, the problem of determining the amount of memory available
12
 * is shoved onto the user.
13
 */
14
15
#define JPEG_INTERNALS
16
#include "jinclude.h"
17
#include "jpeglib.h"
18
#include "jmemsys.h"		/* import the system-dependent declarations */
19
20
#ifndef HAVE_STDLIB_H		/* <stdlib.h> should declare malloc(),free() */
21
extern void * malloc JPP((size_t size));
22
extern void free JPP((void *ptr));
23
#endif
24
25
#ifndef SEEK_SET		/* pre-ANSI systems may not define this; */
26
#define SEEK_SET  0		/* if not, assume 0 is correct */
27
#endif
28
29
30
/*
31
 * Memory allocation and freeing are controlled by the regular library
32
 * routines malloc() and free().
33
 */
34
35
GLOBAL(void *)
36
jpeg_get_small (j_common_ptr cinfo, size_t sizeofobject)
37
{
38
  return (void *) malloc(sizeofobject);
39
}
40
41
GLOBAL(void)
42
jpeg_free_small (j_common_ptr cinfo, void * object, size_t sizeofobject)
43
{
44
  free(object);
45
}
46
47
48
/*
49
 * "Large" objects are treated the same as "small" ones.
50
 * NB: although we include FAR keywords in the routine declarations,
51
 * this file won't actually work in 80x86 small/medium model; at least,
52
 * you probably won't be able to process useful-size images in only 64KB.
53
 */
54
55
GLOBAL(void FAR *)
56
jpeg_get_large (j_common_ptr cinfo, size_t sizeofobject)
57
{
58
  return (void FAR *) malloc(sizeofobject);
59
}
60
61
GLOBAL(void)
62
jpeg_free_large (j_common_ptr cinfo, void FAR * object, size_t sizeofobject)
63
{
64
  free(object);
65
}
66
67
68
/*
69
 * This routine computes the total memory space available for allocation.
70
 * It's impossible to do this in a portable way; our current solution is
71
 * to make the user tell us (with a default value set at compile time).
72
 * If you can actually get the available space, it's a good idea to subtract
73
 * a slop factor of 5% or so.
74
 */
75
76
#ifndef DEFAULT_MAX_MEM		/* so can override from makefile */
77
#define DEFAULT_MAX_MEM		1000000L /* default: one megabyte */
78
#endif
79
80
GLOBAL(long)
81
jpeg_mem_available (j_common_ptr cinfo, long min_bytes_needed,
82
		    long max_bytes_needed, long already_allocated)
83
{
84
  return cinfo->mem->max_memory_to_use - already_allocated;
85
}
86
87
88
/*
89
 * Backing store (temporary file) management.
90
 * Backing store objects are only used when the value returned by
91
 * jpeg_mem_available is less than the total space needed.  You can dispense
92
 * with these routines if you have plenty of virtual memory; see jmemnobs.c.
93
 */
94
95
96
METHODDEF(void)
97
read_backing_store (j_common_ptr cinfo, backing_store_ptr info,
98
		    void FAR * buffer_address,
99
		    long file_offset, long byte_count)
100
{
101
  if (fseek(info->temp_file, file_offset, SEEK_SET))
102
    ERREXIT(cinfo, JERR_TFILE_SEEK);
103
  if (JFREAD(info->temp_file, buffer_address, byte_count)
104
      != (size_t) byte_count)
105
    ERREXIT(cinfo, JERR_TFILE_READ);
106
}
107
108
109
METHODDEF(void)
110
write_backing_store (j_common_ptr cinfo, backing_store_ptr info,
111
		     void FAR * buffer_address,
112
		     long file_offset, long byte_count)
113
{
114
  if (fseek(info->temp_file, file_offset, SEEK_SET))
115
    ERREXIT(cinfo, JERR_TFILE_SEEK);
116
  if (JFWRITE(info->temp_file, buffer_address, byte_count)
117
      != (size_t) byte_count)
118
    ERREXIT(cinfo, JERR_TFILE_WRITE);
119
}
120
121
122
METHODDEF(void)
123
close_backing_store (j_common_ptr cinfo, backing_store_ptr info)
124
{
125
  fclose(info->temp_file);
126
  /* Since this implementation uses tmpfile() to create the file,
127
   * no explicit file deletion is needed.
128
   */
129
}
130
131
132
/*
133
 * Initial opening of a backing-store object.
134
 *
135
 * This version uses tmpfile(), which constructs a suitable file name
136
 * behind the scenes.  We don't have to use info->temp_name[] at all;
137
 * indeed, we can't even find out the actual name of the temp file.
138
 */
139
140
GLOBAL(void)
141
jpeg_open_backing_store (j_common_ptr cinfo, backing_store_ptr info,
142
			 long total_bytes_needed)
143
{
144
  if ((info->temp_file = tmpfile()) == NULL)
145
    ERREXITS(cinfo, JERR_TFILE_CREATE, "");
146
  info->read_backing_store = read_backing_store;
147
  info->write_backing_store = write_backing_store;
148
  info->close_backing_store = close_backing_store;
149
}
150
151
152
/*
153
 * These routines take care of any system-dependent initialization and
154
 * cleanup required.
155
 */
156
157
GLOBAL(long)
158
jpeg_mem_init (j_common_ptr cinfo)
159
{
160
  return DEFAULT_MAX_MEM;	/* default for max_memory_to_use */
161
}
162
163
GLOBAL(void)
164
jpeg_mem_term (j_common_ptr cinfo)
165
{
166
  /* no work */
167
}
(-)a/jpeg/jmemdos.c (-638 lines)
Line     Link Here 
 Lines 1-638    Link Here 
1
/*
2
 * jmemdos.c
3
 *
4
 * Copyright (C) 1992-1997, Thomas G. Lane.
5
 * This file is part of the Independent JPEG Group's software.
6
 * For conditions of distribution and use, see the accompanying README file.
7
 *
8
 * This file provides an MS-DOS-compatible implementation of the system-
9
 * dependent portion of the JPEG memory manager.  Temporary data can be
10
 * stored in extended or expanded memory as well as in regular DOS files.
11
 *
12
 * If you use this file, you must be sure that NEED_FAR_POINTERS is defined
13
 * if you compile in a small-data memory model; it should NOT be defined if
14
 * you use a large-data memory model.  This file is not recommended if you
15
 * are using a flat-memory-space 386 environment such as DJGCC or Watcom C.
16
 * Also, this code will NOT work if struct fields are aligned on greater than
17
 * 2-byte boundaries.
18
 *
19
 * Based on code contributed by Ge' Weijers.
20
 */
21
22
/*
23
 * If you have both extended and expanded memory, you may want to change the
24
 * order in which they are tried in jopen_backing_store.  On a 286 machine
25
 * expanded memory is usually faster, since extended memory access involves
26
 * an expensive protected-mode-and-back switch.  On 386 and better, extended
27
 * memory is usually faster.  As distributed, the code tries extended memory
28
 * first (what? not everyone has a 386? :-).
29
 *
30
 * You can disable use of extended/expanded memory entirely by altering these
31
 * definitions or overriding them from the Makefile (eg, -DEMS_SUPPORTED=0).
32
 */
33
34
#ifndef XMS_SUPPORTED
35
#define XMS_SUPPORTED  1
36
#endif
37
#ifndef EMS_SUPPORTED
38
#define EMS_SUPPORTED  1
39
#endif
40
41
42
#define JPEG_INTERNALS
43
#include "jinclude.h"
44
#include "jpeglib.h"
45
#include "jmemsys.h"		/* import the system-dependent declarations */
46
47
#ifndef HAVE_STDLIB_H		/* <stdlib.h> should declare these */
48
extern void * malloc JPP((size_t size));
49
extern void free JPP((void *ptr));
50
extern char * getenv JPP((const char * name));
51
#endif
52
53
#ifdef NEED_FAR_POINTERS
54
55
#ifdef __TURBOC__
56
/* These definitions work for Borland C (Turbo C) */
57
#include <alloc.h>		/* need farmalloc(), farfree() */
58
#define far_malloc(x)	farmalloc(x)
59
#define far_free(x)	farfree(x)
60
#else
61
/* These definitions work for Microsoft C and compatible compilers */
62
#include <malloc.h>		/* need _fmalloc(), _ffree() */
63
#define far_malloc(x)	_fmalloc(x)
64
#define far_free(x)	_ffree(x)
65
#endif
66
67
#else /* not NEED_FAR_POINTERS */
68
69
#define far_malloc(x)	malloc(x)
70
#define far_free(x)	free(x)
71
72
#endif /* NEED_FAR_POINTERS */
73
74
#ifdef DONT_USE_B_MODE		/* define mode parameters for fopen() */
75
#define READ_BINARY	"r"
76
#else
77
#define READ_BINARY	"rb"
78
#endif
79
80
#ifndef USE_MSDOS_MEMMGR	/* make sure user got configuration right */
81
  You forgot to define USE_MSDOS_MEMMGR in jconfig.h. /* deliberate syntax error */
82
#endif
83
84
#if MAX_ALLOC_CHUNK >= 65535L	/* make sure jconfig.h got this right */
85
  MAX_ALLOC_CHUNK should be less than 64K. /* deliberate syntax error */
86
#endif
87
88
89
/*
90
 * Declarations for assembly-language support routines (see jmemdosa.asm).
91
 *
92
 * The functions are declared "far" as are all their pointer arguments;
93
 * this ensures the assembly source code will work regardless of the
94
 * compiler memory model.  We assume "short" is 16 bits, "long" is 32.
95
 */
96
97
typedef void far * XMSDRIVER;	/* actually a pointer to code */
98
typedef struct {		/* registers for calling XMS driver */
99
	unsigned short ax, dx, bx;
100
	void far * ds_si;
101
      } XMScontext;
102
typedef struct {		/* registers for calling EMS driver */
103
	unsigned short ax, dx, bx;
104
	void far * ds_si;
105
      } EMScontext;
106
107
extern short far jdos_open JPP((short far * handle, char far * filename));
108
extern short far jdos_close JPP((short handle));
109
extern short far jdos_seek JPP((short handle, long offset));
110
extern short far jdos_read JPP((short handle, void far * buffer,
111
				unsigned short count));
112
extern short far jdos_write JPP((short handle, void far * buffer,
113
				 unsigned short count));
114
extern void far jxms_getdriver JPP((XMSDRIVER far *));
115
extern void far jxms_calldriver JPP((XMSDRIVER, XMScontext far *));
116
extern short far jems_available JPP((void));
117
extern void far jems_calldriver JPP((EMScontext far *));
118
119
120
/*
121
 * Selection of a file name for a temporary file.
122
 * This is highly system-dependent, and you may want to customize it.
123
 */
124
125
static int next_file_num;	/* to distinguish among several temp files */
126
127
LOCAL(void)
128
select_file_name (char * fname)
129
{
130
  const char * env;
131
  char * ptr;
132
  FILE * tfile;
133
134
  /* Keep generating file names till we find one that's not in use */
135
  for (;;) {
136
    /* Get temp directory name from environment TMP or TEMP variable;
137
     * if none, use "."
138
     */
139
    if ((env = (const char *) getenv("TMP")) == NULL)
140
      if ((env = (const char *) getenv("TEMP")) == NULL)
141
	env = ".";
142
    if (*env == '\0')		/* null string means "." */
143
      env = ".";
144
    ptr = fname;		/* copy name to fname */
145
    while (*env != '\0')
146
      *ptr++ = *env++;
147
    if (ptr[-1] != '\\' && ptr[-1] != '/')
148
      *ptr++ = '\\';		/* append backslash if not in env variable */
149
    /* Append a suitable file name */
150
    next_file_num++;		/* advance counter */
151
    sprintf(ptr, "JPG%03d.TMP", next_file_num);
152
    /* Probe to see if file name is already in use */
153
    if ((tfile = fopen(fname, READ_BINARY)) == NULL)
154
      break;
155
    fclose(tfile);		/* oops, it's there; close tfile & try again */
156
  }
157
}
158
159
160
/*
161
 * Near-memory allocation and freeing are controlled by the regular library
162
 * routines malloc() and free().
163
 */
164
165
GLOBAL(void *)
166
jpeg_get_small (j_common_ptr cinfo, size_t sizeofobject)
167
{
168
  return (void *) malloc(sizeofobject);
169
}
170
171
GLOBAL(void)
172
jpeg_free_small (j_common_ptr cinfo, void * object, size_t sizeofobject)
173
{
174
  free(object);
175
}
176
177
178
/*
179
 * "Large" objects are allocated in far memory, if possible
180
 */
181
182
GLOBAL(void FAR *)
183
jpeg_get_large (j_common_ptr cinfo, size_t sizeofobject)
184
{
185
  return (void FAR *) far_malloc(sizeofobject);
186
}
187
188
GLOBAL(void)
189
jpeg_free_large (j_common_ptr cinfo, void FAR * object, size_t sizeofobject)
190
{
191
  far_free(object);
192
}
193
194
195
/*
196
 * This routine computes the total memory space available for allocation.
197
 * It's impossible to do this in a portable way; our current solution is
198
 * to make the user tell us (with a default value set at compile time).
199
 * If you can actually get the available space, it's a good idea to subtract
200
 * a slop factor of 5% or so.
201
 */
202
203
#ifndef DEFAULT_MAX_MEM		/* so can override from makefile */
204
#define DEFAULT_MAX_MEM		300000L /* for total usage about 450K */
205
#endif
206
207
GLOBAL(long)
208
jpeg_mem_available (j_common_ptr cinfo, long min_bytes_needed,
209
		    long max_bytes_needed, long already_allocated)
210
{
211
  return cinfo->mem->max_memory_to_use - already_allocated;
212
}
213
214
215
/*
216
 * Backing store (temporary file) management.
217
 * Backing store objects are only used when the value returned by
218
 * jpeg_mem_available is less than the total space needed.  You can dispense
219
 * with these routines if you have plenty of virtual memory; see jmemnobs.c.
220
 */
221
222
/*
223
 * For MS-DOS we support three types of backing storage:
224
 *   1. Conventional DOS files.  We access these by direct DOS calls rather
225
 *      than via the stdio package.  This provides a bit better performance,
226
 *      but the real reason is that the buffers to be read or written are FAR.
227
 *      The stdio library for small-data memory models can't cope with that.
228
 *   2. Extended memory, accessed per the XMS V2.0 specification.
229
 *   3. Expanded memory, accessed per the LIM/EMS 4.0 specification.
230
 * You'll need copies of those specs to make sense of the related code.
231
 * The specs are available by Internet FTP from the SIMTEL archives 
232
 * (oak.oakland.edu and its various mirror sites).  See files
233
 * pub/msdos/microsoft/xms20.arc and pub/msdos/info/limems41.zip.
234
 */
235
236
237
/*
238
 * Access methods for a DOS file.
239
 */
240
241
242
METHODDEF(void)
243
read_file_store (j_common_ptr cinfo, backing_store_ptr info,
244
		 void FAR * buffer_address,
245
		 long file_offset, long byte_count)
246
{
247
  if (jdos_seek(info->handle.file_handle, file_offset))
248
    ERREXIT(cinfo, JERR_TFILE_SEEK);
249
  /* Since MAX_ALLOC_CHUNK is less than 64K, byte_count will be too. */
250
  if (byte_count > 65535L)	/* safety check */
251
    ERREXIT(cinfo, JERR_BAD_ALLOC_CHUNK);
252
  if (jdos_read(info->handle.file_handle, buffer_address,
253
		(unsigned short) byte_count))
254
    ERREXIT(cinfo, JERR_TFILE_READ);
255
}
256
257
258
METHODDEF(void)
259
write_file_store (j_common_ptr cinfo, backing_store_ptr info,
260
		  void FAR * buffer_address,
261
		  long file_offset, long byte_count)
262
{
263
  if (jdos_seek(info->handle.file_handle, file_offset))
264
    ERREXIT(cinfo, JERR_TFILE_SEEK);
265
  /* Since MAX_ALLOC_CHUNK is less than 64K, byte_count will be too. */
266
  if (byte_count > 65535L)	/* safety check */
267
    ERREXIT(cinfo, JERR_BAD_ALLOC_CHUNK);
268
  if (jdos_write(info->handle.file_handle, buffer_address,
269
		 (unsigned short) byte_count))
270
    ERREXIT(cinfo, JERR_TFILE_WRITE);
271
}
272
273
274
METHODDEF(void)
275
close_file_store (j_common_ptr cinfo, backing_store_ptr info)
276
{
277
  jdos_close(info->handle.file_handle);	/* close the file */
278
  remove(info->temp_name);	/* delete the file */
279
/* If your system doesn't have remove(), try unlink() instead.
280
 * remove() is the ANSI-standard name for this function, but
281
 * unlink() was more common in pre-ANSI systems.
282
 */
283
  TRACEMSS(cinfo, 1, JTRC_TFILE_CLOSE, info->temp_name);
284
}
285
286
287
LOCAL(boolean)
288
open_file_store (j_common_ptr cinfo, backing_store_ptr info,
289
		 long total_bytes_needed)
290
{
291
  short handle;
292
293
  select_file_name(info->temp_name);
294
  if (jdos_open((short far *) & handle, (char far *) info->temp_name)) {
295
    /* might as well exit since jpeg_open_backing_store will fail anyway */
296
    ERREXITS(cinfo, JERR_TFILE_CREATE, info->temp_name);
297
    return FALSE;
298
  }
299
  info->handle.file_handle = handle;
300
  info->read_backing_store = read_file_store;
301
  info->write_backing_store = write_file_store;
302
  info->close_backing_store = close_file_store;
303
  TRACEMSS(cinfo, 1, JTRC_TFILE_OPEN, info->temp_name);
304
  return TRUE;			/* succeeded */
305
}
306
307
308
/*
309
 * Access methods for extended memory.
310
 */
311
312
#if XMS_SUPPORTED
313
314
static XMSDRIVER xms_driver;	/* saved address of XMS driver */
315
316
typedef union {			/* either long offset or real-mode pointer */
317
	long offset;
318
	void far * ptr;
319
      } XMSPTR;
320
321
typedef struct {		/* XMS move specification structure */
322
	long length;
323
	XMSH src_handle;
324
	XMSPTR src;
325
	XMSH dst_handle;
326
	XMSPTR dst;
327
      } XMSspec;
328
329
#define ODD(X)	(((X) & 1L) != 0)
330
331
332
METHODDEF(void)
333
read_xms_store (j_common_ptr cinfo, backing_store_ptr info,
334
		void FAR * buffer_address,
335
		long file_offset, long byte_count)
336
{
337
  XMScontext ctx;
338
  XMSspec spec;
339
  char endbuffer[2];
340
341
  /* The XMS driver can't cope with an odd length, so handle the last byte
342
   * specially if byte_count is odd.  We don't expect this to be common.
343
   */
344
345
  spec.length = byte_count & (~ 1L);
346
  spec.src_handle = info->handle.xms_handle;
347
  spec.src.offset = file_offset;
348
  spec.dst_handle = 0;
349
  spec.dst.ptr = buffer_address;
350
  
351
  ctx.ds_si = (void far *) & spec;
352
  ctx.ax = 0x0b00;		/* EMB move */
353
  jxms_calldriver(xms_driver, (XMScontext far *) & ctx);
354
  if (ctx.ax != 1)
355
    ERREXIT(cinfo, JERR_XMS_READ);
356
357
  if (ODD(byte_count)) {
358
    read_xms_store(cinfo, info, (void FAR *) endbuffer,
359
		   file_offset + byte_count - 1L, 2L);
360
    ((char FAR *) buffer_address)[byte_count - 1L] = endbuffer[0];
361
  }
362
}
363
364
365
METHODDEF(void)
366
write_xms_store (j_common_ptr cinfo, backing_store_ptr info,
367
		 void FAR * buffer_address,
368
		 long file_offset, long byte_count)
369
{
370
  XMScontext ctx;
371
  XMSspec spec;
372
  char endbuffer[2];
373
374
  /* The XMS driver can't cope with an odd length, so handle the last byte
375
   * specially if byte_count is odd.  We don't expect this to be common.
376
   */
377
378
  spec.length = byte_count & (~ 1L);
379
  spec.src_handle = 0;
380
  spec.src.ptr = buffer_address;
381
  spec.dst_handle = info->handle.xms_handle;
382
  spec.dst.offset = file_offset;
383
384
  ctx.ds_si = (void far *) & spec;
385
  ctx.ax = 0x0b00;		/* EMB move */
386
  jxms_calldriver(xms_driver, (XMScontext far *) & ctx);
387
  if (ctx.ax != 1)
388
    ERREXIT(cinfo, JERR_XMS_WRITE);
389
390
  if (ODD(byte_count)) {
391
    read_xms_store(cinfo, info, (void FAR *) endbuffer,
392
		   file_offset + byte_count - 1L, 2L);
393
    endbuffer[0] = ((char FAR *) buffer_address)[byte_count - 1L];
394
    write_xms_store(cinfo, info, (void FAR *) endbuffer,
395
		    file_offset + byte_count - 1L, 2L);
396
  }
397
}
398
399
400
METHODDEF(void)
401
close_xms_store (j_common_ptr cinfo, backing_store_ptr info)
402
{
403
  XMScontext ctx;
404
405
  ctx.dx = info->handle.xms_handle;
406
  ctx.ax = 0x0a00;
407
  jxms_calldriver(xms_driver, (XMScontext far *) & ctx);
408
  TRACEMS1(cinfo, 1, JTRC_XMS_CLOSE, info->handle.xms_handle);
409
  /* we ignore any error return from the driver */
410
}
411
412
413
LOCAL(boolean)
414
open_xms_store (j_common_ptr cinfo, backing_store_ptr info,
415
		long total_bytes_needed)
416
{
417
  XMScontext ctx;
418
419
  /* Get address of XMS driver */
420
  jxms_getdriver((XMSDRIVER far *) & xms_driver);
421
  if (xms_driver == NULL)
422
    return FALSE;		/* no driver to be had */
423
424
  /* Get version number, must be >= 2.00 */
425
  ctx.ax = 0x0000;
426
  jxms_calldriver(xms_driver, (XMScontext far *) & ctx);
427
  if (ctx.ax < (unsigned short) 0x0200)
428
    return FALSE;
429
430
  /* Try to get space (expressed in kilobytes) */
431
  ctx.dx = (unsigned short) ((total_bytes_needed + 1023L) >> 10);
432
  ctx.ax = 0x0900;
433
  jxms_calldriver(xms_driver, (XMScontext far *) & ctx);
434
  if (ctx.ax != 1)
435
    return FALSE;
436
437
  /* Succeeded, save the handle and away we go */
438
  info->handle.xms_handle = ctx.dx;
439
  info->read_backing_store = read_xms_store;
440
  info->write_backing_store = write_xms_store;
441
  info->close_backing_store = close_xms_store;
442
  TRACEMS1(cinfo, 1, JTRC_XMS_OPEN, ctx.dx);
443
  return TRUE;			/* succeeded */
444
}
445
446
#endif /* XMS_SUPPORTED */
447
448
449
/*
450
 * Access methods for expanded memory.
451
 */
452
453
#if EMS_SUPPORTED
454
455
/* The EMS move specification structure requires word and long fields aligned
456
 * at odd byte boundaries.  Some compilers will align struct fields at even
457
 * byte boundaries.  While it's usually possible to force byte alignment,
458
 * that causes an overall performance penalty and may pose problems in merging
459
 * JPEG into a larger application.  Instead we accept some rather dirty code
460
 * here.  Note this code would fail if the hardware did not allow odd-byte
461
 * word & long accesses, but all 80x86 CPUs do.
462
 */
463
464
typedef void far * EMSPTR;
465
466
typedef union {			/* EMS move specification structure */
467
	long length;		/* It's easy to access first 4 bytes */
468
	char bytes[18];		/* Misaligned fields in here! */
469
      } EMSspec;
470
471
/* Macros for accessing misaligned fields */
472
#define FIELD_AT(spec,offset,type)  (*((type *) &(spec.bytes[offset])))
473
#define SRC_TYPE(spec)		FIELD_AT(spec,4,char)
474
#define SRC_HANDLE(spec)	FIELD_AT(spec,5,EMSH)
475
#define SRC_OFFSET(spec)	FIELD_AT(spec,7,unsigned short)
476
#define SRC_PAGE(spec)		FIELD_AT(spec,9,unsigned short)
477
#define SRC_PTR(spec)		FIELD_AT(spec,7,EMSPTR)
478
#define DST_TYPE(spec)		FIELD_AT(spec,11,char)
479
#define DST_HANDLE(spec)	FIELD_AT(spec,12,EMSH)
480
#define DST_OFFSET(spec)	FIELD_AT(spec,14,unsigned short)
481
#define DST_PAGE(spec)		FIELD_AT(spec,16,unsigned short)
482
#define DST_PTR(spec)		FIELD_AT(spec,14,EMSPTR)
483
484
#define EMSPAGESIZE	16384L	/* gospel, see the EMS specs */
485
486
#define HIBYTE(W)  (((W) >> 8) & 0xFF)
487
#define LOBYTE(W)  ((W) & 0xFF)
488
489
490
METHODDEF(void)
491
read_ems_store (j_common_ptr cinfo, backing_store_ptr info,
492
		void FAR * buffer_address,
493
		long file_offset, long byte_count)
494
{
495
  EMScontext ctx;
496
  EMSspec spec;
497
498
  spec.length = byte_count;
499
  SRC_TYPE(spec) = 1;
500
  SRC_HANDLE(spec) = info->handle.ems_handle;
501
  SRC_PAGE(spec)   = (unsigned short) (file_offset / EMSPAGESIZE);
502
  SRC_OFFSET(spec) = (unsigned short) (file_offset % EMSPAGESIZE);
503
  DST_TYPE(spec) = 0;
504
  DST_HANDLE(spec) = 0;
505
  DST_PTR(spec)    = buffer_address;
506
  
507
  ctx.ds_si = (void far *) & spec;
508
  ctx.ax = 0x5700;		/* move memory region */
509
  jems_calldriver((EMScontext far *) & ctx);
510
  if (HIBYTE(ctx.ax) != 0)
511
    ERREXIT(cinfo, JERR_EMS_READ);
512
}
513
514
515
METHODDEF(void)
516
write_ems_store (j_common_ptr cinfo, backing_store_ptr info,
517
		 void FAR * buffer_address,
518
		 long file_offset, long byte_count)
519
{
520
  EMScontext ctx;
521
  EMSspec spec;
522
523
  spec.length = byte_count;
524
  SRC_TYPE(spec) = 0;
525
  SRC_HANDLE(spec) = 0;
526
  SRC_PTR(spec)    = buffer_address;
527
  DST_TYPE(spec) = 1;
528
  DST_HANDLE(spec) = info->handle.ems_handle;
529
  DST_PAGE(spec)   = (unsigned short) (file_offset / EMSPAGESIZE);
530
  DST_OFFSET(spec) = (unsigned short) (file_offset % EMSPAGESIZE);
531
  
532
  ctx.ds_si = (void far *) & spec;
533
  ctx.ax = 0x5700;		/* move memory region */
534
  jems_calldriver((EMScontext far *) & ctx);
535
  if (HIBYTE(ctx.ax) != 0)
536
    ERREXIT(cinfo, JERR_EMS_WRITE);
537
}
538
539
540
METHODDEF(void)
541
close_ems_store (j_common_ptr cinfo, backing_store_ptr info)
542
{
543
  EMScontext ctx;
544
545
  ctx.ax = 0x4500;
546
  ctx.dx = info->handle.ems_handle;
547
  jems_calldriver((EMScontext far *) & ctx);
548
  TRACEMS1(cinfo, 1, JTRC_EMS_CLOSE, info->handle.ems_handle);
549
  /* we ignore any error return from the driver */
550
}
551
552
553
LOCAL(boolean)
554
open_ems_store (j_common_ptr cinfo, backing_store_ptr info,
555
		long total_bytes_needed)
556
{
557
  EMScontext ctx;
558
559
  /* Is EMS driver there? */
560
  if (! jems_available())
561
    return FALSE;
562
563
  /* Get status, make sure EMS is OK */
564
  ctx.ax = 0x4000;
565
  jems_calldriver((EMScontext far *) & ctx);
566
  if (HIBYTE(ctx.ax) != 0)
567
    return FALSE;
568
569
  /* Get version, must be >= 4.0 */
570
  ctx.ax = 0x4600;
571
  jems_calldriver((EMScontext far *) & ctx);
572
  if (HIBYTE(ctx.ax) != 0 || LOBYTE(ctx.ax) < 0x40)
573
    return FALSE;
574
575
  /* Try to allocate requested space */
576
  ctx.ax = 0x4300;
577
  ctx.bx = (unsigned short) ((total_bytes_needed + EMSPAGESIZE-1L) / EMSPAGESIZE);
578
  jems_calldriver((EMScontext far *) & ctx);
579
  if (HIBYTE(ctx.ax) != 0)
580
    return FALSE;
581
582
  /* Succeeded, save the handle and away we go */
583
  info->handle.ems_handle = ctx.dx;
584
  info->read_backing_store = read_ems_store;
585
  info->write_backing_store = write_ems_store;
586
  info->close_backing_store = close_ems_store;
587
  TRACEMS1(cinfo, 1, JTRC_EMS_OPEN, ctx.dx);
588
  return TRUE;			/* succeeded */
589
}
590
591
#endif /* EMS_SUPPORTED */
592
593
594
/*
595
 * Initial opening of a backing-store object.
596
 */
597
598
GLOBAL(void)
599
jpeg_open_backing_store (j_common_ptr cinfo, backing_store_ptr info,
600
			 long total_bytes_needed)
601
{
602
  /* Try extended memory, then expanded memory, then regular file. */
603
#if XMS_SUPPORTED
604
  if (open_xms_store(cinfo, info, total_bytes_needed))
605
    return;
606
#endif
607
#if EMS_SUPPORTED
608
  if (open_ems_store(cinfo, info, total_bytes_needed))
609
    return;
610
#endif
611
  if (open_file_store(cinfo, info, total_bytes_needed))
612
    return;
613
  ERREXITS(cinfo, JERR_TFILE_CREATE, "");
614
}
615
616
617
/*
618
 * These routines take care of any system-dependent initialization and
619
 * cleanup required.
620
 */
621
622
GLOBAL(long)
623
jpeg_mem_init (j_common_ptr cinfo)
624
{
625
  next_file_num = 0;		/* initialize temp file name generator */
626
  return DEFAULT_MAX_MEM;	/* default for max_memory_to_use */
627
}
628
629
GLOBAL(void)
630
jpeg_mem_term (j_common_ptr cinfo)
631
{
632
  /* Microsoft C, at least in v6.00A, will not successfully reclaim freed
633
   * blocks of size > 32Kbytes unless we give it a kick in the rear, like so:
634
   */
635
#ifdef NEED_FHEAPMIN
636
  _fheapmin();
637
#endif
638
}
(-)a/jpeg/jmemdosa.asm (-379 lines)
Line     Link Here 
 Lines 1-379    Link Here 
1
;
2
; jmemdosa.asm
3
;
4
; Copyright (C) 1992, Thomas G. Lane.
5
; This file is part of the Independent JPEG Group's software.
6
; For conditions of distribution and use, see the accompanying README file.
7
;
8
; This file contains low-level interface routines to support the MS-DOS
9
; backing store manager (jmemdos.c).  Routines are provided to access disk
10
; files through direct DOS calls, and to access XMS and EMS drivers.
11
;
12
; This file should assemble with Microsoft's MASM or any compatible
13
; assembler (including Borland's Turbo Assembler).  If you haven't got
14
; a compatible assembler, better fall back to jmemansi.c or jmemname.c.
15
;
16
; To minimize dependence on the C compiler's register usage conventions,
17
; we save and restore all 8086 registers, even though most compilers only
18
; require SI,DI,DS to be preserved.  Also, we use only 16-bit-wide return
19
; values, which everybody returns in AX.
20
;
21
; Based on code contributed by Ge' Weijers.
22
;
23
24
JMEMDOSA_TXT	segment byte public 'CODE'
25
26
		assume	cs:JMEMDOSA_TXT
27
28
		public	_jdos_open
29
		public	_jdos_close
30
		public	_jdos_seek
31
		public	_jdos_read
32
		public	_jdos_write
33
		public	_jxms_getdriver
34
		public	_jxms_calldriver
35
		public	_jems_available
36
		public	_jems_calldriver
37
38
;
39
; short far jdos_open (short far * handle, char far * filename)
40
;
41
; Create and open a temporary file
42
;
43
_jdos_open	proc	far
44
		push	bp			; linkage
45
		mov 	bp,sp
46
		push	si			; save all registers for safety
47
		push	di
48
		push	bx
49
		push	cx
50
		push	dx
51
		push	es
52
		push	ds
53
		mov	cx,0			; normal file attributes
54
		lds	dx,dword ptr [bp+10]	; get filename pointer
55
		mov	ah,3ch			; create file
56
		int	21h
57
		jc	open_err		; if failed, return error code
58
		lds	bx,dword ptr [bp+6]	; get handle pointer
59
		mov	word ptr [bx],ax	; save the handle
60
		xor	ax,ax			; return zero for OK
61
open_err:	pop	ds			; restore registers and exit
62
		pop	es
63
		pop	dx
64
		pop	cx
65
		pop	bx
66
		pop	di
67
		pop	si
68
		pop 	bp
69
		ret
70
_jdos_open	endp
71
72
73
;
74
; short far jdos_close (short handle)
75
;
76
; Close the file handle
77
;
78
_jdos_close	proc	far
79
		push	bp			; linkage
80
		mov 	bp,sp
81
		push	si			; save all registers for safety
82
		push	di
83
		push	bx
84
		push	cx
85
		push	dx
86
		push	es
87
		push	ds
88
		mov	bx,word ptr [bp+6]	; file handle
89
		mov	ah,3eh			; close file
90
		int	21h
91
		jc	close_err		; if failed, return error code
92
		xor	ax,ax			; return zero for OK
93
close_err:	pop	ds			; restore registers and exit
94
		pop	es
95
		pop	dx
96
		pop	cx
97
		pop	bx
98
		pop	di
99
		pop	si
100
		pop 	bp
101
		ret
102
_jdos_close	endp
103
104
105
;
106
; short far jdos_seek (short handle, long offset)
107
;
108
; Set file position
109
;
110
_jdos_seek	proc	far
111
		push	bp			; linkage
112
		mov 	bp,sp
113
		push	si			; save all registers for safety
114
		push	di
115
		push	bx
116
		push	cx
117
		push	dx
118
		push	es
119
		push	ds
120
		mov	bx,word ptr [bp+6]	; file handle
121
		mov	dx,word ptr [bp+8]	; LS offset
122
		mov	cx,word ptr [bp+10]	; MS offset
123
		mov	ax,4200h		; absolute seek
124
		int	21h
125
		jc	seek_err		; if failed, return error code
126
		xor	ax,ax			; return zero for OK
127
seek_err:	pop	ds			; restore registers and exit
128
		pop	es
129
		pop	dx
130
		pop	cx
131
		pop	bx
132
		pop	di
133
		pop	si
134
		pop 	bp
135
		ret
136
_jdos_seek	endp
137
138
139
;
140
; short far jdos_read (short handle, void far * buffer, unsigned short count)
141
;
142
; Read from file
143
;
144
_jdos_read	proc	far
145
		push	bp			; linkage
146
		mov 	bp,sp
147
		push	si			; save all registers for safety
148
		push	di
149
		push	bx
150
		push	cx
151
		push	dx
152
		push	es
153
		push	ds
154
		mov	bx,word ptr [bp+6]	; file handle
155
		lds	dx,dword ptr [bp+8]	; buffer address
156
		mov	cx,word ptr [bp+12]	; number of bytes
157
		mov	ah,3fh			; read file
158
		int	21h
159
		jc	read_err		; if failed, return error code
160
		cmp	ax,word ptr [bp+12]	; make sure all bytes were read
161
		je	read_ok
162
		mov	ax,1			; else return 1 for not OK
163
		jmp	short read_err
164
read_ok:	xor	ax,ax			; return zero for OK
165
read_err:	pop	ds			; restore registers and exit
166
		pop	es
167
		pop	dx
168
		pop	cx
169
		pop	bx
170
		pop	di
171
		pop	si
172
		pop 	bp
173
		ret
174
_jdos_read	endp
175
176
177
;
178
; short far jdos_write (short handle, void far * buffer, unsigned short count)
179
;
180
; Write to file
181
;
182
_jdos_write	proc	far
183
		push	bp			; linkage
184
		mov 	bp,sp
185
		push	si			; save all registers for safety
186
		push	di
187
		push	bx
188
		push	cx
189
		push	dx
190
		push	es
191
		push	ds
192
		mov	bx,word ptr [bp+6]	; file handle
193
		lds	dx,dword ptr [bp+8]	; buffer address
194
		mov	cx,word ptr [bp+12]	; number of bytes
195
		mov	ah,40h			; write file
196
		int	21h
197
		jc	write_err		; if failed, return error code
198
		cmp	ax,word ptr [bp+12]	; make sure all bytes written
199
		je	write_ok
200
		mov	ax,1			; else return 1 for not OK
201
		jmp	short write_err
202
write_ok:	xor	ax,ax			; return zero for OK
203
write_err:	pop	ds			; restore registers and exit
204
		pop	es
205
		pop	dx
206
		pop	cx
207
		pop	bx
208
		pop	di
209
		pop	si
210
		pop 	bp
211
		ret
212
_jdos_write	endp
213
214
215
;
216
; void far jxms_getdriver (XMSDRIVER far *)
217
;
218
; Get the address of the XMS driver, or NULL if not available
219
;
220
_jxms_getdriver	proc	far
221
		push	bp			; linkage
222
		mov 	bp,sp
223
		push	si			; save all registers for safety
224
		push	di
225
		push	bx
226
		push	cx
227
		push	dx
228
		push	es
229
		push	ds
230
		mov 	ax,4300h		; call multiplex interrupt with
231
		int	2fh			; a magic cookie, hex 4300
232
		cmp 	al,80h			; AL should contain hex 80
233
		je	xmsavail
234
		xor 	dx,dx			; no XMS driver available
235
		xor 	ax,ax			; return a nil pointer
236
		jmp	short xmsavail_done
237
xmsavail:	mov 	ax,4310h		; fetch driver address with
238
		int	2fh			; another magic cookie
239
		mov 	dx,es			; copy address to dx:ax
240
		mov 	ax,bx
241
xmsavail_done:	les 	bx,dword ptr [bp+6]	; get pointer to return value
242
		mov	word ptr es:[bx],ax
243
		mov	word ptr es:[bx+2],dx
244
		pop	ds			; restore registers and exit
245
		pop	es
246
		pop	dx
247
		pop	cx
248
		pop	bx
249
		pop	di
250
		pop	si
251
		pop	bp
252
		ret
253
_jxms_getdriver	endp
254
255
256
;
257
; void far jxms_calldriver (XMSDRIVER, XMScontext far *)
258
;
259
; The XMScontext structure contains values for the AX,DX,BX,SI,DS registers.
260
; These are loaded, the XMS call is performed, and the new values of the
261
; AX,DX,BX registers are written back to the context structure.
262
;
263
_jxms_calldriver 	proc	far
264
		push	bp			; linkage
265
		mov 	bp,sp
266
		push	si			; save all registers for safety
267
		push	di
268
		push	bx
269
		push	cx
270
		push	dx
271
		push	es
272
		push	ds
273
		les 	bx,dword ptr [bp+10]	; get XMScontext pointer
274
		mov 	ax,word ptr es:[bx]	; load registers
275
		mov 	dx,word ptr es:[bx+2]
276
		mov 	si,word ptr es:[bx+6]
277
		mov 	ds,word ptr es:[bx+8]
278
		mov 	bx,word ptr es:[bx+4]
279
		call	dword ptr [bp+6]	; call the driver
280
		mov	cx,bx			; save returned BX for a sec
281
		les 	bx,dword ptr [bp+10]	; get XMScontext pointer
282
		mov 	word ptr es:[bx],ax	; put back ax,dx,bx
283
		mov 	word ptr es:[bx+2],dx
284
		mov 	word ptr es:[bx+4],cx
285
		pop	ds			; restore registers and exit
286
		pop	es
287
		pop	dx
288
		pop	cx
289
		pop	bx
290
		pop	di
291
		pop	si
292
		pop 	bp
293
		ret
294
_jxms_calldriver 	endp
295
296
297
;
298
; short far jems_available (void)
299
;
300
; Have we got an EMS driver? (this comes straight from the EMS 4.0 specs)
301
;
302
_jems_available	proc	far
303
		push	si			; save all registers for safety
304
		push	di
305
		push	bx
306
		push	cx
307
		push	dx
308
		push	es
309
		push	ds
310
		mov	ax,3567h		; get interrupt vector 67h
311
		int	21h
312
		push	cs
313
		pop	ds
314
		mov	di,000ah		; check offs 10 in returned seg
315
		lea	si,ASCII_device_name	; against literal string
316
		mov	cx,8
317
		cld
318
		repe cmpsb
319
		jne	no_ems
320
		mov	ax,1			; match, it's there
321
		jmp	short avail_done
322
no_ems:		xor	ax,ax			; it's not there
323
avail_done:	pop	ds			; restore registers and exit
324
		pop	es
325
		pop	dx
326
		pop	cx
327
		pop	bx
328
		pop	di
329
		pop	si
330
		ret
331
332
ASCII_device_name	db	"EMMXXXX0"
333
334
_jems_available	endp
335
336
337
;
338
; void far jems_calldriver (EMScontext far *)
339
;
340
; The EMScontext structure contains values for the AX,DX,BX,SI,DS registers.
341
; These are loaded, the EMS trap is performed, and the new values of the
342
; AX,DX,BX registers are written back to the context structure.
343
;
344
_jems_calldriver	proc far
345
		push	bp			; linkage
346
		mov 	bp,sp
347
		push	si			; save all registers for safety
348
		push	di
349
		push	bx
350
		push	cx
351
		push	dx
352
		push	es
353
		push	ds
354
		les 	bx,dword ptr [bp+6]	; get EMScontext pointer
355
		mov 	ax,word ptr es:[bx]	; load registers
356
		mov 	dx,word ptr es:[bx+2]
357
		mov 	si,word ptr es:[bx+6]
358
		mov 	ds,word ptr es:[bx+8]
359
		mov 	bx,word ptr es:[bx+4]
360
		int	67h			; call the EMS driver
361
		mov	cx,bx			; save returned BX for a sec
362
		les 	bx,dword ptr [bp+6]	; get EMScontext pointer
363
		mov 	word ptr es:[bx],ax	; put back ax,dx,bx
364
		mov 	word ptr es:[bx+2],dx
365
		mov 	word ptr es:[bx+4],cx
366
		pop	ds			; restore registers and exit
367
		pop	es
368
		pop	dx
369
		pop	cx
370
		pop	bx
371
		pop	di
372
		pop	si
373
		pop 	bp
374
		ret
375
_jems_calldriver	endp
376
377
JMEMDOSA_TXT	ends
378
379
		end
(-)a/jpeg/jmemmgr.c (-75 / +99 lines)
Line     Link Here 
 Lines 52-119   extern char * getenv JPP((const char * n Link Here 
52
52
53
/*
53
/*
54
 * Many machines require storage alignment: longs must start on 4-byte
54
 * Many machines require storage alignment: longs must start on 4-byte
55
 * boundaries, doubles on 8-byte boundaries, etc.  On such machines, malloc()
55
 * boundaries, doubles on 8-byte boundaries, etc.  On such machines, malloc()
56
 * always returns pointers that are multiples of the worst-case alignment
56
 * always returns pointers that are multiples of the worst-case alignment
57
 * requirement, and we had better do so too.
57
 * requirement, and we had better do so too.
58
 * There isn't any really portable way to determine the worst-case alignment
58
 * There isn't any really portable way to determine the worst-case alignment
59
 * requirement.  This module assumes that the alignment requirement is
59
 * requirement.  This module assumes that the alignment requirement is
60
 * multiples of sizeof(ALIGN_TYPE).
60
 * multiples of ALIGN_SIZE.
61
 * By default, we define ALIGN_TYPE as double.  This is necessary on some
61
 * By default, we define ALIGN_SIZE as sizeof(double).  This is necessary on some
62
 * workstations (where doubles really do need 8-byte alignment) and will work
62
 * workstations (where doubles really do need 8-byte alignment) and will work
63
 * fine on nearly everything.  If your machine has lesser alignment needs,
63
 * fine on nearly everything.  If your machine has lesser alignment needs,
64
 * you can save a few bytes by making ALIGN_TYPE smaller.
64
 * you can save a few bytes by making ALIGN_SIZE smaller.
65
 * The only place I know of where this will NOT work is certain Macintosh
65
 * The only place I know of where this will NOT work is certain Macintosh
66
 * 680x0 compilers that define double as a 10-byte IEEE extended float.
66
 * 680x0 compilers that define double as a 10-byte IEEE extended float.
67
 * Doing 10-byte alignment is counterproductive because longwords won't be
67
 * Doing 10-byte alignment is counterproductive because longwords won't be
68
 * aligned well.  Put "#define ALIGN_TYPE long" in jconfig.h if you have
68
 * aligned well.  Put "#define ALIGN_SIZE 4" in jconfig.h if you have
69
 * such a compiler.
69
 * such a compiler.
70
 */
70
 */
71
71
72
#ifndef ALIGN_TYPE		/* so can override from jconfig.h */
72
#ifndef ALIGN_SIZE		/* so can override from jconfig.h */
73
#define ALIGN_TYPE  double
73
#ifndef WITH_SIMD
74
#define ALIGN_SIZE  SIZEOF(double)
75
#else
76
#define ALIGN_SIZE  16 /* Most SIMD implementations require this */
74
#endif
77
#endif
75
78
#endif
76
79
77
/*
80
/*
78
 * We allocate objects from "pools", where each pool is gotten with a single
81
 * We allocate objects from "pools", where each pool is gotten with a single
79
 * request to jpeg_get_small() or jpeg_get_large().  There is no per-object
82
 * request to jpeg_get_small() or jpeg_get_large().  There is no per-object
80
 * overhead within a pool, except for alignment padding.  Each pool has a
83
 * overhead within a pool, except for alignment padding.  Each pool has a
81
 * header with a link to the next pool of the same class.
84
 * header with a link to the next pool of the same class.
82
 * Small and large pool headers are identical except that the latter's
85
 * Small and large pool headers are identical except that the latter's
83
 * link pointer must be FAR on 80x86 machines.
86
 * link pointer must be FAR on 80x86 machines.
84
 * Notice that the "real" header fields are union'ed with a dummy ALIGN_TYPE
85
 * field.  This forces the compiler to make SIZEOF(small_pool_hdr) a multiple
86
 * of the alignment requirement of ALIGN_TYPE.
87
 */
87
 */
88
88
89
typedef union small_pool_struct * small_pool_ptr;
89
typedef struct small_pool_struct * small_pool_ptr;
90
90
91
typedef union small_pool_struct {
91
typedef struct small_pool_struct {
92
  struct {
92
  small_pool_ptr next;	/* next in list of pools */
93
    small_pool_ptr next;	/* next in list of pools */
93
  size_t bytes_used;		/* how many bytes already used within pool */
94
    size_t bytes_used;		/* how many bytes already used within pool */
94
  size_t bytes_left;		/* bytes still available in this pool */
95
    size_t bytes_left;		/* bytes still available in this pool */
96
  } hdr;
97
  ALIGN_TYPE dummy;		/* included in union to ensure alignment */
98
} small_pool_hdr;
95
} small_pool_hdr;
99
96
100
typedef union large_pool_struct FAR * large_pool_ptr;
97
typedef struct large_pool_struct FAR * large_pool_ptr;
101
98
102
typedef union large_pool_struct {
99
typedef struct large_pool_struct {
103
  struct {
100
  large_pool_ptr next;	/* next in list of pools */
104
    large_pool_ptr next;	/* next in list of pools */
101
  size_t bytes_used;		/* how many bytes already used within pool */
105
    size_t bytes_used;		/* how many bytes already used within pool */
102
  size_t bytes_left;		/* bytes still available in this pool */
106
    size_t bytes_left;		/* bytes still available in this pool */
107
  } hdr;
108
  ALIGN_TYPE dummy;		/* included in union to ensure alignment */
109
} large_pool_hdr;
103
} large_pool_hdr;
110
104
111
112
/*
105
/*
113
 * Here is the full definition of a memory manager object.
106
 * Here is the full definition of a memory manager object.
114
 */
107
 */
115
108
116
typedef struct {
109
typedef struct {
117
  struct jpeg_memory_mgr pub;	/* public fields */
110
  struct jpeg_memory_mgr pub;	/* public fields */
118
111
119
  /* Each pool identifier (lifetime class) names a linked list of pools. */
112
  /* Each pool identifier (lifetime class) names a linked list of pools. */
 Lines 124-140   typedef struct { Link Here 
124
   * linked list is necessary (for each datatype).  Note that the virtual
117
   * linked list is necessary (for each datatype).  Note that the virtual
125
   * array control blocks being linked together are actually stored somewhere
118
   * array control blocks being linked together are actually stored somewhere
126
   * in the small-pool list.
119
   * in the small-pool list.
127
   */
120
   */
128
  jvirt_sarray_ptr virt_sarray_list;
121
  jvirt_sarray_ptr virt_sarray_list;
129
  jvirt_barray_ptr virt_barray_list;
122
  jvirt_barray_ptr virt_barray_list;
130
123
131
  /* This counts total space obtained from jpeg_get_small/large */
124
  /* This counts total space obtained from jpeg_get_small/large */
132
  long total_space_allocated;
125
  size_t total_space_allocated;
133
126
134
  /* alloc_sarray and alloc_barray set this value for use by virtual
127
  /* alloc_sarray and alloc_barray set this value for use by virtual
135
   * array routines.
128
   * array routines.
136
   */
129
   */
137
  JDIMENSION last_rowsperchunk;	/* from most recent alloc_sarray/barray */
130
  JDIMENSION last_rowsperchunk;	/* from most recent alloc_sarray/barray */
138
} my_memory_mgr;
131
} my_memory_mgr;
139
132
140
typedef my_memory_mgr * my_mem_ptr;
133
typedef my_memory_mgr * my_mem_ptr;
 Lines 192-217   print_mem_stats (j_common_ptr cinfo, int Link Here 
192
  /* Since this is only a debugging stub, we can cheat a little by using
185
  /* Since this is only a debugging stub, we can cheat a little by using
193
   * fprintf directly rather than going through the trace message code.
186
   * fprintf directly rather than going through the trace message code.
194
   * This is helpful because message parm array can't handle longs.
187
   * This is helpful because message parm array can't handle longs.
195
   */
188
   */
196
  fprintf(stderr, "Freeing pool %d, total space = %ld\n",
189
  fprintf(stderr, "Freeing pool %d, total space = %ld\n",
197
	  pool_id, mem->total_space_allocated);
190
	  pool_id, mem->total_space_allocated);
198
191
199
  for (lhdr_ptr = mem->large_list[pool_id]; lhdr_ptr != NULL;
192
  for (lhdr_ptr = mem->large_list[pool_id]; lhdr_ptr != NULL;
200
       lhdr_ptr = lhdr_ptr->hdr.next) {
193
       lhdr_ptr = lhdr_ptr->next) {
201
    fprintf(stderr, "  Large chunk used %ld\n",
194
    fprintf(stderr, "  Large chunk used %ld\n",
202
	    (long) lhdr_ptr->hdr.bytes_used);
195
	    (long) lhdr_ptr->bytes_used);
203
  }
196
  }
204
197
205
  for (shdr_ptr = mem->small_list[pool_id]; shdr_ptr != NULL;
198
  for (shdr_ptr = mem->small_list[pool_id]; shdr_ptr != NULL;
206
       shdr_ptr = shdr_ptr->hdr.next) {
199
       shdr_ptr = shdr_ptr->next) {
207
    fprintf(stderr, "  Small chunk used %ld free %ld\n",
200
    fprintf(stderr, "  Small chunk used %ld free %ld\n",
208
	    (long) shdr_ptr->hdr.bytes_used,
201
	    (long) shdr_ptr->bytes_used,
209
	    (long) shdr_ptr->hdr.bytes_left);
202
	    (long) shdr_ptr->bytes_left);
210
  }
203
  }
211
}
204
}
212
205
213
#endif /* MEM_STATS */
206
#endif /* MEM_STATS */
214
207
215
208
216
LOCAL(void)
209
LOCAL(void)
217
out_of_memory (j_common_ptr cinfo, int which)
210
out_of_memory (j_common_ptr cinfo, int which)
 Lines 231-246   out_of_memory (j_common_ptr cinfo, int w Link Here 
231
 * For these, we use pooled storage.  When a new pool must be created,
224
 * For these, we use pooled storage.  When a new pool must be created,
232
 * we try to get enough space for the current request plus a "slop" factor,
225
 * we try to get enough space for the current request plus a "slop" factor,
233
 * where the slop will be the amount of leftover space in the new pool.
226
 * where the slop will be the amount of leftover space in the new pool.
234
 * The speed vs. space tradeoff is largely determined by the slop values.
227
 * The speed vs. space tradeoff is largely determined by the slop values.
235
 * A different slop value is provided for each pool class (lifetime),
228
 * A different slop value is provided for each pool class (lifetime),
236
 * and we also distinguish the first pool of a class from later ones.
229
 * and we also distinguish the first pool of a class from later ones.
237
 * NOTE: the values given work fairly well on both 16- and 32-bit-int
230
 * NOTE: the values given work fairly well on both 16- and 32-bit-int
238
 * machines, but may be too small if longs are 64 bits or more.
231
 * machines, but may be too small if longs are 64 bits or more.
232
 *
233
 * Since we do not know what alignment malloc() gives us, we have to
234
 * allocate ALIGN_SIZE-1 extra space per pool to have room for alignment
235
 * adjustment.
239
 */
236
 */
240
237
241
static const size_t first_pool_slop[JPOOL_NUMPOOLS] = 
238
static const size_t first_pool_slop[JPOOL_NUMPOOLS] = 
242
{
239
{
243
	1600,			/* first PERMANENT pool */
240
	1600,			/* first PERMANENT pool */
244
	16000			/* first IMAGE pool */
241
	16000			/* first IMAGE pool */
245
};
242
};
246
243
 Lines 255-297   static const size_t extra_pool_slop[JPOO Link Here 
255
252
256
METHODDEF(void *)
253
METHODDEF(void *)
257
alloc_small (j_common_ptr cinfo, int pool_id, size_t sizeofobject)
254
alloc_small (j_common_ptr cinfo, int pool_id, size_t sizeofobject)
258
/* Allocate a "small" object */
255
/* Allocate a "small" object */
259
{
256
{
260
  my_mem_ptr mem = (my_mem_ptr) cinfo->mem;
257
  my_mem_ptr mem = (my_mem_ptr) cinfo->mem;
261
  small_pool_ptr hdr_ptr, prev_hdr_ptr;
258
  small_pool_ptr hdr_ptr, prev_hdr_ptr;
262
  char * data_ptr;
259
  char * data_ptr;
263
  size_t odd_bytes, min_request, slop;
260
  size_t min_request, slop;
261
262
  /*
263
   * Round up the requested size to a multiple of ALIGN_SIZE in order
264
   * to assure alignment for the next object allocated in the same pool
265
   * and so that algorithms can straddle outside the proper area up
266
   * to the next alignment.
267
   */
268
  sizeofobject = jround_up(sizeofobject, ALIGN_SIZE);
264
269
265
  /* Check for unsatisfiable request (do now to ensure no overflow below) */
270
  /* Check for unsatisfiable request (do now to ensure no overflow below) */
266
  if (sizeofobject > (size_t) (MAX_ALLOC_CHUNK-SIZEOF(small_pool_hdr)))
271
  if ((SIZEOF(small_pool_hdr) + sizeofobject + ALIGN_SIZE - 1) > MAX_ALLOC_CHUNK)
267
    out_of_memory(cinfo, 1);	/* request exceeds malloc's ability */
272
    out_of_memory(cinfo, 1);	/* request exceeds malloc's ability */
268
273
269
  /* Round up the requested size to a multiple of SIZEOF(ALIGN_TYPE) */
270
  odd_bytes = sizeofobject % SIZEOF(ALIGN_TYPE);
271
  if (odd_bytes > 0)
272
    sizeofobject += SIZEOF(ALIGN_TYPE) - odd_bytes;
273
274
  /* See if space is available in any existing pool */
274
  /* See if space is available in any existing pool */
275
  if (pool_id < 0 || pool_id >= JPOOL_NUMPOOLS)
275
  if (pool_id < 0 || pool_id >= JPOOL_NUMPOOLS)
276
    ERREXIT1(cinfo, JERR_BAD_POOL_ID, pool_id);	/* safety check */
276
    ERREXIT1(cinfo, JERR_BAD_POOL_ID, pool_id);	/* safety check */
277
  prev_hdr_ptr = NULL;
277
  prev_hdr_ptr = NULL;
278
  hdr_ptr = mem->small_list[pool_id];
278
  hdr_ptr = mem->small_list[pool_id];
279
  while (hdr_ptr != NULL) {
279
  while (hdr_ptr != NULL) {
280
    if (hdr_ptr->hdr.bytes_left >= sizeofobject)
280
    if (hdr_ptr->bytes_left >= sizeofobject)
281
      break;			/* found pool with enough space */
281
      break;			/* found pool with enough space */
282
    prev_hdr_ptr = hdr_ptr;
282
    prev_hdr_ptr = hdr_ptr;
283
    hdr_ptr = hdr_ptr->hdr.next;
283
    hdr_ptr = hdr_ptr->next;
284
  }
284
  }
285
285
286
  /* Time to make a new pool? */
286
  /* Time to make a new pool? */
287
  if (hdr_ptr == NULL) {
287
  if (hdr_ptr == NULL) {
288
    /* min_request is what we need now, slop is what will be leftover */
288
    /* min_request is what we need now, slop is what will be leftover */
289
    min_request = sizeofobject + SIZEOF(small_pool_hdr);
289
    min_request = SIZEOF(small_pool_hdr) + sizeofobject + ALIGN_SIZE - 1;
290
    if (prev_hdr_ptr == NULL)	/* first pool in class? */
290
    if (prev_hdr_ptr == NULL)	/* first pool in class? */
291
      slop = first_pool_slop[pool_id];
291
      slop = first_pool_slop[pool_id];
292
    else
292
    else
293
      slop = extra_pool_slop[pool_id];
293
      slop = extra_pool_slop[pool_id];
294
    /* Don't ask for more than MAX_ALLOC_CHUNK */
294
    /* Don't ask for more than MAX_ALLOC_CHUNK */
295
    if (slop > (size_t) (MAX_ALLOC_CHUNK-min_request))
295
    if (slop > (size_t) (MAX_ALLOC_CHUNK-min_request))
296
      slop = (size_t) (MAX_ALLOC_CHUNK-min_request);
296
      slop = (size_t) (MAX_ALLOC_CHUNK-min_request);
297
    /* Try to get space, if fail reduce slop and try again */
297
    /* Try to get space, if fail reduce slop and try again */
 Lines 300-329   alloc_small (j_common_ptr cinfo, int poo Link Here 
300
      if (hdr_ptr != NULL)
300
      if (hdr_ptr != NULL)
301
	break;
301
	break;
302
      slop /= 2;
302
      slop /= 2;
303
      if (slop < MIN_SLOP)	/* give up when it gets real small */
303
      if (slop < MIN_SLOP)	/* give up when it gets real small */
304
	out_of_memory(cinfo, 2); /* jpeg_get_small failed */
304
	out_of_memory(cinfo, 2); /* jpeg_get_small failed */
305
    }
305
    }
306
    mem->total_space_allocated += min_request + slop;
306
    mem->total_space_allocated += min_request + slop;
307
    /* Success, initialize the new pool header and add to end of list */
307
    /* Success, initialize the new pool header and add to end of list */
308
    hdr_ptr->hdr.next = NULL;
308
    hdr_ptr->next = NULL;
309
    hdr_ptr->hdr.bytes_used = 0;
309
    hdr_ptr->bytes_used = 0;
310
    hdr_ptr->hdr.bytes_left = sizeofobject + slop;
310
    hdr_ptr->bytes_left = sizeofobject + slop;
311
    if (prev_hdr_ptr == NULL)	/* first pool in class? */
311
    if (prev_hdr_ptr == NULL)	/* first pool in class? */
312
      mem->small_list[pool_id] = hdr_ptr;
312
      mem->small_list[pool_id] = hdr_ptr;
313
    else
313
    else
314
      prev_hdr_ptr->hdr.next = hdr_ptr;
314
      prev_hdr_ptr->next = hdr_ptr;
315
  }
315
  }
316
316
317
  /* OK, allocate the object from the current pool */
317
  /* OK, allocate the object from the current pool */
318
  data_ptr = (char *) (hdr_ptr + 1); /* point to first data byte in pool */
318
  data_ptr = (char *) hdr_ptr; /* point to first data byte in pool... */
319
  data_ptr += hdr_ptr->hdr.bytes_used; /* point to place for object */
319
  data_ptr += SIZEOF(small_pool_hdr); /* ...by skipping the header... */
320
  hdr_ptr->hdr.bytes_used += sizeofobject;
320
  if ((size_t)data_ptr % ALIGN_SIZE) /* ...and adjust for alignment */
321
  hdr_ptr->hdr.bytes_left -= sizeofobject;
321
    data_ptr += ALIGN_SIZE - (size_t)data_ptr % ALIGN_SIZE;
322
  data_ptr += hdr_ptr->bytes_used; /* point to place for object */
323
  hdr_ptr->bytes_used += sizeofobject;
324
  hdr_ptr->bytes_left -= sizeofobject;
322
325
323
  return (void *) data_ptr;
326
  return (void *) data_ptr;
324
}
327
}
325
328
326
329
327
/*
330
/*
328
 * Allocation of "large" objects.
331
 * Allocation of "large" objects.
329
 *
332
 *
 Lines 339-412   alloc_small (j_common_ptr cinfo, int poo Link Here 
339
 */
342
 */
340
343
341
METHODDEF(void FAR *)
344
METHODDEF(void FAR *)
342
alloc_large (j_common_ptr cinfo, int pool_id, size_t sizeofobject)
345
alloc_large (j_common_ptr cinfo, int pool_id, size_t sizeofobject)
343
/* Allocate a "large" object */
346
/* Allocate a "large" object */
344
{
347
{
345
  my_mem_ptr mem = (my_mem_ptr) cinfo->mem;
348
  my_mem_ptr mem = (my_mem_ptr) cinfo->mem;
346
  large_pool_ptr hdr_ptr;
349
  large_pool_ptr hdr_ptr;
347
  size_t odd_bytes;
350
  char FAR * data_ptr;
351
352
  /*
353
   * Round up the requested size to a multiple of ALIGN_SIZE so that
354
   * algorithms can straddle outside the proper area up to the next
355
   * alignment.
356
   */
357
  sizeofobject = jround_up(sizeofobject, ALIGN_SIZE);
348
358
349
  /* Check for unsatisfiable request (do now to ensure no overflow below) */
359
  /* Check for unsatisfiable request (do now to ensure no overflow below) */
350
  if (sizeofobject > (size_t) (MAX_ALLOC_CHUNK-SIZEOF(large_pool_hdr)))
360
  if ((SIZEOF(large_pool_hdr) + sizeofobject + ALIGN_SIZE - 1) > MAX_ALLOC_CHUNK)
351
    out_of_memory(cinfo, 3);	/* request exceeds malloc's ability */
361
    out_of_memory(cinfo, 3);	/* request exceeds malloc's ability */
352
362
353
  /* Round up the requested size to a multiple of SIZEOF(ALIGN_TYPE) */
354
  odd_bytes = sizeofobject % SIZEOF(ALIGN_TYPE);
355
  if (odd_bytes > 0)
356
    sizeofobject += SIZEOF(ALIGN_TYPE) - odd_bytes;
357
358
  /* Always make a new pool */
363
  /* Always make a new pool */
359
  if (pool_id < 0 || pool_id >= JPOOL_NUMPOOLS)
364
  if (pool_id < 0 || pool_id >= JPOOL_NUMPOOLS)
360
    ERREXIT1(cinfo, JERR_BAD_POOL_ID, pool_id);	/* safety check */
365
    ERREXIT1(cinfo, JERR_BAD_POOL_ID, pool_id);	/* safety check */
361
366
362
  hdr_ptr = (large_pool_ptr) jpeg_get_large(cinfo, sizeofobject +
367
  hdr_ptr = (large_pool_ptr) jpeg_get_large(cinfo, sizeofobject +
363
					    SIZEOF(large_pool_hdr));
368
					    SIZEOF(large_pool_hdr) +
369
					    ALIGN_SIZE - 1);
364
  if (hdr_ptr == NULL)
370
  if (hdr_ptr == NULL)
365
    out_of_memory(cinfo, 4);	/* jpeg_get_large failed */
371
    out_of_memory(cinfo, 4);	/* jpeg_get_large failed */
366
  mem->total_space_allocated += sizeofobject + SIZEOF(large_pool_hdr);
372
  mem->total_space_allocated += sizeofobject + SIZEOF(large_pool_hdr) + ALIGN_SIZE - 1;
367
373
368
  /* Success, initialize the new pool header and add to list */
374
  /* Success, initialize the new pool header and add to list */
369
  hdr_ptr->hdr.next = mem->large_list[pool_id];
375
  hdr_ptr->next = mem->large_list[pool_id];
370
  /* We maintain space counts in each pool header for statistical purposes,
376
  /* We maintain space counts in each pool header for statistical purposes,
371
   * even though they are not needed for allocation.
377
   * even though they are not needed for allocation.
372
   */
378
   */
373
  hdr_ptr->hdr.bytes_used = sizeofobject;
379
  hdr_ptr->bytes_used = sizeofobject;
374
  hdr_ptr->hdr.bytes_left = 0;
380
  hdr_ptr->bytes_left = 0;
375
  mem->large_list[pool_id] = hdr_ptr;
381
  mem->large_list[pool_id] = hdr_ptr;
376
382
377
  return (void FAR *) (hdr_ptr + 1); /* point to first data byte in pool */
383
  data_ptr = (char *) hdr_ptr; /* point to first data byte in pool... */
384
  data_ptr += SIZEOF(small_pool_hdr); /* ...by skipping the header... */
385
  if ((size_t)data_ptr % ALIGN_SIZE) /* ...and adjust for alignment */
386
    data_ptr += ALIGN_SIZE - (size_t)data_ptr % ALIGN_SIZE;
387
388
  return (void FAR *) data_ptr;
378
}
389
}
379
390
380
391
381
/*
392
/*
382
 * Creation of 2-D sample arrays.
393
 * Creation of 2-D sample arrays.
383
 * The pointers are in near heap, the samples themselves in FAR heap.
394
 * The pointers are in near heap, the samples themselves in FAR heap.
384
 *
395
 *
385
 * To minimize allocation overhead and to allow I/O of large contiguous
396
 * To minimize allocation overhead and to allow I/O of large contiguous
386
 * blocks, we allocate the sample rows in groups of as many rows as possible
397
 * blocks, we allocate the sample rows in groups of as many rows as possible
387
 * without exceeding MAX_ALLOC_CHUNK total bytes per allocation request.
398
 * without exceeding MAX_ALLOC_CHUNK total bytes per allocation request.
388
 * NB: the virtual array control routines, later in this file, know about
399
 * NB: the virtual array control routines, later in this file, know about
389
 * this chunking of rows.  The rowsperchunk value is left in the mem manager
400
 * this chunking of rows.  The rowsperchunk value is left in the mem manager
390
 * object so that it can be saved away if this sarray is the workspace for
401
 * object so that it can be saved away if this sarray is the workspace for
391
 * a virtual array.
402
 * a virtual array.
403
 *
404
 * Since we are often upsampling with a factor 2, we align the size (not
405
 * the start) to 2 * ALIGN_SIZE so that the upsampling routines don't have
406
 * to be as careful about size.
392
 */
407
 */
393
408
394
METHODDEF(JSAMPARRAY)
409
METHODDEF(JSAMPARRAY)
395
alloc_sarray (j_common_ptr cinfo, int pool_id,
410
alloc_sarray (j_common_ptr cinfo, int pool_id,
396
	      JDIMENSION samplesperrow, JDIMENSION numrows)
411
	      JDIMENSION samplesperrow, JDIMENSION numrows)
397
/* Allocate a 2-D sample array */
412
/* Allocate a 2-D sample array */
398
{
413
{
399
  my_mem_ptr mem = (my_mem_ptr) cinfo->mem;
414
  my_mem_ptr mem = (my_mem_ptr) cinfo->mem;
400
  JSAMPARRAY result;
415
  JSAMPARRAY result;
401
  JSAMPROW workspace;
416
  JSAMPROW workspace;
402
  JDIMENSION rowsperchunk, currow, i;
417
  JDIMENSION rowsperchunk, currow, i;
403
  long ltemp;
418
  long ltemp;
404
419
420
  /* Make sure each row is properly aligned */
421
  if ((ALIGN_SIZE % SIZEOF(JSAMPLE)) != 0)
422
    out_of_memory(cinfo, 5);	/* safety check */
423
  samplesperrow = (JDIMENSION)jround_up(samplesperrow, (2 * ALIGN_SIZE) / SIZEOF(JSAMPLE));
424
405
  /* Calculate max # of rows allowed in one allocation chunk */
425
  /* Calculate max # of rows allowed in one allocation chunk */
406
  ltemp = (MAX_ALLOC_CHUNK-SIZEOF(large_pool_hdr)) /
426
  ltemp = (MAX_ALLOC_CHUNK-SIZEOF(large_pool_hdr)) /
407
	  ((long) samplesperrow * SIZEOF(JSAMPLE));
427
	  ((long) samplesperrow * SIZEOF(JSAMPLE));
408
  if (ltemp <= 0)
428
  if (ltemp <= 0)
409
    ERREXIT(cinfo, JERR_WIDTH_OVERFLOW);
429
    ERREXIT(cinfo, JERR_WIDTH_OVERFLOW);
410
  if (ltemp < (long) numrows)
430
  if (ltemp < (long) numrows)
411
    rowsperchunk = (JDIMENSION) ltemp;
431
    rowsperchunk = (JDIMENSION) ltemp;
412
  else
432
  else
 Lines 445-460   alloc_barray (j_common_ptr cinfo, int po Link Here 
445
/* Allocate a 2-D coefficient-block array */
465
/* Allocate a 2-D coefficient-block array */
446
{
466
{
447
  my_mem_ptr mem = (my_mem_ptr) cinfo->mem;
467
  my_mem_ptr mem = (my_mem_ptr) cinfo->mem;
448
  JBLOCKARRAY result;
468
  JBLOCKARRAY result;
449
  JBLOCKROW workspace;
469
  JBLOCKROW workspace;
450
  JDIMENSION rowsperchunk, currow, i;
470
  JDIMENSION rowsperchunk, currow, i;
451
  long ltemp;
471
  long ltemp;
452
472
473
  /* Make sure each row is properly aligned */
474
  if ((SIZEOF(JBLOCK) % ALIGN_SIZE) != 0)
475
    out_of_memory(cinfo, 6);	/* safety check */
476
453
  /* Calculate max # of rows allowed in one allocation chunk */
477
  /* Calculate max # of rows allowed in one allocation chunk */
454
  ltemp = (MAX_ALLOC_CHUNK-SIZEOF(large_pool_hdr)) /
478
  ltemp = (MAX_ALLOC_CHUNK-SIZEOF(large_pool_hdr)) /
455
	  ((long) blocksperrow * SIZEOF(JBLOCK));
479
	  ((long) blocksperrow * SIZEOF(JBLOCK));
456
  if (ltemp <= 0)
480
  if (ltemp <= 0)
457
    ERREXIT(cinfo, JERR_WIDTH_OVERFLOW);
481
    ERREXIT(cinfo, JERR_WIDTH_OVERFLOW);
458
  if (ltemp < (long) numrows)
482
  if (ltemp < (long) numrows)
459
    rowsperchunk = (JDIMENSION) ltemp;
483
    rowsperchunk = (JDIMENSION) ltemp;
460
  else
484
  else
 Lines 579-596   request_virt_barray (j_common_ptr cinfo, Link Here 
579
}
603
}
580
604
581
605
582
METHODDEF(void)
606
METHODDEF(void)
583
realize_virt_arrays (j_common_ptr cinfo)
607
realize_virt_arrays (j_common_ptr cinfo)
584
/* Allocate the in-memory buffers for any unrealized virtual arrays */
608
/* Allocate the in-memory buffers for any unrealized virtual arrays */
585
{
609
{
586
  my_mem_ptr mem = (my_mem_ptr) cinfo->mem;
610
  my_mem_ptr mem = (my_mem_ptr) cinfo->mem;
587
  long space_per_minheight, maximum_space, avail_mem;
611
  size_t space_per_minheight, maximum_space, avail_mem;
588
  long minheights, max_minheights;
612
  size_t minheights, max_minheights;
589
  jvirt_sarray_ptr sptr;
613
  jvirt_sarray_ptr sptr;
590
  jvirt_barray_ptr bptr;
614
  jvirt_barray_ptr bptr;
591
615
592
  /* Compute the minimum space needed (maxaccess rows in each buffer)
616
  /* Compute the minimum space needed (maxaccess rows in each buffer)
593
   * and the maximum space needed (full image height in each buffer).
617
   * and the maximum space needed (full image height in each buffer).
594
   * These may be of use to the system-dependent jpeg_mem_available routine.
618
   * These may be of use to the system-dependent jpeg_mem_available routine.
595
   */
619
   */
596
  space_per_minheight = 0;
620
  space_per_minheight = 0;
 Lines 963-995   free_pool (j_common_ptr cinfo, int pool_ Link Here 
963
    mem->virt_barray_list = NULL;
987
    mem->virt_barray_list = NULL;
964
  }
988
  }
965
989
966
  /* Release large objects */
990
  /* Release large objects */
967
  lhdr_ptr = mem->large_list[pool_id];
991
  lhdr_ptr = mem->large_list[pool_id];
968
  mem->large_list[pool_id] = NULL;
992
  mem->large_list[pool_id] = NULL;
969
993
970
  while (lhdr_ptr != NULL) {
994
  while (lhdr_ptr != NULL) {
971
    large_pool_ptr next_lhdr_ptr = lhdr_ptr->hdr.next;
995
    large_pool_ptr next_lhdr_ptr = lhdr_ptr->next;
972
    space_freed = lhdr_ptr->hdr.bytes_used +
996
    space_freed = lhdr_ptr->bytes_used +
973
		  lhdr_ptr->hdr.bytes_left +
997
		  lhdr_ptr->bytes_left +
974
		  SIZEOF(large_pool_hdr);
998
		  SIZEOF(large_pool_hdr);
975
    jpeg_free_large(cinfo, (void FAR *) lhdr_ptr, space_freed);
999
    jpeg_free_large(cinfo, (void FAR *) lhdr_ptr, space_freed);
976
    mem->total_space_allocated -= space_freed;
1000
    mem->total_space_allocated -= space_freed;
977
    lhdr_ptr = next_lhdr_ptr;
1001
    lhdr_ptr = next_lhdr_ptr;
978
  }
1002
  }
979
1003
980
  /* Release small objects */
1004
  /* Release small objects */
981
  shdr_ptr = mem->small_list[pool_id];
1005
  shdr_ptr = mem->small_list[pool_id];
982
  mem->small_list[pool_id] = NULL;
1006
  mem->small_list[pool_id] = NULL;
983
1007
984
  while (shdr_ptr != NULL) {
1008
  while (shdr_ptr != NULL) {
985
    small_pool_ptr next_shdr_ptr = shdr_ptr->hdr.next;
1009
    small_pool_ptr next_shdr_ptr = shdr_ptr->next;
986
    space_freed = shdr_ptr->hdr.bytes_used +
1010
    space_freed = shdr_ptr->bytes_used +
987
		  shdr_ptr->hdr.bytes_left +
1011
		  shdr_ptr->bytes_left +
988
		  SIZEOF(small_pool_hdr);
1012
		  SIZEOF(small_pool_hdr);
989
    jpeg_free_small(cinfo, (void *) shdr_ptr, space_freed);
1013
    jpeg_free_small(cinfo, (void *) shdr_ptr, space_freed);
990
    mem->total_space_allocated -= space_freed;
1014
    mem->total_space_allocated -= space_freed;
991
    shdr_ptr = next_shdr_ptr;
1015
    shdr_ptr = next_shdr_ptr;
992
  }
1016
  }
993
}
1017
}
994
1018
995
1019
 Lines 1036-1061   jinit_memory_mgr (j_common_ptr cinfo) Link Here 
1036
1060
1037
  /* Check for configuration errors.
1061
  /* Check for configuration errors.
1038
   * SIZEOF(ALIGN_TYPE) should be a power of 2; otherwise, it probably
1062
   * SIZEOF(ALIGN_TYPE) should be a power of 2; otherwise, it probably
1039
   * doesn't reflect any real hardware alignment requirement.
1063
   * doesn't reflect any real hardware alignment requirement.
1040
   * The test is a little tricky: for X>0, X and X-1 have no one-bits
1064
   * The test is a little tricky: for X>0, X and X-1 have no one-bits
1041
   * in common if and only if X is a power of 2, ie has only one one-bit.
1065
   * in common if and only if X is a power of 2, ie has only one one-bit.
1042
   * Some compilers may give an "unreachable code" warning here; ignore it.
1066
   * Some compilers may give an "unreachable code" warning here; ignore it.
1043
   */
1067
   */
1044
  if ((SIZEOF(ALIGN_TYPE) & (SIZEOF(ALIGN_TYPE)-1)) != 0)
1068
  if ((ALIGN_SIZE & (ALIGN_SIZE-1)) != 0)
1045
    ERREXIT(cinfo, JERR_BAD_ALIGN_TYPE);
1069
    ERREXIT(cinfo, JERR_BAD_ALIGN_TYPE);
1046
  /* MAX_ALLOC_CHUNK must be representable as type size_t, and must be
1070
  /* MAX_ALLOC_CHUNK must be representable as type size_t, and must be
1047
   * a multiple of SIZEOF(ALIGN_TYPE).
1071
   * a multiple of ALIGN_SIZE.
1048
   * Again, an "unreachable code" warning may be ignored here.
1072
   * Again, an "unreachable code" warning may be ignored here.
1049
   * But a "constant too large" warning means you need to fix MAX_ALLOC_CHUNK.
1073
   * But a "constant too large" warning means you need to fix MAX_ALLOC_CHUNK.
1050
   */
1074
   */
1051
  test_mac = (size_t) MAX_ALLOC_CHUNK;
1075
  test_mac = (size_t) MAX_ALLOC_CHUNK;
1052
  if ((long) test_mac != MAX_ALLOC_CHUNK ||
1076
  if ((long) test_mac != MAX_ALLOC_CHUNK ||
1053
      (MAX_ALLOC_CHUNK % SIZEOF(ALIGN_TYPE)) != 0)
1077
      (MAX_ALLOC_CHUNK % ALIGN_SIZE) != 0)
1054
    ERREXIT(cinfo, JERR_BAD_ALLOC_CHUNK);
1078
    ERREXIT(cinfo, JERR_BAD_ALLOC_CHUNK);
1055
1079
1056
  max_to_use = jpeg_mem_init(cinfo); /* system-dependent initialization */
1080
  max_to_use = jpeg_mem_init(cinfo); /* system-dependent initialization */
1057
1081
1058
  /* Attempt to allocate memory manager's control block */
1082
  /* Attempt to allocate memory manager's control block */
1059
  mem = (my_mem_ptr) jpeg_get_small(cinfo, SIZEOF(my_memory_mgr));
1083
  mem = (my_mem_ptr) jpeg_get_small(cinfo, SIZEOF(my_memory_mgr));
1060
1084
1061
  if (mem == NULL) {
1085
  if (mem == NULL) {
(-)a/jpeg/jmemname.c (-276 lines)
Line     Link Here 
 Lines 1-276    Link Here 
1
/*
2
 * jmemname.c
3
 *
4
 * Copyright (C) 1992-1997, Thomas G. Lane.
5
 * This file is part of the Independent JPEG Group's software.
6
 * For conditions of distribution and use, see the accompanying README file.
7
 *
8
 * This file provides a generic implementation of the system-dependent
9
 * portion of the JPEG memory manager.  This implementation assumes that
10
 * you must explicitly construct a name for each temp file.
11
 * Also, the problem of determining the amount of memory available
12
 * is shoved onto the user.
13
 */
14
15
#define JPEG_INTERNALS
16
#include "jinclude.h"
17
#include "jpeglib.h"
18
#include "jmemsys.h"		/* import the system-dependent declarations */
19
20
#ifndef HAVE_STDLIB_H		/* <stdlib.h> should declare malloc(),free() */
21
extern void * malloc JPP((size_t size));
22
extern void free JPP((void *ptr));
23
#endif
24
25
#ifndef SEEK_SET		/* pre-ANSI systems may not define this; */
26
#define SEEK_SET  0		/* if not, assume 0 is correct */
27
#endif
28
29
#ifdef DONT_USE_B_MODE		/* define mode parameters for fopen() */
30
#define READ_BINARY	"r"
31
#define RW_BINARY	"w+"
32
#else
33
#ifdef VMS			/* VMS is very nonstandard */
34
#define READ_BINARY	"rb", "ctx=stm"
35
#define RW_BINARY	"w+b", "ctx=stm"
36
#else				/* standard ANSI-compliant case */
37
#define READ_BINARY	"rb"
38
#define RW_BINARY	"w+b"
39
#endif
40
#endif
41
42
43
/*
44
 * Selection of a file name for a temporary file.
45
 * This is system-dependent!
46
 *
47
 * The code as given is suitable for most Unix systems, and it is easily
48
 * modified for most non-Unix systems.  Some notes:
49
 *  1.  The temp file is created in the directory named by TEMP_DIRECTORY.
50
 *      The default value is /usr/tmp, which is the conventional place for
51
 *      creating large temp files on Unix.  On other systems you'll probably
52
 *      want to change the file location.  You can do this by editing the
53
 *      #define, or (preferred) by defining TEMP_DIRECTORY in jconfig.h.
54
 *
55
 *  2.  If you need to change the file name as well as its location,
56
 *      you can override the TEMP_FILE_NAME macro.  (Note that this is
57
 *      actually a printf format string; it must contain %s and %d.)
58
 *      Few people should need to do this.
59
 *
60
 *  3.  mktemp() is used to ensure that multiple processes running
61
 *      simultaneously won't select the same file names.  If your system
62
 *      doesn't have mktemp(), define NO_MKTEMP to do it the hard way.
63
 *      (If you don't have <errno.h>, also define NO_ERRNO_H.)
64
 *
65
 *  4.  You probably want to define NEED_SIGNAL_CATCHER so that cjpeg.c/djpeg.c
66
 *      will cause the temp files to be removed if you stop the program early.
67
 */
68
69
#ifndef TEMP_DIRECTORY		/* can override from jconfig.h or Makefile */
70
#define TEMP_DIRECTORY  "/usr/tmp/" /* recommended setting for Unix */
71
#endif
72
73
static int next_file_num;	/* to distinguish among several temp files */
74
75
#ifdef NO_MKTEMP
76
77
#ifndef TEMP_FILE_NAME		/* can override from jconfig.h or Makefile */
78
#define TEMP_FILE_NAME  "%sJPG%03d.TMP"
79
#endif
80
81
#ifndef NO_ERRNO_H
82
#include <errno.h>		/* to define ENOENT */
83
#endif
84
85
/* ANSI C specifies that errno is a macro, but on older systems it's more
86
 * likely to be a plain int variable.  And not all versions of errno.h
87
 * bother to declare it, so we have to in order to be most portable.  Thus:
88
 */
89
#ifndef errno
90
extern int errno;
91
#endif
92
93
94
LOCAL(void)
95
select_file_name (char * fname)
96
{
97
  FILE * tfile;
98
99
  /* Keep generating file names till we find one that's not in use */
100
  for (;;) {
101
    next_file_num++;		/* advance counter */
102
    sprintf(fname, TEMP_FILE_NAME, TEMP_DIRECTORY, next_file_num);
103
    if ((tfile = fopen(fname, READ_BINARY)) == NULL) {
104
      /* fopen could have failed for a reason other than the file not
105
       * being there; for example, file there but unreadable.
106
       * If <errno.h> isn't available, then we cannot test the cause.
107
       */
108
#ifdef ENOENT
109
      if (errno != ENOENT)
110
	continue;
111
#endif
112
      break;
113
    }
114
    fclose(tfile);		/* oops, it's there; close tfile & try again */
115
  }
116
}
117
118
#else /* ! NO_MKTEMP */
119
120
/* Note that mktemp() requires the initial filename to end in six X's */
121
#ifndef TEMP_FILE_NAME		/* can override from jconfig.h or Makefile */
122
#define TEMP_FILE_NAME  "%sJPG%dXXXXXX"
123
#endif
124
125
LOCAL(void)
126
select_file_name (char * fname)
127
{
128
  next_file_num++;		/* advance counter */
129
  sprintf(fname, TEMP_FILE_NAME, TEMP_DIRECTORY, next_file_num);
130
  mktemp(fname);		/* make sure file name is unique */
131
  /* mktemp replaces the trailing XXXXXX with a unique string of characters */
132
}
133
134
#endif /* NO_MKTEMP */
135
136
137
/*
138
 * Memory allocation and freeing are controlled by the regular library
139
 * routines malloc() and free().
140
 */
141
142
GLOBAL(void *)
143
jpeg_get_small (j_common_ptr cinfo, size_t sizeofobject)
144
{
145
  return (void *) malloc(sizeofobject);
146
}
147
148
GLOBAL(void)
149
jpeg_free_small (j_common_ptr cinfo, void * object, size_t sizeofobject)
150
{
151
  free(object);
152
}
153
154
155
/*
156
 * "Large" objects are treated the same as "small" ones.
157
 * NB: although we include FAR keywords in the routine declarations,
158
 * this file won't actually work in 80x86 small/medium model; at least,
159
 * you probably won't be able to process useful-size images in only 64KB.
160
 */
161
162
GLOBAL(void FAR *)
163
jpeg_get_large (j_common_ptr cinfo, size_t sizeofobject)
164
{
165
  return (void FAR *) malloc(sizeofobject);
166
}
167
168
GLOBAL(void)
169
jpeg_free_large (j_common_ptr cinfo, void FAR * object, size_t sizeofobject)
170
{
171
  free(object);
172
}
173
174
175
/*
176
 * This routine computes the total memory space available for allocation.
177
 * It's impossible to do this in a portable way; our current solution is
178
 * to make the user tell us (with a default value set at compile time).
179
 * If you can actually get the available space, it's a good idea to subtract
180
 * a slop factor of 5% or so.
181
 */
182
183
#ifndef DEFAULT_MAX_MEM		/* so can override from makefile */
184
#define DEFAULT_MAX_MEM		1000000L /* default: one megabyte */
185
#endif
186
187
GLOBAL(long)
188
jpeg_mem_available (j_common_ptr cinfo, long min_bytes_needed,
189
		    long max_bytes_needed, long already_allocated)
190
{
191
  return cinfo->mem->max_memory_to_use - already_allocated;
192
}
193
194
195
/*
196
 * Backing store (temporary file) management.
197
 * Backing store objects are only used when the value returned by
198
 * jpeg_mem_available is less than the total space needed.  You can dispense
199
 * with these routines if you have plenty of virtual memory; see jmemnobs.c.
200
 */
201
202
203
METHODDEF(void)
204
read_backing_store (j_common_ptr cinfo, backing_store_ptr info,
205
		    void FAR * buffer_address,
206
		    long file_offset, long byte_count)
207
{
208
  if (fseek(info->temp_file, file_offset, SEEK_SET))
209
    ERREXIT(cinfo, JERR_TFILE_SEEK);
210
  if (JFREAD(info->temp_file, buffer_address, byte_count)
211
      != (size_t) byte_count)
212
    ERREXIT(cinfo, JERR_TFILE_READ);
213
}
214
215
216
METHODDEF(void)
217
write_backing_store (j_common_ptr cinfo, backing_store_ptr info,
218
		     void FAR * buffer_address,
219
		     long file_offset, long byte_count)
220
{
221
  if (fseek(info->temp_file, file_offset, SEEK_SET))
222
    ERREXIT(cinfo, JERR_TFILE_SEEK);
223
  if (JFWRITE(info->temp_file, buffer_address, byte_count)
224
      != (size_t) byte_count)
225
    ERREXIT(cinfo, JERR_TFILE_WRITE);
226
}
227
228
229
METHODDEF(void)
230
close_backing_store (j_common_ptr cinfo, backing_store_ptr info)
231
{
232
  fclose(info->temp_file);	/* close the file */
233
  unlink(info->temp_name);	/* delete the file */
234
/* If your system doesn't have unlink(), use remove() instead.
235
 * remove() is the ANSI-standard name for this function, but if
236
 * your system was ANSI you'd be using jmemansi.c, right?
237
 */
238
  TRACEMSS(cinfo, 1, JTRC_TFILE_CLOSE, info->temp_name);
239
}
240
241
242
/*
243
 * Initial opening of a backing-store object.
244
 */
245
246
GLOBAL(void)
247
jpeg_open_backing_store (j_common_ptr cinfo, backing_store_ptr info,
248
			 long total_bytes_needed)
249
{
250
  select_file_name(info->temp_name);
251
  if ((info->temp_file = fopen(info->temp_name, RW_BINARY)) == NULL)
252
    ERREXITS(cinfo, JERR_TFILE_CREATE, info->temp_name);
253
  info->read_backing_store = read_backing_store;
254
  info->write_backing_store = write_backing_store;
255
  info->close_backing_store = close_backing_store;
256
  TRACEMSS(cinfo, 1, JTRC_TFILE_OPEN, info->temp_name);
257
}
258
259
260
/*
261
 * These routines take care of any system-dependent initialization and
262
 * cleanup required.
263
 */
264
265
GLOBAL(long)
266
jpeg_mem_init (j_common_ptr cinfo)
267
{
268
  next_file_num = 0;		/* initialize temp file name generator */
269
  return DEFAULT_MAX_MEM;	/* default for max_memory_to_use */
270
}
271
272
GLOBAL(void)
273
jpeg_mem_term (j_common_ptr cinfo)
274
{
275
  /* no work */
276
}
(-)a/jpeg/jmemnobs.c (-3 / +3 lines)
Line     Link Here 
 Lines 64-82   jpeg_free_large (j_common_ptr cinfo, voi Link Here 
64
}
64
}
65
65
66
66
67
/*
67
/*
68
 * This routine computes the total memory space available for allocation.
68
 * This routine computes the total memory space available for allocation.
69
 * Here we always say, "we got all you want bud!"
69
 * Here we always say, "we got all you want bud!"
70
 */
70
 */
71
71
72
GLOBAL(long)
72
GLOBAL(size_t)
73
jpeg_mem_available (j_common_ptr cinfo, long min_bytes_needed,
73
jpeg_mem_available (j_common_ptr cinfo, size_t min_bytes_needed,
74
		    long max_bytes_needed, long already_allocated)
74
		    size_t max_bytes_needed, size_t already_allocated)
75
{
75
{
76
  return max_bytes_needed;
76
  return max_bytes_needed;
77
}
77
}
78
78
79
79
80
/*
80
/*
81
 * Backing store (temporary file) management.
81
 * Backing store (temporary file) management.
82
 * Since jpeg_mem_available always promised the moon,
82
 * Since jpeg_mem_available always promised the moon,
(-)a/jpeg/jmemsys.h (-4 / +4 lines)
Line     Link Here 
 Lines 95-114   EXTERN(void) jpeg_free_large JPP((j_comm Link Here 
95
 * (that'll just lead to more backing-store access than is really necessary).
95
 * (that'll just lead to more backing-store access than is really necessary).
96
 * However, an overestimate will lead to failure.  Hence it's wise to subtract
96
 * However, an overestimate will lead to failure.  Hence it's wise to subtract
97
 * a slop factor from the true available space.  5% should be enough.
97
 * a slop factor from the true available space.  5% should be enough.
98
 *
98
 *
99
 * On machines with lots of virtual memory, any large constant may be returned.
99
 * On machines with lots of virtual memory, any large constant may be returned.
100
 * Conversely, zero may be returned to always use the minimum amount of memory.
100
 * Conversely, zero may be returned to always use the minimum amount of memory.
101
 */
101
 */
102
102
103
EXTERN(long) jpeg_mem_available JPP((j_common_ptr cinfo,
103
EXTERN(size_t) jpeg_mem_available JPP((j_common_ptr cinfo,
104
				     long min_bytes_needed,
104
				     size_t min_bytes_needed,
105
				     long max_bytes_needed,
105
				     size_t max_bytes_needed,
106
				     long already_allocated));
106
				     size_t already_allocated));
107
107
108
108
109
/*
109
/*
110
 * This structure holds whatever state is needed to access a single
110
 * This structure holds whatever state is needed to access a single
111
 * backing-store object.  The read/write/close method pointers are called
111
 * backing-store object.  The read/write/close method pointers are called
112
 * by jmemmgr.c to manipulate the backing-store object; all other fields
112
 * by jmemmgr.c to manipulate the backing-store object; all other fields
113
 * are private to the system-dependent backing store routines.
113
 * are private to the system-dependent backing store routines.
114
 */
114
 */
(-)a/jpeg/jmorecfg.h (-119 / +43 lines)
Line     Link Here 
 Lines 1-27    Link Here 
1
/*
1
/*
2
 * jmorecfg.h
2
 * jmorecfg.h
3
 *
3
 *
4
 * Copyright (C) 1991-1997, Thomas G. Lane.
4
 * Copyright (C) 1991-1997, Thomas G. Lane.
5
 * Copyright (C) 2009, D. R. Commander.
5
 * This file is part of the Independent JPEG Group's software.
6
 * This file is part of the Independent JPEG Group's software.
6
 * For conditions of distribution and use, see the accompanying README file.
7
 * For conditions of distribution and use, see the accompanying README file.
7
 *
8
 *
8
 * This file contains additional configuration options that customize the
9
 * This file contains additional configuration options that customize the
9
 * JPEG software for special applications or support machine-dependent
10
 * JPEG software for special applications or support machine-dependent
10
 * optimizations.  Most users will not need to touch this file.
11
 * optimizations.  Most users will not need to touch this file.
11
 */
12
 */
12
13
13
/*
14
#include "prtypes.h"
14
 * This file has been modified for the Mozilla/Netscape environment.
15
 * Modifications are distributed under the mozilla.org tri-license and are
16
 * Copyright (C) 1998 Netscape Communications Corporation.  All Rights
17
 * Reserved. See http://www.mozilla.org/MPL/
18
 */
19
20
15
21
/*
16
/*
22
 * Define BITS_IN_JSAMPLE as either
17
 * Define BITS_IN_JSAMPLE as either
23
 *   8   for 8-bit sample values (the usual setting)
18
 *   8   for 8-bit sample values (the usual setting)
24
 *   12  for 12-bit sample values
19
 *   12  for 12-bit sample values
25
 * Only 8 and 12 are legal data precisions for lossy JPEG according to the
20
 * Only 8 and 12 are legal data precisions for lossy JPEG according to the
26
 * JPEG standard, and the IJG code does not support anything else!
21
 * JPEG standard, and the IJG code does not support anything else!
27
 * We do not support run-time selection of data precision, sorry.
22
 * We do not support run-time selection of data precision, sorry.
 Lines 64-84    Link Here 
64
#ifdef HAVE_UNSIGNED_CHAR
59
#ifdef HAVE_UNSIGNED_CHAR
65
60
66
typedef unsigned char JSAMPLE;
61
typedef unsigned char JSAMPLE;
67
#define GETJSAMPLE(value)  ((int) (value))
62
#define GETJSAMPLE(value)  ((int) (value))
68
63
69
#else /* not HAVE_UNSIGNED_CHAR */
64
#else /* not HAVE_UNSIGNED_CHAR */
70
65
71
typedef char JSAMPLE;
66
typedef char JSAMPLE;
72
#ifdef CHAR_IS_UNSIGNED
67
#ifdef __CHAR_UNSIGNED__
73
#define GETJSAMPLE(value)  ((int) (value))
68
#define GETJSAMPLE(value)  ((int) (value))
74
#else
69
#else
75
#define GETJSAMPLE(value)  ((int) (value) & 0xFF)
70
#define GETJSAMPLE(value)  ((int) (value) & 0xFF)
76
#endif /* CHAR_IS_UNSIGNED */
71
#endif /* __CHAR_UNSIGNED__ */
77
72
78
#endif /* HAVE_UNSIGNED_CHAR */
73
#endif /* HAVE_UNSIGNED_CHAR */
79
74
80
#define MAXJSAMPLE	255
75
#define MAXJSAMPLE	255
81
#define CENTERJSAMPLE	128
76
#define CENTERJSAMPLE	128
82
77
83
#endif /* BITS_IN_JSAMPLE == 8 */
78
#endif /* BITS_IN_JSAMPLE == 8 */
84
79
 Lines 100-199   typedef short JSAMPLE; Link Here 
100
/* Representation of a DCT frequency coefficient.
95
/* Representation of a DCT frequency coefficient.
101
 * This should be a signed value of at least 16 bits; "short" is usually OK.
96
 * This should be a signed value of at least 16 bits; "short" is usually OK.
102
 * Again, we allocate large arrays of these, but you can change to int
97
 * Again, we allocate large arrays of these, but you can change to int
103
 * if you have memory to burn and "short" is really slow.
98
 * if you have memory to burn and "short" is really slow.
104
 */
99
 */
105
100
106
typedef short JCOEF;
101
typedef short JCOEF;
107
102
108
/* Defines for MMX/SSE2 support. */
109
110
#if defined(XP_WIN32) && defined(_M_IX86) && !defined(__GNUC__)
111
#define HAVE_MMX_INTEL_MNEMONICS 
112
113
/* SSE2 code appears broken for some cpus (bug 247437) */
114
#define HAVE_SSE2_INTEL_MNEMONICS
115
#define HAVE_SSE2_INTRINSICS
116
#endif
117
118
#if defined(__GNUC__) && defined(__i386__)
119
#if defined(XP_MACOSX)
120
#define HAVE_SSE2_INTRINSICS
121
#endif /* ! XP_MACOSX */
122
#endif /* ! GNUC && i386 */
123
124
/* Add support for other platforms here */
125
126
103
127
/* Compressed datastreams are represented as arrays of JOCTET.
104
/* Compressed datastreams are represented as arrays of JOCTET.
128
 * These must be EXACTLY 8 bits wide, at least once they are written to
105
 * These must be EXACTLY 8 bits wide, at least once they are written to
129
 * external storage.  Note that when using the stdio data source/destination
106
 * external storage.  Note that when using the stdio data source/destination
130
 * managers, this is also the data type passed to fread/fwrite.
107
 * managers, this is also the data type passed to fread/fwrite.
131
 */
108
 */
132
109
133
#ifdef HAVE_UNSIGNED_CHAR
110
#ifdef HAVE_UNSIGNED_CHAR
134
111
135
typedef unsigned char JOCTET;
112
typedef unsigned char JOCTET;
136
#define GETJOCTET(value)  (value)
113
#define GETJOCTET(value)  (value)
137
114
138
#else /* not HAVE_UNSIGNED_CHAR */
115
#else /* not HAVE_UNSIGNED_CHAR */
139
116
140
typedef char JOCTET;
117
typedef char JOCTET;
141
#ifdef CHAR_IS_UNSIGNED
118
#ifdef __CHAR_UNSIGNED__
142
#define GETJOCTET(value)  (value)
119
#define GETJOCTET(value)  (value)
143
#else
120
#else
144
#define GETJOCTET(value)  ((value) & 0xFF)
121
#define GETJOCTET(value)  ((value) & 0xFF)
145
#endif /* CHAR_IS_UNSIGNED */
122
#endif /* __CHAR_UNSIGNED__ */
146
123
147
#endif /* HAVE_UNSIGNED_CHAR */
124
#endif /* HAVE_UNSIGNED_CHAR */
148
125
149
126
150
/* These typedefs are used for various table entries and so forth.
127
/* These typedefs are used for various table entries and so forth.
151
 * They must be at least as wide as specified; but making them too big
128
 * They must be at least as wide as specified; but making them too big
152
 * won't cost a huge amount of memory, so we don't provide special
129
 * won't cost a huge amount of memory, so we don't provide special
153
 * extraction code like we did for JSAMPLE.  (In other words, these
130
 * extraction code like we did for JSAMPLE.  (In other words, these
154
 * typedefs live at a different point on the speed/space tradeoff curve.)
131
 * typedefs live at a different point on the speed/space tradeoff curve.)
155
 */
132
 */
156
133
157
/* UINT8 must hold at least the values 0..255. */
134
/* UINT8 must hold at least the values 0..255. */
158
135
159
#ifdef HAVE_UNSIGNED_CHAR
136
typedef PRUint8 UINT8;
160
typedef unsigned char UINT8;
161
#else /* not HAVE_UNSIGNED_CHAR */
162
#ifdef CHAR_IS_UNSIGNED
163
typedef char UINT8;
164
#else /* not CHAR_IS_UNSIGNED */
165
typedef short UINT8;
166
#endif /* CHAR_IS_UNSIGNED */
167
#endif /* HAVE_UNSIGNED_CHAR */
168
137
169
/* UINT16 must hold at least the values 0..65535. */
138
/* UINT16 must hold at least the values 0..65535. */
170
139
171
#ifdef HAVE_UNSIGNED_SHORT
140
typedef PRUint16 UINT16;
172
typedef unsigned short UINT16;
173
#else /* not HAVE_UNSIGNED_SHORT */
174
typedef unsigned int UINT16;
175
#endif /* HAVE_UNSIGNED_SHORT */
176
141
177
/* INT16 must hold at least the values -32768..32767. */
142
/* INT16 must hold at least the values -32768..32767. */
178
143
179
#ifndef XMD_H			/* X11/xmd.h correctly defines INT16 */
144
typedef PRInt16 INT16;
180
typedef short INT16;
181
#endif
182
145
183
/* INT32 must hold at least signed 32-bit values. */
146
/* INT32 must hold at least signed 32-bit values. */
184
147
185
#ifndef XMD_H			/* X11/xmd.h correctly defines INT32 */
148
typedef PRInt32 INT32;
186
#ifndef _BASETSD_H_		/* basetsd.h correctly defines INT32 */
187
#ifndef _BASETSD_H
188
typedef long INT32;
189
#endif
190
#endif
191
#endif
192
149
193
/* Datatype used for image dimensions.  The JPEG standard only supports
150
/* Datatype used for image dimensions.  The JPEG standard only supports
194
 * images up to 64K*64K due to 16-bit fields in SOF markers.  Therefore
151
 * images up to 64K*64K due to 16-bit fields in SOF markers.  Therefore
195
 * "unsigned int" is sufficient on all machines.  However, if you need to
152
 * "unsigned int" is sufficient on all machines.  However, if you need to
196
 * handle larger images and you don't mind deviating from the spec, you
153
 * handle larger images and you don't mind deviating from the spec, you
197
 * can change this datatype.
154
 * can change this datatype.
198
 */
155
 */
199
156
 Lines 204-234   typedef unsigned int JDIMENSION; Link Here 
204
161
205
/* These macros are used in all function definitions and extern declarations.
162
/* These macros are used in all function definitions and extern declarations.
206
 * You could modify them if you need to change function linkage conventions;
163
 * You could modify them if you need to change function linkage conventions;
207
 * in particular, you'll need to do that to make the library a Windows DLL.
164
 * in particular, you'll need to do that to make the library a Windows DLL.
208
 * Another application is to make all functions global for use with debuggers
165
 * Another application is to make all functions global for use with debuggers
209
 * or code profilers that require it.
166
 * or code profilers that require it.
210
 */
167
 */
211
168
212
/* Mozilla mod: make external functions be DLL-able via JRI_PUBLIC_API(),
213
 * and supply extern "C" for C++ users of the C-compiled IJG library.
214
 * (Well, not anymore, but there's still a modification here.)
215
 */
216
#include "prtypes.h"
217
218
/* a function called through method pointers: */
169
/* a function called through method pointers: */
219
#define METHODDEF(type)		static type
170
#define METHODDEF(type)		static type
220
/* a function used only in its module: */
171
/* a function used only in its module: */
221
#define LOCAL(type)		static type
172
#define LOCAL(type)		static type
222
173
/* a function referenced thru EXTERNs: */
223
PR_BEGIN_EXTERN_C
174
#define GLOBAL(type)		type
224
#define GLOBAL(type) type
175
/* a reference to a GLOBAL function: */
225
#define EXTERN(type) extern type
176
#define EXTERN(type)		extern type
226
PR_END_EXTERN_C
227
177
228
178
229
/* This macro is used to declare a "method", that is, a function pointer.
179
/* This macro is used to declare a "method", that is, a function pointer.
230
 * We want to supply prototype parameters if the compiler can cope.
180
 * We want to supply prototype parameters if the compiler can cope.
231
 * Note that the arglist parameter must be parenthesized!
181
 * Note that the arglist parameter must be parenthesized!
232
 * Again, you can customize this if you need special linkage keywords.
182
 * Again, you can customize this if you need special linkage keywords.
233
 */
183
 */
234
184
 Lines 240-285   PR_END_EXTERN_C Link Here 
240
190
241
191
242
/* Here is the pseudo-keyword for declaring pointers that must be "far"
192
/* Here is the pseudo-keyword for declaring pointers that must be "far"
243
 * on 80x86 machines.  Most of the specialized coding for 80x86 is handled
193
 * on 80x86 machines.  Most of the specialized coding for 80x86 is handled
244
 * by just saying "FAR *" where such a pointer is needed.  In a few places
194
 * by just saying "FAR *" where such a pointer is needed.  In a few places
245
 * explicit coding is needed; see uses of the NEED_FAR_POINTERS symbol.
195
 * explicit coding is needed; see uses of the NEED_FAR_POINTERS symbol.
246
 */
196
 */
247
197
248
#ifndef FAR
249
#ifdef NEED_FAR_POINTERS
198
#ifdef NEED_FAR_POINTERS
250
#define FAR  far
199
#define FAR  far
251
#else
200
#else
252
#define FAR
201
#define FAR
253
#endif
202
#endif
254
#endif
255
203
256
204
257
/*
205
/*
258
 * On a few systems, type boolean and/or its values FALSE, TRUE may appear
206
 * On a few systems, type boolean and/or its values FALSE, TRUE may appear
259
 * in standard header files.  Or you may have conflicts with application-
207
 * in standard header files.  Or you may have conflicts with application-
260
 * specific header files that you want to include together with these files.
208
 * specific header files that you want to include together with these files.
261
 * Defining HAVE_BOOLEAN before including jpeglib.h should make it work.
209
 * Defining HAVE_BOOLEAN before including jpeglib.h should make it work.
262
 */
210
 */
263
211
264
/* Mozilla mod: IJG distribution makes boolean = int, but on Windows
265
 * it's far safer to define boolean = unsigned char.  Easier to switch
266
 * than fight.
267
 */
268
269
/* For some reason, on SunOS 5.3 HAVE_BOOLEAN gets defined when using
270
 * gcc, but boolean doesn't.  Even if you use -UHAVE_BOOLEAN, it still
271
 * gets reset somewhere.
272
 */
273
#if defined(MUST_UNDEF_HAVE_BOOLEAN_AFTER_INCLUDES) && defined(HAVE_BOOLEAN)
274
#undef HAVE_BOOLEAN
275
#endif
276
#ifndef HAVE_BOOLEAN
212
#ifndef HAVE_BOOLEAN
277
typedef unsigned char boolean;
213
typedef int boolean;
278
#endif
214
#endif
279
#ifndef FALSE			/* in case these macros already exist */
215
#ifndef FALSE			/* in case these macros already exist */
280
#define FALSE	0		/* values of boolean */
216
#define FALSE	0		/* values of boolean */
281
#endif
217
#endif
282
#ifndef TRUE
218
#ifndef TRUE
283
#define TRUE	1
219
#define TRUE	1
284
#endif
220
#endif
285
221
 Lines 301-361   typedef unsigned char boolean; Link Here 
301
/*
237
/*
302
 * These defines indicate whether to include various optional functions.
238
 * These defines indicate whether to include various optional functions.
303
 * Undefining some of these symbols will produce a smaller but less capable
239
 * Undefining some of these symbols will produce a smaller but less capable
304
 * library.  Note that you can leave certain source files out of the
240
 * library.  Note that you can leave certain source files out of the
305
 * compilation/linking process if you've #undef'd the corresponding symbols.
241
 * compilation/linking process if you've #undef'd the corresponding symbols.
306
 * (You may HAVE to do that if your compiler doesn't like null source files.)
242
 * (You may HAVE to do that if your compiler doesn't like null source files.)
307
 */
243
 */
308
244
309
/*
310
 * Mozilla mods here: undef some features not actually used by the browser.
311
 * This reduces object code size and more importantly allows us to compile
312
 * even with broken compilers that crash when fed certain modules of the
313
 * IJG sources.  Currently we undef:
314
 * DCT_FLOAT_SUPPORTED INPUT_SMOOTHING_SUPPORTED IDCT_SCALING_SUPPORTED
315
 * QUANT_1PASS_SUPPORTED QUANT_2PASS_SUPPORTED
316
 */
317
318
/* Arithmetic coding is unsupported for legal reasons.  Complaints to IBM. */
245
/* Arithmetic coding is unsupported for legal reasons.  Complaints to IBM. */
319
246
320
/* Capability options common to encoder and decoder: */
247
/* Capability options common to encoder and decoder: */
321
248
322
#define DCT_ISLOW_SUPPORTED	/* slow but accurate integer algorithm */
249
#define DCT_ISLOW_SUPPORTED	/* slow but accurate integer algorithm */
323
#undef  DCT_IFAST_SUPPORTED	/* faster, less accurate integer method */
250
#define DCT_IFAST_SUPPORTED	/* faster, less accurate integer method */
324
#undef  DCT_FLOAT_SUPPORTED	/* floating-point: accurate, fast on fast HW */
251
#define DCT_FLOAT_SUPPORTED	/* floating-point: accurate, fast on fast HW */
325
252
326
/* Encoder capability options: */
253
/* Encoder capability options: */
327
254
328
#undef  C_ARITH_CODING_SUPPORTED    /* Arithmetic coding back end? */
255
#undef  C_ARITH_CODING_SUPPORTED    /* Arithmetic coding back end? */
329
#define C_MULTISCAN_FILES_SUPPORTED /* Multiple-scan JPEG files? */
256
#define C_MULTISCAN_FILES_SUPPORTED /* Multiple-scan JPEG files? */
330
#define C_PROGRESSIVE_SUPPORTED	    /* Progressive JPEG? (Requires MULTISCAN)*/
257
#define C_PROGRESSIVE_SUPPORTED	    /* Progressive JPEG? (Requires MULTISCAN)*/
331
#define ENTROPY_OPT_SUPPORTED	    /* Optimization of entropy coding parms? */
258
#define ENTROPY_OPT_SUPPORTED	    /* Optimization of entropy coding parms? */
332
/* Note: if you selected 12-bit data precision, it is dangerous to turn off
259
/* Note: if you selected 12-bit data precision, it is dangerous to turn off
333
 * ENTROPY_OPT_SUPPORTED.  The standard Huffman tables are only good for 8-bit
260
 * ENTROPY_OPT_SUPPORTED.  The standard Huffman tables are only good for 8-bit
334
 * precision, so jchuff.c normally uses entropy optimization to compute
261
 * precision, so jchuff.c normally uses entropy optimization to compute
335
 * usable tables for higher precision.  If you don't want to do optimization,
262
 * usable tables for higher precision.  If you don't want to do optimization,
336
 * you'll have to supply different default Huffman tables.
263
 * you'll have to supply different default Huffman tables.
337
 * The exact same statements apply for progressive JPEG: the default tables
264
 * The exact same statements apply for progressive JPEG: the default tables
338
 * don't work for progressive mode.  (This may get fixed, however.)
265
 * don't work for progressive mode.  (This may get fixed, however.)
339
 */
266
 */
340
#undef  INPUT_SMOOTHING_SUPPORTED   /* Input image smoothing option? */
267
#define INPUT_SMOOTHING_SUPPORTED   /* Input image smoothing option? */
341
268
342
/* Decoder capability options: */
269
/* Decoder capability options: */
343
270
344
#undef  D_ARITH_CODING_SUPPORTED    /* Arithmetic coding back end? */
271
#undef  D_ARITH_CODING_SUPPORTED    /* Arithmetic coding back end? */
345
#define D_MULTISCAN_FILES_SUPPORTED /* Multiple-scan JPEG files? */
272
#define D_MULTISCAN_FILES_SUPPORTED /* Multiple-scan JPEG files? */
346
#define D_PROGRESSIVE_SUPPORTED	    /* Progressive JPEG? (Requires MULTISCAN)*/
273
#define D_PROGRESSIVE_SUPPORTED	    /* Progressive JPEG? (Requires MULTISCAN)*/
347
#define SAVE_MARKERS_SUPPORTED	    /* jpeg_save_markers() needed? */
274
#define SAVE_MARKERS_SUPPORTED	    /* jpeg_save_markers() needed? */
348
#define BLOCK_SMOOTHING_SUPPORTED   /* Block smoothing? (Progressive only) */
275
#define BLOCK_SMOOTHING_SUPPORTED   /* Block smoothing? (Progressive only) */
349
#undef  IDCT_SCALING_SUPPORTED	    /* Output rescaling via IDCT? */
276
#define IDCT_SCALING_SUPPORTED	    /* Output rescaling via IDCT? */
350
#undef  UPSAMPLE_SCALING_SUPPORTED  /* Output rescaling at upsample stage? */
277
#undef  UPSAMPLE_SCALING_SUPPORTED  /* Output rescaling at upsample stage? */
351
#define UPSAMPLE_MERGING_SUPPORTED  /* Fast path for sloppy upsampling? */
278
#define UPSAMPLE_MERGING_SUPPORTED  /* Fast path for sloppy upsampling? */
352
#undef  QUANT_1PASS_SUPPORTED	    /* 1-pass color quantization? */
279
#define QUANT_1PASS_SUPPORTED	    /* 1-pass color quantization? */
353
#undef  QUANT_2PASS_SUPPORTED	    /* 2-pass color quantization? */
280
#define QUANT_2PASS_SUPPORTED	    /* 2-pass color quantization? */
354
281
355
/* more capability options later, no doubt */
282
/* more capability options later, no doubt */
356
283
357
284
358
/*
285
/*
359
 * Ordering of RGB data in scanlines passed to or from the application.
286
 * Ordering of RGB data in scanlines passed to or from the application.
360
 * If your application wants to deal with data in the order B,G,R, just
287
 * If your application wants to deal with data in the order B,G,R, just
361
 * change these macros.  You can also deal with formats such as R,G,B,X
288
 * change these macros.  You can also deal with formats such as R,G,B,X
 Lines 370-419   typedef unsigned char boolean; Link Here 
370
 *    can't use color quantization if you change that value.
297
 *    can't use color quantization if you change that value.
371
 */
298
 */
372
299
373
#define RGB_RED		0	/* Offset of Red in an RGB scanline element */
300
#define RGB_RED		0	/* Offset of Red in an RGB scanline element */
374
#define RGB_GREEN	1	/* Offset of Green */
301
#define RGB_GREEN	1	/* Offset of Green */
375
#define RGB_BLUE	2	/* Offset of Blue */
302
#define RGB_BLUE	2	/* Offset of Blue */
376
#define RGB_PIXELSIZE	3	/* JSAMPLEs per RGB scanline element */
303
#define RGB_PIXELSIZE	3	/* JSAMPLEs per RGB scanline element */
377
304
305
#define JPEG_NUMCS 12
306
307
static const int rgb_red[JPEG_NUMCS] = {
308
	-1, -1, RGB_RED, -1, -1, -1, 0, 0, 2, 2, 3, 1
309
};
310
311
static const int rgb_green[JPEG_NUMCS] = {
312
	-1, -1, RGB_GREEN, -1, -1, -1, 1, 1, 1, 1, 2, 2
313
};
314
315
static const int rgb_blue[JPEG_NUMCS] = {
316
	-1, -1, RGB_BLUE, -1, -1, -1, 2, 2, 0, 0, 1, 3
317
};
318
319
static const int rgb_pixelsize[JPEG_NUMCS] = {
320
	-1, -1, RGB_PIXELSIZE, -1, -1, -1, 3, 4, 3, 4, 4, 4
321
};
378
322
379
/* Definitions for speed-related optimizations. */
323
/* Definitions for speed-related optimizations. */
380
324
381
382
/* If your compiler supports inline functions, define INLINE
383
 * as the inline keyword; otherwise define it as empty.
384
 */
385
386
/* Mozilla mods here: add more ways of defining INLINE */
387
388
#ifndef INLINE
389
#ifdef __GNUC__			/* for instance, GNU C knows about inline */
390
#define INLINE __inline__
391
#endif
392
#if defined( __IBMC__ ) || defined (__IBMCPP__)
393
#define INLINE _Inline
394
#endif
395
#ifndef INLINE
396
#ifdef __cplusplus
397
#define INLINE inline		/* a C++ compiler should have it too */
398
#else
399
#define INLINE			/* default is to define it as empty */
400
#endif
401
#endif
402
#endif
403
404
405
/* On some machines (notably 68000 series) "int" is 32 bits, but multiplying
325
/* On some machines (notably 68000 series) "int" is 32 bits, but multiplying
406
 * two 16-bit shorts is faster than multiplying two ints.  Define MULTIPLIER
326
 * two 16-bit shorts is faster than multiplying two ints.  Define MULTIPLIER
407
 * as short on such a machine.  MULTIPLIER must be at least 16 bits wide.
327
 * as short on such a machine.  MULTIPLIER must be at least 16 bits wide.
408
 */
328
 */
409
329
410
#ifndef MULTIPLIER
330
#ifndef MULTIPLIER
411
#define MULTIPLIER  int16		/* type for fastest integer multiply */
331
#ifndef WITH_SIMD
332
#define MULTIPLIER  int		/* type for fastest integer multiply */
333
#else
334
#define MULTIPLIER short  /* prefer 16-bit with SIMD for parellelism */
335
#endif
412
#endif
336
#endif
413
337
414
338
415
/* FAST_FLOAT should be either float or double, whichever is done faster
339
/* FAST_FLOAT should be either float or double, whichever is done faster
416
 * by your compiler.  (Note that this type is only used in the floating point
340
 * by your compiler.  (Note that this type is only used in the floating point
417
 * DCT routines, so it only matters if you've defined DCT_FLOAT_SUPPORTED.)
341
 * DCT routines, so it only matters if you've defined DCT_FLOAT_SUPPORTED.)
418
 * Typically, float is faster in ANSI C compilers, while double is faster in
342
 * Typically, float is faster in ANSI C compilers, while double is faster in
419
 * pre-ANSI compilers (because they insist on converting to double anyway).
343
 * pre-ANSI compilers (because they insist on converting to double anyway).
(-)a/jpeg/jos2fig.h (-45 lines)
Line     Link Here 
 Lines 1-45    Link Here 
1
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2
/* ***** BEGIN LICENSE BLOCK *****
3
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4
 *
5
 * The contents of this file are subject to the Mozilla Public License Version
6
 * 1.1 (the "License"); you may not use this file except in compliance with
7
 * the License. You may obtain a copy of the License at
8
 * http://www.mozilla.org/MPL/
9
 *
10
 * Software distributed under the License is distributed on an "AS IS" basis,
11
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12
 * for the specific language governing rights and limitations under the
13
 * License.
14
 *
15
 * The Original Code is mozilla.org code.
16
 *
17
 * The Initial Developer of the Original Code is
18
 * Netscape Communications Corporation.
19
 * Portions created by the Initial Developer are Copyright (C) 1998
20
 * the Initial Developer. All Rights Reserved.
21
 *
22
 * Contributor(s):
23
 *
24
 * Alternatively, the contents of this file may be used under the terms of
25
 * either the GNU General Public License Version 2 or later (the "GPL"), or
26
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27
 * in which case the provisions of the GPL or the LGPL are applicable instead
28
 * of those above. If you wish to allow use of your version of this file only
29
 * under the terms of either the GPL or the LGPL, and not to allow others to
30
 * use your version of this file under the terms of the MPL, indicate your
31
 * decision by deleting the provisions above and replace them with the notice
32
 * and other provisions required by the GPL or the LGPL. If you do not delete
33
 * the provisions above, a recipient may use your version of this file under
34
 * the terms of any one of the MPL, the GPL or the LGPL.
35
 *
36
 * ***** END LICENSE BLOCK ***** */
37
38
#ifndef __jos2fig_h__
39
#define __jos2fig_h__
40
41
/*
42
** Place holder for the OS/2 code that might actually make it into the trunk someday.  Maybe.
43
*/
44
45
#endif  /* __jos2fig_h__ */
(-)a/jpeg/jpegint.h (-1 / +1 lines)
Line     Link Here 
 Lines 364-380   EXTERN(void) jinit_color_deconverter JPP Link Here 
364
EXTERN(void) jinit_1pass_quantizer JPP((j_decompress_ptr cinfo));
364
EXTERN(void) jinit_1pass_quantizer JPP((j_decompress_ptr cinfo));
365
EXTERN(void) jinit_2pass_quantizer JPP((j_decompress_ptr cinfo));
365
EXTERN(void) jinit_2pass_quantizer JPP((j_decompress_ptr cinfo));
366
EXTERN(void) jinit_merged_upsampler JPP((j_decompress_ptr cinfo));
366
EXTERN(void) jinit_merged_upsampler JPP((j_decompress_ptr cinfo));
367
/* Memory manager initialization */
367
/* Memory manager initialization */
368
EXTERN(void) jinit_memory_mgr JPP((j_common_ptr cinfo));
368
EXTERN(void) jinit_memory_mgr JPP((j_common_ptr cinfo));
369
369
370
/* Utility routines in jutils.c */
370
/* Utility routines in jutils.c */
371
EXTERN(long) jdiv_round_up JPP((long a, long b));
371
EXTERN(long) jdiv_round_up JPP((long a, long b));
372
EXTERN(long) jround_up JPP((long a, long b));
372
EXTERN(size_t) jround_up JPP((size_t a, size_t b));
373
EXTERN(void) jcopy_sample_rows JPP((JSAMPARRAY input_array, int source_row,
373
EXTERN(void) jcopy_sample_rows JPP((JSAMPARRAY input_array, int source_row,
374
				    JSAMPARRAY output_array, int dest_row,
374
				    JSAMPARRAY output_array, int dest_row,
375
				    int num_rows, JDIMENSION num_cols));
375
				    int num_rows, JDIMENSION num_cols));
376
EXTERN(void) jcopy_block_row JPP((JBLOCKROW input_row, JBLOCKROW output_row,
376
EXTERN(void) jcopy_block_row JPP((JBLOCKROW input_row, JBLOCKROW output_row,
377
				  JDIMENSION num_blocks));
377
				  JDIMENSION num_blocks));
378
EXTERN(void) jzero_far JPP((void FAR * target, size_t bytestozero));
378
EXTERN(void) jzero_far JPP((void FAR * target, size_t bytestozero));
379
/* Constant tables in jutils.c */
379
/* Constant tables in jutils.c */
380
#if 0				/* This table is not actually needed in v6a */
380
#if 0				/* This table is not actually needed in v6a */
(-)a/jpeg/jpeglib.h (-28 / +18 lines)
Line     Link Here 
 Lines 1-58    Link Here 
1
/*
1
/*
2
 * jpeglib.h
2
 * jpeglib.h
3
 *
3
 *
4
 * Copyright (C) 1991-1998, Thomas G. Lane.
4
 * Copyright (C) 1991-1998, Thomas G. Lane.
5
 * Copyright (C) 2009, D. R. Commander.
5
 * This file is part of the Independent JPEG Group's software.
6
 * This file is part of the Independent JPEG Group's software.
6
 * For conditions of distribution and use, see the accompanying README file.
7
 * For conditions of distribution and use, see the accompanying README file.
7
 *
8
 *
8
 * This file defines the application interface for the JPEG library.
9
 * This file defines the application interface for the JPEG library.
9
 * Most applications using the library need only include this file,
10
 * Most applications using the library need only include this file,
10
 * and perhaps jerror.h if they want to know the exact error codes.
11
 * and perhaps jerror.h if they want to know the exact error codes.
11
 */
12
 */
12
13
13
#ifndef JPEGLIB_H
14
#ifndef JPEGLIB_H
14
#define JPEGLIB_H
15
#define JPEGLIB_H
15
16
16
#ifdef XP_OS2
17
#ifdef __cplusplus
17
/*
18
extern "C" {
18
 * On OS/2, the system will have defined RGB_* so we #undef 'em to avoid warnings
19
 * from jmorecfg.h.
20
 */
21
#ifdef RGB_RED
22
	#undef RGB_RED
23
#endif
24
#ifdef RGB_GREEN
25
	#undef RGB_GREEN
26
#endif
27
#ifdef RGB_BLUE
28
	#undef RGB_BLUE
29
#endif
30
31
#endif
19
#endif
32
20
33
/*
21
/*
34
 * First we include the configuration files that record how this
22
 * First we include the configuration files that record how this
35
 * installation of the JPEG library is set up.  jconfig.h can be
23
 * installation of the JPEG library is set up.  jconfig.h can be
36
 * generated automatically for many systems.  jmorecfg.h contains
24
 * generated automatically for many systems.  jmorecfg.h contains
37
 * manual configuration options that most people need not worry about.
25
 * manual configuration options that most people need not worry about.
38
 */
26
 */
39
27
40
#ifndef JCONFIG_INCLUDED	/* in case jinclude.h already did */
28
#ifndef JCONFIG_INCLUDED	/* in case jinclude.h already did */
41
#include "jconfig.h"		/* widely used configuration options */
29
#include "jconfig.h"		/* widely used configuration options */
42
#endif
30
#endif
43
#include "jmorecfg.h"		/* seldom changed options */
31
#include "jmorecfg.h"		/* seldom changed options */
44
32
45
33
46
#ifdef HAVE_MMX_INTEL_MNEMONICS
47
	extern int MMXAvailable;
48
#endif
49
50
51
/* Version ID for the JPEG library.
34
/* Version ID for the JPEG library.
52
 * Might be useful for tests like "#if JPEG_LIB_VERSION >= 60".
35
 * Might be useful for tests like "#if JPEG_LIB_VERSION >= 60".
53
 */
36
 */
54
37
55
#define JPEG_LIB_VERSION  62	/* Version 6b */
38
#define JPEG_LIB_VERSION  62	/* Version 6b */
56
39
57
40
58
/* Various constants determining the sizes of things.
41
/* Various constants determining the sizes of things.
 Lines 220-242   struct jpeg_marker_struct { Link Here 
220
  unsigned int original_length;	/* # bytes of data in the file */
203
  unsigned int original_length;	/* # bytes of data in the file */
221
  unsigned int data_length;	/* # bytes of data saved at data[] */
204
  unsigned int data_length;	/* # bytes of data saved at data[] */
222
  JOCTET FAR * data;		/* the data contained in the marker */
205
  JOCTET FAR * data;		/* the data contained in the marker */
223
  /* the marker length word is not counted in data_length or original_length */
206
  /* the marker length word is not counted in data_length or original_length */
224
};
207
};
225
208
226
/* Known color spaces. */
209
/* Known color spaces. */
227
210
211
#define JCS_EXTENSIONS 1
212
228
typedef enum {
213
typedef enum {
229
	JCS_UNKNOWN,		/* error/unspecified */
214
	JCS_UNKNOWN,		/* error/unspecified */
230
	JCS_GRAYSCALE,		/* monochrome */
215
	JCS_GRAYSCALE,		/* monochrome */
231
	JCS_RGB,		/* red/green/blue */
216
	JCS_RGB,		/* red/green/blue as specified by the RGB_RED, RGB_GREEN,
217
                 RGB_BLUE, and RGB_PIXELSIZE macros */
232
	JCS_YCbCr,		/* Y/Cb/Cr (also known as YUV) */
218
	JCS_YCbCr,		/* Y/Cb/Cr (also known as YUV) */
233
	JCS_CMYK,		/* C/M/Y/K */
219
	JCS_CMYK,		/* C/M/Y/K */
234
	JCS_YCCK		/* Y/Cb/Cr/K */
220
	JCS_YCCK,		/* Y/Cb/Cr/K */
221
	JCS_EXT_RGB,		/* red/green/blue */
222
	JCS_EXT_RGBX,		/* red/green/blue/x */
223
	JCS_EXT_BGR,		/* blue/green/red */
224
	JCS_EXT_BGRX,		/* blue/green/red/x */
225
	JCS_EXT_XBGR,		/* x/blue/green/red */
226
	JCS_EXT_XRGB		/* x/red/green/blue */
235
} J_COLOR_SPACE;
227
} J_COLOR_SPACE;
236
228
237
/* DCT/IDCT algorithm options. */
229
/* DCT/IDCT algorithm options. */
238
230
239
typedef enum {
231
typedef enum {
240
	JDCT_ISLOW,		/* slow but accurate integer algorithm */
232
	JDCT_ISLOW,		/* slow but accurate integer algorithm */
241
	JDCT_IFAST,		/* faster, less accurate integer method */
233
	JDCT_IFAST,		/* faster, less accurate integer method */
242
	JDCT_FLOAT		/* floating-point: accurate, fast on fast HW */
234
	JDCT_FLOAT		/* floating-point: accurate, fast on fast HW */
 Lines 896-914   typedef JMETHOD(boolean, jpeg_marker_par Link Here 
896
#define jpeg_copy_critical_parameters	jCopyCrit
888
#define jpeg_copy_critical_parameters	jCopyCrit
897
#define jpeg_abort_compress	jAbrtCompress
889
#define jpeg_abort_compress	jAbrtCompress
898
#define jpeg_abort_decompress	jAbrtDecompress
890
#define jpeg_abort_decompress	jAbrtDecompress
899
#define jpeg_abort		jAbort
891
#define jpeg_abort		jAbort
900
#define jpeg_destroy		jDestroy
892
#define jpeg_destroy		jDestroy
901
#define jpeg_resync_to_restart	jResyncRestart
893
#define jpeg_resync_to_restart	jResyncRestart
902
#endif /* NEED_SHORT_EXTERNAL_NAMES */
894
#endif /* NEED_SHORT_EXTERNAL_NAMES */
903
895
904
#ifdef __cplusplus
905
extern "C" {
906
#endif
907
896
908
/* Default error-management setup */
897
/* Default error-management setup */
909
EXTERN(struct jpeg_error_mgr *) jpeg_std_error
898
EXTERN(struct jpeg_error_mgr *) jpeg_std_error
910
	JPP((struct jpeg_error_mgr * err));
899
	JPP((struct jpeg_error_mgr * err));
911
900
912
/* Initialization of JPEG compression objects.
901
/* Initialization of JPEG compression objects.
913
 * jpeg_create_compress() and jpeg_create_decompress() are the exported
902
 * jpeg_create_compress() and jpeg_create_decompress() are the exported
914
 * names that applications should call.  These expand to calls on
903
 * names that applications should call.  These expand to calls on
 Lines 1057-1075   EXTERN(void) jpeg_abort_decompress JPP(( Link Here 
1057
 */
1046
 */
1058
EXTERN(void) jpeg_abort JPP((j_common_ptr cinfo));
1047
EXTERN(void) jpeg_abort JPP((j_common_ptr cinfo));
1059
EXTERN(void) jpeg_destroy JPP((j_common_ptr cinfo));
1048
EXTERN(void) jpeg_destroy JPP((j_common_ptr cinfo));
1060
1049
1061
/* Default restart-marker-resync procedure for use by data source modules */
1050
/* Default restart-marker-resync procedure for use by data source modules */
1062
EXTERN(boolean) jpeg_resync_to_restart JPP((j_decompress_ptr cinfo,
1051
EXTERN(boolean) jpeg_resync_to_restart JPP((j_decompress_ptr cinfo,
1063
					    int desired));
1052
					    int desired));
1064
1053
1065
#ifdef __cplusplus
1066
} /* extern "C" */
1067
#endif /* __cplusplus */
1068
1054
1069
/* These marker codes are exported since applications and data source modules
1055
/* These marker codes are exported since applications and data source modules
1070
 * are likely to want to use them.
1056
 * are likely to want to use them.
1071
 */
1057
 */
1072
1058
1073
#define JPEG_RST0	0xD0	/* RST0 marker code */
1059
#define JPEG_RST0	0xD0	/* RST0 marker code */
1074
#define JPEG_EOI	0xD9	/* EOI marker code */
1060
#define JPEG_EOI	0xD9	/* EOI marker code */
1075
#define JPEG_APP0	0xE0	/* APP0 marker code */
1061
#define JPEG_APP0	0xE0	/* APP0 marker code */
 Lines 1116-1124   struct jpeg_color_quantizer { long dummy Link Here 
1116
 * to include jerror.h.
1102
 * to include jerror.h.
1117
 */
1103
 */
1118
1104
1119
#ifdef JPEG_INTERNALS
1105
#ifdef JPEG_INTERNALS
1120
#include "jpegint.h"		/* fetch private declarations */
1106
#include "jpegint.h"		/* fetch private declarations */
1121
#include "jerror.h"		/* fetch error codes too */
1107
#include "jerror.h"		/* fetch error codes too */
1122
#endif
1108
#endif
1123
1109
1110
#ifdef __cplusplus
1111
}
1112
#endif
1113
1124
#endif /* JPEGLIB_H */
1114
#endif /* JPEGLIB_H */
(-)a/jpeg/jpegtran.1 (+238 lines)
Line     Link Here 
Line 0    Link Here 
1
.TH JPEGTRAN 1 "3 August 1997"
2
.SH NAME
3
jpegtran \- lossless transformation of JPEG files
4
.SH SYNOPSIS
5
.B jpegtran
6
[
7
.I options
8
]
9
[
10
.I filename
11
]
12
.LP
13
.SH DESCRIPTION
14
.LP
15
.B jpegtran
16
performs various useful transformations of JPEG files.
17
It can translate the coded representation from one variant of JPEG to another,
18
for example from baseline JPEG to progressive JPEG or vice versa.  It can also
19
perform some rearrangements of the image data, for example turning an image
20
from landscape to portrait format by rotation.
21
.PP
22
.B jpegtran
23
works by rearranging the compressed data (DCT coefficients), without
24
ever fully decoding the image.  Therefore, its transformations are lossless:
25
there is no image degradation at all, which would not be true if you used
26
.B djpeg
27
followed by
28
.B cjpeg
29
to accomplish the same conversion.  But by the same token,
30
.B jpegtran
31
cannot perform lossy operations such as changing the image quality.
32
.PP
33
.B jpegtran
34
reads the named JPEG/JFIF file, or the standard input if no file is
35
named, and produces a JPEG/JFIF file on the standard output.
36
.SH OPTIONS
37
All switch names may be abbreviated; for example,
38
.B \-optimize
39
may be written
40
.B \-opt
41
or
42
.BR \-o .
43
Upper and lower case are equivalent.
44
British spellings are also accepted (e.g.,
45
.BR \-optimise ),
46
though for brevity these are not mentioned below.
47
.PP
48
To specify the coded JPEG representation used in the output file,
49
.B jpegtran
50
accepts a subset of the switches recognized by
51
.BR cjpeg :
52
.TP
53
.B \-optimize
54
Perform optimization of entropy encoding parameters.
55
.TP
56
.B \-progressive
57
Create progressive JPEG file.
58
.TP
59
.BI \-restart " N"
60
Emit a JPEG restart marker every N MCU rows, or every N MCU blocks if "B" is
61
attached to the number.
62
.TP
63
.BI \-scans " file"
64
Use the scan script given in the specified text file.
65
.PP
66
See
67
.BR cjpeg (1)
68
for more details about these switches.
69
If you specify none of these switches, you get a plain baseline-JPEG output
70
file.  The quality setting and so forth are determined by the input file.
71
.PP
72
The image can be losslessly transformed by giving one of these switches:
73
.TP
74
.B \-flip horizontal
75
Mirror image horizontally (left-right).
76
.TP
77
.B \-flip vertical
78
Mirror image vertically (top-bottom).
79
.TP
80
.B \-rotate 90
81
Rotate image 90 degrees clockwise.
82
.TP
83
.B \-rotate 180
84
Rotate image 180 degrees.
85
.TP
86
.B \-rotate 270
87
Rotate image 270 degrees clockwise (or 90 ccw).
88
.TP
89
.B \-transpose
90
Transpose image (across UL-to-LR axis).
91
.TP
92
.B \-transverse
93
Transverse transpose (across UR-to-LL axis).
94
.PP
95
The transpose transformation has no restrictions regarding image dimensions.
96
The other transformations operate rather oddly if the image dimensions are not
97
a multiple of the iMCU size (usually 8 or 16 pixels), because they can only
98
transform complete blocks of DCT coefficient data in the desired way.
99
.PP
100
.BR jpegtran 's
101
default behavior when transforming an odd-size image is designed
102
to preserve exact reversibility and mathematical consistency of the
103
transformation set.  As stated, transpose is able to flip the entire image
104
area.  Horizontal mirroring leaves any partial iMCU column at the right edge
105
untouched, but is able to flip all rows of the image.  Similarly, vertical
106
mirroring leaves any partial iMCU row at the bottom edge untouched, but is
107
able to flip all columns.  The other transforms can be built up as sequences
108
of transpose and flip operations; for consistency, their actions on edge
109
pixels are defined to be the same as the end result of the corresponding
110
transpose-and-flip sequence.
111
.PP
112
For practical use, you may prefer to discard any untransformable edge pixels
113
rather than having a strange-looking strip along the right and/or bottom edges
114
of a transformed image.  To do this, add the
115
.B \-trim
116
switch:
117
.TP
118
.B \-trim
119
Drop non-transformable edge blocks.
120
.PP
121
Obviously, a transformation with
122
.B \-trim
123
is not reversible, so strictly speaking
124
.B jpegtran
125
with this switch is not lossless.  Also, the expected mathematical
126
equivalences between the transformations no longer hold.  For example,
127
.B \-rot 270 -trim
128
trims only the bottom edge, but
129
.B \-rot 90 -trim
130
followed by
131
.B \-rot 180 -trim
132
trims both edges.
133
.PP
134
Another not-strictly-lossless transformation switch is:
135
.TP
136
.B \-grayscale
137
Force grayscale output.
138
.PP
139
This option discards the chrominance channels if the input image is YCbCr
140
(ie, a standard color JPEG), resulting in a grayscale JPEG file.  The
141
luminance channel is preserved exactly, so this is a better method of reducing
142
to grayscale than decompression, conversion, and recompression.  This switch
143
is particularly handy for fixing a monochrome picture that was mistakenly
144
encoded as a color JPEG.  (In such a case, the space savings from getting rid
145
of the near-empty chroma channels won't be large; but the decoding time for
146
a grayscale JPEG is substantially less than that for a color JPEG.)
147
.PP
148
.B jpegtran
149
also recognizes these switches that control what to do with "extra" markers,
150
such as comment blocks:
151
.TP
152
.B \-copy none
153
Copy no extra markers from source file.  This setting suppresses all
154
comments and other excess baggage present in the source file.
155
.TP
156
.B \-copy comments
157
Copy only comment markers.  This setting copies comments from the source file,
158
but discards any other inessential data.
159
.TP
160
.B \-copy all
161
Copy all extra markers.  This setting preserves miscellaneous markers
162
found in the source file, such as JFIF thumbnails and Photoshop settings.
163
In some files these extra markers can be sizable.
164
.PP
165
The default behavior is
166
.BR "\-copy comments" .
167
(Note: in IJG releases v6 and v6a,
168
.B jpegtran
169
always did the equivalent of
170
.BR "\-copy none" .)
171
.PP
172
Additional switches recognized by jpegtran are:
173
.TP
174
.BI \-maxmemory " N"
175
Set limit for amount of memory to use in processing large images.  Value is
176
in thousands of bytes, or millions of bytes if "M" is attached to the
177
number.  For example,
178
.B \-max 4m
179
selects 4000000 bytes.  If more space is needed, temporary files will be used.
180
.TP
181
.BI \-outfile " name"
182
Send output image to the named file, not to standard output.
183
.TP
184
.B \-verbose
185
Enable debug printout.  More
186
.BR \-v 's
187
give more output.  Also, version information is printed at startup.
188
.TP
189
.B \-debug
190
Same as
191
.BR \-verbose .
192
.SH EXAMPLES
193
.LP
194
This example converts a baseline JPEG file to progressive form:
195
.IP
196
.B jpegtran \-progressive
197
.I foo.jpg
198
.B >
199
.I fooprog.jpg
200
.PP
201
This example rotates an image 90 degrees clockwise, discarding any
202
unrotatable edge pixels:
203
.IP
204
.B jpegtran \-rot 90 -trim
205
.I foo.jpg
206
.B >
207
.I foo90.jpg
208
.SH ENVIRONMENT
209
.TP
210
.B JPEGMEM
211
If this environment variable is set, its value is the default memory limit.
212
The value is specified as described for the
213
.B \-maxmemory
214
switch.
215
.B JPEGMEM
216
overrides the default value specified when the program was compiled, and
217
itself is overridden by an explicit
218
.BR \-maxmemory .
219
.SH SEE ALSO
220
.BR cjpeg (1),
221
.BR djpeg (1),
222
.BR rdjpgcom (1),
223
.BR wrjpgcom (1)
224
.br
225
Wallace, Gregory K.  "The JPEG Still Picture Compression Standard",
226
Communications of the ACM, April 1991 (vol. 34, no. 4), pp. 30-44.
227
.SH AUTHOR
228
Independent JPEG Group
229
.SH BUGS
230
Arithmetic coding is not supported for legal reasons.
231
.PP
232
The transform options can't transform odd-size images perfectly.  Use
233
.B \-trim
234
if you don't like the results without it.
235
.PP
236
The entire image is read into memory and then written out again, even in
237
cases where this isn't really necessary.  Expect swapping on large images,
238
especially when using the more complex transform options.
(-)a/jpeg/jpegtran.c (+504 lines)
Line     Link Here 
Line 0    Link Here 
1
/*
2
 * jpegtran.c
3
 *
4
 * Copyright (C) 1995-1997, Thomas G. Lane.
5
 * This file is part of the Independent JPEG Group's software.
6
 * For conditions of distribution and use, see the accompanying README file.
7
 *
8
 * This file contains a command-line user interface for JPEG transcoding.
9
 * It is very similar to cjpeg.c, but provides lossless transcoding between
10
 * different JPEG file formats.  It also provides some lossless and sort-of-
11
 * lossless transformations of JPEG data.
12
 */
13
14
#include "cdjpeg.h"		/* Common decls for cjpeg/djpeg applications */
15
#include "transupp.h"		/* Support routines for jpegtran */
16
#include "jversion.h"		/* for version message */
17
18
#ifdef USE_CCOMMAND		/* command-line reader for Macintosh */
19
#ifdef __MWERKS__
20
#include <SIOUX.h>              /* Metrowerks needs this */
21
#include <console.h>		/* ... and this */
22
#endif
23
#ifdef THINK_C
24
#include <console.h>		/* Think declares it here */
25
#endif
26
#endif
27
28
29
/*
30
 * Argument-parsing code.
31
 * The switch parser is designed to be useful with DOS-style command line
32
 * syntax, ie, intermixed switches and file names, where only the switches
33
 * to the left of a given file name affect processing of that file.
34
 * The main program in this file doesn't actually use this capability...
35
 */
36
37
38
static const char * progname;	/* program name for error messages */
39
static char * outfilename;	/* for -outfile switch */
40
static JCOPY_OPTION copyoption;	/* -copy switch */
41
static jpeg_transform_info transformoption; /* image transformation options */
42
43
44
LOCAL(void)
45
usage (void)
46
/* complain about bad command line */
47
{
48
  fprintf(stderr, "usage: %s [switches] ", progname);
49
#ifdef TWO_FILE_COMMANDLINE
50
  fprintf(stderr, "inputfile outputfile\n");
51
#else
52
  fprintf(stderr, "[inputfile]\n");
53
#endif
54
55
  fprintf(stderr, "Switches (names may be abbreviated):\n");
56
  fprintf(stderr, "  -copy none     Copy no extra markers from source file\n");
57
  fprintf(stderr, "  -copy comments Copy only comment markers (default)\n");
58
  fprintf(stderr, "  -copy all      Copy all extra markers\n");
59
#ifdef ENTROPY_OPT_SUPPORTED
60
  fprintf(stderr, "  -optimize      Optimize Huffman table (smaller file, but slow compression)\n");
61
#endif
62
#ifdef C_PROGRESSIVE_SUPPORTED
63
  fprintf(stderr, "  -progressive   Create progressive JPEG file\n");
64
#endif
65
#if TRANSFORMS_SUPPORTED
66
  fprintf(stderr, "Switches for modifying the image:\n");
67
  fprintf(stderr, "  -grayscale     Reduce to grayscale (omit color data)\n");
68
  fprintf(stderr, "  -flip [horizontal|vertical]  Mirror image (left-right or top-bottom)\n");
69
  fprintf(stderr, "  -rotate [90|180|270]         Rotate image (degrees clockwise)\n");
70
  fprintf(stderr, "  -transpose     Transpose image\n");
71
  fprintf(stderr, "  -transverse    Transverse transpose image\n");
72
  fprintf(stderr, "  -trim          Drop non-transformable edge blocks\n");
73
#endif /* TRANSFORMS_SUPPORTED */
74
  fprintf(stderr, "Switches for advanced users:\n");
75
  fprintf(stderr, "  -restart N     Set restart interval in rows, or in blocks with B\n");
76
  fprintf(stderr, "  -maxmemory N   Maximum memory to use (in kbytes)\n");
77
  fprintf(stderr, "  -outfile name  Specify name for output file\n");
78
  fprintf(stderr, "  -verbose  or  -debug   Emit debug output\n");
79
  fprintf(stderr, "Switches for wizards:\n");
80
#ifdef C_ARITH_CODING_SUPPORTED
81
  fprintf(stderr, "  -arithmetic    Use arithmetic coding\n");
82
#endif
83
#ifdef C_MULTISCAN_FILES_SUPPORTED
84
  fprintf(stderr, "  -scans file    Create multi-scan JPEG per script file\n");
85
#endif
86
  exit(EXIT_FAILURE);
87
}
88
89
90
LOCAL(void)
91
select_transform (JXFORM_CODE transform)
92
/* Silly little routine to detect multiple transform options,
93
 * which we can't handle.
94
 */
95
{
96
#if TRANSFORMS_SUPPORTED
97
  if (transformoption.transform == JXFORM_NONE ||
98
      transformoption.transform == transform) {
99
    transformoption.transform = transform;
100
  } else {
101
    fprintf(stderr, "%s: can only do one image transformation at a time\n",
102
	    progname);
103
    usage();
104
  }
105
#else
106
  fprintf(stderr, "%s: sorry, image transformation was not compiled\n",
107
	  progname);
108
  exit(EXIT_FAILURE);
109
#endif
110
}
111
112
113
LOCAL(int)
114
parse_switches (j_compress_ptr cinfo, int argc, char **argv,
115
		int last_file_arg_seen, boolean for_real)
116
/* Parse optional switches.
117
 * Returns argv[] index of first file-name argument (== argc if none).
118
 * Any file names with indexes <= last_file_arg_seen are ignored;
119
 * they have presumably been processed in a previous iteration.
120
 * (Pass 0 for last_file_arg_seen on the first or only iteration.)
121
 * for_real is FALSE on the first (dummy) pass; we may skip any expensive
122
 * processing.
123
 */
124
{
125
  int argn;
126
  char * arg;
127
  boolean simple_progressive;
128
  char * scansarg = NULL;	/* saves -scans parm if any */
129
130
  /* Set up default JPEG parameters. */
131
  simple_progressive = FALSE;
132
  outfilename = NULL;
133
  copyoption = JCOPYOPT_DEFAULT;
134
  transformoption.transform = JXFORM_NONE;
135
  transformoption.trim = FALSE;
136
  transformoption.force_grayscale = FALSE;
137
  cinfo->err->trace_level = 0;
138
139
  /* Scan command line options, adjust parameters */
140
141
  for (argn = 1; argn < argc; argn++) {
142
    arg = argv[argn];
143
    if (*arg != '-') {
144
      /* Not a switch, must be a file name argument */
145
      if (argn <= last_file_arg_seen) {
146
	outfilename = NULL;	/* -outfile applies to just one input file */
147
	continue;		/* ignore this name if previously processed */
148
      }
149
      break;			/* else done parsing switches */
150
    }
151
    arg++;			/* advance past switch marker character */
152
153
    if (keymatch(arg, "arithmetic", 1)) {
154
      /* Use arithmetic coding. */
155
#ifdef C_ARITH_CODING_SUPPORTED
156
      cinfo->arith_code = TRUE;
157
#else
158
      fprintf(stderr, "%s: sorry, arithmetic coding not supported\n",
159
	      progname);
160
      exit(EXIT_FAILURE);
161
#endif
162
163
    } else if (keymatch(arg, "copy", 1)) {
164
      /* Select which extra markers to copy. */
165
      if (++argn >= argc)	/* advance to next argument */
166
	usage();
167
      if (keymatch(argv[argn], "none", 1)) {
168
	copyoption = JCOPYOPT_NONE;
169
      } else if (keymatch(argv[argn], "comments", 1)) {
170
	copyoption = JCOPYOPT_COMMENTS;
171
      } else if (keymatch(argv[argn], "all", 1)) {
172
	copyoption = JCOPYOPT_ALL;
173
      } else
174
	usage();
175
176
    } else if (keymatch(arg, "debug", 1) || keymatch(arg, "verbose", 1)) {
177
      /* Enable debug printouts. */
178
      /* On first -d, print version identification */
179
      static boolean printed_version = FALSE;
180
181
      if (! printed_version) {
182
	fprintf(stderr, "Independent JPEG Group's JPEGTRAN, version %s\n%s\n",
183
		JVERSION, JCOPYRIGHT);
184
	printed_version = TRUE;
185
      }
186
      cinfo->err->trace_level++;
187
188
    } else if (keymatch(arg, "flip", 1)) {
189
      /* Mirror left-right or top-bottom. */
190
      if (++argn >= argc)	/* advance to next argument */
191
	usage();
192
      if (keymatch(argv[argn], "horizontal", 1))
193
	select_transform(JXFORM_FLIP_H);
194
      else if (keymatch(argv[argn], "vertical", 1))
195
	select_transform(JXFORM_FLIP_V);
196
      else
197
	usage();
198
199
    } else if (keymatch(arg, "grayscale", 1) || keymatch(arg, "greyscale",1)) {
200
      /* Force to grayscale. */
201
#if TRANSFORMS_SUPPORTED
202
      transformoption.force_grayscale = TRUE;
203
#else
204
      select_transform(JXFORM_NONE);	/* force an error */
205
#endif
206
207
    } else if (keymatch(arg, "maxmemory", 3)) {
208
      /* Maximum memory in Kb (or Mb with 'm'). */
209
      long lval;
210
      char ch = 'x';
211
212
      if (++argn >= argc)	/* advance to next argument */
213
	usage();
214
      if (sscanf(argv[argn], "%ld%c", &lval, &ch) < 1)
215
	usage();
216
      if (ch == 'm' || ch == 'M')
217
	lval *= 1000L;
218
      cinfo->mem->max_memory_to_use = lval * 1000L;
219
220
    } else if (keymatch(arg, "optimize", 1) || keymatch(arg, "optimise", 1)) {
221
      /* Enable entropy parm optimization. */
222
#ifdef ENTROPY_OPT_SUPPORTED
223
      cinfo->optimize_coding = TRUE;
224
#else
225
      fprintf(stderr, "%s: sorry, entropy optimization was not compiled\n",
226
	      progname);
227
      exit(EXIT_FAILURE);
228
#endif
229
230
    } else if (keymatch(arg, "outfile", 4)) {
231
      /* Set output file name. */
232
      if (++argn >= argc)	/* advance to next argument */
233
	usage();
234
      outfilename = argv[argn];	/* save it away for later use */
235
236
    } else if (keymatch(arg, "progressive", 1)) {
237
      /* Select simple progressive mode. */
238
#ifdef C_PROGRESSIVE_SUPPORTED
239
      simple_progressive = TRUE;
240
      /* We must postpone execution until num_components is known. */
241
#else
242
      fprintf(stderr, "%s: sorry, progressive output was not compiled\n",
243
	      progname);
244
      exit(EXIT_FAILURE);
245
#endif
246
247
    } else if (keymatch(arg, "restart", 1)) {
248
      /* Restart interval in MCU rows (or in MCUs with 'b'). */
249
      long lval;
250
      char ch = 'x';
251
252
      if (++argn >= argc)	/* advance to next argument */
253
	usage();
254
      if (sscanf(argv[argn], "%ld%c", &lval, &ch) < 1)
255
	usage();
256
      if (lval < 0 || lval > 65535L)
257
	usage();
258
      if (ch == 'b' || ch == 'B') {
259
	cinfo->restart_interval = (unsigned int) lval;
260
	cinfo->restart_in_rows = 0; /* else prior '-restart n' overrides me */
261
      } else {
262
	cinfo->restart_in_rows = (int) lval;
263
	/* restart_interval will be computed during startup */
264
      }
265
266
    } else if (keymatch(arg, "rotate", 2)) {
267
      /* Rotate 90, 180, or 270 degrees (measured clockwise). */
268
      if (++argn >= argc)	/* advance to next argument */
269
	usage();
270
      if (keymatch(argv[argn], "90", 2))
271
	select_transform(JXFORM_ROT_90);
272
      else if (keymatch(argv[argn], "180", 3))
273
	select_transform(JXFORM_ROT_180);
274
      else if (keymatch(argv[argn], "270", 3))
275
	select_transform(JXFORM_ROT_270);
276
      else
277
	usage();
278
279
    } else if (keymatch(arg, "scans", 1)) {
280
      /* Set scan script. */
281
#ifdef C_MULTISCAN_FILES_SUPPORTED
282
      if (++argn >= argc)	/* advance to next argument */
283
	usage();
284
      scansarg = argv[argn];
285
      /* We must postpone reading the file in case -progressive appears. */
286
#else
287
      fprintf(stderr, "%s: sorry, multi-scan output was not compiled\n",
288
	      progname);
289
      exit(EXIT_FAILURE);
290
#endif
291
292
    } else if (keymatch(arg, "transpose", 1)) {
293
      /* Transpose (across UL-to-LR axis). */
294
      select_transform(JXFORM_TRANSPOSE);
295
296
    } else if (keymatch(arg, "transverse", 6)) {
297
      /* Transverse transpose (across UR-to-LL axis). */
298
      select_transform(JXFORM_TRANSVERSE);
299
300
    } else if (keymatch(arg, "trim", 3)) {
301
      /* Trim off any partial edge MCUs that the transform can't handle. */
302
      transformoption.trim = TRUE;
303
304
    } else {
305
      usage();			/* bogus switch */
306
    }
307
  }
308
309
  /* Post-switch-scanning cleanup */
310
311
  if (for_real) {
312
313
#ifdef C_PROGRESSIVE_SUPPORTED
314
    if (simple_progressive)	/* process -progressive; -scans can override */
315
      jpeg_simple_progression(cinfo);
316
#endif
317
318
#ifdef C_MULTISCAN_FILES_SUPPORTED
319
    if (scansarg != NULL)	/* process -scans if it was present */
320
      if (! read_scan_script(cinfo, scansarg))
321
	usage();
322
#endif
323
  }
324
325
  return argn;			/* return index of next arg (file name) */
326
}
327
328
329
/*
330
 * The main program.
331
 */
332
333
int
334
main (int argc, char **argv)
335
{
336
  struct jpeg_decompress_struct srcinfo;
337
  struct jpeg_compress_struct dstinfo;
338
  struct jpeg_error_mgr jsrcerr, jdsterr;
339
#ifdef PROGRESS_REPORT
340
  struct cdjpeg_progress_mgr progress;
341
#endif
342
  jvirt_barray_ptr * src_coef_arrays;
343
  jvirt_barray_ptr * dst_coef_arrays;
344
  int file_index;
345
  FILE * input_file;
346
  FILE * output_file;
347
348
  /* On Mac, fetch a command line. */
349
#ifdef USE_CCOMMAND
350
  argc = ccommand(&argv);
351
#endif
352
353
  progname = argv[0];
354
  if (progname == NULL || progname[0] == 0)
355
    progname = "jpegtran";	/* in case C library doesn't provide it */
356
357
  /* Initialize the JPEG decompression object with default error handling. */
358
  srcinfo.err = jpeg_std_error(&jsrcerr);
359
  jpeg_create_decompress(&srcinfo);
360
  /* Initialize the JPEG compression object with default error handling. */
361
  dstinfo.err = jpeg_std_error(&jdsterr);
362
  jpeg_create_compress(&dstinfo);
363
364
  /* Now safe to enable signal catcher.
365
   * Note: we assume only the decompression object will have virtual arrays.
366
   */
367
#ifdef NEED_SIGNAL_CATCHER
368
  enable_signal_catcher((j_common_ptr) &srcinfo);
369
#endif
370
371
  /* Scan command line to find file names.
372
   * It is convenient to use just one switch-parsing routine, but the switch
373
   * values read here are mostly ignored; we will rescan the switches after
374
   * opening the input file.  Also note that most of the switches affect the
375
   * destination JPEG object, so we parse into that and then copy over what
376
   * needs to affects the source too.
377
   */
378
379
  file_index = parse_switches(&dstinfo, argc, argv, 0, FALSE);
380
  jsrcerr.trace_level = jdsterr.trace_level;
381
  srcinfo.mem->max_memory_to_use = dstinfo.mem->max_memory_to_use;
382
383
#ifdef TWO_FILE_COMMANDLINE
384
  /* Must have either -outfile switch or explicit output file name */
385
  if (outfilename == NULL) {
386
    if (file_index != argc-2) {
387
      fprintf(stderr, "%s: must name one input and one output file\n",
388
	      progname);
389
      usage();
390
    }
391
    outfilename = argv[file_index+1];
392
  } else {
393
    if (file_index != argc-1) {
394
      fprintf(stderr, "%s: must name one input and one output file\n",
395
	      progname);
396
      usage();
397
    }
398
  }
399
#else
400
  /* Unix style: expect zero or one file name */
401
  if (file_index < argc-1) {
402
    fprintf(stderr, "%s: only one input file\n", progname);
403
    usage();
404
  }
405
#endif /* TWO_FILE_COMMANDLINE */
406
407
  /* Open the input file. */
408
  if (file_index < argc) {
409
    if ((input_file = fopen(argv[file_index], READ_BINARY)) == NULL) {
410
      fprintf(stderr, "%s: can't open %s\n", progname, argv[file_index]);
411
      exit(EXIT_FAILURE);
412
    }
413
  } else {
414
    /* default input file is stdin */
415
    input_file = read_stdin();
416
  }
417
418
  /* Open the output file. */
419
  if (outfilename != NULL) {
420
    if ((output_file = fopen(outfilename, WRITE_BINARY)) == NULL) {
421
      fprintf(stderr, "%s: can't open %s\n", progname, outfilename);
422
      exit(EXIT_FAILURE);
423
    }
424
  } else {
425
    /* default output file is stdout */
426
    output_file = write_stdout();
427
  }
428
429
#ifdef PROGRESS_REPORT
430
  start_progress_monitor((j_common_ptr) &dstinfo, &progress);
431
#endif
432
433
  /* Specify data source for decompression */
434
  jpeg_stdio_src(&srcinfo, input_file);
435
436
  /* Enable saving of extra markers that we want to copy */
437
  jcopy_markers_setup(&srcinfo, copyoption);
438
439
  /* Read file header */
440
  (void) jpeg_read_header(&srcinfo, TRUE);
441
442
  /* Any space needed by a transform option must be requested before
443
   * jpeg_read_coefficients so that memory allocation will be done right.
444
   */
445
#if TRANSFORMS_SUPPORTED
446
  jtransform_request_workspace(&srcinfo, &transformoption);
447
#endif
448
449
  /* Read source file as DCT coefficients */
450
  src_coef_arrays = jpeg_read_coefficients(&srcinfo);
451
452
  /* Initialize destination compression parameters from source values */
453
  jpeg_copy_critical_parameters(&srcinfo, &dstinfo);
454
455
  /* Adjust destination parameters if required by transform options;
456
   * also find out which set of coefficient arrays will hold the output.
457
   */
458
#if TRANSFORMS_SUPPORTED
459
  dst_coef_arrays = jtransform_adjust_parameters(&srcinfo, &dstinfo,
460
						 src_coef_arrays,
461
						 &transformoption);
462
#else
463
  dst_coef_arrays = src_coef_arrays;
464
#endif
465
466
  /* Adjust default compression parameters by re-parsing the options */
467
  file_index = parse_switches(&dstinfo, argc, argv, 0, TRUE);
468
469
  /* Specify data destination for compression */
470
  jpeg_stdio_dest(&dstinfo, output_file);
471
472
  /* Start compressor (note no image data is actually written here) */
473
  jpeg_write_coefficients(&dstinfo, dst_coef_arrays);
474
475
  /* Copy to the output file any extra markers that we want to preserve */
476
  jcopy_markers_execute(&srcinfo, &dstinfo, copyoption);
477
478
  /* Execute image transformation, if any */
479
#if TRANSFORMS_SUPPORTED
480
  jtransform_execute_transformation(&srcinfo, &dstinfo,
481
				    src_coef_arrays,
482
				    &transformoption);
483
#endif
484
485
  /* Finish compression and release memory */
486
  jpeg_finish_compress(&dstinfo);
487
  jpeg_destroy_compress(&dstinfo);
488
  (void) jpeg_finish_decompress(&srcinfo);
489
  jpeg_destroy_decompress(&srcinfo);
490
491
  /* Close files, if we opened them */
492
  if (input_file != stdin)
493
    fclose(input_file);
494
  if (output_file != stdout)
495
    fclose(output_file);
496
497
#ifdef PROGRESS_REPORT
498
  end_progress_monitor((j_common_ptr) &dstinfo);
499
#endif
500
501
  /* All done. */
502
  exit(jsrcerr.num_warnings + jdsterr.num_warnings ?EXIT_WARNING:EXIT_SUCCESS);
503
  return 0;			/* suppress no-return-value warnings */
504
}
(-)a/jpeg/jquant1.c (-1 / +5 lines)
Line     Link Here 
 Lines 1-12    Link Here 
1
/*
1
/*
2
 * jquant1.c
2
 * jquant1.c
3
 *
3
 *
4
 * Copyright (C) 1991-1996, Thomas G. Lane.
4
 * Copyright (C) 1991-1996, Thomas G. Lane.
5
 * Copyright (C) 2009, D. R. Commander
5
 * This file is part of the Independent JPEG Group's software.
6
 * This file is part of the Independent JPEG Group's software.
6
 * For conditions of distribution and use, see the accompanying README file.
7
 * For conditions of distribution and use, see the accompanying README file.
7
 *
8
 *
8
 * This file contains 1-pass color quantization (color mapping) routines.
9
 * This file contains 1-pass color quantization (color mapping) routines.
9
 * These routines provide mapping to a fixed color map using equally spaced
10
 * These routines provide mapping to a fixed color map using equally spaced
10
 * color values.  Optional Floyd-Steinberg or ordered dithering is available.
11
 * color values.  Optional Floyd-Steinberg or ordered dithering is available.
11
 */
12
 */
12
13
 Lines 188-204   select_ncolors (j_decompress_ptr cinfo, Link Here 
188
/* and fill in Ncolors[] array to indicate choice. */
189
/* and fill in Ncolors[] array to indicate choice. */
189
/* Return value is total number of colors (product of Ncolors[] values). */
190
/* Return value is total number of colors (product of Ncolors[] values). */
190
{
191
{
191
  int nc = cinfo->out_color_components; /* number of color components */
192
  int nc = cinfo->out_color_components; /* number of color components */
192
  int max_colors = cinfo->desired_number_of_colors;
193
  int max_colors = cinfo->desired_number_of_colors;
193
  int total_colors, iroot, i, j;
194
  int total_colors, iroot, i, j;
194
  boolean changed;
195
  boolean changed;
195
  long temp;
196
  long temp;
196
  static const int RGB_order[3] = { RGB_GREEN, RGB_RED, RGB_BLUE };
197
  int RGB_order[3] = { RGB_GREEN, RGB_RED, RGB_BLUE };
198
  RGB_order[0] = rgb_green[cinfo->out_color_space];
199
  RGB_order[1] = rgb_red[cinfo->out_color_space];
200
  RGB_order[2] = rgb_blue[cinfo->out_color_space];
197
201
198
  /* We can allocate at least the nc'th root of max_colors per component. */
202
  /* We can allocate at least the nc'th root of max_colors per component. */
199
  /* Compute floor(nc'th root of max_colors). */
203
  /* Compute floor(nc'th root of max_colors). */
200
  iroot = 1;
204
  iroot = 1;
201
  do {
205
  do {
202
    iroot++;
206
    iroot++;
203
    temp = iroot;		/* set temp = iroot ** nc */
207
    temp = iroot;		/* set temp = iroot ** nc */
204
    for (i = 1; i < nc; i++)
208
    for (i = 1; i < nc; i++)
(-)a/jpeg/jquant2.c (-32 / +15 lines)
Line     Link Here 
 Lines 1-12    Link Here 
1
/*
1
/*
2
 * jquant2.c
2
 * jquant2.c
3
 *
3
 *
4
 * Copyright (C) 1991-1996, Thomas G. Lane.
4
 * Copyright (C) 1991-1996, Thomas G. Lane.
5
 * Copyright (C) 2009, D. R. Commander.
5
 * This file is part of the Independent JPEG Group's software.
6
 * This file is part of the Independent JPEG Group's software.
6
 * For conditions of distribution and use, see the accompanying README file.
7
 * For conditions of distribution and use, see the accompanying README file.
7
 *
8
 *
8
 * This file contains 2-pass color quantization (color mapping) routines.
9
 * This file contains 2-pass color quantization (color mapping) routines.
9
 * These routines provide selection of a custom color map for an image,
10
 * These routines provide selection of a custom color map for an image,
10
 * followed by mapping of the image to that color map, with optional
11
 * followed by mapping of the image to that color map, with optional
11
 * Floyd-Steinberg dithering.
12
 * Floyd-Steinberg dithering.
12
 * It is also possible to use just the second pass to map to an arbitrary
13
 * It is also possible to use just the second pass to map to an arbitrary
 Lines 69-107    Link Here 
69
 * If you want to use this code to quantize a non-RGB color space, you'll
70
 * If you want to use this code to quantize a non-RGB color space, you'll
70
 * probably need to change these scale factors.
71
 * probably need to change these scale factors.
71
 */
72
 */
72
73
73
#define R_SCALE 2		/* scale R distances by this much */
74
#define R_SCALE 2		/* scale R distances by this much */
74
#define G_SCALE 3		/* scale G distances by this much */
75
#define G_SCALE 3		/* scale G distances by this much */
75
#define B_SCALE 1		/* and B by this much */
76
#define B_SCALE 1		/* and B by this much */
76
77
77
/* Relabel R/G/B as components 0/1/2, respecting the RGB ordering defined
78
static const int c_scales[3]={R_SCALE, G_SCALE, B_SCALE};
78
 * in jmorecfg.h.  As the code stands, it will do the right thing for R,G,B
79
#define C0_SCALE c_scales[rgb_red[cinfo->out_color_space]]
79
 * and B,G,R orders.  If you define some other weird order in jmorecfg.h,
80
#define C1_SCALE c_scales[rgb_green[cinfo->out_color_space]]
80
 * you'll get compile errors until you extend this logic.  In that case
81
#define C2_SCALE c_scales[rgb_blue[cinfo->out_color_space]]
81
 * you'll probably want to tweak the histogram sizes too.
82
 */
83
84
#if RGB_RED == 0
85
#define C0_SCALE R_SCALE
86
#endif
87
#if RGB_BLUE == 0
88
#define C0_SCALE B_SCALE
89
#endif
90
#if RGB_GREEN == 1
91
#define C1_SCALE G_SCALE
92
#endif
93
#if RGB_RED == 2
94
#define C2_SCALE R_SCALE
95
#endif
96
#if RGB_BLUE == 2
97
#define C2_SCALE B_SCALE
98
#endif
99
100
82
101
/*
83
/*
102
 * First we have the histogram data structure and routines for creating it.
84
 * First we have the histogram data structure and routines for creating it.
103
 *
85
 *
104
 * The number of bits of precision can be adjusted by changing these symbols.
86
 * The number of bits of precision can be adjusted by changing these symbols.
105
 * We recommend keeping 6 bits for G and 5 each for R and B.
87
 * We recommend keeping 6 bits for G and 5 each for R and B.
106
 * If you have plenty of memory and cycles, 6 bits all around gives marginally
88
 * If you have plenty of memory and cycles, 6 bits all around gives marginally
107
 * better results; if you are short of memory, 5 bits all around will save
89
 * better results; if you are short of memory, 5 bits all around will save
 Lines 449-473   median_cut (j_decompress_ptr cinfo, boxp Link Here 
449
     * See notes in update_box about scaling distances.
431
     * See notes in update_box about scaling distances.
450
     */
432
     */
451
    c0 = ((b1->c0max - b1->c0min) << C0_SHIFT) * C0_SCALE;
433
    c0 = ((b1->c0max - b1->c0min) << C0_SHIFT) * C0_SCALE;
452
    c1 = ((b1->c1max - b1->c1min) << C1_SHIFT) * C1_SCALE;
434
    c1 = ((b1->c1max - b1->c1min) << C1_SHIFT) * C1_SCALE;
453
    c2 = ((b1->c2max - b1->c2min) << C2_SHIFT) * C2_SCALE;
435
    c2 = ((b1->c2max - b1->c2min) << C2_SHIFT) * C2_SCALE;
454
    /* We want to break any ties in favor of green, then red, blue last.
436
    /* We want to break any ties in favor of green, then red, blue last.
455
     * This code does the right thing for R,G,B or B,G,R color orders only.
437
     * This code does the right thing for R,G,B or B,G,R color orders only.
456
     */
438
     */
457
#if RGB_RED == 0
439
    if (rgb_red[cinfo->out_color_space] == 0) {
458
    cmax = c1; n = 1;
440
      cmax = c1; n = 1;
459
    if (c0 > cmax) { cmax = c0; n = 0; }
441
      if (c0 > cmax) { cmax = c0; n = 0; }
460
    if (c2 > cmax) { n = 2; }
442
      if (c2 > cmax) { n = 2; }
461
#else
443
    }
462
    cmax = c1; n = 1;
444
    else {
463
    if (c2 > cmax) { cmax = c2; n = 2; }
445
      cmax = c1; n = 1;
464
    if (c0 > cmax) { n = 0; }
446
      if (c2 > cmax) { cmax = c2; n = 2; }
465
#endif
447
      if (c0 > cmax) { n = 0; }
448
    }
466
    /* Choose split point along selected axis, and update box bounds.
449
    /* Choose split point along selected axis, and update box bounds.
467
     * Current algorithm: split at halfway point.
450
     * Current algorithm: split at halfway point.
468
     * (Since the box has been shrunk to minimum volume,
451
     * (Since the box has been shrunk to minimum volume,
469
     * any split will produce two nonempty subboxes.)
452
     * any split will produce two nonempty subboxes.)
470
     * Note that lb value is max for lower box, so must be < old max.
453
     * Note that lb value is max for lower box, so must be < old max.
471
     */
454
     */
472
    switch (n) {
455
    switch (n) {
473
    case 0:
456
    case 0:
(-)a/jpeg/jsimd.h (+89 lines)
Line     Link Here 
Line 0    Link Here 
1
/*
2
 * jsimd.h
3
 *
4
 * Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
5
 * 
6
 * Based on the x86 SIMD extension for IJG JPEG library,
7
 * Copyright (C) 1999-2006, MIYASAKA Masaru.
8
 *
9
 */
10
11
/* Short forms of external names for systems with brain-damaged linkers. */
12
13
#ifdef NEED_SHORT_EXTERNAL_NAMES
14
#define jsimd_can_rgb_ycc                 jSCanRgbYcc
15
#define jsimd_can_ycc_rgb                 jSCanYccRgb
16
#define jsimd_rgb_ycc_convert             jSRgbYccConv
17
#define jsimd_ycc_rgb_convert             jSYccRgbConv
18
#define jsimd_can_h2v2_downsample         jSCanH2V2Down
19
#define jsimd_can_h2v1_downsample         jSCanH2V1Down
20
#define jsimd_h2v2_downsample             jSH2V2Down
21
#define jsimd_h2v1_downsample             jSH2V1Down
22
#define jsimd_can_h2v2_upsample           jSCanH2V2Up
23
#define jsimd_can_h2v1_upsample           jSCanH2V1Up
24
#define jsimd_h2v2_upsample               jSH2V2Up
25
#define jsimd_h2v1_upsample               jSH2V1Up
26
#define jsimd_can_h2v2_fancy_upsample     jSCanH2V2FUp
27
#define jsimd_can_h2v1_fancy_upsample     jSCanH2V1FUp
28
#define jsimd_h2v2_fancy_upsample         jSH2V2FUp
29
#define jsimd_h2v1_fancy_upsample         jSH2V1FUp
30
#define jsimd_can_h2v2_merged_upsample    jSCanH2V2MUp
31
#define jsimd_can_h2v1_merged_upsample    jSCanH2V1MUp
32
#define jsimd_h2v2_merged_upsample        jSH2V2MUp
33
#define jsimd_h2v1_merged_upsample        jSH2V1MUp
34
#endif /* NEED_SHORT_EXTERNAL_NAMES */
35
36
EXTERN(int) jsimd_can_rgb_ycc JPP((void));
37
EXTERN(int) jsimd_can_ycc_rgb JPP((void));
38
39
EXTERN(void) jsimd_rgb_ycc_convert
40
        JPP((j_compress_ptr cinfo,
41
             JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
42
             JDIMENSION output_row, int num_rows));
43
EXTERN(void) jsimd_ycc_rgb_convert
44
        JPP((j_decompress_ptr cinfo,
45
             JSAMPIMAGE input_buf, JDIMENSION input_row,
46
             JSAMPARRAY output_buf, int num_rows));
47
48
EXTERN(int) jsimd_can_h2v2_downsample JPP((void));
49
EXTERN(int) jsimd_can_h2v1_downsample JPP((void));
50
51
EXTERN(void) jsimd_h2v2_downsample
52
        JPP((j_compress_ptr cinfo, jpeg_component_info * compptr,
53
             JSAMPARRAY input_data, JSAMPARRAY output_data));
54
EXTERN(void) jsimd_h2v1_downsample
55
        JPP((j_compress_ptr cinfo, jpeg_component_info * compptr,
56
             JSAMPARRAY input_data, JSAMPARRAY output_data));
57
58
EXTERN(int) jsimd_can_h2v2_upsample JPP((void));
59
EXTERN(int) jsimd_can_h2v1_upsample JPP((void));
60
61
EXTERN(void) jsimd_h2v2_upsample
62
        JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr,
63
             JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr));
64
EXTERN(void) jsimd_h2v1_upsample
65
        JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr,
66
             JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr));
67
68
EXTERN(int) jsimd_can_h2v2_fancy_upsample JPP((void));
69
EXTERN(int) jsimd_can_h2v1_fancy_upsample JPP((void));
70
71
EXTERN(void) jsimd_h2v2_fancy_upsample
72
        JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr,
73
             JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr));
74
EXTERN(void) jsimd_h2v1_fancy_upsample
75
        JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr,
76
             JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr));
77
78
EXTERN(int) jsimd_can_h2v2_merged_upsample JPP((void));
79
EXTERN(int) jsimd_can_h2v1_merged_upsample JPP((void));
80
81
EXTERN(void) jsimd_h2v2_merged_upsample
82
        JPP((j_decompress_ptr cinfo,
83
             JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
84
             JSAMPARRAY output_buf));
85
EXTERN(void) jsimd_h2v1_merged_upsample
86
        JPP((j_decompress_ptr cinfo,
87
             JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
88
             JSAMPARRAY output_buf));
89
(-)a/jpeg/jsimd_none.c (+299 lines)
Line     Link Here 
Line 0    Link Here 
1
/*
2
 * jsimd_none.c
3
 *
4
 * Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
5
 * Copyright 2009 D. R. Commander
6
 * 
7
 * Based on the x86 SIMD extension for IJG JPEG library,
8
 * Copyright (C) 1999-2006, MIYASAKA Masaru.
9
 *
10
 * This file contains stubs for when there is no SIMD support available.
11
 */
12
13
#define JPEG_INTERNALS
14
#include "jinclude.h"
15
#include "jpeglib.h"
16
#include "jsimd.h"
17
#include "jdct.h"
18
#include "jsimddct.h"
19
20
GLOBAL(int)
21
jsimd_can_rgb_ycc (void)
22
{
23
  return 0;
24
}
25
26
GLOBAL(int)
27
jsimd_can_ycc_rgb (void)
28
{
29
  return 0;
30
}
31
32
GLOBAL(void)
33
jsimd_rgb_ycc_convert (j_compress_ptr cinfo,
34
                       JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
35
                       JDIMENSION output_row, int num_rows)
36
{
37
}
38
39
GLOBAL(void)
40
jsimd_ycc_rgb_convert (j_decompress_ptr cinfo,
41
                       JSAMPIMAGE input_buf, JDIMENSION input_row,
42
                       JSAMPARRAY output_buf, int num_rows)
43
{
44
}
45
46
GLOBAL(int)
47
jsimd_can_h2v2_downsample (void)
48
{
49
  return 0;
50
}
51
52
GLOBAL(int)
53
jsimd_can_h2v1_downsample (void)
54
{
55
  return 0;
56
}
57
58
GLOBAL(void)
59
jsimd_h2v2_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr,
60
                       JSAMPARRAY input_data, JSAMPARRAY output_data)
61
{
62
}
63
64
GLOBAL(void)
65
jsimd_h2v1_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr,
66
                       JSAMPARRAY input_data, JSAMPARRAY output_data)
67
{
68
}
69
70
GLOBAL(int)
71
jsimd_can_h2v2_upsample (void)
72
{
73
  return 0;
74
}
75
76
GLOBAL(int)
77
jsimd_can_h2v1_upsample (void)
78
{
79
  return 0;
80
}
81
82
GLOBAL(void)
83
jsimd_h2v2_upsample (j_decompress_ptr cinfo,
84
                     jpeg_component_info * compptr, 
85
                     JSAMPARRAY input_data,
86
                     JSAMPARRAY * output_data_ptr)
87
{
88
}
89
90
GLOBAL(void)
91
jsimd_h2v1_upsample (j_decompress_ptr cinfo,
92
                     jpeg_component_info * compptr, 
93
                     JSAMPARRAY input_data,
94
                     JSAMPARRAY * output_data_ptr)
95
{
96
}
97
98
GLOBAL(int)
99
jsimd_can_h2v2_fancy_upsample (void)
100
{
101
  return 0;
102
}
103
104
GLOBAL(int)
105
jsimd_can_h2v1_fancy_upsample (void)
106
{
107
  return 0;
108
}
109
110
GLOBAL(void)
111
jsimd_h2v2_fancy_upsample (j_decompress_ptr cinfo,
112
                           jpeg_component_info * compptr, 
113
                           JSAMPARRAY input_data,
114
                           JSAMPARRAY * output_data_ptr)
115
{
116
}
117
118
GLOBAL(void)
119
jsimd_h2v1_fancy_upsample (j_decompress_ptr cinfo,
120
                           jpeg_component_info * compptr, 
121
                           JSAMPARRAY input_data,
122
                           JSAMPARRAY * output_data_ptr)
123
{
124
}
125
126
GLOBAL(int)
127
jsimd_can_h2v2_merged_upsample (void)
128
{
129
  return 0;
130
}
131
132
GLOBAL(int)
133
jsimd_can_h2v1_merged_upsample (void)
134
{
135
  return 0;
136
}
137
138
GLOBAL(void)
139
jsimd_h2v2_merged_upsample (j_decompress_ptr cinfo,
140
                            JSAMPIMAGE input_buf,
141
                            JDIMENSION in_row_group_ctr,
142
                            JSAMPARRAY output_buf)
143
{
144
}
145
146
GLOBAL(void)
147
jsimd_h2v1_merged_upsample (j_decompress_ptr cinfo,
148
                            JSAMPIMAGE input_buf,
149
                            JDIMENSION in_row_group_ctr,
150
                            JSAMPARRAY output_buf)
151
{
152
}
153
154
GLOBAL(int)
155
jsimd_can_convsamp (void)
156
{
157
  return 0;
158
}
159
160
GLOBAL(int)
161
jsimd_can_convsamp_float (void)
162
{
163
  return 0;
164
}
165
166
GLOBAL(void)
167
jsimd_convsamp (JSAMPARRAY sample_data, JDIMENSION start_col,
168
                DCTELEM * workspace)
169
{
170
}
171
172
GLOBAL(void)
173
jsimd_convsamp_float (JSAMPARRAY sample_data, JDIMENSION start_col,
174
                      FAST_FLOAT * workspace)
175
{
176
}
177
178
GLOBAL(int)
179
jsimd_can_fdct_islow (void)
180
{
181
  return 0;
182
}
183
184
GLOBAL(int)
185
jsimd_can_fdct_ifast (void)
186
{
187
  return 0;
188
}
189
190
GLOBAL(int)
191
jsimd_can_fdct_float (void)
192
{
193
  return 0;
194
}
195
196
GLOBAL(void)
197
jsimd_fdct_islow (DCTELEM * data)
198
{
199
}
200
201
GLOBAL(void)
202
jsimd_fdct_ifast (DCTELEM * data)
203
{
204
}
205
206
GLOBAL(void)
207
jsimd_fdct_float (FAST_FLOAT * data)
208
{
209
}
210
211
GLOBAL(int)
212
jsimd_can_quantize (void)
213
{
214
  return 0;
215
}
216
217
GLOBAL(int)
218
jsimd_can_quantize_float (void)
219
{
220
  return 0;
221
}
222
223
GLOBAL(void)
224
jsimd_quantize (JCOEFPTR coef_block, DCTELEM * divisors,
225
                DCTELEM * workspace)
226
{
227
}
228
229
GLOBAL(void)
230
jsimd_quantize_float (JCOEFPTR coef_block, FAST_FLOAT * divisors,
231
                      FAST_FLOAT * workspace)
232
{
233
}
234
235
GLOBAL(int)
236
jsimd_can_idct_2x2 (void)
237
{
238
  return 0;
239
}
240
241
GLOBAL(int)
242
jsimd_can_idct_4x4 (void)
243
{
244
  return 0;
245
}
246
247
GLOBAL(void)
248
jsimd_idct_2x2 (j_decompress_ptr cinfo, jpeg_component_info * compptr,
249
                JCOEFPTR coef_block, JSAMPARRAY output_buf,
250
                JDIMENSION output_col)
251
{
252
}
253
254
GLOBAL(void)
255
jsimd_idct_4x4 (j_decompress_ptr cinfo, jpeg_component_info * compptr,
256
                JCOEFPTR coef_block, JSAMPARRAY output_buf,
257
                JDIMENSION output_col)
258
{
259
}
260
261
GLOBAL(int)
262
jsimd_can_idct_islow (void)
263
{
264
  return 0;
265
}
266
267
GLOBAL(int)
268
jsimd_can_idct_ifast (void)
269
{
270
  return 0;
271
}
272
273
GLOBAL(int)
274
jsimd_can_idct_float (void)
275
{
276
  return 0;
277
}
278
279
GLOBAL(void)
280
jsimd_idct_islow (j_decompress_ptr cinfo, jpeg_component_info * compptr,
281
                JCOEFPTR coef_block, JSAMPARRAY output_buf,
282
                JDIMENSION output_col)
283
{
284
}
285
286
GLOBAL(void)
287
jsimd_idct_ifast (j_decompress_ptr cinfo, jpeg_component_info * compptr,
288
                JCOEFPTR coef_block, JSAMPARRAY output_buf,
289
                JDIMENSION output_col)
290
{
291
}
292
293
GLOBAL(void)
294
jsimd_idct_float (j_decompress_ptr cinfo, jpeg_component_info * compptr,
295
                JCOEFPTR coef_block, JSAMPARRAY output_buf,
296
                JDIMENSION output_col)
297
{
298
}
299
(-)a/jpeg/jsimddct.h (+101 lines)
Line     Link Here 
Line 0    Link Here 
1
/*
2
 * jsimddct.h
3
 *
4
 * Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
5
 * 
6
 * Based on the x86 SIMD extension for IJG JPEG library,
7
 * Copyright (C) 1999-2006, MIYASAKA Masaru.
8
 *
9
 */
10
11
/* Short forms of external names for systems with brain-damaged linkers. */
12
13
#ifdef NEED_SHORT_EXTERNAL_NAMES
14
#define jsimd_can_convsamp                jSCanConv
15
#define jsimd_can_convsamp_float          jSCanConvF
16
#define jsimd_convsamp                    jSConv
17
#define jsimd_convsamp_float              jSConvF
18
#define jsimd_can_fdct_islow              jSCanFDCTIS
19
#define jsimd_can_fdct_ifast              jSCanFDCTIF
20
#define jsimd_can_fdct_float              jSCanFDCTFl
21
#define jsimd_fdct_islow                  jSFDCTIS
22
#define jsimd_fdct_ifast                  jSFDCTIF
23
#define jsimd_fdct_float                  jSFDCTFl
24
#define jsimd_can_quantize                jSCanQuant
25
#define jsimd_can_quantize_float          jSCanQuantF
26
#define jsimd_quantize                    jSQuant
27
#define jsimd_quantize_float              jSQuantF
28
#define jsimd_can_idct_2x2                jSCanIDCT22
29
#define jsimd_can_idct_4x4                jSCanIDCT44
30
#define jsimd_idct_2x2                    jSIDCT22
31
#define jsimd_idct_4x4                    jSIDCT44
32
#define jsimd_can_idct_islow              jSCanIDCTIS
33
#define jsimd_can_idct_ifast              jSCanIDCTIF
34
#define jsimd_can_idct_float              jSCanIDCTFl
35
#define jsimd_idct_islow                  jSIDCTIS
36
#define jsimd_idct_ifast                  jSIDCTIF
37
#define jsimd_idct_float                  jSIDCTFl
38
#endif /* NEED_SHORT_EXTERNAL_NAMES */
39
40
EXTERN(int) jsimd_can_convsamp JPP((void));
41
EXTERN(int) jsimd_can_convsamp_float JPP((void));
42
43
EXTERN(void) jsimd_convsamp JPP((JSAMPARRAY sample_data,
44
                                 JDIMENSION start_col,
45
                                 DCTELEM * workspace));
46
EXTERN(void) jsimd_convsamp_float JPP((JSAMPARRAY sample_data,
47
                                       JDIMENSION start_col,
48
                                       FAST_FLOAT * workspace));
49
50
EXTERN(int) jsimd_can_fdct_islow JPP((void));
51
EXTERN(int) jsimd_can_fdct_ifast JPP((void));
52
EXTERN(int) jsimd_can_fdct_float JPP((void));
53
54
EXTERN(void) jsimd_fdct_islow JPP((DCTELEM * data));
55
EXTERN(void) jsimd_fdct_ifast JPP((DCTELEM * data));
56
EXTERN(void) jsimd_fdct_float JPP((FAST_FLOAT * data));
57
58
EXTERN(int) jsimd_can_quantize JPP((void));
59
EXTERN(int) jsimd_can_quantize_float JPP((void));
60
61
EXTERN(void) jsimd_quantize JPP((JCOEFPTR coef_block,
62
                                 DCTELEM * divisors,
63
                                 DCTELEM * workspace));
64
EXTERN(void) jsimd_quantize_float JPP((JCOEFPTR coef_block,
65
                                       FAST_FLOAT * divisors,
66
                                       FAST_FLOAT * workspace));
67
68
EXTERN(int) jsimd_can_idct_2x2 JPP((void));
69
EXTERN(int) jsimd_can_idct_4x4 JPP((void));
70
71
EXTERN(void) jsimd_idct_2x2 JPP((j_decompress_ptr cinfo,
72
                                 jpeg_component_info * compptr,
73
                                 JCOEFPTR coef_block,
74
                                 JSAMPARRAY output_buf,
75
                                 JDIMENSION output_col));
76
EXTERN(void) jsimd_idct_4x4 JPP((j_decompress_ptr cinfo,
77
                                 jpeg_component_info * compptr,
78
                                 JCOEFPTR coef_block,
79
                                 JSAMPARRAY output_buf,
80
                                 JDIMENSION output_col));
81
82
EXTERN(int) jsimd_can_idct_islow JPP((void));
83
EXTERN(int) jsimd_can_idct_ifast JPP((void));
84
EXTERN(int) jsimd_can_idct_float JPP((void));
85
86
EXTERN(void) jsimd_idct_islow JPP((j_decompress_ptr cinfo,
87
                                   jpeg_component_info * compptr,
88
                                   JCOEFPTR coef_block,
89
                                   JSAMPARRAY output_buf,
90
                                   JDIMENSION output_col));
91
EXTERN(void) jsimd_idct_ifast JPP((j_decompress_ptr cinfo,
92
                                   jpeg_component_info * compptr,
93
                                   JCOEFPTR coef_block,
94
                                   JSAMPARRAY output_buf,
95
                                   JDIMENSION output_col));
96
EXTERN(void) jsimd_idct_float JPP((j_decompress_ptr cinfo,
97
                                   jpeg_component_info * compptr,
98
                                   JCOEFPTR coef_block,
99
                                   JSAMPARRAY output_buf,
100
                                   JDIMENSION output_col));
101
(-)a/jpeg/jutils.c (-2 / +2 lines)
Line     Link Here 
 Lines 72-89   GLOBAL(long) Link Here 
72
jdiv_round_up (long a, long b)
72
jdiv_round_up (long a, long b)
73
/* Compute a/b rounded up to next integer, ie, ceil(a/b) */
73
/* Compute a/b rounded up to next integer, ie, ceil(a/b) */
74
/* Assumes a >= 0, b > 0 */
74
/* Assumes a >= 0, b > 0 */
75
{
75
{
76
  return (a + b - 1L) / b;
76
  return (a + b - 1L) / b;
77
}
77
}
78
78
79
79
80
GLOBAL(long)
80
GLOBAL(size_t)
81
jround_up (long a, long b)
81
jround_up (size_t a, size_t b)
82
/* Compute a rounded up to next multiple of b, ie, ceil(a/b)*b */
82
/* Compute a rounded up to next multiple of b, ie, ceil(a/b)*b */
83
/* Assumes a >= 0, b > 0 */
83
/* Assumes a >= 0, b > 0 */
84
{
84
{
85
  a += b - 1L;
85
  a += b - 1L;
86
  return a - (a % b);
86
  return a - (a % b);
87
}
87
}
88
88
89
89
(-)a/jpeg/jwinfig.h (-48 lines)
Line     Link Here 
 Lines 1-48    Link Here 
1
/* jconfig.mc6 --- jconfig.h for Microsoft C on MS-DOS, version 6.00A & up. */
2
/* see jconfig.doc for explanations */
3
4
/* this is a hack */
5
#define HAVE_BOOLEAN
6
#ifndef __RPCNDR_H__
7
typedef unsigned char boolean;
8
#endif
9
10
#define HAVE_PROTOTYPES
11
#define HAVE_UNSIGNED_CHAR
12
#define HAVE_UNSIGNED_SHORT
13
/* #define void char */
14
/* #define const */
15
#undef CHAR_IS_UNSIGNED
16
#define HAVE_STDDEF_H
17
#define HAVE_STDLIB_H
18
#undef NEED_BSD_STRINGS
19
#undef NEED_SYS_TYPES_H
20
#undef NEED_FAR_POINTERS	/* for small or medium memory model */
21
#undef NEED_SHORT_EXTERNAL_NAMES
22
#undef INCOMPLETE_TYPES_BROKEN
23
24
#ifdef JPEG_INTERNALS
25
26
#undef RIGHT_SHIFT_IS_UNSIGNED
27
28
#define USE_MSDOS_MEMANSI
29
30
#define MAX_ALLOC_CHUNK 65520L	/* Maximum request to malloc() */
31
32
#endif /* JPEG_INTERNALS */
33
34
#ifdef JPEG_CJPEG_DJPEG
35
36
#define BMP_SUPPORTED		/* BMP image file format */
37
#define GIF_SUPPORTED		/* GIF image file format */
38
#define PPM_SUPPORTED		/* PBMPLUS PPM/PGM image file format */
39
#undef RLE_SUPPORTED		/* Utah RLE image file format */
40
#define TARGA_SUPPORTED		/* Targa image file format */
41
42
#define TWO_FILE_COMMANDLINE
43
#define USE_SETMODE		/* Microsoft has setmode() */
44
#define NEED_SIGNAL_CATCHER	/* Define this if you use jmemdos.c */
45
#undef DONT_USE_B_MODE
46
#undef PROGRESS_REPORT		/* optional */
47
48
#endif /* JPEG_CJPEG_DJPEG */
(-)a/jpeg/makefile.gen (-274 lines)
Line     Link Here 
 Lines 1-274    Link Here 
1
# Generated automatically from makefile.cfg by configure.
2
# Makefile for Independent JPEG Group's software
3
4
# makefile.cfg is edited by configure to produce a custom Makefile.
5
6
# Read installation instructions before saying "make" !!
7
8
# For compiling with source and object files in different directories.
9
srcdir = $(VPATH)
10
11
# Where to install the programs and man pages.
12
prefix = /usr/local
13
exec_prefix = ${prefix}
14
bindir = $(exec_prefix)/bin
15
libdir = $(exec_prefix)/lib
16
includedir = $(prefix)/include
17
binprefix =
18
manprefix =
19
manext = 1
20
mandir = $(prefix)/man/man$(manext)
21
22
# The name of your C compiler:
23
CC= cc
24
25
# You may need to adjust these cc options:
26
CFLAGS= -O3  -I$(srcdir)
27
# Generally, we recommend defining any configuration symbols in jconfig.h,
28
# NOT via -D switches here.
29
# However, any special defines for ansi2knr.c may be included here:
30
ANSI2KNRFLAGS= 
31
32
# Link-time cc options:
33
LDFLAGS= 
34
35
# To link any special libraries, add the necessary -l commands here.
36
LDLIBS= 
37
38
# Put here the object file name for the correct system-dependent memory
39
# manager file.  For Unix this is usually jmemnobs.o, but you may want
40
# to use jmemansi.o or jmemname.o if you have limited swap space.
41
SYSDEPMEM= jmemnobs.o
42
43
# miscellaneous OS-dependent stuff
44
SHELL= /bin/sh
45
# linker
46
LN= $(CC)
47
# file deletion command
48
RM= rm -f
49
# file rename command
50
MV= mv
51
# library (.a) file creation command
52
AR= ar rc
53
# second step in .a creation (use "touch" if not needed)
54
AR2= ranlib
55
# installation program
56
INSTALL= cp
57
INSTALL_PROGRAM= ${INSTALL}
58
INSTALL_DATA= ${INSTALL}
59
60
# End of configurable options.
61
62
63
# source files: JPEG library proper
64
LIBSOURCES= jcapimin.c jcapistd.c jccoefct.c jccolor.c jcdctmgr.c jchuff.c \
65
        jcinit.c jcmainct.c jcmarker.c jcmaster.c jcomapi.c jcparam.c \
66
        jcphuff.c jcprepct.c jcsample.c jctrans.c jdapimin.c jdapistd.c \
67
        jdatadst.c jdatasrc.c jdcoefct.c jdcolor.c jddctmgr.c jdhuff.c \
68
        jdinput.c jdmainct.c jdmarker.c jdmaster.c jdmerge.c jdphuff.c \
69
        jdpostct.c jdsample.c jdtrans.c jerror.c jfdctflt.c jfdctfst.c \
70
        jfdctint.c jidctflt.c jidctfst.c jidctint.c jidctred.c jquant1.c \
71
        jquant2.c jutils.c jmemmgr.c jmemansi.c jmemname.c jmemnobs.c \
72
        jmemdos.c
73
# source files: cjpeg/djpeg/jpegtran applications, also rdjpgcom/wrjpgcom
74
APPSOURCES= cjpeg.c djpeg.c jpegtran.c cdjpeg.c rdcolmap.c rdswitch.c \
75
        rdjpgcom.c wrjpgcom.c rdppm.c wrppm.c rdgif.c wrgif.c rdtarga.c \
76
        wrtarga.c rdbmp.c wrbmp.c rdrle.c wrrle.c
77
SOURCES= $(LIBSOURCES) $(APPSOURCES)
78
# files included by source files
79
INCLUDES= jchuff.h jdhuff.h jdct.h jerror.h jinclude.h jmemsys.h jmorecfg.h \
80
        jpegint.h jpeglib.h jversion.h cdjpeg.h cderror.h
81
# documentation, test, and support files
82
DOCS= README install.doc usage.doc cjpeg.1 djpeg.1 jpegtran.1 rdjpgcom.1 \
83
        wrjpgcom.1 wizard.doc example.c libjpeg.doc structure.doc \
84
        coderules.doc filelist.doc change.log
85
MKFILES= configure makefile.cfg makefile.ansi makefile.unix makefile.bcc \
86
        makefile.mc6 makefile.dj makefile.wat makcjpeg.st makdjpeg.st \
87
        makljpeg.st maktjpeg.st makefile.manx makefile.sas makefile.mms \
88
        makefile.vms makvms.opt
89
CONFIGFILES= jconfig.cfg jconfig.manx jconfig.sas jconfig.st jconfig.bcc \
90
        jconfig.mc6 jconfig.dj jconfig.wat jconfig.vms
91
OTHERFILES= jconfig.doc ckconfig.c ansi2knr.c ansi2knr.1 jmemdosa.asm
92
TESTFILES= testorig.jpg testimg.ppm testimg.gif testimg.jpg testprog.jpg \
93
        testimgp.jpg
94
DISTFILES= $(DOCS) $(MKFILES) $(CONFIGFILES) $(SOURCES) $(INCLUDES) \
95
        $(OTHERFILES) $(TESTFILES)
96
# library object files common to compression and decompression
97
COMOBJECTS= jcomapi.o jutils.o jerror.o jmemmgr.o $(SYSDEPMEM)
98
# compression library object files
99
CLIBOBJECTS= jcapimin.o jcapistd.o jctrans.o jcparam.o jdatadst.o jcinit.o \
100
        jcmaster.o jcmarker.o jcmainct.o jcprepct.o jccoefct.o jccolor.o \
101
        jcsample.o jchuff.o jcphuff.o jcdctmgr.o jfdctfst.o jfdctflt.o \
102
        jfdctint.o
103
# decompression library object files
104
DLIBOBJECTS= jdapimin.o jdapistd.o jdatasrc.o jdmaster.o \
105
        jdinput.o jdmarker.o jdhuff.o jdphuff.o jdmainct.o jdcoefct.o \
106
        jdpostct.o jddctmgr.o jidctfst.o jidctflt.o jidctint.o jidctred.o \
107
        jdsample.o jdcolor.o jquant1.o jquant2.o jdmerge.o
108
# These objectfiles are included in libjpeg.a
109
LIBOBJECTS= $(CLIBOBJECTS) $(DLIBOBJECTS) $(COMOBJECTS)
110
# object files for sample applications (excluding library files)
111
COBJECTS= cjpeg.o rdppm.o rdgif.o rdtarga.o rdrle.o rdbmp.o rdswitch.o \
112
        cdjpeg.o
113
DOBJECTS= djpeg.o wrppm.o wrgif.o wrtarga.o wrrle.o wrbmp.o rdcolmap.o \
114
        cdjpeg.o
115
TROBJECTS= jpegtran.o rdswitch.o cdjpeg.o
116
117
all: libjpeg.a
118
119
realall:  libjpeg.a cjpeg djpeg jpegtran rdjpgcom wrjpgcom
120
121
# This rule causes ansi2knr to be invoked.
122
# .c.o:
123
# 	./ansi2knr $(srcdir)/$*.c T$*.c
124
# 	$(CC) $(CFLAGS) -c T$*.c
125
# 	$(RM) T$*.c $*.o
126
# 	$(MV) T$*.o $*.o
127
128
ansi2knr: ansi2knr.c
129
	$(CC) $(CFLAGS) $(ANSI2KNRFLAGS) -o ansi2knr ansi2knr.c
130
131
# Decompression-only library
132
libjpeg.a:  $(DLIBOBJECTS) $(COMOBJECTS)
133
	$(RM) libjpeg.a
134
	$(AR) libjpeg.a  $(DLIBOBJECTS) $(COMOBJECTS)
135
	$(AR2) libjpeg.a
136
137
cjpeg: $(COBJECTS) libjpeg.a
138
	$(LN) $(LDFLAGS) -o cjpeg $(COBJECTS) libjpeg.a $(LDLIBS)
139
140
djpeg: $(DOBJECTS) libjpeg.a
141
	$(LN) $(LDFLAGS) -o djpeg $(DOBJECTS) libjpeg.a $(LDLIBS)
142
143
jpegtran: $(TROBJECTS) libjpeg.a
144
	$(LN) $(LDFLAGS) -o jpegtran $(TROBJECTS) libjpeg.a $(LDLIBS)
145
146
rdjpgcom: rdjpgcom.o
147
	$(LN) $(LDFLAGS) -o rdjpgcom rdjpgcom.o $(LDLIBS)
148
149
wrjpgcom: wrjpgcom.o
150
	$(LN) $(LDFLAGS) -o wrjpgcom wrjpgcom.o $(LDLIBS)
151
152
jconfig.h: jconfig.doc
153
	echo You must prepare a system-dependent jconfig.h file.
154
	echo Please read the installation directions in install.doc.
155
	exit 1
156
157
install: cjpeg djpeg jpegtran rdjpgcom wrjpgcom
158
	$(INSTALL_PROGRAM) cjpeg $(bindir)/$(binprefix)cjpeg
159
	$(INSTALL_PROGRAM) djpeg $(bindir)/$(binprefix)djpeg
160
	$(INSTALL_PROGRAM) jpegtran $(bindir)/$(binprefix)jpegtran
161
	$(INSTALL_PROGRAM) rdjpgcom $(bindir)/$(binprefix)rdjpgcom
162
	$(INSTALL_PROGRAM) wrjpgcom $(bindir)/$(binprefix)wrjpgcom
163
	$(INSTALL_DATA) $(srcdir)/cjpeg.1 $(mandir)/$(manprefix)cjpeg.$(manext)
164
	$(INSTALL_DATA) $(srcdir)/djpeg.1 $(mandir)/$(manprefix)djpeg.$(manext)
165
	$(INSTALL_DATA) $(srcdir)/jpegtran.1 $(mandir)/$(manprefix)jpegtran.$(manext)
166
	$(INSTALL_DATA) $(srcdir)/rdjpgcom.1 $(mandir)/$(manprefix)rdjpgcom.$(manext)
167
	$(INSTALL_DATA) $(srcdir)/wrjpgcom.1 $(mandir)/$(manprefix)wrjpgcom.$(manext)
168
169
install-lib: libjpeg.a install-headers
170
	$(INSTALL_DATA) libjpeg.a $(libdir)/$(binprefix)libjpeg.a
171
172
install-headers: jconfig.h
173
	$(INSTALL_DATA) jconfig.h $(includedir)/jconfig.h
174
	$(INSTALL_DATA) $(srcdir)/jpeglib.h $(includedir)/jpeglib.h
175
	$(INSTALL_DATA) $(srcdir)/jmorecfg.h $(includedir)/jmorecfg.h
176
	$(INSTALL_DATA) $(srcdir)/jerror.h $(includedir)/jerror.h
177
178
clean:
179
	$(RM) *.o cjpeg djpeg jpegtran libjpeg.a rdjpgcom wrjpgcom
180
	$(RM) ansi2knr core testout* config.log config.status
181
182
distribute:
183
	$(RM) jpegsrc.tar*
184
	tar cvf jpegsrc.tar $(DISTFILES)
185
	compress -v jpegsrc.tar
186
187
test: cjpeg djpeg jpegtran
188
	$(RM) testout*
189
	./djpeg -dct int -ppm -outfile testout.ppm  $(srcdir)/testorig.jpg
190
	./djpeg -dct int -gif -outfile testout.gif  $(srcdir)/testorig.jpg
191
	./cjpeg -dct int -outfile testout.jpg  $(srcdir)/testimg.ppm
192
	./djpeg -dct int -ppm -outfile testoutp.ppm $(srcdir)/testprog.jpg
193
	./cjpeg -dct int -progressive -opt -outfile testoutp.jpg $(srcdir)/testimg.ppm
194
	./jpegtran -outfile testoutt.jpg $(srcdir)/testprog.jpg
195
	cmp $(srcdir)/testimg.ppm testout.ppm
196
	cmp $(srcdir)/testimg.gif testout.gif
197
	cmp $(srcdir)/testimg.jpg testout.jpg
198
	cmp $(srcdir)/testimg.ppm testoutp.ppm
199
	cmp $(srcdir)/testimgp.jpg testoutp.jpg
200
	cmp $(srcdir)/testorig.jpg testoutt.jpg
201
202
check: test
203
204
# GNU Make likes to know which target names are not really files to be made:
205
.PHONY: all install install-lib install-headers clean distribute test check
206
207
208
jcapimin.o: jcapimin.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
209
jcapistd.o: jcapistd.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
210
jccoefct.o: jccoefct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
211
jccolor.o: jccolor.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
212
jcdctmgr.o: jcdctmgr.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
213
jchuff.o: jchuff.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jchuff.h
214
jcinit.o: jcinit.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
215
jcmainct.o: jcmainct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
216
jcmarker.o: jcmarker.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
217
jcmaster.o: jcmaster.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
218
jcomapi.o: jcomapi.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
219
jcparam.o: jcparam.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
220
jcphuff.o: jcphuff.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jchuff.h
221
jcprepct.o: jcprepct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
222
jcsample.o: jcsample.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
223
jctrans.o: jctrans.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
224
jdapimin.o: jdapimin.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
225
jdapistd.o: jdapistd.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
226
jdatadst.o: jdatadst.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h
227
jdatasrc.o: jdatasrc.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h
228
jdcoefct.o: jdcoefct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
229
jdcolor.o: jdcolor.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
230
jddctmgr.o: jddctmgr.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
231
jdhuff.o: jdhuff.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdhuff.h
232
jdinput.o: jdinput.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
233
jdmainct.o: jdmainct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
234
jdmarker.o: jdmarker.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
235
jdmaster.o: jdmaster.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
236
jdmerge.o: jdmerge.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
237
jdphuff.o: jdphuff.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdhuff.h
238
jdpostct.o: jdpostct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
239
jdsample.o: jdsample.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
240
jdtrans.o: jdtrans.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
241
jerror.o: jerror.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jversion.h jerror.h
242
jfdctflt.o: jfdctflt.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
243
jfdctfst.o: jfdctfst.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
244
jfdctint.o: jfdctint.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
245
jidctflt.o: jidctflt.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
246
jidctfst.o: jidctfst.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
247
jidctint.o: jidctint.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
248
jidctred.o: jidctred.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
249
jquant1.o: jquant1.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
250
jquant2.o: jquant2.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
251
jutils.o: jutils.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
252
jmemmgr.o: jmemmgr.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h
253
jmemansi.o: jmemansi.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h
254
jmemname.o: jmemname.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h
255
jmemnobs.o: jmemnobs.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h
256
jmemdos.o: jmemdos.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h
257
cjpeg.o: cjpeg.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h jversion.h
258
djpeg.o: djpeg.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h jversion.h
259
jpegtran.o: jpegtran.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h jversion.h
260
cdjpeg.o: cdjpeg.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
261
rdcolmap.o: rdcolmap.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
262
rdswitch.o: rdswitch.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
263
rdjpgcom.o: rdjpgcom.c jinclude.h jconfig.h
264
wrjpgcom.o: wrjpgcom.c jinclude.h jconfig.h
265
rdppm.o: rdppm.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
266
wrppm.o: wrppm.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
267
rdgif.o: rdgif.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
268
wrgif.o: wrgif.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
269
rdtarga.o: rdtarga.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
270
wrtarga.o: wrtarga.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
271
rdbmp.o: rdbmp.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
272
wrbmp.o: wrbmp.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
273
rdrle.o: rdrle.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
274
wrrle.o: wrrle.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
(-)a/jpeg/netscape_mods.doc (-52 lines)
Line     Link Here 
 Lines 1-52    Link Here 
1
***** BEGIN LICENSE BLOCK *****
2
Version: MPL 1.1/GPL 2.0/LGPL 2.1
3
4
The contents of this file are subject to the Mozilla Public License Version 
5
1.1 (the "License"); you may not use this file except in compliance with 
6
the License. You may obtain a copy of the License at 
7
http://www.mozilla.org/MPL/
8
9
Software distributed under the License is distributed on an "AS IS" basis,
10
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
11
for the specific language governing rights and limitations under the
12
License.
13
14
The Original Code is mozilla.org code.
15
16
The Initial Developer of the Original Code is
17
Netscape Communications Corporation
18
Portions created by the Initial Developer are Copyright (C) 1998
19
the Initial Developer. All Rights Reserved.
20
21
Contributor(s):
22
23
Alternatively, the contents of this file may be used under the terms of
24
either the GNU General Public License Version 2 or later (the "GPL"), or
25
the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
26
in which case the provisions of the GPL or the LGPL are applicable instead
27
of those above. If you wish to allow use of your version of this file only
28
under the terms of either the GPL or the LGPL, and not to allow others to
29
use your version of this file under the terms of the MPL, indicate your
30
decision by deleting the provisions above and replace them with the notice
31
and other provisions required by the GPL or the LGPL. If you do not delete
32
the provisions above, a recipient may use your version of this file under
33
the terms of any one of the MPL, the GPL or the LGPL.
34
35
***** END LICENSE BLOCK *****
36
37
This directory contains a subset of the IJG JPEG library.  Among other
38
omissions, most of the original IJG documentation has been deleted.
39
You can find the full IJG distribution at the archive sites mentioned in
40
the README file.  Please note that the IJG code does not fall under the
41
Netscape NPL, but is freely distributable under its own copyright terms
42
(see README).
43
44
Several files have been modified to allow incorporation of the IJG code
45
into the Netscape environment.  As of this writing, jconfig.h, jmorecfg.h,
46
and jerror.c contain Netscape-specific changes.  In addition, we have created
47
our own makefiles following Netscape conventions, rather than using any of
48
those provided by IJG.
49
50
There are some other changes herein, such as MMX-specific optimizations,
51
which should eventually make their way back into the standard IJG
52
distribution.
(-)a/jpeg/rdbmp.c (+439 lines)
Line     Link Here 
Line 0    Link Here 
1
/*
2
 * rdbmp.c
3
 *
4
 * Copyright (C) 1994-1996, Thomas G. Lane.
5
 * This file is part of the Independent JPEG Group's software.
6
 * For conditions of distribution and use, see the accompanying README file.
7
 *
8
 * This file contains routines to read input images in Microsoft "BMP"
9
 * format (MS Windows 3.x, OS/2 1.x, and OS/2 2.x flavors).
10
 * Currently, only 8-bit and 24-bit images are supported, not 1-bit or
11
 * 4-bit (feeding such low-depth images into JPEG would be silly anyway).
12
 * Also, we don't support RLE-compressed files.
13
 *
14
 * These routines may need modification for non-Unix environments or
15
 * specialized applications.  As they stand, they assume input from
16
 * an ordinary stdio stream.  They further assume that reading begins
17
 * at the start of the file; start_input may need work if the
18
 * user interface has already read some data (e.g., to determine that
19
 * the file is indeed BMP format).
20
 *
21
 * This code contributed by James Arthur Boucher.
22
 */
23
24
#include "cdjpeg.h"		/* Common decls for cjpeg/djpeg applications */
25
26
#ifdef BMP_SUPPORTED
27
28
29
/* Macros to deal with unsigned chars as efficiently as compiler allows */
30
31
#ifdef HAVE_UNSIGNED_CHAR
32
typedef unsigned char U_CHAR;
33
#define UCH(x)	((int) (x))
34
#else /* !HAVE_UNSIGNED_CHAR */
35
#ifdef CHAR_IS_UNSIGNED
36
typedef char U_CHAR;
37
#define UCH(x)	((int) (x))
38
#else
39
typedef char U_CHAR;
40
#define UCH(x)	((int) (x) & 0xFF)
41
#endif
42
#endif /* HAVE_UNSIGNED_CHAR */
43
44
45
#define	ReadOK(file,buffer,len)	(JFREAD(file,buffer,len) == ((size_t) (len)))
46
47
48
/* Private version of data source object */
49
50
typedef struct _bmp_source_struct * bmp_source_ptr;
51
52
typedef struct _bmp_source_struct {
53
  struct cjpeg_source_struct pub; /* public fields */
54
55
  j_compress_ptr cinfo;		/* back link saves passing separate parm */
56
57
  JSAMPARRAY colormap;		/* BMP colormap (converted to my format) */
58
59
  jvirt_sarray_ptr whole_image;	/* Needed to reverse row order */
60
  JDIMENSION source_row;	/* Current source row number */
61
  JDIMENSION row_width;		/* Physical width of scanlines in file */
62
63
  int bits_per_pixel;		/* remembers 8- or 24-bit format */
64
} bmp_source_struct;
65
66
67
LOCAL(int)
68
read_byte (bmp_source_ptr sinfo)
69
/* Read next byte from BMP file */
70
{
71
  register FILE *infile = sinfo->pub.input_file;
72
  register int c;
73
74
  if ((c = getc(infile)) == EOF)
75
    ERREXIT(sinfo->cinfo, JERR_INPUT_EOF);
76
  return c;
77
}
78
79
80
LOCAL(void)
81
read_colormap (bmp_source_ptr sinfo, int cmaplen, int mapentrysize)
82
/* Read the colormap from a BMP file */
83
{
84
  int i;
85
86
  switch (mapentrysize) {
87
  case 3:
88
    /* BGR format (occurs in OS/2 files) */
89
    for (i = 0; i < cmaplen; i++) {
90
      sinfo->colormap[2][i] = (JSAMPLE) read_byte(sinfo);
91
      sinfo->colormap[1][i] = (JSAMPLE) read_byte(sinfo);
92
      sinfo->colormap[0][i] = (JSAMPLE) read_byte(sinfo);
93
    }
94
    break;
95
  case 4:
96
    /* BGR0 format (occurs in MS Windows files) */
97
    for (i = 0; i < cmaplen; i++) {
98
      sinfo->colormap[2][i] = (JSAMPLE) read_byte(sinfo);
99
      sinfo->colormap[1][i] = (JSAMPLE) read_byte(sinfo);
100
      sinfo->colormap[0][i] = (JSAMPLE) read_byte(sinfo);
101
      (void) read_byte(sinfo);
102
    }
103
    break;
104
  default:
105
    ERREXIT(sinfo->cinfo, JERR_BMP_BADCMAP);
106
    break;
107
  }
108
}
109
110
111
/*
112
 * Read one row of pixels.
113
 * The image has been read into the whole_image array, but is otherwise
114
 * unprocessed.  We must read it out in top-to-bottom row order, and if
115
 * it is an 8-bit image, we must expand colormapped pixels to 24bit format.
116
 */
117
118
METHODDEF(JDIMENSION)
119
get_8bit_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
120
/* This version is for reading 8-bit colormap indexes */
121
{
122
  bmp_source_ptr source = (bmp_source_ptr) sinfo;
123
  register JSAMPARRAY colormap = source->colormap;
124
  JSAMPARRAY image_ptr;
125
  register int t;
126
  register JSAMPROW inptr, outptr;
127
  register JDIMENSION col;
128
129
  /* Fetch next row from virtual array */
130
  source->source_row--;
131
  image_ptr = (*cinfo->mem->access_virt_sarray)
132
    ((j_common_ptr) cinfo, source->whole_image,
133
     source->source_row, (JDIMENSION) 1, FALSE);
134
135
  /* Expand the colormap indexes to real data */
136
  inptr = image_ptr[0];
137
  outptr = source->pub.buffer[0];
138
  for (col = cinfo->image_width; col > 0; col--) {
139
    t = GETJSAMPLE(*inptr++);
140
    *outptr++ = colormap[0][t];	/* can omit GETJSAMPLE() safely */
141
    *outptr++ = colormap[1][t];
142
    *outptr++ = colormap[2][t];
143
  }
144
145
  return 1;
146
}
147
148
149
METHODDEF(JDIMENSION)
150
get_24bit_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
151
/* This version is for reading 24-bit pixels */
152
{
153
  bmp_source_ptr source = (bmp_source_ptr) sinfo;
154
  JSAMPARRAY image_ptr;
155
  register JSAMPROW inptr, outptr;
156
  register JDIMENSION col;
157
158
  /* Fetch next row from virtual array */
159
  source->source_row--;
160
  image_ptr = (*cinfo->mem->access_virt_sarray)
161
    ((j_common_ptr) cinfo, source->whole_image,
162
     source->source_row, (JDIMENSION) 1, FALSE);
163
164
  /* Transfer data.  Note source values are in BGR order
165
   * (even though Microsoft's own documents say the opposite).
166
   */
167
  inptr = image_ptr[0];
168
  outptr = source->pub.buffer[0];
169
  for (col = cinfo->image_width; col > 0; col--) {
170
    outptr[2] = *inptr++;	/* can omit GETJSAMPLE() safely */
171
    outptr[1] = *inptr++;
172
    outptr[0] = *inptr++;
173
    outptr += 3;
174
  }
175
176
  return 1;
177
}
178
179
180
/*
181
 * This method loads the image into whole_image during the first call on
182
 * get_pixel_rows.  The get_pixel_rows pointer is then adjusted to call
183
 * get_8bit_row or get_24bit_row on subsequent calls.
184
 */
185
186
METHODDEF(JDIMENSION)
187
preload_image (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
188
{
189
  bmp_source_ptr source = (bmp_source_ptr) sinfo;
190
  register FILE *infile = source->pub.input_file;
191
  register int c;
192
  register JSAMPROW out_ptr;
193
  JSAMPARRAY image_ptr;
194
  JDIMENSION row, col;
195
  cd_progress_ptr progress = (cd_progress_ptr) cinfo->progress;
196
197
  /* Read the data into a virtual array in input-file row order. */
198
  for (row = 0; row < cinfo->image_height; row++) {
199
    if (progress != NULL) {
200
      progress->pub.pass_counter = (long) row;
201
      progress->pub.pass_limit = (long) cinfo->image_height;
202
      (*progress->pub.progress_monitor) ((j_common_ptr) cinfo);
203
    }
204
    image_ptr = (*cinfo->mem->access_virt_sarray)
205
      ((j_common_ptr) cinfo, source->whole_image,
206
       row, (JDIMENSION) 1, TRUE);
207
    out_ptr = image_ptr[0];
208
    for (col = source->row_width; col > 0; col--) {
209
      /* inline copy of read_byte() for speed */
210
      if ((c = getc(infile)) == EOF)
211
	ERREXIT(cinfo, JERR_INPUT_EOF);
212
      *out_ptr++ = (JSAMPLE) c;
213
    }
214
  }
215
  if (progress != NULL)
216
    progress->completed_extra_passes++;
217
218
  /* Set up to read from the virtual array in top-to-bottom order */
219
  switch (source->bits_per_pixel) {
220
  case 8:
221
    source->pub.get_pixel_rows = get_8bit_row;
222
    break;
223
  case 24:
224
    source->pub.get_pixel_rows = get_24bit_row;
225
    break;
226
  default:
227
    ERREXIT(cinfo, JERR_BMP_BADDEPTH);
228
  }
229
  source->source_row = cinfo->image_height;
230
231
  /* And read the first row */
232
  return (*source->pub.get_pixel_rows) (cinfo, sinfo);
233
}
234
235
236
/*
237
 * Read the file header; return image size and component count.
238
 */
239
240
METHODDEF(void)
241
start_input_bmp (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
242
{
243
  bmp_source_ptr source = (bmp_source_ptr) sinfo;
244
  U_CHAR bmpfileheader[14];
245
  U_CHAR bmpinfoheader[64];
246
#define GET_2B(array,offset)  ((unsigned int) UCH(array[offset]) + \
247
			       (((unsigned int) UCH(array[offset+1])) << 8))
248
#define GET_4B(array,offset)  ((INT32) UCH(array[offset]) + \
249
			       (((INT32) UCH(array[offset+1])) << 8) + \
250
			       (((INT32) UCH(array[offset+2])) << 16) + \
251
			       (((INT32) UCH(array[offset+3])) << 24))
252
  INT32 bfOffBits;
253
  INT32 headerSize;
254
  INT32 biWidth = 0;		/* initialize to avoid compiler warning */
255
  INT32 biHeight = 0;
256
  unsigned int biPlanes;
257
  INT32 biCompression;
258
  INT32 biXPelsPerMeter,biYPelsPerMeter;
259
  INT32 biClrUsed = 0;
260
  int mapentrysize = 0;		/* 0 indicates no colormap */
261
  INT32 bPad;
262
  JDIMENSION row_width;
263
264
  /* Read and verify the bitmap file header */
265
  if (! ReadOK(source->pub.input_file, bmpfileheader, 14))
266
    ERREXIT(cinfo, JERR_INPUT_EOF);
267
  if (GET_2B(bmpfileheader,0) != 0x4D42) /* 'BM' */
268
    ERREXIT(cinfo, JERR_BMP_NOT);
269
  bfOffBits = (INT32) GET_4B(bmpfileheader,10);
270
  /* We ignore the remaining fileheader fields */
271
272
  /* The infoheader might be 12 bytes (OS/2 1.x), 40 bytes (Windows),
273
   * or 64 bytes (OS/2 2.x).  Check the first 4 bytes to find out which.
274
   */
275
  if (! ReadOK(source->pub.input_file, bmpinfoheader, 4))
276
    ERREXIT(cinfo, JERR_INPUT_EOF);
277
  headerSize = (INT32) GET_4B(bmpinfoheader,0);
278
  if (headerSize < 12 || headerSize > 64)
279
    ERREXIT(cinfo, JERR_BMP_BADHEADER);
280
  if (! ReadOK(source->pub.input_file, bmpinfoheader+4, headerSize-4))
281
    ERREXIT(cinfo, JERR_INPUT_EOF);
282
283
  switch ((int) headerSize) {
284
  case 12:
285
    /* Decode OS/2 1.x header (Microsoft calls this a BITMAPCOREHEADER) */
286
    biWidth = (INT32) GET_2B(bmpinfoheader,4);
287
    biHeight = (INT32) GET_2B(bmpinfoheader,6);
288
    biPlanes = GET_2B(bmpinfoheader,8);
289
    source->bits_per_pixel = (int) GET_2B(bmpinfoheader,10);
290
291
    switch (source->bits_per_pixel) {
292
    case 8:			/* colormapped image */
293
      mapentrysize = 3;		/* OS/2 uses RGBTRIPLE colormap */
294
      TRACEMS2(cinfo, 1, JTRC_BMP_OS2_MAPPED, (int) biWidth, (int) biHeight);
295
      break;
296
    case 24:			/* RGB image */
297
      TRACEMS2(cinfo, 1, JTRC_BMP_OS2, (int) biWidth, (int) biHeight);
298
      break;
299
    default:
300
      ERREXIT(cinfo, JERR_BMP_BADDEPTH);
301
      break;
302
    }
303
    if (biPlanes != 1)
304
      ERREXIT(cinfo, JERR_BMP_BADPLANES);
305
    break;
306
  case 40:
307
  case 64:
308
    /* Decode Windows 3.x header (Microsoft calls this a BITMAPINFOHEADER) */
309
    /* or OS/2 2.x header, which has additional fields that we ignore */
310
    biWidth = GET_4B(bmpinfoheader,4);
311
    biHeight = GET_4B(bmpinfoheader,8);
312
    biPlanes = GET_2B(bmpinfoheader,12);
313
    source->bits_per_pixel = (int) GET_2B(bmpinfoheader,14);
314
    biCompression = GET_4B(bmpinfoheader,16);
315
    biXPelsPerMeter = GET_4B(bmpinfoheader,24);
316
    biYPelsPerMeter = GET_4B(bmpinfoheader,28);
317
    biClrUsed = GET_4B(bmpinfoheader,32);
318
    /* biSizeImage, biClrImportant fields are ignored */
319
320
    switch (source->bits_per_pixel) {
321
    case 8:			/* colormapped image */
322
      mapentrysize = 4;		/* Windows uses RGBQUAD colormap */
323
      TRACEMS2(cinfo, 1, JTRC_BMP_MAPPED, (int) biWidth, (int) biHeight);
324
      break;
325
    case 24:			/* RGB image */
326
      TRACEMS2(cinfo, 1, JTRC_BMP, (int) biWidth, (int) biHeight);
327
      break;
328
    default:
329
      ERREXIT(cinfo, JERR_BMP_BADDEPTH);
330
      break;
331
    }
332
    if (biPlanes != 1)
333
      ERREXIT(cinfo, JERR_BMP_BADPLANES);
334
    if (biCompression != 0)
335
      ERREXIT(cinfo, JERR_BMP_COMPRESSED);
336
337
    if (biXPelsPerMeter > 0 && biYPelsPerMeter > 0) {
338
      /* Set JFIF density parameters from the BMP data */
339
      cinfo->X_density = (UINT16) (biXPelsPerMeter/100); /* 100 cm per meter */
340
      cinfo->Y_density = (UINT16) (biYPelsPerMeter/100);
341
      cinfo->density_unit = 2;	/* dots/cm */
342
    }
343
    break;
344
  default:
345
    ERREXIT(cinfo, JERR_BMP_BADHEADER);
346
    break;
347
  }
348
349
  /* Compute distance to bitmap data --- will adjust for colormap below */
350
  bPad = bfOffBits - (headerSize + 14);
351
352
  /* Read the colormap, if any */
353
  if (mapentrysize > 0) {
354
    if (biClrUsed <= 0)
355
      biClrUsed = 256;		/* assume it's 256 */
356
    else if (biClrUsed > 256)
357
      ERREXIT(cinfo, JERR_BMP_BADCMAP);
358
    /* Allocate space to store the colormap */
359
    source->colormap = (*cinfo->mem->alloc_sarray)
360
      ((j_common_ptr) cinfo, JPOOL_IMAGE,
361
       (JDIMENSION) biClrUsed, (JDIMENSION) 3);
362
    /* and read it from the file */
363
    read_colormap(source, (int) biClrUsed, mapentrysize);
364
    /* account for size of colormap */
365
    bPad -= biClrUsed * mapentrysize;
366
  }
367
368
  /* Skip any remaining pad bytes */
369
  if (bPad < 0)			/* incorrect bfOffBits value? */
370
    ERREXIT(cinfo, JERR_BMP_BADHEADER);
371
  while (--bPad >= 0) {
372
    (void) read_byte(source);
373
  }
374
375
  /* Compute row width in file, including padding to 4-byte boundary */
376
  if (source->bits_per_pixel == 24)
377
    row_width = (JDIMENSION) (biWidth * 3);
378
  else
379
    row_width = (JDIMENSION) biWidth;
380
  while ((row_width & 3) != 0) row_width++;
381
  source->row_width = row_width;
382
383
  /* Allocate space for inversion array, prepare for preload pass */
384
  source->whole_image = (*cinfo->mem->request_virt_sarray)
385
    ((j_common_ptr) cinfo, JPOOL_IMAGE, FALSE,
386
     row_width, (JDIMENSION) biHeight, (JDIMENSION) 1);
387
  source->pub.get_pixel_rows = preload_image;
388
  if (cinfo->progress != NULL) {
389
    cd_progress_ptr progress = (cd_progress_ptr) cinfo->progress;
390
    progress->total_extra_passes++; /* count file input as separate pass */
391
  }
392
393
  /* Allocate one-row buffer for returned data */
394
  source->pub.buffer = (*cinfo->mem->alloc_sarray)
395
    ((j_common_ptr) cinfo, JPOOL_IMAGE,
396
     (JDIMENSION) (biWidth * 3), (JDIMENSION) 1);
397
  source->pub.buffer_height = 1;
398
399
  cinfo->in_color_space = JCS_RGB;
400
  cinfo->input_components = 3;
401
  cinfo->data_precision = 8;
402
  cinfo->image_width = (JDIMENSION) biWidth;
403
  cinfo->image_height = (JDIMENSION) biHeight;
404
}
405
406
407
/*
408
 * Finish up at the end of the file.
409
 */
410
411
METHODDEF(void)
412
finish_input_bmp (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
413
{
414
  /* no work */
415
}
416
417
418
/*
419
 * The module selection routine for BMP format input.
420
 */
421
422
GLOBAL(cjpeg_source_ptr)
423
jinit_read_bmp (j_compress_ptr cinfo)
424
{
425
  bmp_source_ptr source;
426
427
  /* Create module interface object */
428
  source = (bmp_source_ptr)
429
      (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
430
				  SIZEOF(bmp_source_struct));
431
  source->cinfo = cinfo;	/* make back link for subroutines */
432
  /* Fill in method ptrs, except get_pixel_rows which start_input sets */
433
  source->pub.start_input = start_input_bmp;
434
  source->pub.finish_input = finish_input_bmp;
435
436
  return (cjpeg_source_ptr) source;
437
}
438
439
#endif /* BMP_SUPPORTED */
(-)a/jpeg/rdcolmap.c (+253 lines)
Line     Link Here 
Line 0    Link Here 
1
/*
2
 * rdcolmap.c
3
 *
4
 * Copyright (C) 1994-1996, Thomas G. Lane.
5
 * This file is part of the Independent JPEG Group's software.
6
 * For conditions of distribution and use, see the accompanying README file.
7
 *
8
 * This file implements djpeg's "-map file" switch.  It reads a source image
9
 * and constructs a colormap to be supplied to the JPEG decompressor.
10
 *
11
 * Currently, these file formats are supported for the map file:
12
 *   GIF: the contents of the GIF's global colormap are used.
13
 *   PPM (either text or raw flavor): the entire file is read and
14
 *      each unique pixel value is entered in the map.
15
 * Note that reading a large PPM file will be horrendously slow.
16
 * Typically, a PPM-format map file should contain just one pixel
17
 * of each desired color.  Such a file can be extracted from an
18
 * ordinary image PPM file with ppmtomap(1).
19
 *
20
 * Rescaling a PPM that has a maxval unequal to MAXJSAMPLE is not
21
 * currently implemented.
22
 */
23
24
#include "cdjpeg.h"		/* Common decls for cjpeg/djpeg applications */
25
26
#ifdef QUANT_2PASS_SUPPORTED	/* otherwise can't quantize to supplied map */
27
28
/* Portions of this code are based on the PBMPLUS library, which is:
29
**
30
** Copyright (C) 1988 by Jef Poskanzer.
31
**
32
** Permission to use, copy, modify, and distribute this software and its
33
** documentation for any purpose and without fee is hereby granted, provided
34
** that the above copyright notice appear in all copies and that both that
35
** copyright notice and this permission notice appear in supporting
36
** documentation.  This software is provided "as is" without express or
37
** implied warranty.
38
*/
39
40
41
/*
42
 * Add a (potentially) new color to the color map.
43
 */
44
45
LOCAL(void)
46
add_map_entry (j_decompress_ptr cinfo, int R, int G, int B)
47
{
48
  JSAMPROW colormap0 = cinfo->colormap[0];
49
  JSAMPROW colormap1 = cinfo->colormap[1];
50
  JSAMPROW colormap2 = cinfo->colormap[2];
51
  int ncolors = cinfo->actual_number_of_colors;
52
  int index;
53
54
  /* Check for duplicate color. */
55
  for (index = 0; index < ncolors; index++) {
56
    if (GETJSAMPLE(colormap0[index]) == R &&
57
	GETJSAMPLE(colormap1[index]) == G &&
58
	GETJSAMPLE(colormap2[index]) == B)
59
      return;			/* color is already in map */
60
  }
61
62
  /* Check for map overflow. */
63
  if (ncolors >= (MAXJSAMPLE+1))
64
    ERREXIT1(cinfo, JERR_QUANT_MANY_COLORS, (MAXJSAMPLE+1));
65
66
  /* OK, add color to map. */
67
  colormap0[ncolors] = (JSAMPLE) R;
68
  colormap1[ncolors] = (JSAMPLE) G;
69
  colormap2[ncolors] = (JSAMPLE) B;
70
  cinfo->actual_number_of_colors++;
71
}
72
73
74
/*
75
 * Extract color map from a GIF file.
76
 */
77
78
LOCAL(void)
79
read_gif_map (j_decompress_ptr cinfo, FILE * infile)
80
{
81
  int header[13];
82
  int i, colormaplen;
83
  int R, G, B;
84
85
  /* Initial 'G' has already been read by read_color_map */
86
  /* Read the rest of the GIF header and logical screen descriptor */
87
  for (i = 1; i < 13; i++) {
88
    if ((header[i] = getc(infile)) == EOF)
89
      ERREXIT(cinfo, JERR_BAD_CMAP_FILE);
90
  }
91
92
  /* Verify GIF Header */
93
  if (header[1] != 'I' || header[2] != 'F')
94
    ERREXIT(cinfo, JERR_BAD_CMAP_FILE);
95
96
  /* There must be a global color map. */
97
  if ((header[10] & 0x80) == 0)
98
    ERREXIT(cinfo, JERR_BAD_CMAP_FILE);
99
100
  /* OK, fetch it. */
101
  colormaplen = 2 << (header[10] & 0x07);
102
103
  for (i = 0; i < colormaplen; i++) {
104
    R = getc(infile);
105
    G = getc(infile);
106
    B = getc(infile);
107
    if (R == EOF || G == EOF || B == EOF)
108
      ERREXIT(cinfo, JERR_BAD_CMAP_FILE);
109
    add_map_entry(cinfo,
110
		  R << (BITS_IN_JSAMPLE-8),
111
		  G << (BITS_IN_JSAMPLE-8),
112
		  B << (BITS_IN_JSAMPLE-8));
113
  }
114
}
115
116
117
/* Support routines for reading PPM */
118
119
120
LOCAL(int)
121
pbm_getc (FILE * infile)
122
/* Read next char, skipping over any comments */
123
/* A comment/newline sequence is returned as a newline */
124
{
125
  register int ch;
126
  
127
  ch = getc(infile);
128
  if (ch == '#') {
129
    do {
130
      ch = getc(infile);
131
    } while (ch != '\n' && ch != EOF);
132
  }
133
  return ch;
134
}
135
136
137
LOCAL(unsigned int)
138
read_pbm_integer (j_decompress_ptr cinfo, FILE * infile)
139
/* Read an unsigned decimal integer from the PPM file */
140
/* Swallows one trailing character after the integer */
141
/* Note that on a 16-bit-int machine, only values up to 64k can be read. */
142
/* This should not be a problem in practice. */
143
{
144
  register int ch;
145
  register unsigned int val;
146
  
147
  /* Skip any leading whitespace */
148
  do {
149
    ch = pbm_getc(infile);
150
    if (ch == EOF)
151
      ERREXIT(cinfo, JERR_BAD_CMAP_FILE);
152
  } while (ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r');
153
  
154
  if (ch < '0' || ch > '9')
155
    ERREXIT(cinfo, JERR_BAD_CMAP_FILE);
156
  
157
  val = ch - '0';
158
  while ((ch = pbm_getc(infile)) >= '0' && ch <= '9') {
159
    val *= 10;
160
    val += ch - '0';
161
  }
162
  return val;
163
}
164
165
166
/*
167
 * Extract color map from a PPM file.
168
 */
169
170
LOCAL(void)
171
read_ppm_map (j_decompress_ptr cinfo, FILE * infile)
172
{
173
  int c;
174
  unsigned int w, h, maxval, row, col;
175
  int R, G, B;
176
177
  /* Initial 'P' has already been read by read_color_map */
178
  c = getc(infile);		/* save format discriminator for a sec */
179
180
  /* while we fetch the remaining header info */
181
  w = read_pbm_integer(cinfo, infile);
182
  h = read_pbm_integer(cinfo, infile);
183
  maxval = read_pbm_integer(cinfo, infile);
184
185
  if (w <= 0 || h <= 0 || maxval <= 0) /* error check */
186
    ERREXIT(cinfo, JERR_BAD_CMAP_FILE);
187
188
  /* For now, we don't support rescaling from an unusual maxval. */
189
  if (maxval != (unsigned int) MAXJSAMPLE)
190
    ERREXIT(cinfo, JERR_BAD_CMAP_FILE);
191
192
  switch (c) {
193
  case '3':			/* it's a text-format PPM file */
194
    for (row = 0; row < h; row++) {
195
      for (col = 0; col < w; col++) {
196
	R = read_pbm_integer(cinfo, infile);
197
	G = read_pbm_integer(cinfo, infile);
198
	B = read_pbm_integer(cinfo, infile);
199
	add_map_entry(cinfo, R, G, B);
200
      }
201
    }
202
    break;
203
204
  case '6':			/* it's a raw-format PPM file */
205
    for (row = 0; row < h; row++) {
206
      for (col = 0; col < w; col++) {
207
	R = getc(infile);
208
	G = getc(infile);
209
	B = getc(infile);
210
	if (R == EOF || G == EOF || B == EOF)
211
	  ERREXIT(cinfo, JERR_BAD_CMAP_FILE);
212
	add_map_entry(cinfo, R, G, B);
213
      }
214
    }
215
    break;
216
217
  default:
218
    ERREXIT(cinfo, JERR_BAD_CMAP_FILE);
219
    break;
220
  }
221
}
222
223
224
/*
225
 * Main entry point from djpeg.c.
226
 *  Input: opened input file (from file name argument on command line).
227
 *  Output: colormap and actual_number_of_colors fields are set in cinfo.
228
 */
229
230
GLOBAL(void)
231
read_color_map (j_decompress_ptr cinfo, FILE * infile)
232
{
233
  /* Allocate space for a color map of maximum supported size. */
234
  cinfo->colormap = (*cinfo->mem->alloc_sarray)
235
    ((j_common_ptr) cinfo, JPOOL_IMAGE,
236
     (JDIMENSION) (MAXJSAMPLE+1), (JDIMENSION) 3);
237
  cinfo->actual_number_of_colors = 0; /* initialize map to empty */
238
239
  /* Read first byte to determine file format */
240
  switch (getc(infile)) {
241
  case 'G':
242
    read_gif_map(cinfo, infile);
243
    break;
244
  case 'P':
245
    read_ppm_map(cinfo, infile);
246
    break;
247
  default:
248
    ERREXIT(cinfo, JERR_BAD_CMAP_FILE);
249
    break;
250
  }
251
}
252
253
#endif /* QUANT_2PASS_SUPPORTED */
(-)a/jpeg/rdgif.c (+38 lines)
Line     Link Here 
Line 0    Link Here 
1
/*
2
 * rdgif.c
3
 *
4
 * Copyright (C) 1991-1997, Thomas G. Lane.
5
 * This file is part of the Independent JPEG Group's software.
6
 * For conditions of distribution and use, see the accompanying README file.
7
 *
8
 * This file contains routines to read input images in GIF format.
9
 *
10
 *****************************************************************************
11
 * NOTE: to avoid entanglements with Unisys' patent on LZW compression,      *
12
 * the ability to read GIF files has been removed from the IJG distribution. *
13
 * Sorry about that.                                                         *
14
 *****************************************************************************
15
 *
16
 * We are required to state that
17
 *    "The Graphics Interchange Format(c) is the Copyright property of
18
 *    CompuServe Incorporated. GIF(sm) is a Service Mark property of
19
 *    CompuServe Incorporated."
20
 */
21
22
#include "cdjpeg.h"		/* Common decls for cjpeg/djpeg applications */
23
24
#ifdef GIF_SUPPORTED
25
26
/*
27
 * The module selection routine for GIF format input.
28
 */
29
30
GLOBAL(cjpeg_source_ptr)
31
jinit_read_gif (j_compress_ptr cinfo)
32
{
33
  fprintf(stderr, "GIF input is unsupported for legal reasons.  Sorry.\n");
34
  exit(EXIT_FAILURE);
35
  return NULL;			/* keep compiler happy */
36
}
37
38
#endif /* GIF_SUPPORTED */
(-)a/jpeg/rdjpgcom.1 (+54 lines)
Line     Link Here 
Line 0    Link Here 
1
.TH RDJPGCOM 1 "11 October 1997"
2
.SH NAME
3
rdjpgcom \- display text comments from a JPEG file
4
.SH SYNOPSIS
5
.B rdjpgcom
6
[
7
.B \-verbose
8
]
9
[
10
.I filename
11
]
12
.LP
13
.SH DESCRIPTION
14
.LP
15
.B rdjpgcom
16
reads the named JPEG/JFIF file, or the standard input if no file is named,
17
and prints any text comments found in the file on the standard output.
18
.PP
19
The JPEG standard allows "comment" (COM) blocks to occur within a JPEG file.
20
Although the standard doesn't actually define what COM blocks are for, they
21
are widely used to hold user-supplied text strings.  This lets you add
22
annotations, titles, index terms, etc to your JPEG files, and later retrieve
23
them as text.  COM blocks do not interfere with the image stored in the JPEG
24
file.  The maximum size of a COM block is 64K, but you can have as many of
25
them as you like in one JPEG file.
26
.SH OPTIONS
27
.TP
28
.B \-verbose
29
Causes
30
.B rdjpgcom
31
to also display the JPEG image dimensions.
32
.PP
33
Switch names may be abbreviated, and are not case sensitive.
34
.SH HINTS
35
.B rdjpgcom
36
does not depend on the IJG JPEG library.  Its source code is intended as an
37
illustration of the minimum amount of code required to parse a JPEG file
38
header correctly.
39
.PP
40
In
41
.B \-verbose
42
mode,
43
.B rdjpgcom
44
will also attempt to print the contents of any "APP12" markers as text.
45
Some digital cameras produce APP12 markers containing useful textual
46
information.  If you like, you can modify the source code to print
47
other APPn marker types as well.
48
.SH SEE ALSO
49
.BR cjpeg (1),
50
.BR djpeg (1),
51
.BR jpegtran (1),
52
.BR wrjpgcom (1)
53
.SH AUTHOR
54
Independent JPEG Group
(-)a/jpeg/rdjpgcom.c (+496 lines)
Line     Link Here 
Line 0    Link Here 
1
/*
2
 * rdjpgcom.c
3
 *
4
 * Copyright (C) 1994-1997, Thomas G. Lane.
5
 * This file is part of the Independent JPEG Group's software.
6
 * For conditions of distribution and use, see the accompanying README file.
7
 *
8
 * This file contains a very simple stand-alone application that displays
9
 * the text in COM (comment) markers in a JFIF file.
10
 * This may be useful as an example of the minimum logic needed to parse
11
 * JPEG markers.
12
 */
13
14
#define JPEG_CJPEG_DJPEG	/* to get the command-line config symbols */
15
#include "jinclude.h"		/* get auto-config symbols, <stdio.h> */
16
17
#include <ctype.h>		/* to declare isupper(), tolower() */
18
#ifdef USE_SETMODE
19
#include <fcntl.h>		/* to declare setmode()'s parameter macros */
20
/* If you have setmode() but not <io.h>, just delete this line: */
21
#include <io.h>			/* to declare setmode() */
22
#endif
23
24
#ifdef USE_CCOMMAND		/* command-line reader for Macintosh */
25
#ifdef __MWERKS__
26
#include <SIOUX.h>              /* Metrowerks needs this */
27
#include <console.h>		/* ... and this */
28
#endif
29
#ifdef THINK_C
30
#include <console.h>		/* Think declares it here */
31
#endif
32
#endif
33
34
#ifdef DONT_USE_B_MODE		/* define mode parameters for fopen() */
35
#define READ_BINARY	"r"
36
#else
37
#ifdef VMS			/* VMS is very nonstandard */
38
#define READ_BINARY	"rb", "ctx=stm"
39
#else				/* standard ANSI-compliant case */
40
#define READ_BINARY	"rb"
41
#endif
42
#endif
43
44
#ifndef EXIT_FAILURE		/* define exit() codes if not provided */
45
#define EXIT_FAILURE  1
46
#endif
47
#ifndef EXIT_SUCCESS
48
#ifdef VMS
49
#define EXIT_SUCCESS  1		/* VMS is very nonstandard */
50
#else
51
#define EXIT_SUCCESS  0
52
#endif
53
#endif
54
55
56
/*
57
 * These macros are used to read the input file.
58
 * To reuse this code in another application, you might need to change these.
59
 */
60
61
static FILE * infile;		/* input JPEG file */
62
63
/* Return next input byte, or EOF if no more */
64
#define NEXTBYTE()  getc(infile)
65
66
67
/* Error exit handler */
68
#define ERREXIT(msg)  (fprintf(stderr, "%s\n", msg), exit(EXIT_FAILURE))
69
70
71
/* Read one byte, testing for EOF */
72
static int
73
read_1_byte (void)
74
{
75
  int c;
76
77
  c = NEXTBYTE();
78
  if (c == EOF)
79
    ERREXIT("Premature EOF in JPEG file");
80
  return c;
81
}
82
83
/* Read 2 bytes, convert to unsigned int */
84
/* All 2-byte quantities in JPEG markers are MSB first */
85
static unsigned int
86
read_2_bytes (void)
87
{
88
  int c1, c2;
89
90
  c1 = NEXTBYTE();
91
  if (c1 == EOF)
92
    ERREXIT("Premature EOF in JPEG file");
93
  c2 = NEXTBYTE();
94
  if (c2 == EOF)
95
    ERREXIT("Premature EOF in JPEG file");
96
  return (((unsigned int) c1) << 8) + ((unsigned int) c2);
97
}
98
99
100
/*
101
 * JPEG markers consist of one or more 0xFF bytes, followed by a marker
102
 * code byte (which is not an FF).  Here are the marker codes of interest
103
 * in this program.  (See jdmarker.c for a more complete list.)
104
 */
105
106
#define M_SOF0  0xC0		/* Start Of Frame N */
107
#define M_SOF1  0xC1		/* N indicates which compression process */
108
#define M_SOF2  0xC2		/* Only SOF0-SOF2 are now in common use */
109
#define M_SOF3  0xC3
110
#define M_SOF5  0xC5		/* NB: codes C4 and CC are NOT SOF markers */
111
#define M_SOF6  0xC6
112
#define M_SOF7  0xC7
113
#define M_SOF9  0xC9
114
#define M_SOF10 0xCA
115
#define M_SOF11 0xCB
116
#define M_SOF13 0xCD
117
#define M_SOF14 0xCE
118
#define M_SOF15 0xCF
119
#define M_SOI   0xD8		/* Start Of Image (beginning of datastream) */
120
#define M_EOI   0xD9		/* End Of Image (end of datastream) */
121
#define M_SOS   0xDA		/* Start Of Scan (begins compressed data) */
122
#define M_APP0	0xE0		/* Application-specific marker, type N */
123
#define M_APP12	0xEC		/* (we don't bother to list all 16 APPn's) */
124
#define M_COM   0xFE		/* COMment */
125
126
127
/*
128
 * Find the next JPEG marker and return its marker code.
129
 * We expect at least one FF byte, possibly more if the compressor used FFs
130
 * to pad the file.
131
 * There could also be non-FF garbage between markers.  The treatment of such
132
 * garbage is unspecified; we choose to skip over it but emit a warning msg.
133
 * NB: this routine must not be used after seeing SOS marker, since it will
134
 * not deal correctly with FF/00 sequences in the compressed image data...
135
 */
136
137
static int
138
next_marker (void)
139
{
140
  int c;
141
  int discarded_bytes = 0;
142
143
  /* Find 0xFF byte; count and skip any non-FFs. */
144
  c = read_1_byte();
145
  while (c != 0xFF) {
146
    discarded_bytes++;
147
    c = read_1_byte();
148
  }
149
  /* Get marker code byte, swallowing any duplicate FF bytes.  Extra FFs
150
   * are legal as pad bytes, so don't count them in discarded_bytes.
151
   */
152
  do {
153
    c = read_1_byte();
154
  } while (c == 0xFF);
155
156
  if (discarded_bytes != 0) {
157
    fprintf(stderr, "Warning: garbage data found in JPEG file\n");
158
  }
159
160
  return c;
161
}
162
163
164
/*
165
 * Read the initial marker, which should be SOI.
166
 * For a JFIF file, the first two bytes of the file should be literally
167
 * 0xFF M_SOI.  To be more general, we could use next_marker, but if the
168
 * input file weren't actually JPEG at all, next_marker might read the whole
169
 * file and then return a misleading error message...
170
 */
171
172
static int
173
first_marker (void)
174
{
175
  int c1, c2;
176
177
  c1 = NEXTBYTE();
178
  c2 = NEXTBYTE();
179
  if (c1 != 0xFF || c2 != M_SOI)
180
    ERREXIT("Not a JPEG file");
181
  return c2;
182
}
183
184
185
/*
186
 * Most types of marker are followed by a variable-length parameter segment.
187
 * This routine skips over the parameters for any marker we don't otherwise
188
 * want to process.
189
 * Note that we MUST skip the parameter segment explicitly in order not to
190
 * be fooled by 0xFF bytes that might appear within the parameter segment;
191
 * such bytes do NOT introduce new markers.
192
 */
193
194
static void
195
skip_variable (void)
196
/* Skip over an unknown or uninteresting variable-length marker */
197
{
198
  unsigned int length;
199
200
  /* Get the marker parameter length count */
201
  length = read_2_bytes();
202
  /* Length includes itself, so must be at least 2 */
203
  if (length < 2)
204
    ERREXIT("Erroneous JPEG marker length");
205
  length -= 2;
206
  /* Skip over the remaining bytes */
207
  while (length > 0) {
208
    (void) read_1_byte();
209
    length--;
210
  }
211
}
212
213
214
/*
215
 * Process a COM marker.
216
 * We want to print out the marker contents as legible text;
217
 * we must guard against non-text junk and varying newline representations.
218
 */
219
220
static void
221
process_COM (void)
222
{
223
  unsigned int length;
224
  int ch;
225
  int lastch = 0;
226
227
  /* Get the marker parameter length count */
228
  length = read_2_bytes();
229
  /* Length includes itself, so must be at least 2 */
230
  if (length < 2)
231
    ERREXIT("Erroneous JPEG marker length");
232
  length -= 2;
233
234
  while (length > 0) {
235
    ch = read_1_byte();
236
    /* Emit the character in a readable form.
237
     * Nonprintables are converted to \nnn form,
238
     * while \ is converted to \\.
239
     * Newlines in CR, CR/LF, or LF form will be printed as one newline.
240
     */
241
    if (ch == '\r') {
242
      printf("\n");
243
    } else if (ch == '\n') {
244
      if (lastch != '\r')
245
	printf("\n");
246
    } else if (ch == '\\') {
247
      printf("\\\\");
248
    } else if (isprint(ch)) {
249
      putc(ch, stdout);
250
    } else {
251
      printf("\\%03o", ch);
252
    }
253
    lastch = ch;
254
    length--;
255
  }
256
  printf("\n");
257
}
258
259
260
/*
261
 * Process a SOFn marker.
262
 * This code is only needed if you want to know the image dimensions...
263
 */
264
265
static void
266
process_SOFn (int marker)
267
{
268
  unsigned int length;
269
  unsigned int image_height, image_width;
270
  int data_precision, num_components;
271
  const char * process;
272
  int ci;
273
274
  length = read_2_bytes();	/* usual parameter length count */
275
276
  data_precision = read_1_byte();
277
  image_height = read_2_bytes();
278
  image_width = read_2_bytes();
279
  num_components = read_1_byte();
280
281
  switch (marker) {
282
  case M_SOF0:	process = "Baseline";  break;
283
  case M_SOF1:	process = "Extended sequential";  break;
284
  case M_SOF2:	process = "Progressive";  break;
285
  case M_SOF3:	process = "Lossless";  break;
286
  case M_SOF5:	process = "Differential sequential";  break;
287
  case M_SOF6:	process = "Differential progressive";  break;
288
  case M_SOF7:	process = "Differential lossless";  break;
289
  case M_SOF9:	process = "Extended sequential, arithmetic coding";  break;
290
  case M_SOF10:	process = "Progressive, arithmetic coding";  break;
291
  case M_SOF11:	process = "Lossless, arithmetic coding";  break;
292
  case M_SOF13:	process = "Differential sequential, arithmetic coding";  break;
293
  case M_SOF14:	process = "Differential progressive, arithmetic coding"; break;
294
  case M_SOF15:	process = "Differential lossless, arithmetic coding";  break;
295
  default:	process = "Unknown";  break;
296
  }
297
298
  printf("JPEG image is %uw * %uh, %d color components, %d bits per sample\n",
299
	 image_width, image_height, num_components, data_precision);
300
  printf("JPEG process: %s\n", process);
301
302
  if (length != (unsigned int) (8 + num_components * 3))
303
    ERREXIT("Bogus SOF marker length");
304
305
  for (ci = 0; ci < num_components; ci++) {
306
    (void) read_1_byte();	/* Component ID code */
307
    (void) read_1_byte();	/* H, V sampling factors */
308
    (void) read_1_byte();	/* Quantization table number */
309
  }
310
}
311
312
313
/*
314
 * Parse the marker stream until SOS or EOI is seen;
315
 * display any COM markers.
316
 * While the companion program wrjpgcom will always insert COM markers before
317
 * SOFn, other implementations might not, so we scan to SOS before stopping.
318
 * If we were only interested in the image dimensions, we would stop at SOFn.
319
 * (Conversely, if we only cared about COM markers, there would be no need
320
 * for special code to handle SOFn; we could treat it like other markers.)
321
 */
322
323
static int
324
scan_JPEG_header (int verbose)
325
{
326
  int marker;
327
328
  /* Expect SOI at start of file */
329
  if (first_marker() != M_SOI)
330
    ERREXIT("Expected SOI marker first");
331
332
  /* Scan miscellaneous markers until we reach SOS. */
333
  for (;;) {
334
    marker = next_marker();
335
    switch (marker) {
336
      /* Note that marker codes 0xC4, 0xC8, 0xCC are not, and must not be,
337
       * treated as SOFn.  C4 in particular is actually DHT.
338
       */
339
    case M_SOF0:		/* Baseline */
340
    case M_SOF1:		/* Extended sequential, Huffman */
341
    case M_SOF2:		/* Progressive, Huffman */
342
    case M_SOF3:		/* Lossless, Huffman */
343
    case M_SOF5:		/* Differential sequential, Huffman */
344
    case M_SOF6:		/* Differential progressive, Huffman */
345
    case M_SOF7:		/* Differential lossless, Huffman */
346
    case M_SOF9:		/* Extended sequential, arithmetic */
347
    case M_SOF10:		/* Progressive, arithmetic */
348
    case M_SOF11:		/* Lossless, arithmetic */
349
    case M_SOF13:		/* Differential sequential, arithmetic */
350
    case M_SOF14:		/* Differential progressive, arithmetic */
351
    case M_SOF15:		/* Differential lossless, arithmetic */
352
      if (verbose)
353
	process_SOFn(marker);
354
      else
355
	skip_variable();
356
      break;
357
358
    case M_SOS:			/* stop before hitting compressed data */
359
      return marker;
360
361
    case M_EOI:			/* in case it's a tables-only JPEG stream */
362
      return marker;
363
364
    case M_COM:
365
      process_COM();
366
      break;
367
368
    case M_APP12:
369
      /* Some digital camera makers put useful textual information into
370
       * APP12 markers, so we print those out too when in -verbose mode.
371
       */
372
      if (verbose) {
373
	printf("APP12 contains:\n");
374
	process_COM();
375
      } else
376
	skip_variable();
377
      break;
378
379
    default:			/* Anything else just gets skipped */
380
      skip_variable();		/* we assume it has a parameter count... */
381
      break;
382
    }
383
  } /* end loop */
384
}
385
386
387
/* Command line parsing code */
388
389
static const char * progname;	/* program name for error messages */
390
391
392
static void
393
usage (void)
394
/* complain about bad command line */
395
{
396
  fprintf(stderr, "rdjpgcom displays any textual comments in a JPEG file.\n");
397
398
  fprintf(stderr, "Usage: %s [switches] [inputfile]\n", progname);
399
400
  fprintf(stderr, "Switches (names may be abbreviated):\n");
401
  fprintf(stderr, "  -verbose    Also display dimensions of JPEG image\n");
402
403
  exit(EXIT_FAILURE);
404
}
405
406
407
static int
408
keymatch (char * arg, const char * keyword, int minchars)
409
/* Case-insensitive matching of (possibly abbreviated) keyword switches. */
410
/* keyword is the constant keyword (must be lower case already), */
411
/* minchars is length of minimum legal abbreviation. */
412
{
413
  register int ca, ck;
414
  register int nmatched = 0;
415
416
  while ((ca = *arg++) != '\0') {
417
    if ((ck = *keyword++) == '\0')
418
      return 0;			/* arg longer than keyword, no good */
419
    if (isupper(ca))		/* force arg to lcase (assume ck is already) */
420
      ca = tolower(ca);
421
    if (ca != ck)
422
      return 0;			/* no good */
423
    nmatched++;			/* count matched characters */
424
  }
425
  /* reached end of argument; fail if it's too short for unique abbrev */
426
  if (nmatched < minchars)
427
    return 0;
428
  return 1;			/* A-OK */
429
}
430
431
432
/*
433
 * The main program.
434
 */
435
436
int
437
main (int argc, char **argv)
438
{
439
  int argn;
440
  char * arg;
441
  int verbose = 0;
442
443
  /* On Mac, fetch a command line. */
444
#ifdef USE_CCOMMAND
445
  argc = ccommand(&argv);
446
#endif
447
448
  progname = argv[0];
449
  if (progname == NULL || progname[0] == 0)
450
    progname = "rdjpgcom";	/* in case C library doesn't provide it */
451
452
  /* Parse switches, if any */
453
  for (argn = 1; argn < argc; argn++) {
454
    arg = argv[argn];
455
    if (arg[0] != '-')
456
      break;			/* not switch, must be file name */
457
    arg++;			/* advance over '-' */
458
    if (keymatch(arg, "verbose", 1)) {
459
      verbose++;
460
    } else
461
      usage();
462
  }
463
464
  /* Open the input file. */
465
  /* Unix style: expect zero or one file name */
466
  if (argn < argc-1) {
467
    fprintf(stderr, "%s: only one input file\n", progname);
468
    usage();
469
  }
470
  if (argn < argc) {
471
    if ((infile = fopen(argv[argn], READ_BINARY)) == NULL) {
472
      fprintf(stderr, "%s: can't open %s\n", progname, argv[argn]);
473
      exit(EXIT_FAILURE);
474
    }
475
  } else {
476
    /* default input file is stdin */
477
#ifdef USE_SETMODE		/* need to hack file mode? */
478
    setmode(fileno(stdin), O_BINARY);
479
#endif
480
#ifdef USE_FDOPEN		/* need to re-open in binary mode? */
481
    if ((infile = fdopen(fileno(stdin), READ_BINARY)) == NULL) {
482
      fprintf(stderr, "%s: can't open stdin\n", progname);
483
      exit(EXIT_FAILURE);
484
    }
485
#else
486
    infile = stdin;
487
#endif
488
  }
489
490
  /* Scan the JPEG headers. */
491
  (void) scan_JPEG_header(verbose);
492
493
  /* All done. */
494
  exit(EXIT_SUCCESS);
495
  return 0;			/* suppress no-return-value warnings */
496
}
(-)a/jpeg/rdppm.c (+458 lines)
Line     Link Here 
Line 0    Link Here 
1
/*
2
 * rdppm.c
3
 *
4
 * Copyright (C) 1991-1997, Thomas G. Lane.
5
 * This file is part of the Independent JPEG Group's software.
6
 * For conditions of distribution and use, see the accompanying README file.
7
 *
8
 * This file contains routines to read input images in PPM/PGM format.
9
 * The extended 2-byte-per-sample raw PPM/PGM formats are supported.
10
 * The PBMPLUS library is NOT required to compile this software
11
 * (but it is highly useful as a set of PPM image manipulation programs).
12
 *
13
 * These routines may need modification for non-Unix environments or
14
 * specialized applications.  As they stand, they assume input from
15
 * an ordinary stdio stream.  They further assume that reading begins
16
 * at the start of the file; start_input may need work if the
17
 * user interface has already read some data (e.g., to determine that
18
 * the file is indeed PPM format).
19
 */
20
21
#include "cdjpeg.h"		/* Common decls for cjpeg/djpeg applications */
22
23
#ifdef PPM_SUPPORTED
24
25
26
/* Portions of this code are based on the PBMPLUS library, which is:
27
**
28
** Copyright (C) 1988 by Jef Poskanzer.
29
**
30
** Permission to use, copy, modify, and distribute this software and its
31
** documentation for any purpose and without fee is hereby granted, provided
32
** that the above copyright notice appear in all copies and that both that
33
** copyright notice and this permission notice appear in supporting
34
** documentation.  This software is provided "as is" without express or
35
** implied warranty.
36
*/
37
38
39
/* Macros to deal with unsigned chars as efficiently as compiler allows */
40
41
#ifdef HAVE_UNSIGNED_CHAR
42
typedef unsigned char U_CHAR;
43
#define UCH(x)	((int) (x))
44
#else /* !HAVE_UNSIGNED_CHAR */
45
#ifdef CHAR_IS_UNSIGNED
46
typedef char U_CHAR;
47
#define UCH(x)	((int) (x))
48
#else
49
typedef char U_CHAR;
50
#define UCH(x)	((int) (x) & 0xFF)
51
#endif
52
#endif /* HAVE_UNSIGNED_CHAR */
53
54
55
#define	ReadOK(file,buffer,len)	(JFREAD(file,buffer,len) == ((size_t) (len)))
56
57
58
/*
59
 * On most systems, reading individual bytes with getc() is drastically less
60
 * efficient than buffering a row at a time with fread().  On PCs, we must
61
 * allocate the buffer in near data space, because we are assuming small-data
62
 * memory model, wherein fread() can't reach far memory.  If you need to
63
 * process very wide images on a PC, you might have to compile in large-memory
64
 * model, or else replace fread() with a getc() loop --- which will be much
65
 * slower.
66
 */
67
68
69
/* Private version of data source object */
70
71
typedef struct {
72
  struct cjpeg_source_struct pub; /* public fields */
73
74
  U_CHAR *iobuffer;		/* non-FAR pointer to I/O buffer */
75
  JSAMPROW pixrow;		/* FAR pointer to same */
76
  size_t buffer_width;		/* width of I/O buffer */
77
  JSAMPLE *rescale;		/* => maxval-remapping array, or NULL */
78
} ppm_source_struct;
79
80
typedef ppm_source_struct * ppm_source_ptr;
81
82
83
LOCAL(int)
84
pbm_getc (FILE * infile)
85
/* Read next char, skipping over any comments */
86
/* A comment/newline sequence is returned as a newline */
87
{
88
  register int ch;
89
90
  ch = getc(infile);
91
  if (ch == '#') {
92
    do {
93
      ch = getc(infile);
94
    } while (ch != '\n' && ch != EOF);
95
  }
96
  return ch;
97
}
98
99
100
LOCAL(unsigned int)
101
read_pbm_integer (j_compress_ptr cinfo, FILE * infile)
102
/* Read an unsigned decimal integer from the PPM file */
103
/* Swallows one trailing character after the integer */
104
/* Note that on a 16-bit-int machine, only values up to 64k can be read. */
105
/* This should not be a problem in practice. */
106
{
107
  register int ch;
108
  register unsigned int val;
109
110
  /* Skip any leading whitespace */
111
  do {
112
    ch = pbm_getc(infile);
113
    if (ch == EOF)
114
      ERREXIT(cinfo, JERR_INPUT_EOF);
115
  } while (ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r');
116
117
  if (ch < '0' || ch > '9')
118
    ERREXIT(cinfo, JERR_PPM_NONNUMERIC);
119
120
  val = ch - '0';
121
  while ((ch = pbm_getc(infile)) >= '0' && ch <= '9') {
122
    val *= 10;
123
    val += ch - '0';
124
  }
125
  return val;
126
}
127
128
129
/*
130
 * Read one row of pixels.
131
 *
132
 * We provide several different versions depending on input file format.
133
 * In all cases, input is scaled to the size of JSAMPLE.
134
 *
135
 * A really fast path is provided for reading byte/sample raw files with
136
 * maxval = MAXJSAMPLE, which is the normal case for 8-bit data.
137
 */
138
139
140
METHODDEF(JDIMENSION)
141
get_text_gray_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
142
/* This version is for reading text-format PGM files with any maxval */
143
{
144
  ppm_source_ptr source = (ppm_source_ptr) sinfo;
145
  FILE * infile = source->pub.input_file;
146
  register JSAMPROW ptr;
147
  register JSAMPLE *rescale = source->rescale;
148
  JDIMENSION col;
149
150
  ptr = source->pub.buffer[0];
151
  for (col = cinfo->image_width; col > 0; col--) {
152
    *ptr++ = rescale[read_pbm_integer(cinfo, infile)];
153
  }
154
  return 1;
155
}
156
157
158
METHODDEF(JDIMENSION)
159
get_text_rgb_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
160
/* This version is for reading text-format PPM files with any maxval */
161
{
162
  ppm_source_ptr source = (ppm_source_ptr) sinfo;
163
  FILE * infile = source->pub.input_file;
164
  register JSAMPROW ptr;
165
  register JSAMPLE *rescale = source->rescale;
166
  JDIMENSION col;
167
168
  ptr = source->pub.buffer[0];
169
  for (col = cinfo->image_width; col > 0; col--) {
170
    *ptr++ = rescale[read_pbm_integer(cinfo, infile)];
171
    *ptr++ = rescale[read_pbm_integer(cinfo, infile)];
172
    *ptr++ = rescale[read_pbm_integer(cinfo, infile)];
173
  }
174
  return 1;
175
}
176
177
178
METHODDEF(JDIMENSION)
179
get_scaled_gray_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
180
/* This version is for reading raw-byte-format PGM files with any maxval */
181
{
182
  ppm_source_ptr source = (ppm_source_ptr) sinfo;
183
  register JSAMPROW ptr;
184
  register U_CHAR * bufferptr;
185
  register JSAMPLE *rescale = source->rescale;
186
  JDIMENSION col;
187
188
  if (! ReadOK(source->pub.input_file, source->iobuffer, source->buffer_width))
189
    ERREXIT(cinfo, JERR_INPUT_EOF);
190
  ptr = source->pub.buffer[0];
191
  bufferptr = source->iobuffer;
192
  for (col = cinfo->image_width; col > 0; col--) {
193
    *ptr++ = rescale[UCH(*bufferptr++)];
194
  }
195
  return 1;
196
}
197
198
199
METHODDEF(JDIMENSION)
200
get_scaled_rgb_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
201
/* This version is for reading raw-byte-format PPM files with any maxval */
202
{
203
  ppm_source_ptr source = (ppm_source_ptr) sinfo;
204
  register JSAMPROW ptr;
205
  register U_CHAR * bufferptr;
206
  register JSAMPLE *rescale = source->rescale;
207
  JDIMENSION col;
208
209
  if (! ReadOK(source->pub.input_file, source->iobuffer, source->buffer_width))
210
    ERREXIT(cinfo, JERR_INPUT_EOF);
211
  ptr = source->pub.buffer[0];
212
  bufferptr = source->iobuffer;
213
  for (col = cinfo->image_width; col > 0; col--) {
214
    *ptr++ = rescale[UCH(*bufferptr++)];
215
    *ptr++ = rescale[UCH(*bufferptr++)];
216
    *ptr++ = rescale[UCH(*bufferptr++)];
217
  }
218
  return 1;
219
}
220
221
222
METHODDEF(JDIMENSION)
223
get_raw_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
224
/* This version is for reading raw-byte-format files with maxval = MAXJSAMPLE.
225
 * In this case we just read right into the JSAMPLE buffer!
226
 * Note that same code works for PPM and PGM files.
227
 */
228
{
229
  ppm_source_ptr source = (ppm_source_ptr) sinfo;
230
231
  if (! ReadOK(source->pub.input_file, source->iobuffer, source->buffer_width))
232
    ERREXIT(cinfo, JERR_INPUT_EOF);
233
  return 1;
234
}
235
236
237
METHODDEF(JDIMENSION)
238
get_word_gray_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
239
/* This version is for reading raw-word-format PGM files with any maxval */
240
{
241
  ppm_source_ptr source = (ppm_source_ptr) sinfo;
242
  register JSAMPROW ptr;
243
  register U_CHAR * bufferptr;
244
  register JSAMPLE *rescale = source->rescale;
245
  JDIMENSION col;
246
247
  if (! ReadOK(source->pub.input_file, source->iobuffer, source->buffer_width))
248
    ERREXIT(cinfo, JERR_INPUT_EOF);
249
  ptr = source->pub.buffer[0];
250
  bufferptr = source->iobuffer;
251
  for (col = cinfo->image_width; col > 0; col--) {
252
    register int temp;
253
    temp  = UCH(*bufferptr++);
254
    temp |= UCH(*bufferptr++) << 8;
255
    *ptr++ = rescale[temp];
256
  }
257
  return 1;
258
}
259
260
261
METHODDEF(JDIMENSION)
262
get_word_rgb_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
263
/* This version is for reading raw-word-format PPM files with any maxval */
264
{
265
  ppm_source_ptr source = (ppm_source_ptr) sinfo;
266
  register JSAMPROW ptr;
267
  register U_CHAR * bufferptr;
268
  register JSAMPLE *rescale = source->rescale;
269
  JDIMENSION col;
270
271
  if (! ReadOK(source->pub.input_file, source->iobuffer, source->buffer_width))
272
    ERREXIT(cinfo, JERR_INPUT_EOF);
273
  ptr = source->pub.buffer[0];
274
  bufferptr = source->iobuffer;
275
  for (col = cinfo->image_width; col > 0; col--) {
276
    register int temp;
277
    temp  = UCH(*bufferptr++);
278
    temp |= UCH(*bufferptr++) << 8;
279
    *ptr++ = rescale[temp];
280
    temp  = UCH(*bufferptr++);
281
    temp |= UCH(*bufferptr++) << 8;
282
    *ptr++ = rescale[temp];
283
    temp  = UCH(*bufferptr++);
284
    temp |= UCH(*bufferptr++) << 8;
285
    *ptr++ = rescale[temp];
286
  }
287
  return 1;
288
}
289
290
291
/*
292
 * Read the file header; return image size and component count.
293
 */
294
295
METHODDEF(void)
296
start_input_ppm (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
297
{
298
  ppm_source_ptr source = (ppm_source_ptr) sinfo;
299
  int c;
300
  unsigned int w, h, maxval;
301
  boolean need_iobuffer, use_raw_buffer, need_rescale;
302
303
  if (getc(source->pub.input_file) != 'P')
304
    ERREXIT(cinfo, JERR_PPM_NOT);
305
306
  c = getc(source->pub.input_file); /* subformat discriminator character */
307
308
  /* detect unsupported variants (ie, PBM) before trying to read header */
309
  switch (c) {
310
  case '2':			/* it's a text-format PGM file */
311
  case '3':			/* it's a text-format PPM file */
312
  case '5':			/* it's a raw-format PGM file */
313
  case '6':			/* it's a raw-format PPM file */
314
    break;
315
  default:
316
    ERREXIT(cinfo, JERR_PPM_NOT);
317
    break;
318
  }
319
320
  /* fetch the remaining header info */
321
  w = read_pbm_integer(cinfo, source->pub.input_file);
322
  h = read_pbm_integer(cinfo, source->pub.input_file);
323
  maxval = read_pbm_integer(cinfo, source->pub.input_file);
324
325
  if (w <= 0 || h <= 0 || maxval <= 0) /* error check */
326
    ERREXIT(cinfo, JERR_PPM_NOT);
327
328
  cinfo->data_precision = BITS_IN_JSAMPLE; /* we always rescale data to this */
329
  cinfo->image_width = (JDIMENSION) w;
330
  cinfo->image_height = (JDIMENSION) h;
331
332
  /* initialize flags to most common settings */
333
  need_iobuffer = TRUE;		/* do we need an I/O buffer? */
334
  use_raw_buffer = FALSE;	/* do we map input buffer onto I/O buffer? */
335
  need_rescale = TRUE;		/* do we need a rescale array? */
336
337
  switch (c) {
338
  case '2':			/* it's a text-format PGM file */
339
    cinfo->input_components = 1;
340
    cinfo->in_color_space = JCS_GRAYSCALE;
341
    TRACEMS2(cinfo, 1, JTRC_PGM_TEXT, w, h);
342
    source->pub.get_pixel_rows = get_text_gray_row;
343
    need_iobuffer = FALSE;
344
    break;
345
346
  case '3':			/* it's a text-format PPM file */
347
    cinfo->input_components = 3;
348
    cinfo->in_color_space = JCS_RGB;
349
    TRACEMS2(cinfo, 1, JTRC_PPM_TEXT, w, h);
350
    source->pub.get_pixel_rows = get_text_rgb_row;
351
    need_iobuffer = FALSE;
352
    break;
353
354
  case '5':			/* it's a raw-format PGM file */
355
    cinfo->input_components = 1;
356
    cinfo->in_color_space = JCS_GRAYSCALE;
357
    TRACEMS2(cinfo, 1, JTRC_PGM, w, h);
358
    if (maxval > 255) {
359
      source->pub.get_pixel_rows = get_word_gray_row;
360
    } else if (maxval == MAXJSAMPLE && SIZEOF(JSAMPLE) == SIZEOF(U_CHAR)) {
361
      source->pub.get_pixel_rows = get_raw_row;
362
      use_raw_buffer = TRUE;
363
      need_rescale = FALSE;
364
    } else {
365
      source->pub.get_pixel_rows = get_scaled_gray_row;
366
    }
367
    break;
368
369
  case '6':			/* it's a raw-format PPM file */
370
    cinfo->input_components = 3;
371
    cinfo->in_color_space = JCS_RGB;
372
    TRACEMS2(cinfo, 1, JTRC_PPM, w, h);
373
    if (maxval > 255) {
374
      source->pub.get_pixel_rows = get_word_rgb_row;
375
    } else if (maxval == MAXJSAMPLE && SIZEOF(JSAMPLE) == SIZEOF(U_CHAR)) {
376
      source->pub.get_pixel_rows = get_raw_row;
377
      use_raw_buffer = TRUE;
378
      need_rescale = FALSE;
379
    } else {
380
      source->pub.get_pixel_rows = get_scaled_rgb_row;
381
    }
382
    break;
383
  }
384
385
  /* Allocate space for I/O buffer: 1 or 3 bytes or words/pixel. */
386
  if (need_iobuffer) {
387
    source->buffer_width = (size_t) w * cinfo->input_components *
388
      ((maxval<=255) ? SIZEOF(U_CHAR) : (2*SIZEOF(U_CHAR)));
389
    source->iobuffer = (U_CHAR *)
390
      (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
391
				  source->buffer_width);
392
  }
393
394
  /* Create compressor input buffer. */
395
  if (use_raw_buffer) {
396
    /* For unscaled raw-input case, we can just map it onto the I/O buffer. */
397
    /* Synthesize a JSAMPARRAY pointer structure */
398
    /* Cast here implies near->far pointer conversion on PCs */
399
    source->pixrow = (JSAMPROW) source->iobuffer;
400
    source->pub.buffer = & source->pixrow;
401
    source->pub.buffer_height = 1;
402
  } else {
403
    /* Need to translate anyway, so make a separate sample buffer. */
404
    source->pub.buffer = (*cinfo->mem->alloc_sarray)
405
      ((j_common_ptr) cinfo, JPOOL_IMAGE,
406
       (JDIMENSION) w * cinfo->input_components, (JDIMENSION) 1);
407
    source->pub.buffer_height = 1;
408
  }
409
410
  /* Compute the rescaling array if required. */
411
  if (need_rescale) {
412
    INT32 val, half_maxval;
413
414
    /* On 16-bit-int machines we have to be careful of maxval = 65535 */
415
    source->rescale = (JSAMPLE *)
416
      (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
417
				  (size_t) (((long) maxval + 1L) * SIZEOF(JSAMPLE)));
418
    half_maxval = maxval / 2;
419
    for (val = 0; val <= (INT32) maxval; val++) {
420
      /* The multiplication here must be done in 32 bits to avoid overflow */
421
      source->rescale[val] = (JSAMPLE) ((val*MAXJSAMPLE + half_maxval)/maxval);
422
    }
423
  }
424
}
425
426
427
/*
428
 * Finish up at the end of the file.
429
 */
430
431
METHODDEF(void)
432
finish_input_ppm (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
433
{
434
  /* no work */
435
}
436
437
438
/*
439
 * The module selection routine for PPM format input.
440
 */
441
442
GLOBAL(cjpeg_source_ptr)
443
jinit_read_ppm (j_compress_ptr cinfo)
444
{
445
  ppm_source_ptr source;
446
447
  /* Create module interface object */
448
  source = (ppm_source_ptr)
449
      (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
450
				  SIZEOF(ppm_source_struct));
451
  /* Fill in method ptrs, except get_pixel_rows which start_input sets */
452
  source->pub.start_input = start_input_ppm;
453
  source->pub.finish_input = finish_input_ppm;
454
455
  return (cjpeg_source_ptr) source;
456
}
457
458
#endif /* PPM_SUPPORTED */
(-)a/jpeg/rdrle.c (+387 lines)
Line     Link Here 
Line 0    Link Here 
1
/*
2
 * rdrle.c
3
 *
4
 * Copyright (C) 1991-1996, Thomas G. Lane.
5
 * This file is part of the Independent JPEG Group's software.
6
 * For conditions of distribution and use, see the accompanying README file.
7
 *
8
 * This file contains routines to read input images in Utah RLE format.
9
 * The Utah Raster Toolkit library is required (version 3.1 or later).
10
 *
11
 * These routines may need modification for non-Unix environments or
12
 * specialized applications.  As they stand, they assume input from
13
 * an ordinary stdio stream.  They further assume that reading begins
14
 * at the start of the file; start_input may need work if the
15
 * user interface has already read some data (e.g., to determine that
16
 * the file is indeed RLE format).
17
 *
18
 * Based on code contributed by Mike Lijewski,
19
 * with updates from Robert Hutchinson.
20
 */
21
22
#include "cdjpeg.h"		/* Common decls for cjpeg/djpeg applications */
23
24
#ifdef RLE_SUPPORTED
25
26
/* rle.h is provided by the Utah Raster Toolkit. */
27
28
#include <rle.h>
29
30
/*
31
 * We assume that JSAMPLE has the same representation as rle_pixel,
32
 * to wit, "unsigned char".  Hence we can't cope with 12- or 16-bit samples.
33
 */
34
35
#if BITS_IN_JSAMPLE != 8
36
  Sorry, this code only copes with 8-bit JSAMPLEs. /* deliberate syntax err */
37
#endif
38
39
/*
40
 * We support the following types of RLE files:
41
 *   
42
 *   GRAYSCALE   - 8 bits, no colormap
43
 *   MAPPEDGRAY  - 8 bits, 1 channel colomap
44
 *   PSEUDOCOLOR - 8 bits, 3 channel colormap
45
 *   TRUECOLOR   - 24 bits, 3 channel colormap
46
 *   DIRECTCOLOR - 24 bits, no colormap
47
 *
48
 * For now, we ignore any alpha channel in the image.
49
 */
50
51
typedef enum
52
  { GRAYSCALE, MAPPEDGRAY, PSEUDOCOLOR, TRUECOLOR, DIRECTCOLOR } rle_kind;
53
54
55
/*
56
 * Since RLE stores scanlines bottom-to-top, we have to invert the image
57
 * to conform to JPEG's top-to-bottom order.  To do this, we read the
58
 * incoming image into a virtual array on the first get_pixel_rows call,
59
 * then fetch the required row from the virtual array on subsequent calls.
60
 */
61
62
typedef struct _rle_source_struct * rle_source_ptr;
63
64
typedef struct _rle_source_struct {
65
  struct cjpeg_source_struct pub; /* public fields */
66
67
  rle_kind visual;              /* actual type of input file */
68
  jvirt_sarray_ptr image;       /* virtual array to hold the image */
69
  JDIMENSION row;		/* current row # in the virtual array */
70
  rle_hdr header;               /* Input file information */
71
  rle_pixel** rle_row;          /* holds a row returned by rle_getrow() */
72
73
} rle_source_struct;
74
75
76
/*
77
 * Read the file header; return image size and component count.
78
 */
79
80
METHODDEF(void)
81
start_input_rle (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
82
{
83
  rle_source_ptr source = (rle_source_ptr) sinfo;
84
  JDIMENSION width, height;
85
#ifdef PROGRESS_REPORT
86
  cd_progress_ptr progress = (cd_progress_ptr) cinfo->progress;
87
#endif
88
89
  /* Use RLE library routine to get the header info */
90
  source->header = *rle_hdr_init(NULL);
91
  source->header.rle_file = source->pub.input_file;
92
  switch (rle_get_setup(&(source->header))) {
93
  case RLE_SUCCESS:
94
    /* A-OK */
95
    break;
96
  case RLE_NOT_RLE:
97
    ERREXIT(cinfo, JERR_RLE_NOT);
98
    break;
99
  case RLE_NO_SPACE:
100
    ERREXIT(cinfo, JERR_RLE_MEM);
101
    break;
102
  case RLE_EMPTY:
103
    ERREXIT(cinfo, JERR_RLE_EMPTY);
104
    break;
105
  case RLE_EOF:
106
    ERREXIT(cinfo, JERR_RLE_EOF);
107
    break;
108
  default:
109
    ERREXIT(cinfo, JERR_RLE_BADERROR);
110
    break;
111
  }
112
113
  /* Figure out what we have, set private vars and return values accordingly */
114
  
115
  width  = source->header.xmax - source->header.xmin + 1;
116
  height = source->header.ymax - source->header.ymin + 1;
117
  source->header.xmin = 0;		/* realign horizontally */
118
  source->header.xmax = width-1;
119
120
  cinfo->image_width      = width;
121
  cinfo->image_height     = height;
122
  cinfo->data_precision   = 8;  /* we can only handle 8 bit data */
123
124
  if (source->header.ncolors == 1 && source->header.ncmap == 0) {
125
    source->visual     = GRAYSCALE;
126
    TRACEMS2(cinfo, 1, JTRC_RLE_GRAY, width, height);
127
  } else if (source->header.ncolors == 1 && source->header.ncmap == 1) {
128
    source->visual     = MAPPEDGRAY;
129
    TRACEMS3(cinfo, 1, JTRC_RLE_MAPGRAY, width, height,
130
             1 << source->header.cmaplen);
131
  } else if (source->header.ncolors == 1 && source->header.ncmap == 3) {
132
    source->visual     = PSEUDOCOLOR;
133
    TRACEMS3(cinfo, 1, JTRC_RLE_MAPPED, width, height,
134
	     1 << source->header.cmaplen);
135
  } else if (source->header.ncolors == 3 && source->header.ncmap == 3) {
136
    source->visual     = TRUECOLOR;
137
    TRACEMS3(cinfo, 1, JTRC_RLE_FULLMAP, width, height,
138
	     1 << source->header.cmaplen);
139
  } else if (source->header.ncolors == 3 && source->header.ncmap == 0) {
140
    source->visual     = DIRECTCOLOR;
141
    TRACEMS2(cinfo, 1, JTRC_RLE, width, height);
142
  } else
143
    ERREXIT(cinfo, JERR_RLE_UNSUPPORTED);
144
  
145
  if (source->visual == GRAYSCALE || source->visual == MAPPEDGRAY) {
146
    cinfo->in_color_space   = JCS_GRAYSCALE;
147
    cinfo->input_components = 1;
148
  } else {
149
    cinfo->in_color_space   = JCS_RGB;
150
    cinfo->input_components = 3;
151
  }
152
153
  /*
154
   * A place to hold each scanline while it's converted.
155
   * (GRAYSCALE scanlines don't need converting)
156
   */
157
  if (source->visual != GRAYSCALE) {
158
    source->rle_row = (rle_pixel**) (*cinfo->mem->alloc_sarray)
159
      ((j_common_ptr) cinfo, JPOOL_IMAGE,
160
       (JDIMENSION) width, (JDIMENSION) cinfo->input_components);
161
  }
162
163
  /* request a virtual array to hold the image */
164
  source->image = (*cinfo->mem->request_virt_sarray)
165
    ((j_common_ptr) cinfo, JPOOL_IMAGE, FALSE,
166
     (JDIMENSION) (width * source->header.ncolors),
167
     (JDIMENSION) height, (JDIMENSION) 1);
168
169
#ifdef PROGRESS_REPORT
170
  if (progress != NULL) {
171
    /* count file input as separate pass */
172
    progress->total_extra_passes++;
173
  }
174
#endif
175
176
  source->pub.buffer_height = 1;
177
}
178
179
180
/*
181
 * Read one row of pixels.
182
 * Called only after load_image has read the image into the virtual array.
183
 * Used for GRAYSCALE, MAPPEDGRAY, TRUECOLOR, and DIRECTCOLOR images.
184
 */
185
186
METHODDEF(JDIMENSION)
187
get_rle_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
188
{
189
  rle_source_ptr source = (rle_source_ptr) sinfo;
190
191
  source->row--;
192
  source->pub.buffer = (*cinfo->mem->access_virt_sarray)
193
    ((j_common_ptr) cinfo, source->image, source->row, (JDIMENSION) 1, FALSE);
194
195
  return 1;
196
}
197
198
/*
199
 * Read one row of pixels.
200
 * Called only after load_image has read the image into the virtual array.
201
 * Used for PSEUDOCOLOR images.
202
 */
203
204
METHODDEF(JDIMENSION)
205
get_pseudocolor_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
206
{
207
  rle_source_ptr source = (rle_source_ptr) sinfo;
208
  JSAMPROW src_row, dest_row;
209
  JDIMENSION col;
210
  rle_map *colormap;
211
  int val;
212
213
  colormap = source->header.cmap;
214
  dest_row = source->pub.buffer[0];
215
  source->row--;
216
  src_row = * (*cinfo->mem->access_virt_sarray)
217
    ((j_common_ptr) cinfo, source->image, source->row, (JDIMENSION) 1, FALSE);
218
219
  for (col = cinfo->image_width; col > 0; col--) {
220
    val = GETJSAMPLE(*src_row++);
221
    *dest_row++ = (JSAMPLE) (colormap[val      ] >> 8);
222
    *dest_row++ = (JSAMPLE) (colormap[val + 256] >> 8);
223
    *dest_row++ = (JSAMPLE) (colormap[val + 512] >> 8);
224
  }
225
226
  return 1;
227
}
228
229
230
/*
231
 * Load the image into a virtual array.  We have to do this because RLE
232
 * files start at the lower left while the JPEG standard has them starting
233
 * in the upper left.  This is called the first time we want to get a row
234
 * of input.  What we do is load the RLE data into the array and then call
235
 * the appropriate routine to read one row from the array.  Before returning,
236
 * we set source->pub.get_pixel_rows so that subsequent calls go straight to
237
 * the appropriate row-reading routine.
238
 */
239
240
METHODDEF(JDIMENSION)
241
load_image (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
242
{
243
  rle_source_ptr source = (rle_source_ptr) sinfo;
244
  JDIMENSION row, col;
245
  JSAMPROW  scanline, red_ptr, green_ptr, blue_ptr;
246
  rle_pixel **rle_row;
247
  rle_map *colormap;
248
  char channel;
249
#ifdef PROGRESS_REPORT
250
  cd_progress_ptr progress = (cd_progress_ptr) cinfo->progress;
251
#endif
252
253
  colormap = source->header.cmap;
254
  rle_row = source->rle_row;
255
256
  /* Read the RLE data into our virtual array.
257
   * We assume here that (a) rle_pixel is represented the same as JSAMPLE,
258
   * and (b) we are not on a machine where FAR pointers differ from regular.
259
   */
260
  RLE_CLR_BIT(source->header, RLE_ALPHA); /* don't read the alpha channel */
261
262
#ifdef PROGRESS_REPORT
263
  if (progress != NULL) {
264
    progress->pub.pass_limit = cinfo->image_height;
265
    progress->pub.pass_counter = 0;
266
    (*progress->pub.progress_monitor) ((j_common_ptr) cinfo);
267
  }
268
#endif
269
270
  switch (source->visual) {
271
272
  case GRAYSCALE:
273
  case PSEUDOCOLOR:
274
    for (row = 0; row < cinfo->image_height; row++) {
275
      rle_row = (rle_pixel **) (*cinfo->mem->access_virt_sarray)
276
         ((j_common_ptr) cinfo, source->image, row, (JDIMENSION) 1, TRUE);
277
      rle_getrow(&source->header, rle_row);
278
#ifdef PROGRESS_REPORT
279
      if (progress != NULL) {
280
        progress->pub.pass_counter++;
281
        (*progress->pub.progress_monitor) ((j_common_ptr) cinfo);
282
      }
283
#endif
284
    }
285
    break;
286
287
  case MAPPEDGRAY:
288
  case TRUECOLOR:
289
    for (row = 0; row < cinfo->image_height; row++) {
290
      scanline = * (*cinfo->mem->access_virt_sarray)
291
        ((j_common_ptr) cinfo, source->image, row, (JDIMENSION) 1, TRUE);
292
      rle_row = source->rle_row;
293
      rle_getrow(&source->header, rle_row);
294
295
      for (col = 0; col < cinfo->image_width; col++) {
296
        for (channel = 0; channel < source->header.ncolors; channel++) {
297
          *scanline++ = (JSAMPLE)
298
            (colormap[GETJSAMPLE(rle_row[channel][col]) + 256 * channel] >> 8);
299
        }
300
      }
301
302
#ifdef PROGRESS_REPORT
303
      if (progress != NULL) {
304
        progress->pub.pass_counter++;
305
        (*progress->pub.progress_monitor) ((j_common_ptr) cinfo);
306
      }
307
#endif
308
    }
309
    break;
310
311
  case DIRECTCOLOR:
312
    for (row = 0; row < cinfo->image_height; row++) {
313
      scanline = * (*cinfo->mem->access_virt_sarray)
314
        ((j_common_ptr) cinfo, source->image, row, (JDIMENSION) 1, TRUE);
315
      rle_getrow(&source->header, rle_row);
316
317
      red_ptr   = rle_row[0];
318
      green_ptr = rle_row[1];
319
      blue_ptr  = rle_row[2];
320
321
      for (col = cinfo->image_width; col > 0; col--) {
322
        *scanline++ = *red_ptr++;
323
        *scanline++ = *green_ptr++;
324
        *scanline++ = *blue_ptr++;
325
      }
326
327
#ifdef PROGRESS_REPORT
328
      if (progress != NULL) {
329
        progress->pub.pass_counter++;
330
        (*progress->pub.progress_monitor) ((j_common_ptr) cinfo);
331
      }
332
#endif
333
    }
334
  }
335
336
#ifdef PROGRESS_REPORT
337
  if (progress != NULL)
338
    progress->completed_extra_passes++;
339
#endif
340
341
  /* Set up to call proper row-extraction routine in future */
342
  if (source->visual == PSEUDOCOLOR) {
343
    source->pub.buffer = source->rle_row;
344
    source->pub.get_pixel_rows = get_pseudocolor_row;
345
  } else {
346
    source->pub.get_pixel_rows = get_rle_row;
347
  }
348
  source->row = cinfo->image_height;
349
350
  /* And fetch the topmost (bottommost) row */
351
  return (*source->pub.get_pixel_rows) (cinfo, sinfo);   
352
}
353
354
355
/*
356
 * Finish up at the end of the file.
357
 */
358
359
METHODDEF(void)
360
finish_input_rle (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
361
{
362
  /* no work */
363
}
364
365
366
/*
367
 * The module selection routine for RLE format input.
368
 */
369
370
GLOBAL(cjpeg_source_ptr)
371
jinit_read_rle (j_compress_ptr cinfo)
372
{
373
  rle_source_ptr source;
374
375
  /* Create module interface object */
376
  source = (rle_source_ptr)
377
      (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
378
                                  SIZEOF(rle_source_struct));
379
  /* Fill in method ptrs */
380
  source->pub.start_input = start_input_rle;
381
  source->pub.finish_input = finish_input_rle;
382
  source->pub.get_pixel_rows = load_image;
383
384
  return (cjpeg_source_ptr) source;
385
}
386
387
#endif /* RLE_SUPPORTED */
(-)a/jpeg/rdswitch.c (+332 lines)
Line     Link Here 
Line 0    Link Here 
1
/*
2
 * rdswitch.c
3
 *
4
 * Copyright (C) 1991-1996, Thomas G. Lane.
5
 * This file is part of the Independent JPEG Group's software.
6
 * For conditions of distribution and use, see the accompanying README file.
7
 *
8
 * This file contains routines to process some of cjpeg's more complicated
9
 * command-line switches.  Switches processed here are:
10
 *	-qtables file		Read quantization tables from text file
11
 *	-scans file		Read scan script from text file
12
 *	-qslots N[,N,...]	Set component quantization table selectors
13
 *	-sample HxV[,HxV,...]	Set component sampling factors
14
 */
15
16
#include "cdjpeg.h"		/* Common decls for cjpeg/djpeg applications */
17
#include <ctype.h>		/* to declare isdigit(), isspace() */
18
19
20
LOCAL(int)
21
text_getc (FILE * file)
22
/* Read next char, skipping over any comments (# to end of line) */
23
/* A comment/newline sequence is returned as a newline */
24
{
25
  register int ch;
26
  
27
  ch = getc(file);
28
  if (ch == '#') {
29
    do {
30
      ch = getc(file);
31
    } while (ch != '\n' && ch != EOF);
32
  }
33
  return ch;
34
}
35
36
37
LOCAL(boolean)
38
read_text_integer (FILE * file, long * result, int * termchar)
39
/* Read an unsigned decimal integer from a file, store it in result */
40
/* Reads one trailing character after the integer; returns it in termchar */
41
{
42
  register int ch;
43
  register long val;
44
  
45
  /* Skip any leading whitespace, detect EOF */
46
  do {
47
    ch = text_getc(file);
48
    if (ch == EOF) {
49
      *termchar = ch;
50
      return FALSE;
51
    }
52
  } while (isspace(ch));
53
  
54
  if (! isdigit(ch)) {
55
    *termchar = ch;
56
    return FALSE;
57
  }
58
59
  val = ch - '0';
60
  while ((ch = text_getc(file)) != EOF) {
61
    if (! isdigit(ch))
62
      break;
63
    val *= 10;
64
    val += ch - '0';
65
  }
66
  *result = val;
67
  *termchar = ch;
68
  return TRUE;
69
}
70
71
72
GLOBAL(boolean)
73
read_quant_tables (j_compress_ptr cinfo, char * filename,
74
		   int scale_factor, boolean force_baseline)
75
/* Read a set of quantization tables from the specified file.
76
 * The file is plain ASCII text: decimal numbers with whitespace between.
77
 * Comments preceded by '#' may be included in the file.
78
 * There may be one to NUM_QUANT_TBLS tables in the file, each of 64 values.
79
 * The tables are implicitly numbered 0,1,etc.
80
 * NOTE: does not affect the qslots mapping, which will default to selecting
81
 * table 0 for luminance (or primary) components, 1 for chrominance components.
82
 * You must use -qslots if you want a different component->table mapping.
83
 */
84
{
85
  FILE * fp;
86
  int tblno, i, termchar;
87
  long val;
88
  unsigned int table[DCTSIZE2];
89
90
  if ((fp = fopen(filename, "r")) == NULL) {
91
    fprintf(stderr, "Can't open table file %s\n", filename);
92
    return FALSE;
93
  }
94
  tblno = 0;
95
96
  while (read_text_integer(fp, &val, &termchar)) { /* read 1st element of table */
97
    if (tblno >= NUM_QUANT_TBLS) {
98
      fprintf(stderr, "Too many tables in file %s\n", filename);
99
      fclose(fp);
100
      return FALSE;
101
    }
102
    table[0] = (unsigned int) val;
103
    for (i = 1; i < DCTSIZE2; i++) {
104
      if (! read_text_integer(fp, &val, &termchar)) {
105
	fprintf(stderr, "Invalid table data in file %s\n", filename);
106
	fclose(fp);
107
	return FALSE;
108
      }
109
      table[i] = (unsigned int) val;
110
    }
111
    jpeg_add_quant_table(cinfo, tblno, table, scale_factor, force_baseline);
112
    tblno++;
113
  }
114
115
  if (termchar != EOF) {
116
    fprintf(stderr, "Non-numeric data in file %s\n", filename);
117
    fclose(fp);
118
    return FALSE;
119
  }
120
121
  fclose(fp);
122
  return TRUE;
123
}
124
125
126
#ifdef C_MULTISCAN_FILES_SUPPORTED
127
128
LOCAL(boolean)
129
read_scan_integer (FILE * file, long * result, int * termchar)
130
/* Variant of read_text_integer that always looks for a non-space termchar;
131
 * this simplifies parsing of punctuation in scan scripts.
132
 */
133
{
134
  register int ch;
135
136
  if (! read_text_integer(file, result, termchar))
137
    return FALSE;
138
  ch = *termchar;
139
  while (ch != EOF && isspace(ch))
140
    ch = text_getc(file);
141
  if (isdigit(ch)) {		/* oops, put it back */
142
    if (ungetc(ch, file) == EOF)
143
      return FALSE;
144
    ch = ' ';
145
  } else {
146
    /* Any separators other than ';' and ':' are ignored;
147
     * this allows user to insert commas, etc, if desired.
148
     */
149
    if (ch != EOF && ch != ';' && ch != ':')
150
      ch = ' ';
151
  }
152
  *termchar = ch;
153
  return TRUE;
154
}
155
156
157
GLOBAL(boolean)
158
read_scan_script (j_compress_ptr cinfo, char * filename)
159
/* Read a scan script from the specified text file.
160
 * Each entry in the file defines one scan to be emitted.
161
 * Entries are separated by semicolons ';'.
162
 * An entry contains one to four component indexes,
163
 * optionally followed by a colon ':' and four progressive-JPEG parameters.
164
 * The component indexes denote which component(s) are to be transmitted
165
 * in the current scan.  The first component has index 0.
166
 * Sequential JPEG is used if the progressive-JPEG parameters are omitted.
167
 * The file is free format text: any whitespace may appear between numbers
168
 * and the ':' and ';' punctuation marks.  Also, other punctuation (such
169
 * as commas or dashes) can be placed between numbers if desired.
170
 * Comments preceded by '#' may be included in the file.
171
 * Note: we do very little validity checking here;
172
 * jcmaster.c will validate the script parameters.
173
 */
174
{
175
  FILE * fp;
176
  int scanno, ncomps, termchar;
177
  long val;
178
  jpeg_scan_info * scanptr;
179
#define MAX_SCANS  100		/* quite arbitrary limit */
180
  jpeg_scan_info scans[MAX_SCANS];
181
182
  if ((fp = fopen(filename, "r")) == NULL) {
183
    fprintf(stderr, "Can't open scan definition file %s\n", filename);
184
    return FALSE;
185
  }
186
  scanptr = scans;
187
  scanno = 0;
188
189
  while (read_scan_integer(fp, &val, &termchar)) {
190
    if (scanno >= MAX_SCANS) {
191
      fprintf(stderr, "Too many scans defined in file %s\n", filename);
192
      fclose(fp);
193
      return FALSE;
194
    }
195
    scanptr->component_index[0] = (int) val;
196
    ncomps = 1;
197
    while (termchar == ' ') {
198
      if (ncomps >= MAX_COMPS_IN_SCAN) {
199
	fprintf(stderr, "Too many components in one scan in file %s\n",
200
		filename);
201
	fclose(fp);
202
	return FALSE;
203
      }
204
      if (! read_scan_integer(fp, &val, &termchar))
205
	goto bogus;
206
      scanptr->component_index[ncomps] = (int) val;
207
      ncomps++;
208
    }
209
    scanptr->comps_in_scan = ncomps;
210
    if (termchar == ':') {
211
      if (! read_scan_integer(fp, &val, &termchar) || termchar != ' ')
212
	goto bogus;
213
      scanptr->Ss = (int) val;
214
      if (! read_scan_integer(fp, &val, &termchar) || termchar != ' ')
215
	goto bogus;
216
      scanptr->Se = (int) val;
217
      if (! read_scan_integer(fp, &val, &termchar) || termchar != ' ')
218
	goto bogus;
219
      scanptr->Ah = (int) val;
220
      if (! read_scan_integer(fp, &val, &termchar))
221
	goto bogus;
222
      scanptr->Al = (int) val;
223
    } else {
224
      /* set non-progressive parameters */
225
      scanptr->Ss = 0;
226
      scanptr->Se = DCTSIZE2-1;
227
      scanptr->Ah = 0;
228
      scanptr->Al = 0;
229
    }
230
    if (termchar != ';' && termchar != EOF) {
231
bogus:
232
      fprintf(stderr, "Invalid scan entry format in file %s\n", filename);
233
      fclose(fp);
234
      return FALSE;
235
    }
236
    scanptr++, scanno++;
237
  }
238
239
  if (termchar != EOF) {
240
    fprintf(stderr, "Non-numeric data in file %s\n", filename);
241
    fclose(fp);
242
    return FALSE;
243
  }
244
245
  if (scanno > 0) {
246
    /* Stash completed scan list in cinfo structure.
247
     * NOTE: for cjpeg's use, JPOOL_IMAGE is the right lifetime for this data,
248
     * but if you want to compress multiple images you'd want JPOOL_PERMANENT.
249
     */
250
    scanptr = (jpeg_scan_info *)
251
      (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
252
				  scanno * SIZEOF(jpeg_scan_info));
253
    MEMCOPY(scanptr, scans, scanno * SIZEOF(jpeg_scan_info));
254
    cinfo->scan_info = scanptr;
255
    cinfo->num_scans = scanno;
256
  }
257
258
  fclose(fp);
259
  return TRUE;
260
}
261
262
#endif /* C_MULTISCAN_FILES_SUPPORTED */
263
264
265
GLOBAL(boolean)
266
set_quant_slots (j_compress_ptr cinfo, char *arg)
267
/* Process a quantization-table-selectors parameter string, of the form
268
 *     N[,N,...]
269
 * If there are more components than parameters, the last value is replicated.
270
 */
271
{
272
  int val = 0;			/* default table # */
273
  int ci;
274
  char ch;
275
276
  for (ci = 0; ci < MAX_COMPONENTS; ci++) {
277
    if (*arg) {
278
      ch = ',';			/* if not set by sscanf, will be ',' */
279
      if (sscanf(arg, "%d%c", &val, &ch) < 1)
280
	return FALSE;
281
      if (ch != ',')		/* syntax check */
282
	return FALSE;
283
      if (val < 0 || val >= NUM_QUANT_TBLS) {
284
	fprintf(stderr, "JPEG quantization tables are numbered 0..%d\n",
285
		NUM_QUANT_TBLS-1);
286
	return FALSE;
287
      }
288
      cinfo->comp_info[ci].quant_tbl_no = val;
289
      while (*arg && *arg++ != ',') /* advance to next segment of arg string */
290
	;
291
    } else {
292
      /* reached end of parameter, set remaining components to last table */
293
      cinfo->comp_info[ci].quant_tbl_no = val;
294
    }
295
  }
296
  return TRUE;
297
}
298
299
300
GLOBAL(boolean)
301
set_sample_factors (j_compress_ptr cinfo, char *arg)
302
/* Process a sample-factors parameter string, of the form
303
 *     HxV[,HxV,...]
304
 * If there are more components than parameters, "1x1" is assumed for the rest.
305
 */
306
{
307
  int ci, val1, val2;
308
  char ch1, ch2;
309
310
  for (ci = 0; ci < MAX_COMPONENTS; ci++) {
311
    if (*arg) {
312
      ch2 = ',';		/* if not set by sscanf, will be ',' */
313
      if (sscanf(arg, "%d%c%d%c", &val1, &ch1, &val2, &ch2) < 3)
314
	return FALSE;
315
      if ((ch1 != 'x' && ch1 != 'X') || ch2 != ',') /* syntax check */
316
	return FALSE;
317
      if (val1 <= 0 || val1 > 4 || val2 <= 0 || val2 > 4) {
318
	fprintf(stderr, "JPEG sampling factors must be 1..4\n");
319
	return FALSE;
320
      }
321
      cinfo->comp_info[ci].h_samp_factor = val1;
322
      cinfo->comp_info[ci].v_samp_factor = val2;
323
      while (*arg && *arg++ != ',') /* advance to next segment of arg string */
324
	;
325
    } else {
326
      /* reached end of parameter, set remaining components to 1x1 sampling */
327
      cinfo->comp_info[ci].h_samp_factor = 1;
328
      cinfo->comp_info[ci].v_samp_factor = 1;
329
    }
330
  }
331
  return TRUE;
332
}
(-)a/jpeg/rdtarga.c (+500 lines)
Line     Link Here 
Line 0    Link Here 
1
/*
2
 * rdtarga.c
3
 *
4
 * Copyright (C) 1991-1996, Thomas G. Lane.
5
 * This file is part of the Independent JPEG Group's software.
6
 * For conditions of distribution and use, see the accompanying README file.
7
 *
8
 * This file contains routines to read input images in Targa format.
9
 *
10
 * These routines may need modification for non-Unix environments or
11
 * specialized applications.  As they stand, they assume input from
12
 * an ordinary stdio stream.  They further assume that reading begins
13
 * at the start of the file; start_input may need work if the
14
 * user interface has already read some data (e.g., to determine that
15
 * the file is indeed Targa format).
16
 *
17
 * Based on code contributed by Lee Daniel Crocker.
18
 */
19
20
#include "cdjpeg.h"		/* Common decls for cjpeg/djpeg applications */
21
22
#ifdef TARGA_SUPPORTED
23
24
25
/* Macros to deal with unsigned chars as efficiently as compiler allows */
26
27
#ifdef HAVE_UNSIGNED_CHAR
28
typedef unsigned char U_CHAR;
29
#define UCH(x)	((int) (x))
30
#else /* !HAVE_UNSIGNED_CHAR */
31
#ifdef CHAR_IS_UNSIGNED
32
typedef char U_CHAR;
33
#define UCH(x)	((int) (x))
34
#else
35
typedef char U_CHAR;
36
#define UCH(x)	((int) (x) & 0xFF)
37
#endif
38
#endif /* HAVE_UNSIGNED_CHAR */
39
40
41
#define	ReadOK(file,buffer,len)	(JFREAD(file,buffer,len) == ((size_t) (len)))
42
43
44
/* Private version of data source object */
45
46
typedef struct _tga_source_struct * tga_source_ptr;
47
48
typedef struct _tga_source_struct {
49
  struct cjpeg_source_struct pub; /* public fields */
50
51
  j_compress_ptr cinfo;		/* back link saves passing separate parm */
52
53
  JSAMPARRAY colormap;		/* Targa colormap (converted to my format) */
54
55
  jvirt_sarray_ptr whole_image;	/* Needed if funny input row order */
56
  JDIMENSION current_row;	/* Current logical row number to read */
57
58
  /* Pointer to routine to extract next Targa pixel from input file */
59
  JMETHOD(void, read_pixel, (tga_source_ptr sinfo));
60
61
  /* Result of read_pixel is delivered here: */
62
  U_CHAR tga_pixel[4];
63
64
  int pixel_size;		/* Bytes per Targa pixel (1 to 4) */
65
66
  /* State info for reading RLE-coded pixels; both counts must be init to 0 */
67
  int block_count;		/* # of pixels remaining in RLE block */
68
  int dup_pixel_count;		/* # of times to duplicate previous pixel */
69
70
  /* This saves the correct pixel-row-expansion method for preload_image */
71
  JMETHOD(JDIMENSION, get_pixel_rows, (j_compress_ptr cinfo,
72
				       cjpeg_source_ptr sinfo));
73
} tga_source_struct;
74
75
76
/* For expanding 5-bit pixel values to 8-bit with best rounding */
77
78
static const UINT8 c5to8bits[32] = {
79
    0,   8,  16,  25,  33,  41,  49,  58,
80
   66,  74,  82,  90,  99, 107, 115, 123,
81
  132, 140, 148, 156, 165, 173, 181, 189,
82
  197, 206, 214, 222, 230, 239, 247, 255
83
};
84
85
86
87
LOCAL(int)
88
read_byte (tga_source_ptr sinfo)
89
/* Read next byte from Targa file */
90
{
91
  register FILE *infile = sinfo->pub.input_file;
92
  register int c;
93
94
  if ((c = getc(infile)) == EOF)
95
    ERREXIT(sinfo->cinfo, JERR_INPUT_EOF);
96
  return c;
97
}
98
99
100
LOCAL(void)
101
read_colormap (tga_source_ptr sinfo, int cmaplen, int mapentrysize)
102
/* Read the colormap from a Targa file */
103
{
104
  int i;
105
106
  /* Presently only handles 24-bit BGR format */
107
  if (mapentrysize != 24)
108
    ERREXIT(sinfo->cinfo, JERR_TGA_BADCMAP);
109
110
  for (i = 0; i < cmaplen; i++) {
111
    sinfo->colormap[2][i] = (JSAMPLE) read_byte(sinfo);
112
    sinfo->colormap[1][i] = (JSAMPLE) read_byte(sinfo);
113
    sinfo->colormap[0][i] = (JSAMPLE) read_byte(sinfo);
114
  }
115
}
116
117
118
/*
119
 * read_pixel methods: get a single pixel from Targa file into tga_pixel[]
120
 */
121
122
METHODDEF(void)
123
read_non_rle_pixel (tga_source_ptr sinfo)
124
/* Read one Targa pixel from the input file; no RLE expansion */
125
{
126
  register FILE *infile = sinfo->pub.input_file;
127
  register int i;
128
129
  for (i = 0; i < sinfo->pixel_size; i++) {
130
    sinfo->tga_pixel[i] = (U_CHAR) getc(infile);
131
  }
132
}
133
134
135
METHODDEF(void)
136
read_rle_pixel (tga_source_ptr sinfo)
137
/* Read one Targa pixel from the input file, expanding RLE data as needed */
138
{
139
  register FILE *infile = sinfo->pub.input_file;
140
  register int i;
141
142
  /* Duplicate previously read pixel? */
143
  if (sinfo->dup_pixel_count > 0) {
144
    sinfo->dup_pixel_count--;
145
    return;
146
  }
147
148
  /* Time to read RLE block header? */
149
  if (--sinfo->block_count < 0) { /* decrement pixels remaining in block */
150
    i = read_byte(sinfo);
151
    if (i & 0x80) {		/* Start of duplicate-pixel block? */
152
      sinfo->dup_pixel_count = i & 0x7F; /* number of dups after this one */
153
      sinfo->block_count = 0;	/* then read new block header */
154
    } else {
155
      sinfo->block_count = i & 0x7F; /* number of pixels after this one */
156
    }
157
  }
158
159
  /* Read next pixel */
160
  for (i = 0; i < sinfo->pixel_size; i++) {
161
    sinfo->tga_pixel[i] = (U_CHAR) getc(infile);
162
  }
163
}
164
165
166
/*
167
 * Read one row of pixels.
168
 *
169
 * We provide several different versions depending on input file format.
170
 */
171
172
173
METHODDEF(JDIMENSION)
174
get_8bit_gray_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
175
/* This version is for reading 8-bit grayscale pixels */
176
{
177
  tga_source_ptr source = (tga_source_ptr) sinfo;
178
  register JSAMPROW ptr;
179
  register JDIMENSION col;
180
  
181
  ptr = source->pub.buffer[0];
182
  for (col = cinfo->image_width; col > 0; col--) {
183
    (*source->read_pixel) (source); /* Load next pixel into tga_pixel */
184
    *ptr++ = (JSAMPLE) UCH(source->tga_pixel[0]);
185
  }
186
  return 1;
187
}
188
189
METHODDEF(JDIMENSION)
190
get_8bit_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
191
/* This version is for reading 8-bit colormap indexes */
192
{
193
  tga_source_ptr source = (tga_source_ptr) sinfo;
194
  register int t;
195
  register JSAMPROW ptr;
196
  register JDIMENSION col;
197
  register JSAMPARRAY colormap = source->colormap;
198
199
  ptr = source->pub.buffer[0];
200
  for (col = cinfo->image_width; col > 0; col--) {
201
    (*source->read_pixel) (source); /* Load next pixel into tga_pixel */
202
    t = UCH(source->tga_pixel[0]);
203
    *ptr++ = colormap[0][t];
204
    *ptr++ = colormap[1][t];
205
    *ptr++ = colormap[2][t];
206
  }
207
  return 1;
208
}
209
210
METHODDEF(JDIMENSION)
211
get_16bit_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
212
/* This version is for reading 16-bit pixels */
213
{
214
  tga_source_ptr source = (tga_source_ptr) sinfo;
215
  register int t;
216
  register JSAMPROW ptr;
217
  register JDIMENSION col;
218
  
219
  ptr = source->pub.buffer[0];
220
  for (col = cinfo->image_width; col > 0; col--) {
221
    (*source->read_pixel) (source); /* Load next pixel into tga_pixel */
222
    t = UCH(source->tga_pixel[0]);
223
    t += UCH(source->tga_pixel[1]) << 8;
224
    /* We expand 5 bit data to 8 bit sample width.
225
     * The format of the 16-bit (LSB first) input word is
226
     *     xRRRRRGGGGGBBBBB
227
     */
228
    ptr[2] = (JSAMPLE) c5to8bits[t & 0x1F];
229
    t >>= 5;
230
    ptr[1] = (JSAMPLE) c5to8bits[t & 0x1F];
231
    t >>= 5;
232
    ptr[0] = (JSAMPLE) c5to8bits[t & 0x1F];
233
    ptr += 3;
234
  }
235
  return 1;
236
}
237
238
METHODDEF(JDIMENSION)
239
get_24bit_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
240
/* This version is for reading 24-bit pixels */
241
{
242
  tga_source_ptr source = (tga_source_ptr) sinfo;
243
  register JSAMPROW ptr;
244
  register JDIMENSION col;
245
  
246
  ptr = source->pub.buffer[0];
247
  for (col = cinfo->image_width; col > 0; col--) {
248
    (*source->read_pixel) (source); /* Load next pixel into tga_pixel */
249
    *ptr++ = (JSAMPLE) UCH(source->tga_pixel[2]); /* change BGR to RGB order */
250
    *ptr++ = (JSAMPLE) UCH(source->tga_pixel[1]);
251
    *ptr++ = (JSAMPLE) UCH(source->tga_pixel[0]);
252
  }
253
  return 1;
254
}
255
256
/*
257
 * Targa also defines a 32-bit pixel format with order B,G,R,A.
258
 * We presently ignore the attribute byte, so the code for reading
259
 * these pixels is identical to the 24-bit routine above.
260
 * This works because the actual pixel length is only known to read_pixel.
261
 */
262
263
#define get_32bit_row  get_24bit_row
264
265
266
/*
267
 * This method is for re-reading the input data in standard top-down
268
 * row order.  The entire image has already been read into whole_image
269
 * with proper conversion of pixel format, but it's in a funny row order.
270
 */
271
272
METHODDEF(JDIMENSION)
273
get_memory_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
274
{
275
  tga_source_ptr source = (tga_source_ptr) sinfo;
276
  JDIMENSION source_row;
277
278
  /* Compute row of source that maps to current_row of normal order */
279
  /* For now, assume image is bottom-up and not interlaced. */
280
  /* NEEDS WORK to support interlaced images! */
281
  source_row = cinfo->image_height - source->current_row - 1;
282
283
  /* Fetch that row from virtual array */
284
  source->pub.buffer = (*cinfo->mem->access_virt_sarray)
285
    ((j_common_ptr) cinfo, source->whole_image,
286
     source_row, (JDIMENSION) 1, FALSE);
287
288
  source->current_row++;
289
  return 1;
290
}
291
292
293
/*
294
 * This method loads the image into whole_image during the first call on
295
 * get_pixel_rows.  The get_pixel_rows pointer is then adjusted to call
296
 * get_memory_row on subsequent calls.
297
 */
298
299
METHODDEF(JDIMENSION)
300
preload_image (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
301
{
302
  tga_source_ptr source = (tga_source_ptr) sinfo;
303
  JDIMENSION row;
304
  cd_progress_ptr progress = (cd_progress_ptr) cinfo->progress;
305
306
  /* Read the data into a virtual array in input-file row order. */
307
  for (row = 0; row < cinfo->image_height; row++) {
308
    if (progress != NULL) {
309
      progress->pub.pass_counter = (long) row;
310
      progress->pub.pass_limit = (long) cinfo->image_height;
311
      (*progress->pub.progress_monitor) ((j_common_ptr) cinfo);
312
    }
313
    source->pub.buffer = (*cinfo->mem->access_virt_sarray)
314
      ((j_common_ptr) cinfo, source->whole_image, row, (JDIMENSION) 1, TRUE);
315
    (*source->get_pixel_rows) (cinfo, sinfo);
316
  }
317
  if (progress != NULL)
318
    progress->completed_extra_passes++;
319
320
  /* Set up to read from the virtual array in unscrambled order */
321
  source->pub.get_pixel_rows = get_memory_row;
322
  source->current_row = 0;
323
  /* And read the first row */
324
  return get_memory_row(cinfo, sinfo);
325
}
326
327
328
/*
329
 * Read the file header; return image size and component count.
330
 */
331
332
METHODDEF(void)
333
start_input_tga (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
334
{
335
  tga_source_ptr source = (tga_source_ptr) sinfo;
336
  U_CHAR targaheader[18];
337
  int idlen, cmaptype, subtype, flags, interlace_type, components;
338
  unsigned int width, height, maplen;
339
  boolean is_bottom_up;
340
341
#define GET_2B(offset)	((unsigned int) UCH(targaheader[offset]) + \
342
			 (((unsigned int) UCH(targaheader[offset+1])) << 8))
343
344
  if (! ReadOK(source->pub.input_file, targaheader, 18))
345
    ERREXIT(cinfo, JERR_INPUT_EOF);
346
347
  /* Pretend "15-bit" pixels are 16-bit --- we ignore attribute bit anyway */
348
  if (targaheader[16] == 15)
349
    targaheader[16] = 16;
350
351
  idlen = UCH(targaheader[0]);
352
  cmaptype = UCH(targaheader[1]);
353
  subtype = UCH(targaheader[2]);
354
  maplen = GET_2B(5);
355
  width = GET_2B(12);
356
  height = GET_2B(14);
357
  source->pixel_size = UCH(targaheader[16]) >> 3;
358
  flags = UCH(targaheader[17]);	/* Image Descriptor byte */
359
360
  is_bottom_up = ((flags & 0x20) == 0);	/* bit 5 set => top-down */
361
  interlace_type = flags >> 6;	/* bits 6/7 are interlace code */
362
363
  if (cmaptype > 1 ||		/* cmaptype must be 0 or 1 */
364
      source->pixel_size < 1 || source->pixel_size > 4 ||
365
      (UCH(targaheader[16]) & 7) != 0 || /* bits/pixel must be multiple of 8 */
366
      interlace_type != 0)	/* currently don't allow interlaced image */
367
    ERREXIT(cinfo, JERR_TGA_BADPARMS);
368
  
369
  if (subtype > 8) {
370
    /* It's an RLE-coded file */
371
    source->read_pixel = read_rle_pixel;
372
    source->block_count = source->dup_pixel_count = 0;
373
    subtype -= 8;
374
  } else {
375
    /* Non-RLE file */
376
    source->read_pixel = read_non_rle_pixel;
377
  }
378
379
  /* Now should have subtype 1, 2, or 3 */
380
  components = 3;		/* until proven different */
381
  cinfo->in_color_space = JCS_RGB;
382
383
  switch (subtype) {
384
  case 1:			/* Colormapped image */
385
    if (source->pixel_size == 1 && cmaptype == 1)
386
      source->get_pixel_rows = get_8bit_row;
387
    else
388
      ERREXIT(cinfo, JERR_TGA_BADPARMS);
389
    TRACEMS2(cinfo, 1, JTRC_TGA_MAPPED, width, height);
390
    break;
391
  case 2:			/* RGB image */
392
    switch (source->pixel_size) {
393
    case 2:
394
      source->get_pixel_rows = get_16bit_row;
395
      break;
396
    case 3:
397
      source->get_pixel_rows = get_24bit_row;
398
      break;
399
    case 4:
400
      source->get_pixel_rows = get_32bit_row;
401
      break;
402
    default:
403
      ERREXIT(cinfo, JERR_TGA_BADPARMS);
404
      break;
405
    }
406
    TRACEMS2(cinfo, 1, JTRC_TGA, width, height);
407
    break;
408
  case 3:			/* Grayscale image */
409
    components = 1;
410
    cinfo->in_color_space = JCS_GRAYSCALE;
411
    if (source->pixel_size == 1)
412
      source->get_pixel_rows = get_8bit_gray_row;
413
    else
414
      ERREXIT(cinfo, JERR_TGA_BADPARMS);
415
    TRACEMS2(cinfo, 1, JTRC_TGA_GRAY, width, height);
416
    break;
417
  default:
418
    ERREXIT(cinfo, JERR_TGA_BADPARMS);
419
    break;
420
  }
421
422
  if (is_bottom_up) {
423
    /* Create a virtual array to buffer the upside-down image. */
424
    source->whole_image = (*cinfo->mem->request_virt_sarray)
425
      ((j_common_ptr) cinfo, JPOOL_IMAGE, FALSE,
426
       (JDIMENSION) width * components, (JDIMENSION) height, (JDIMENSION) 1);
427
    if (cinfo->progress != NULL) {
428
      cd_progress_ptr progress = (cd_progress_ptr) cinfo->progress;
429
      progress->total_extra_passes++; /* count file input as separate pass */
430
    }
431
    /* source->pub.buffer will point to the virtual array. */
432
    source->pub.buffer_height = 1; /* in case anyone looks at it */
433
    source->pub.get_pixel_rows = preload_image;
434
  } else {
435
    /* Don't need a virtual array, but do need a one-row input buffer. */
436
    source->whole_image = NULL;
437
    source->pub.buffer = (*cinfo->mem->alloc_sarray)
438
      ((j_common_ptr) cinfo, JPOOL_IMAGE,
439
       (JDIMENSION) width * components, (JDIMENSION) 1);
440
    source->pub.buffer_height = 1;
441
    source->pub.get_pixel_rows = source->get_pixel_rows;
442
  }
443
  
444
  while (idlen--)		/* Throw away ID field */
445
    (void) read_byte(source);
446
447
  if (maplen > 0) {
448
    if (maplen > 256 || GET_2B(3) != 0)
449
      ERREXIT(cinfo, JERR_TGA_BADCMAP);
450
    /* Allocate space to store the colormap */
451
    source->colormap = (*cinfo->mem->alloc_sarray)
452
      ((j_common_ptr) cinfo, JPOOL_IMAGE, (JDIMENSION) maplen, (JDIMENSION) 3);
453
    /* and read it from the file */
454
    read_colormap(source, (int) maplen, UCH(targaheader[7]));
455
  } else {
456
    if (cmaptype)		/* but you promised a cmap! */
457
      ERREXIT(cinfo, JERR_TGA_BADPARMS);
458
    source->colormap = NULL;
459
  }
460
461
  cinfo->input_components = components;
462
  cinfo->data_precision = 8;
463
  cinfo->image_width = width;
464
  cinfo->image_height = height;
465
}
466
467
468
/*
469
 * Finish up at the end of the file.
470
 */
471
472
METHODDEF(void)
473
finish_input_tga (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
474
{
475
  /* no work */
476
}
477
478
479
/*
480
 * The module selection routine for Targa format input.
481
 */
482
483
GLOBAL(cjpeg_source_ptr)
484
jinit_read_targa (j_compress_ptr cinfo)
485
{
486
  tga_source_ptr source;
487
488
  /* Create module interface object */
489
  source = (tga_source_ptr)
490
      (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
491
				  SIZEOF(tga_source_struct));
492
  source->cinfo = cinfo;	/* make back link for subroutines */
493
  /* Fill in method ptrs, except get_pixel_rows which start_input sets */
494
  source->pub.start_input = start_input_tga;
495
  source->pub.finish_input = finish_input_tga;
496
497
  return (cjpeg_source_ptr) source;
498
}
499
500
#endif /* TARGA_SUPPORTED */
(-)a/jpeg/simd/Makefile.am (+58 lines)
Line     Link Here 
Line 0    Link Here 
1
noinst_LTLIBRARIES = libsimd.la
2
3
BUILT_SOURCES = jsimdcfg.inc
4
5
EXTRA_DIST = nasm_lt.sh jcclrmmx.asm jcclrss2.asm jdclrmmx.asm jdclrss2.asm \
6
	jdmrgmmx.asm jdmrgss2.asm jcclrss2-64.asm jdclrss2-64.asm \
7
	jdmrgss2-64.asm
8
9
if SIMD_X86_64
10
11
libsimd_la_SOURCES = jsimd_x86_64.c \
12
	jsimd.h jsimdcfg.inc.h \
13
	jsimdext.inc jcolsamp.inc jdct.inc \
14
	jfsseflt-64.asm \
15
	jccolss2-64.asm jdcolss2-64.asm \
16
	jcsamss2-64.asm jdsamss2-64.asm jdmerss2-64.asm \
17
	jcqnts2i-64.asm jfss2fst-64.asm jfss2int-64.asm \
18
	jiss2red-64.asm jiss2int-64.asm jiss2fst-64.asm \
19
	jcqnts2f-64.asm jiss2flt-64.asm
20
21
jccolss2-64.lo: jcclrss2-64.asm
22
jdcolss2-64.lo: jdclrss2-64.asm
23
jdmerss2-64.lo: jdmrgss2-64.asm
24
endif
25
26
if SIMD_I386
27
28
libsimd_la_SOURCES = jsimd_i386.c \
29
	jsimd.h jsimdcfg.inc.h \
30
	jsimdext.inc jcolsamp.inc jdct.inc \
31
	jsimdcpu.asm \
32
	jccolmmx.asm jdcolmmx.asm \
33
	jcsammmx.asm jdsammmx.asm jdmermmx.asm \
34
	jcqntmmx.asm jfmmxfst.asm jfmmxint.asm \
35
	jimmxred.asm jimmxint.asm jimmxfst.asm \
36
	jcqnt3dn.asm jf3dnflt.asm ji3dnflt.asm \
37
	jcqntsse.asm jfsseflt.asm jisseflt.asm \
38
	jccolss2.asm jdcolss2.asm \
39
	jcsamss2.asm jdsamss2.asm jdmerss2.asm \
40
	jcqnts2i.asm jfss2fst.asm jfss2int.asm \
41
	jiss2red.asm jiss2int.asm jiss2fst.asm \
42
	jcqnts2f.asm jiss2flt.asm
43
44
jccolmmx.lo: jcclrmmx.asm
45
jccolss2.lo: jcclrss2.asm
46
jdcolmmx.lo: jdclrmmx.asm
47
jdcolss2.lo: jdclrss2.asm
48
jdmermmx.lo: jdmrgmmx.asm
49
jdmerss2.lo: jdmrgss2.asm
50
endif
51
52
AM_CPPFLAGS = -I$(top_srcdir) 
53
54
.asm.lo:
55
	$(LIBTOOL) --mode=compile --tag NASM $(srcdir)/nasm_lt.sh $(NASM) $(NAFLAGS) -I$(srcdir) $< -o $@
56
57
jsimdcfg.inc: $(srcdir)/jsimdcfg.inc.h ../jpeglib.h ../jconfig.h ../jmorecfg.h
58
	$(CPP) -I$(top_builddir) -I$(top_builddir)/simd $(srcdir)/jsimdcfg.inc.h | $(EGREP) "^[\;%]|^\ %" | sed 's%_cpp_protection_%%' | sed 's@% define@%define@g' > $@
(-)a/jpeg/simd/Makefile.in (+48 lines)
Line     Link Here 
Line 0    Link Here 
1
#
2
# ***** BEGIN LICENSE BLOCK *****
3
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
4
#
5
# The contents of this file are subject to the Mozilla Public License Version
6
# 1.1 (the "License"); you may not use this file except in compliance with
7
# the License. You may obtain a copy of the License at
8
# http://www.mozilla.org/MPL/
9
#
10
# Software distributed under the License is distributed on an "AS IS" basis,
11
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12
# for the specific language governing rights and limitations under the
13
# License.
14
#
15
# The Original Code is mozilla.org code.
16
#
17
# The Initial Developer of the Original Code is
18
# Mozilla Corporation
19
# Portions created by the Initial Developer are Copyright (C) 2010
20
# the Initial Developer. All Rights Reserved.
21
#
22
# Contributor(s):
23
#  Justin Lebar <justin.lebar@gmail.com>
24
#
25
# Alternatively, the contents of this file may be used under the terms of
26
# either the GNU General Public License Version 2 or later (the "GPL"), or
27
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
28
# in which case the provisions of the GPL or the LGPL are applicable instead
29
# of those above. If you wish to allow use of your version of this file only
30
# under the terms of either the GPL or the LGPL, and not to allow others to
31
# use your version of this file under the terms of the MPL, indicate your
32
# decision by deleting the provisions above and replace them with the notice
33
# and other provisions required by the GPL or the LGPL. If you do not delete
34
# the provisions above, a recipient may use your version of this file under
35
# the terms of any one of the MPL, the GPL or the LGPL.
36
#
37
# ***** END LICENSE BLOCK *****
38
39
DEPTH		= ../..
40
topsrcdir	= @top_srcdir@
41
srcdir		= @srcdir@
42
VPATH		= @srcdir@
43
44
include $(DEPTH)/config/autoconf.mk
45
46
# empty makefile so this directory gets created in the objdir.
47
48
include $(topsrcdir)/config/rules.mk
(-)a/jpeg/simd/jcclrmmx.asm (+479 lines)
Line     Link Here 
Line 0    Link Here 
1
;
2
; jcclrmmx.asm - colorspace conversion (MMX)
3
;
4
; Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
5
;
6
; Based on
7
; x86 SIMD extension for IJG JPEG library
8
; Copyright (C) 1999-2006, MIYASAKA Masaru.
9
; For conditions of distribution and use, see copyright notice in jsimdext.inc
10
;
11
; This file should be assembled with NASM (Netwide Assembler),
12
; can *not* be assembled with Microsoft's MASM or any compatible
13
; assembler (including Borland's Turbo Assembler).
14
; NASM is available from http://nasm.sourceforge.net/ or
15
; http://sourceforge.net/project/showfiles.php?group_id=6208
16
;
17
; [TAB8]
18
19
%include "jcolsamp.inc"
20
21
; --------------------------------------------------------------------------
22
	SECTION	SEG_TEXT
23
	BITS	32
24
;
25
; Convert some rows of samples to the output colorspace.
26
;
27
; GLOBAL(void)
28
; jsimd_rgb_ycc_convert_mmx (JDIMENSION img_width,
29
;                           JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
30
;                           JDIMENSION output_row, int num_rows);
31
;
32
33
%define img_width(b)	(b)+8			; JDIMENSION img_width
34
%define input_buf(b)	(b)+12		; JSAMPARRAY input_buf
35
%define output_buf(b)	(b)+16		; JSAMPIMAGE output_buf
36
%define output_row(b)	(b)+20		; JDIMENSION output_row
37
%define num_rows(b)	(b)+24		; int num_rows
38
39
%define original_ebp	ebp+0
40
%define wk(i)		ebp-(WK_NUM-(i))*SIZEOF_MMWORD	; mmword wk[WK_NUM]
41
%define WK_NUM		8
42
%define gotptr		wk(0)-SIZEOF_POINTER	; void * gotptr
43
44
	align	16
45
	global	EXTN(jsimd_rgb_ycc_convert_mmx)
46
47
EXTN(jsimd_rgb_ycc_convert_mmx):
48
	push	ebp
49
	mov	eax,esp				; eax = original ebp
50
	sub	esp, byte 4
51
	and	esp, byte (-SIZEOF_MMWORD)	; align to 64 bits
52
	mov	[esp],eax
53
	mov	ebp,esp				; ebp = aligned ebp
54
	lea	esp, [wk(0)]
55
	pushpic	eax		; make a room for GOT address
56
	push	ebx
57
;	push	ecx		; need not be preserved
58
;	push	edx		; need not be preserved
59
	push	esi
60
	push	edi
61
62
	get_GOT	ebx			; get GOT address
63
	movpic	POINTER [gotptr], ebx	; save GOT address
64
65
	mov	ecx, JDIMENSION [img_width(eax)]	; num_cols
66
	test	ecx,ecx
67
	jz	near .return
68
69
	push	ecx
70
71
	mov	esi, JSAMPIMAGE [output_buf(eax)]
72
	mov	ecx, JDIMENSION [output_row(eax)]
73
	mov	edi, JSAMPARRAY [esi+0*SIZEOF_JSAMPARRAY]
74
	mov	ebx, JSAMPARRAY [esi+1*SIZEOF_JSAMPARRAY]
75
	mov	edx, JSAMPARRAY [esi+2*SIZEOF_JSAMPARRAY]
76
	lea	edi, [edi+ecx*SIZEOF_JSAMPROW]
77
	lea	ebx, [ebx+ecx*SIZEOF_JSAMPROW]
78
	lea	edx, [edx+ecx*SIZEOF_JSAMPROW]
79
80
	pop	ecx
81
82
	mov	esi, JSAMPARRAY [input_buf(eax)]
83
	mov	eax, INT [num_rows(eax)]
84
	test	eax,eax
85
	jle	near .return
86
	alignx	16,7
87
.rowloop:
88
	pushpic	eax
89
	push	edx
90
	push	ebx
91
	push	edi
92
	push	esi
93
	push	ecx			; col
94
95
	mov	esi, JSAMPROW [esi]	; inptr
96
	mov	edi, JSAMPROW [edi]	; outptr0
97
	mov	ebx, JSAMPROW [ebx]	; outptr1
98
	mov	edx, JSAMPROW [edx]	; outptr2
99
	movpic	eax, POINTER [gotptr]	; load GOT address (eax)
100
101
	cmp	ecx, byte SIZEOF_MMWORD
102
	jae	short .columnloop
103
	alignx	16,7
104
105
%if RGB_PIXELSIZE == 3 ; ---------------
106
107
.column_ld1:
108
	push	eax
109
	push	edx
110
	lea	ecx,[ecx+ecx*2]		; imul ecx,RGB_PIXELSIZE
111
	test	cl, SIZEOF_BYTE
112
	jz	short .column_ld2
113
	sub	ecx, byte SIZEOF_BYTE
114
	xor	eax,eax
115
	mov	al, BYTE [esi+ecx]
116
.column_ld2:
117
	test	cl, SIZEOF_WORD
118
	jz	short .column_ld4
119
	sub	ecx, byte SIZEOF_WORD
120
	xor	edx,edx
121
	mov	dx, WORD [esi+ecx]
122
	shl	eax, WORD_BIT
123
	or	eax,edx
124
.column_ld4:
125
	movd	mmA,eax
126
	pop	edx
127
	pop	eax
128
	test	cl, SIZEOF_DWORD
129
	jz	short .column_ld8
130
	sub	ecx, byte SIZEOF_DWORD
131
	movd	mmG, DWORD [esi+ecx]
132
	psllq	mmA, DWORD_BIT
133
	por	mmA,mmG
134
.column_ld8:
135
	test	cl, SIZEOF_MMWORD
136
	jz	short .column_ld16
137
	movq	mmG,mmA
138
	movq	mmA, MMWORD [esi+0*SIZEOF_MMWORD]
139
	mov	ecx, SIZEOF_MMWORD
140
	jmp	short .rgb_ycc_cnv
141
.column_ld16:
142
	test	cl, 2*SIZEOF_MMWORD
143
	mov	ecx, SIZEOF_MMWORD
144
	jz	short .rgb_ycc_cnv
145
	movq	mmF,mmA
146
	movq	mmA, MMWORD [esi+0*SIZEOF_MMWORD]
147
	movq	mmG, MMWORD [esi+1*SIZEOF_MMWORD]
148
	jmp	short .rgb_ycc_cnv
149
	alignx	16,7
150
151
.columnloop:
152
	movq	mmA, MMWORD [esi+0*SIZEOF_MMWORD]
153
	movq	mmG, MMWORD [esi+1*SIZEOF_MMWORD]
154
	movq	mmF, MMWORD [esi+2*SIZEOF_MMWORD]
155
156
.rgb_ycc_cnv:
157
	; mmA=(00 10 20 01 11 21 02 12)
158
	; mmG=(22 03 13 23 04 14 24 05)
159
	; mmF=(15 25 06 16 26 07 17 27)
160
161
	movq      mmD,mmA
162
	psllq     mmA,4*BYTE_BIT	; mmA=(-- -- -- -- 00 10 20 01)
163
	psrlq     mmD,4*BYTE_BIT	; mmD=(11 21 02 12 -- -- -- --)
164
165
	punpckhbw mmA,mmG		; mmA=(00 04 10 14 20 24 01 05)
166
	psllq     mmG,4*BYTE_BIT	; mmG=(-- -- -- -- 22 03 13 23)
167
168
	punpcklbw mmD,mmF		; mmD=(11 15 21 25 02 06 12 16)
169
	punpckhbw mmG,mmF		; mmG=(22 26 03 07 13 17 23 27)
170
171
	movq      mmE,mmA
172
	psllq     mmA,4*BYTE_BIT	; mmA=(-- -- -- -- 00 04 10 14)
173
	psrlq     mmE,4*BYTE_BIT	; mmE=(20 24 01 05 -- -- -- --)
174
175
	punpckhbw mmA,mmD		; mmA=(00 02 04 06 10 12 14 16)
176
	psllq     mmD,4*BYTE_BIT	; mmD=(-- -- -- -- 11 15 21 25)
177
178
	punpcklbw mmE,mmG		; mmE=(20 22 24 26 01 03 05 07)
179
	punpckhbw mmD,mmG		; mmD=(11 13 15 17 21 23 25 27)
180
181
	pxor      mmH,mmH
182
183
	movq      mmC,mmA
184
	punpcklbw mmA,mmH		; mmA=(00 02 04 06)
185
	punpckhbw mmC,mmH		; mmC=(10 12 14 16)
186
187
	movq      mmB,mmE
188
	punpcklbw mmE,mmH		; mmE=(20 22 24 26)
189
	punpckhbw mmB,mmH		; mmB=(01 03 05 07)
190
191
	movq      mmF,mmD
192
	punpcklbw mmD,mmH		; mmD=(11 13 15 17)
193
	punpckhbw mmF,mmH		; mmF=(21 23 25 27)
194
195
%else ; RGB_PIXELSIZE == 4 ; -----------
196
197
.column_ld1:
198
	test	cl, SIZEOF_MMWORD/8
199
	jz	short .column_ld2
200
	sub	ecx, byte SIZEOF_MMWORD/8
201
	movd	mmA, DWORD [esi+ecx*RGB_PIXELSIZE]
202
.column_ld2:
203
	test	cl, SIZEOF_MMWORD/4
204
	jz	short .column_ld4
205
	sub	ecx, byte SIZEOF_MMWORD/4
206
	movq	mmF,mmA
207
	movq	mmA, MMWORD [esi+ecx*RGB_PIXELSIZE]
208
.column_ld4:
209
	test	cl, SIZEOF_MMWORD/2
210
	mov	ecx, SIZEOF_MMWORD
211
	jz	short .rgb_ycc_cnv
212
	movq	mmD,mmA
213
	movq	mmC,mmF
214
	movq	mmA, MMWORD [esi+0*SIZEOF_MMWORD]
215
	movq	mmF, MMWORD [esi+1*SIZEOF_MMWORD]
216
	jmp	short .rgb_ycc_cnv
217
	alignx	16,7
218
219
.columnloop:
220
	movq	mmA, MMWORD [esi+0*SIZEOF_MMWORD]
221
	movq	mmF, MMWORD [esi+1*SIZEOF_MMWORD]
222
	movq	mmD, MMWORD [esi+2*SIZEOF_MMWORD]
223
	movq	mmC, MMWORD [esi+3*SIZEOF_MMWORD]
224
225
.rgb_ycc_cnv:
226
	; mmA=(00 10 20 30 01 11 21 31)
227
	; mmF=(02 12 22 32 03 13 23 33)
228
	; mmD=(04 14 24 34 05 15 25 35)
229
	; mmC=(06 16 26 36 07 17 27 37)
230
231
	movq      mmB,mmA
232
	punpcklbw mmA,mmF		; mmA=(00 02 10 12 20 22 30 32)
233
	punpckhbw mmB,mmF		; mmB=(01 03 11 13 21 23 31 33)
234
235
	movq      mmG,mmD
236
	punpcklbw mmD,mmC		; mmD=(04 06 14 16 24 26 34 36)
237
	punpckhbw mmG,mmC		; mmG=(05 07 15 17 25 27 35 37)
238
239
	movq      mmE,mmA
240
	punpcklwd mmA,mmD		; mmA=(00 02 04 06 10 12 14 16)
241
	punpckhwd mmE,mmD		; mmE=(20 22 24 26 30 32 34 36)
242
243
	movq      mmH,mmB
244
	punpcklwd mmB,mmG		; mmB=(01 03 05 07 11 13 15 17)
245
	punpckhwd mmH,mmG		; mmH=(21 23 25 27 31 33 35 37)
246
247
	pxor      mmF,mmF
248
249
	movq      mmC,mmA
250
	punpcklbw mmA,mmF		; mmA=(00 02 04 06)
251
	punpckhbw mmC,mmF		; mmC=(10 12 14 16)
252
253
	movq      mmD,mmB
254
	punpcklbw mmB,mmF		; mmB=(01 03 05 07)
255
	punpckhbw mmD,mmF		; mmD=(11 13 15 17)
256
257
	movq      mmG,mmE
258
	punpcklbw mmE,mmF		; mmE=(20 22 24 26)
259
	punpckhbw mmG,mmF		; mmG=(30 32 34 36)
260
261
	punpcklbw mmF,mmH
262
	punpckhbw mmH,mmH
263
	psrlw     mmF,BYTE_BIT		; mmF=(21 23 25 27)
264
	psrlw     mmH,BYTE_BIT		; mmH=(31 33 35 37)
265
266
%endif ; RGB_PIXELSIZE ; ---------------
267
268
	; mm0=(R0 R2 R4 R6)=RE, mm2=(G0 G2 G4 G6)=GE, mm4=(B0 B2 B4 B6)=BE
269
	; mm1=(R1 R3 R5 R7)=RO, mm3=(G1 G3 G5 G7)=GO, mm5=(B1 B3 B5 B7)=BO
270
271
	; (Original)
272
	; Y  =  0.29900 * R + 0.58700 * G + 0.11400 * B
273
	; Cb = -0.16874 * R - 0.33126 * G + 0.50000 * B + CENTERJSAMPLE
274
	; Cr =  0.50000 * R - 0.41869 * G - 0.08131 * B + CENTERJSAMPLE
275
	;
276
	; (This implementation)
277
	; Y  =  0.29900 * R + 0.33700 * G + 0.11400 * B + 0.25000 * G
278
	; Cb = -0.16874 * R - 0.33126 * G + 0.50000 * B + CENTERJSAMPLE
279
	; Cr =  0.50000 * R - 0.41869 * G - 0.08131 * B + CENTERJSAMPLE
280
281
	movq      MMWORD [wk(0)], mm0	; wk(0)=RE
282
	movq      MMWORD [wk(1)], mm1	; wk(1)=RO
283
	movq      MMWORD [wk(2)], mm4	; wk(2)=BE
284
	movq      MMWORD [wk(3)], mm5	; wk(3)=BO
285
286
	movq      mm6,mm1
287
	punpcklwd mm1,mm3
288
	punpckhwd mm6,mm3
289
	movq      mm7,mm1
290
	movq      mm4,mm6
291
	pmaddwd   mm1,[GOTOFF(eax,PW_F0299_F0337)] ; mm1=ROL*FIX(0.299)+GOL*FIX(0.337)
292
	pmaddwd   mm6,[GOTOFF(eax,PW_F0299_F0337)] ; mm6=ROH*FIX(0.299)+GOH*FIX(0.337)
293
	pmaddwd   mm7,[GOTOFF(eax,PW_MF016_MF033)] ; mm7=ROL*-FIX(0.168)+GOL*-FIX(0.331)
294
	pmaddwd   mm4,[GOTOFF(eax,PW_MF016_MF033)] ; mm4=ROH*-FIX(0.168)+GOH*-FIX(0.331)
295
296
	movq      MMWORD [wk(4)], mm1	; wk(4)=ROL*FIX(0.299)+GOL*FIX(0.337)
297
	movq      MMWORD [wk(5)], mm6	; wk(5)=ROH*FIX(0.299)+GOH*FIX(0.337)
298
299
	pxor      mm1,mm1
300
	pxor      mm6,mm6
301
	punpcklwd mm1,mm5		; mm1=BOL
302
	punpckhwd mm6,mm5		; mm6=BOH
303
	psrld     mm1,1			; mm1=BOL*FIX(0.500)
304
	psrld     mm6,1			; mm6=BOH*FIX(0.500)
305
306
	movq      mm5,[GOTOFF(eax,PD_ONEHALFM1_CJ)] ; mm5=[PD_ONEHALFM1_CJ]
307
308
	paddd     mm7,mm1
309
	paddd     mm4,mm6
310
	paddd     mm7,mm5
311
	paddd     mm4,mm5
312
	psrld     mm7,SCALEBITS		; mm7=CbOL
313
	psrld     mm4,SCALEBITS		; mm4=CbOH
314
	packssdw  mm7,mm4		; mm7=CbO
315
316
	movq      mm1, MMWORD [wk(2)]	; mm1=BE
317
318
	movq      mm6,mm0
319
	punpcklwd mm0,mm2
320
	punpckhwd mm6,mm2
321
	movq      mm5,mm0
322
	movq      mm4,mm6
323
	pmaddwd   mm0,[GOTOFF(eax,PW_F0299_F0337)] ; mm0=REL*FIX(0.299)+GEL*FIX(0.337)
324
	pmaddwd   mm6,[GOTOFF(eax,PW_F0299_F0337)] ; mm6=REH*FIX(0.299)+GEH*FIX(0.337)
325
	pmaddwd   mm5,[GOTOFF(eax,PW_MF016_MF033)] ; mm5=REL*-FIX(0.168)+GEL*-FIX(0.331)
326
	pmaddwd   mm4,[GOTOFF(eax,PW_MF016_MF033)] ; mm4=REH*-FIX(0.168)+GEH*-FIX(0.331)
327
328
	movq      MMWORD [wk(6)], mm0	; wk(6)=REL*FIX(0.299)+GEL*FIX(0.337)
329
	movq      MMWORD [wk(7)], mm6	; wk(7)=REH*FIX(0.299)+GEH*FIX(0.337)
330
331
	pxor      mm0,mm0
332
	pxor      mm6,mm6
333
	punpcklwd mm0,mm1		; mm0=BEL
334
	punpckhwd mm6,mm1		; mm6=BEH
335
	psrld     mm0,1			; mm0=BEL*FIX(0.500)
336
	psrld     mm6,1			; mm6=BEH*FIX(0.500)
337
338
	movq      mm1,[GOTOFF(eax,PD_ONEHALFM1_CJ)] ; mm1=[PD_ONEHALFM1_CJ]
339
340
	paddd     mm5,mm0
341
	paddd     mm4,mm6
342
	paddd     mm5,mm1
343
	paddd     mm4,mm1
344
	psrld     mm5,SCALEBITS		; mm5=CbEL
345
	psrld     mm4,SCALEBITS		; mm4=CbEH
346
	packssdw  mm5,mm4		; mm5=CbE
347
348
	psllw     mm7,BYTE_BIT
349
	por       mm5,mm7		; mm5=Cb
350
	movq      MMWORD [ebx], mm5	; Save Cb
351
352
	movq      mm0, MMWORD [wk(3)]	; mm0=BO
353
	movq      mm6, MMWORD [wk(2)]	; mm6=BE
354
	movq      mm1, MMWORD [wk(1)]	; mm1=RO
355
356
	movq      mm4,mm0
357
	punpcklwd mm0,mm3
358
	punpckhwd mm4,mm3
359
	movq      mm7,mm0
360
	movq      mm5,mm4
361
	pmaddwd   mm0,[GOTOFF(eax,PW_F0114_F0250)] ; mm0=BOL*FIX(0.114)+GOL*FIX(0.250)
362
	pmaddwd   mm4,[GOTOFF(eax,PW_F0114_F0250)] ; mm4=BOH*FIX(0.114)+GOH*FIX(0.250)
363
	pmaddwd   mm7,[GOTOFF(eax,PW_MF008_MF041)] ; mm7=BOL*-FIX(0.081)+GOL*-FIX(0.418)
364
	pmaddwd   mm5,[GOTOFF(eax,PW_MF008_MF041)] ; mm5=BOH*-FIX(0.081)+GOH*-FIX(0.418)
365
366
	movq      mm3,[GOTOFF(eax,PD_ONEHALF)]	; mm3=[PD_ONEHALF]
367
368
	paddd     mm0, MMWORD [wk(4)]
369
	paddd     mm4, MMWORD [wk(5)]
370
	paddd     mm0,mm3
371
	paddd     mm4,mm3
372
	psrld     mm0,SCALEBITS		; mm0=YOL
373
	psrld     mm4,SCALEBITS		; mm4=YOH
374
	packssdw  mm0,mm4		; mm0=YO
375
376
	pxor      mm3,mm3
377
	pxor      mm4,mm4
378
	punpcklwd mm3,mm1		; mm3=ROL
379
	punpckhwd mm4,mm1		; mm4=ROH
380
	psrld     mm3,1			; mm3=ROL*FIX(0.500)
381
	psrld     mm4,1			; mm4=ROH*FIX(0.500)
382
383
	movq      mm1,[GOTOFF(eax,PD_ONEHALFM1_CJ)] ; mm1=[PD_ONEHALFM1_CJ]
384
385
	paddd     mm7,mm3
386
	paddd     mm5,mm4
387
	paddd     mm7,mm1
388
	paddd     mm5,mm1
389
	psrld     mm7,SCALEBITS		; mm7=CrOL
390
	psrld     mm5,SCALEBITS		; mm5=CrOH
391
	packssdw  mm7,mm5		; mm7=CrO
392
393
	movq      mm3, MMWORD [wk(0)]	; mm3=RE
394
395
	movq      mm4,mm6
396
	punpcklwd mm6,mm2
397
	punpckhwd mm4,mm2
398
	movq      mm1,mm6
399
	movq      mm5,mm4
400
	pmaddwd   mm6,[GOTOFF(eax,PW_F0114_F0250)] ; mm6=BEL*FIX(0.114)+GEL*FIX(0.250)
401
	pmaddwd   mm4,[GOTOFF(eax,PW_F0114_F0250)] ; mm4=BEH*FIX(0.114)+GEH*FIX(0.250)
402
	pmaddwd   mm1,[GOTOFF(eax,PW_MF008_MF041)] ; mm1=BEL*-FIX(0.081)+GEL*-FIX(0.418)
403
	pmaddwd   mm5,[GOTOFF(eax,PW_MF008_MF041)] ; mm5=BEH*-FIX(0.081)+GEH*-FIX(0.418)
404
405
	movq      mm2,[GOTOFF(eax,PD_ONEHALF)]	; mm2=[PD_ONEHALF]
406
407
	paddd     mm6, MMWORD [wk(6)]
408
	paddd     mm4, MMWORD [wk(7)]
409
	paddd     mm6,mm2
410
	paddd     mm4,mm2
411
	psrld     mm6,SCALEBITS		; mm6=YEL
412
	psrld     mm4,SCALEBITS		; mm4=YEH
413
	packssdw  mm6,mm4		; mm6=YE
414
415
	psllw     mm0,BYTE_BIT
416
	por       mm6,mm0		; mm6=Y
417
	movq      MMWORD [edi], mm6	; Save Y
418
419
	pxor      mm2,mm2
420
	pxor      mm4,mm4
421
	punpcklwd mm2,mm3		; mm2=REL
422
	punpckhwd mm4,mm3		; mm4=REH
423
	psrld     mm2,1			; mm2=REL*FIX(0.500)
424
	psrld     mm4,1			; mm4=REH*FIX(0.500)
425
426
	movq      mm0,[GOTOFF(eax,PD_ONEHALFM1_CJ)] ; mm0=[PD_ONEHALFM1_CJ]
427
428
	paddd     mm1,mm2
429
	paddd     mm5,mm4
430
	paddd     mm1,mm0
431
	paddd     mm5,mm0
432
	psrld     mm1,SCALEBITS		; mm1=CrEL
433
	psrld     mm5,SCALEBITS		; mm5=CrEH
434
	packssdw  mm1,mm5		; mm1=CrE
435
436
	psllw     mm7,BYTE_BIT
437
	por       mm1,mm7		; mm1=Cr
438
	movq      MMWORD [edx], mm1	; Save Cr
439
440
	sub	ecx, byte SIZEOF_MMWORD
441
	add	esi, byte RGB_PIXELSIZE*SIZEOF_MMWORD	; inptr
442
	add	edi, byte SIZEOF_MMWORD			; outptr0
443
	add	ebx, byte SIZEOF_MMWORD			; outptr1
444
	add	edx, byte SIZEOF_MMWORD			; outptr2
445
	cmp	ecx, byte SIZEOF_MMWORD
446
	jae	near .columnloop
447
	test	ecx,ecx
448
	jnz	near .column_ld1
449
450
	pop	ecx			; col
451
	pop	esi
452
	pop	edi
453
	pop	ebx
454
	pop	edx
455
	poppic	eax
456
457
	add	esi, byte SIZEOF_JSAMPROW	; input_buf
458
	add	edi, byte SIZEOF_JSAMPROW
459
	add	ebx, byte SIZEOF_JSAMPROW
460
	add	edx, byte SIZEOF_JSAMPROW
461
	dec	eax				; num_rows
462
	jg	near .rowloop
463
464
	emms		; empty MMX state
465
466
.return:
467
	pop	edi
468
	pop	esi
469
;	pop	edx		; need not be preserved
470
;	pop	ecx		; need not be preserved
471
	pop	ebx
472
	mov	esp,ebp		; esp <- aligned ebp
473
	pop	esp		; esp <- original ebp
474
	pop	ebp
475
	ret
476
477
; For some reason, the OS X linker does not honor the request to align the
478
; segment unless we do this.
479
	align	16
(-)a/jpeg/simd/jcclrss2-64.asm (+487 lines)
Line     Link Here 
Line 0    Link Here 
1
;
2
; jcclrss2-64.asm - colorspace conversion (64-bit SSE2)
3
;
4
; x86 SIMD extension for IJG JPEG library
5
; Copyright (C) 1999-2006, MIYASAKA Masaru.
6
; Copyright (C) 2009, D. R. Commander.
7
; For conditions of distribution and use, see copyright notice in jsimdext.inc
8
;
9
; This file should be assembled with NASM (Netwide Assembler),
10
; can *not* be assembled with Microsoft's MASM or any compatible
11
; assembler (including Borland's Turbo Assembler).
12
; NASM is available from http://nasm.sourceforge.net/ or
13
; http://sourceforge.net/project/showfiles.php?group_id=6208
14
;
15
; [TAB8]
16
17
%include "jcolsamp.inc"
18
19
; --------------------------------------------------------------------------
20
	SECTION	SEG_TEXT
21
	BITS	64
22
;
23
; Convert some rows of samples to the output colorspace.
24
;
25
; GLOBAL(void)
26
; jsimd_rgb_ycc_convert_sse2 (JDIMENSION img_width,
27
;                             JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
28
;                             JDIMENSION output_row, int num_rows);
29
;
30
31
; r10 = JDIMENSION img_width
32
; r11 = JSAMPARRAY input_buf
33
; r12 = JSAMPIMAGE output_buf
34
; r13 = JDIMENSION output_row
35
; r14 = int num_rows
36
37
%define wk(i)		rbp-(WK_NUM-(i))*SIZEOF_XMMWORD	; xmmword wk[WK_NUM]
38
%define WK_NUM		8
39
40
	align	16
41
42
	global	EXTN(jsimd_rgb_ycc_convert_sse2)
43
44
EXTN(jsimd_rgb_ycc_convert_sse2):
45
	push	rbp
46
	mov	rax,rsp				; rax = original rbp
47
	sub	rsp, byte 4
48
	and	rsp, byte (-SIZEOF_XMMWORD)	; align to 128 bits
49
	mov	[rsp],rax
50
	mov	rbp,rsp				; rbp = aligned rbp
51
	lea	rsp, [wk(0)]
52
	collect_args
53
	push	rbx
54
55
	mov	rcx, r10
56
	test	rcx,rcx
57
	jz	near .return
58
59
	push	rcx
60
61
	mov rsi, r12
62
	mov rcx, r13
63
	mov	rdi, JSAMPARRAY [rsi+0*SIZEOF_JSAMPARRAY]
64
	mov	rbx, JSAMPARRAY [rsi+1*SIZEOF_JSAMPARRAY]
65
	mov	rdx, JSAMPARRAY [rsi+2*SIZEOF_JSAMPARRAY]
66
	lea	rdi, [rdi+rcx*SIZEOF_JSAMPROW]
67
	lea	rbx, [rbx+rcx*SIZEOF_JSAMPROW]
68
	lea	rdx, [rdx+rcx*SIZEOF_JSAMPROW]
69
70
	pop	rcx
71
72
	mov rsi, r11
73
	mov	eax, r14d
74
	test	rax,rax
75
	jle	near .return
76
.rowloop:
77
	push	rdx
78
	push	rbx
79
	push	rdi
80
	push	rsi
81
	push	rcx			; col
82
83
	mov	rsi, JSAMPROW [rsi]	; inptr
84
	mov	rdi, JSAMPROW [rdi]	; outptr0
85
	mov	rbx, JSAMPROW [rbx]	; outptr1
86
	mov	rdx, JSAMPROW [rdx]	; outptr2
87
88
	cmp	rcx, byte SIZEOF_XMMWORD
89
	jae	near .columnloop
90
91
%if RGB_PIXELSIZE == 3 ; ---------------
92
93
.column_ld1:
94
	push	rax
95
	push	rdx
96
	lea	rcx,[rcx+rcx*2]		; imul ecx,RGB_PIXELSIZE
97
	test	cl, SIZEOF_BYTE
98
	jz	short .column_ld2
99
	sub	rcx, byte SIZEOF_BYTE
100
	movzx	rax, BYTE [rsi+rcx]
101
.column_ld2:
102
	test	cl, SIZEOF_WORD
103
	jz	short .column_ld4
104
	sub	rcx, byte SIZEOF_WORD
105
	movzx	rdx, WORD [rsi+rcx]
106
	shl	rax, WORD_BIT
107
	or	rax,rdx
108
.column_ld4:
109
	movd	xmmA,eax
110
	pop	rdx
111
	pop	rax
112
	test	cl, SIZEOF_DWORD
113
	jz	short .column_ld8
114
	sub	rcx, byte SIZEOF_DWORD
115
	movd	xmmF, XMM_DWORD [rsi+rcx]
116
	pslldq	xmmA, SIZEOF_DWORD
117
	por	xmmA,xmmF
118
.column_ld8:
119
	test	cl, SIZEOF_MMWORD
120
	jz	short .column_ld16
121
	sub	rcx, byte SIZEOF_MMWORD
122
	movq	xmmB, XMM_MMWORD [rsi+rcx]
123
	pslldq	xmmA, SIZEOF_MMWORD
124
	por	xmmA,xmmB
125
.column_ld16:
126
	test	cl, SIZEOF_XMMWORD
127
	jz	short .column_ld32
128
	movdqa	xmmF,xmmA
129
	movdqu	xmmA, XMMWORD [rsi+0*SIZEOF_XMMWORD]
130
	mov	rcx, SIZEOF_XMMWORD
131
	jmp	short .rgb_ycc_cnv
132
.column_ld32:
133
	test	cl, 2*SIZEOF_XMMWORD
134
	mov	rcx, SIZEOF_XMMWORD
135
	jz	short .rgb_ycc_cnv
136
	movdqa	xmmB,xmmA
137
	movdqu	xmmA, XMMWORD [rsi+0*SIZEOF_XMMWORD]
138
	movdqu	xmmF, XMMWORD [rsi+1*SIZEOF_XMMWORD]
139
	jmp	short .rgb_ycc_cnv
140
141
.columnloop:
142
	movdqu	xmmA, XMMWORD [rsi+0*SIZEOF_XMMWORD]
143
	movdqu	xmmF, XMMWORD [rsi+1*SIZEOF_XMMWORD]
144
	movdqu	xmmB, XMMWORD [rsi+2*SIZEOF_XMMWORD]
145
146
.rgb_ycc_cnv:
147
	; xmmA=(00 10 20 01 11 21 02 12 22 03 13 23 04 14 24 05)
148
	; xmmF=(15 25 06 16 26 07 17 27 08 18 28 09 19 29 0A 1A)
149
	; xmmB=(2A 0B 1B 2B 0C 1C 2C 0D 1D 2D 0E 1E 2E 0F 1F 2F)
150
151
	movdqa    xmmG,xmmA
152
	pslldq    xmmA,8	; xmmA=(-- -- -- -- -- -- -- -- 00 10 20 01 11 21 02 12)
153
	psrldq    xmmG,8	; xmmG=(22 03 13 23 04 14 24 05 -- -- -- -- -- -- -- --)
154
155
	punpckhbw xmmA,xmmF	; xmmA=(00 08 10 18 20 28 01 09 11 19 21 29 02 0A 12 1A)
156
	pslldq    xmmF,8	; xmmF=(-- -- -- -- -- -- -- -- 15 25 06 16 26 07 17 27)
157
158
	punpcklbw xmmG,xmmB	; xmmG=(22 2A 03 0B 13 1B 23 2B 04 0C 14 1C 24 2C 05 0D)
159
	punpckhbw xmmF,xmmB	; xmmF=(15 1D 25 2D 06 0E 16 1E 26 2E 07 0F 17 1F 27 2F)
160
161
	movdqa    xmmD,xmmA
162
	pslldq    xmmA,8	; xmmA=(-- -- -- -- -- -- -- -- 00 08 10 18 20 28 01 09)
163
	psrldq    xmmD,8	; xmmD=(11 19 21 29 02 0A 12 1A -- -- -- -- -- -- -- --)
164
165
	punpckhbw xmmA,xmmG	; xmmA=(00 04 08 0C 10 14 18 1C 20 24 28 2C 01 05 09 0D)
166
	pslldq    xmmG,8	; xmmG=(-- -- -- -- -- -- -- -- 22 2A 03 0B 13 1B 23 2B)
167
168
	punpcklbw xmmD,xmmF	; xmmD=(11 15 19 1D 21 25 29 2D 02 06 0A 0E 12 16 1A 1E)
169
	punpckhbw xmmG,xmmF	; xmmG=(22 26 2A 2E 03 07 0B 0F 13 17 1B 1F 23 27 2B 2F)
170
171
	movdqa    xmmE,xmmA
172
	pslldq    xmmA,8	; xmmA=(-- -- -- -- -- -- -- -- 00 04 08 0C 10 14 18 1C)
173
	psrldq    xmmE,8	; xmmE=(20 24 28 2C 01 05 09 0D -- -- -- -- -- -- -- --)
174
175
	punpckhbw xmmA,xmmD	; xmmA=(00 02 04 06 08 0A 0C 0E 10 12 14 16 18 1A 1C 1E)
176
	pslldq    xmmD,8	; xmmD=(-- -- -- -- -- -- -- -- 11 15 19 1D 21 25 29 2D)
177
178
	punpcklbw xmmE,xmmG	; xmmE=(20 22 24 26 28 2A 2C 2E 01 03 05 07 09 0B 0D 0F)
179
	punpckhbw xmmD,xmmG	; xmmD=(11 13 15 17 19 1B 1D 1F 21 23 25 27 29 2B 2D 2F)
180
181
	pxor      xmmH,xmmH
182
183
	movdqa    xmmC,xmmA
184
	punpcklbw xmmA,xmmH	; xmmA=(00 02 04 06 08 0A 0C 0E)
185
	punpckhbw xmmC,xmmH	; xmmC=(10 12 14 16 18 1A 1C 1E)
186
187
	movdqa    xmmB,xmmE
188
	punpcklbw xmmE,xmmH	; xmmE=(20 22 24 26 28 2A 2C 2E)
189
	punpckhbw xmmB,xmmH	; xmmB=(01 03 05 07 09 0B 0D 0F)
190
191
	movdqa    xmmF,xmmD
192
	punpcklbw xmmD,xmmH	; xmmD=(11 13 15 17 19 1B 1D 1F)
193
	punpckhbw xmmF,xmmH	; xmmF=(21 23 25 27 29 2B 2D 2F)
194
195
%else ; RGB_PIXELSIZE == 4 ; -----------
196
197
.column_ld1:
198
	test	cl, SIZEOF_XMMWORD/16
199
	jz	short .column_ld2
200
	sub	rcx, byte SIZEOF_XMMWORD/16
201
	movd	xmmA, XMM_DWORD [rsi+rcx*RGB_PIXELSIZE]
202
.column_ld2:
203
	test	cl, SIZEOF_XMMWORD/8
204
	jz	short .column_ld4
205
	sub	rcx, byte SIZEOF_XMMWORD/8
206
	movq	xmmE, XMM_MMWORD [rsi+rcx*RGB_PIXELSIZE]
207
	pslldq	xmmA, SIZEOF_MMWORD
208
	por	xmmA,xmmE
209
.column_ld4:
210
	test	cl, SIZEOF_XMMWORD/4
211
	jz	short .column_ld8
212
	sub	rcx, byte SIZEOF_XMMWORD/4
213
	movdqa	xmmE,xmmA
214
	movdqu	xmmA, XMMWORD [rsi+rcx*RGB_PIXELSIZE]
215
.column_ld8:
216
	test	cl, SIZEOF_XMMWORD/2
217
	mov	rcx, SIZEOF_XMMWORD
218
	jz	short .rgb_ycc_cnv
219
	movdqa	xmmF,xmmA
220
	movdqa	xmmH,xmmE
221
	movdqu	xmmA, XMMWORD [rsi+0*SIZEOF_XMMWORD]
222
	movdqu	xmmE, XMMWORD [rsi+1*SIZEOF_XMMWORD]
223
	jmp	short .rgb_ycc_cnv
224
225
.columnloop:
226
	movdqu	xmmA, XMMWORD [rsi+0*SIZEOF_XMMWORD]
227
	movdqu	xmmE, XMMWORD [rsi+1*SIZEOF_XMMWORD]
228
	movdqu	xmmF, XMMWORD [rsi+2*SIZEOF_XMMWORD]
229
	movdqu	xmmH, XMMWORD [rsi+3*SIZEOF_XMMWORD]
230
231
.rgb_ycc_cnv:
232
	; xmmA=(00 10 20 30 01 11 21 31 02 12 22 32 03 13 23 33)
233
	; xmmE=(04 14 24 34 05 15 25 35 06 16 26 36 07 17 27 37)
234
	; xmmF=(08 18 28 38 09 19 29 39 0A 1A 2A 3A 0B 1B 2B 3B)
235
	; xmmH=(0C 1C 2C 3C 0D 1D 2D 3D 0E 1E 2E 3E 0F 1F 2F 3F)
236
237
	movdqa    xmmD,xmmA
238
	punpcklbw xmmA,xmmE	; xmmA=(00 04 10 14 20 24 30 34 01 05 11 15 21 25 31 35)
239
	punpckhbw xmmD,xmmE	; xmmD=(02 06 12 16 22 26 32 36 03 07 13 17 23 27 33 37)
240
241
	movdqa    xmmC,xmmF
242
	punpcklbw xmmF,xmmH	; xmmF=(08 0C 18 1C 28 2C 38 3C 09 0D 19 1D 29 2D 39 3D)
243
	punpckhbw xmmC,xmmH	; xmmC=(0A 0E 1A 1E 2A 2E 3A 3E 0B 0F 1B 1F 2B 2F 3B 3F)
244
245
	movdqa    xmmB,xmmA
246
	punpcklwd xmmA,xmmF	; xmmA=(00 04 08 0C 10 14 18 1C 20 24 28 2C 30 34 38 3C)
247
	punpckhwd xmmB,xmmF	; xmmB=(01 05 09 0D 11 15 19 1D 21 25 29 2D 31 35 39 3D)
248
249
	movdqa    xmmG,xmmD
250
	punpcklwd xmmD,xmmC	; xmmD=(02 06 0A 0E 12 16 1A 1E 22 26 2A 2E 32 36 3A 3E)
251
	punpckhwd xmmG,xmmC	; xmmG=(03 07 0B 0F 13 17 1B 1F 23 27 2B 2F 33 37 3B 3F)
252
253
	movdqa    xmmE,xmmA
254
	punpcklbw xmmA,xmmD	; xmmA=(00 02 04 06 08 0A 0C 0E 10 12 14 16 18 1A 1C 1E)
255
	punpckhbw xmmE,xmmD	; xmmE=(20 22 24 26 28 2A 2C 2E 30 32 34 36 38 3A 3C 3E)
256
257
	movdqa    xmmH,xmmB
258
	punpcklbw xmmB,xmmG	; xmmB=(01 03 05 07 09 0B 0D 0F 11 13 15 17 19 1B 1D 1F)
259
	punpckhbw xmmH,xmmG	; xmmH=(21 23 25 27 29 2B 2D 2F 31 33 35 37 39 3B 3D 3F)
260
261
	pxor      xmmF,xmmF
262
263
	movdqa    xmmC,xmmA
264
	punpcklbw xmmA,xmmF	; xmmA=(00 02 04 06 08 0A 0C 0E)
265
	punpckhbw xmmC,xmmF	; xmmC=(10 12 14 16 18 1A 1C 1E)
266
267
	movdqa    xmmD,xmmB
268
	punpcklbw xmmB,xmmF	; xmmB=(01 03 05 07 09 0B 0D 0F)
269
	punpckhbw xmmD,xmmF	; xmmD=(11 13 15 17 19 1B 1D 1F)
270
271
	movdqa    xmmG,xmmE
272
	punpcklbw xmmE,xmmF	; xmmE=(20 22 24 26 28 2A 2C 2E)
273
	punpckhbw xmmG,xmmF	; xmmG=(30 32 34 36 38 3A 3C 3E)
274
275
	punpcklbw xmmF,xmmH
276
	punpckhbw xmmH,xmmH
277
	psrlw     xmmF,BYTE_BIT	; xmmF=(21 23 25 27 29 2B 2D 2F)
278
	psrlw     xmmH,BYTE_BIT	; xmmH=(31 33 35 37 39 3B 3D 3F)
279
280
%endif ; RGB_PIXELSIZE ; ---------------
281
282
	; xmm0=R(02468ACE)=RE, xmm2=G(02468ACE)=GE, xmm4=B(02468ACE)=BE
283
	; xmm1=R(13579BDF)=RO, xmm3=G(13579BDF)=GO, xmm5=B(13579BDF)=BO
284
285
	; (Original)
286
	; Y  =  0.29900 * R + 0.58700 * G + 0.11400 * B
287
	; Cb = -0.16874 * R - 0.33126 * G + 0.50000 * B + CENTERJSAMPLE
288
	; Cr =  0.50000 * R - 0.41869 * G - 0.08131 * B + CENTERJSAMPLE
289
	;
290
	; (This implementation)
291
	; Y  =  0.29900 * R + 0.33700 * G + 0.11400 * B + 0.25000 * G
292
	; Cb = -0.16874 * R - 0.33126 * G + 0.50000 * B + CENTERJSAMPLE
293
	; Cr =  0.50000 * R - 0.41869 * G - 0.08131 * B + CENTERJSAMPLE
294
295
	movdqa    XMMWORD [wk(0)], xmm0	; wk(0)=RE
296
	movdqa    XMMWORD [wk(1)], xmm1	; wk(1)=RO
297
	movdqa    XMMWORD [wk(2)], xmm4	; wk(2)=BE
298
	movdqa    XMMWORD [wk(3)], xmm5	; wk(3)=BO
299
300
	movdqa    xmm6,xmm1
301
	punpcklwd xmm1,xmm3
302
	punpckhwd xmm6,xmm3
303
	movdqa    xmm7,xmm1
304
	movdqa    xmm4,xmm6
305
	pmaddwd   xmm1,[rel PW_F0299_F0337] ; xmm1=ROL*FIX(0.299)+GOL*FIX(0.337)
306
	pmaddwd   xmm6,[rel PW_F0299_F0337] ; xmm6=ROH*FIX(0.299)+GOH*FIX(0.337)
307
	pmaddwd   xmm7,[rel PW_MF016_MF033] ; xmm7=ROL*-FIX(0.168)+GOL*-FIX(0.331)
308
	pmaddwd   xmm4,[rel PW_MF016_MF033] ; xmm4=ROH*-FIX(0.168)+GOH*-FIX(0.331)
309
310
	movdqa    XMMWORD [wk(4)], xmm1	; wk(4)=ROL*FIX(0.299)+GOL*FIX(0.337)
311
	movdqa    XMMWORD [wk(5)], xmm6	; wk(5)=ROH*FIX(0.299)+GOH*FIX(0.337)
312
313
	pxor      xmm1,xmm1
314
	pxor      xmm6,xmm6
315
	punpcklwd xmm1,xmm5		; xmm1=BOL
316
	punpckhwd xmm6,xmm5		; xmm6=BOH
317
	psrld     xmm1,1		; xmm1=BOL*FIX(0.500)
318
	psrld     xmm6,1		; xmm6=BOH*FIX(0.500)
319
320
	movdqa    xmm5,[rel PD_ONEHALFM1_CJ] ; xmm5=[PD_ONEHALFM1_CJ]
321
322
	paddd     xmm7,xmm1
323
	paddd     xmm4,xmm6
324
	paddd     xmm7,xmm5
325
	paddd     xmm4,xmm5
326
	psrld     xmm7,SCALEBITS	; xmm7=CbOL
327
	psrld     xmm4,SCALEBITS	; xmm4=CbOH
328
	packssdw  xmm7,xmm4		; xmm7=CbO
329
330
	movdqa    xmm1, XMMWORD [wk(2)]	; xmm1=BE
331
332
	movdqa    xmm6,xmm0
333
	punpcklwd xmm0,xmm2
334
	punpckhwd xmm6,xmm2
335
	movdqa    xmm5,xmm0
336
	movdqa    xmm4,xmm6
337
	pmaddwd   xmm0,[rel PW_F0299_F0337] ; xmm0=REL*FIX(0.299)+GEL*FIX(0.337)
338
	pmaddwd   xmm6,[rel PW_F0299_F0337] ; xmm6=REH*FIX(0.299)+GEH*FIX(0.337)
339
	pmaddwd   xmm5,[rel PW_MF016_MF033] ; xmm5=REL*-FIX(0.168)+GEL*-FIX(0.331)
340
	pmaddwd   xmm4,[rel PW_MF016_MF033] ; xmm4=REH*-FIX(0.168)+GEH*-FIX(0.331)
341
342
	movdqa    XMMWORD [wk(6)], xmm0	; wk(6)=REL*FIX(0.299)+GEL*FIX(0.337)
343
	movdqa    XMMWORD [wk(7)], xmm6	; wk(7)=REH*FIX(0.299)+GEH*FIX(0.337)
344
345
	pxor      xmm0,xmm0
346
	pxor      xmm6,xmm6
347
	punpcklwd xmm0,xmm1		; xmm0=BEL
348
	punpckhwd xmm6,xmm1		; xmm6=BEH
349
	psrld     xmm0,1		; xmm0=BEL*FIX(0.500)
350
	psrld     xmm6,1		; xmm6=BEH*FIX(0.500)
351
352
	movdqa    xmm1,[rel PD_ONEHALFM1_CJ] ; xmm1=[PD_ONEHALFM1_CJ]
353
354
	paddd     xmm5,xmm0
355
	paddd     xmm4,xmm6
356
	paddd     xmm5,xmm1
357
	paddd     xmm4,xmm1
358
	psrld     xmm5,SCALEBITS	; xmm5=CbEL
359
	psrld     xmm4,SCALEBITS	; xmm4=CbEH
360
	packssdw  xmm5,xmm4		; xmm5=CbE
361
362
	psllw     xmm7,BYTE_BIT
363
	por       xmm5,xmm7		; xmm5=Cb
364
	movdqa    XMMWORD [rbx], xmm5	; Save Cb
365
366
	movdqa    xmm0, XMMWORD [wk(3)]	; xmm0=BO
367
	movdqa    xmm6, XMMWORD [wk(2)]	; xmm6=BE
368
	movdqa    xmm1, XMMWORD [wk(1)]	; xmm1=RO
369
370
	movdqa    xmm4,xmm0
371
	punpcklwd xmm0,xmm3
372
	punpckhwd xmm4,xmm3
373
	movdqa    xmm7,xmm0
374
	movdqa    xmm5,xmm4
375
	pmaddwd   xmm0,[rel PW_F0114_F0250] ; xmm0=BOL*FIX(0.114)+GOL*FIX(0.250)
376
	pmaddwd   xmm4,[rel PW_F0114_F0250] ; xmm4=BOH*FIX(0.114)+GOH*FIX(0.250)
377
	pmaddwd   xmm7,[rel PW_MF008_MF041] ; xmm7=BOL*-FIX(0.081)+GOL*-FIX(0.418)
378
	pmaddwd   xmm5,[rel PW_MF008_MF041] ; xmm5=BOH*-FIX(0.081)+GOH*-FIX(0.418)
379
380
	movdqa    xmm3,[rel PD_ONEHALF]	; xmm3=[PD_ONEHALF]
381
382
	paddd     xmm0, XMMWORD [wk(4)]
383
	paddd     xmm4, XMMWORD [wk(5)]
384
	paddd     xmm0,xmm3
385
	paddd     xmm4,xmm3
386
	psrld     xmm0,SCALEBITS	; xmm0=YOL
387
	psrld     xmm4,SCALEBITS	; xmm4=YOH
388
	packssdw  xmm0,xmm4		; xmm0=YO
389
390
	pxor      xmm3,xmm3
391
	pxor      xmm4,xmm4
392
	punpcklwd xmm3,xmm1		; xmm3=ROL
393
	punpckhwd xmm4,xmm1		; xmm4=ROH
394
	psrld     xmm3,1		; xmm3=ROL*FIX(0.500)
395
	psrld     xmm4,1		; xmm4=ROH*FIX(0.500)
396
397
	movdqa    xmm1,[rel PD_ONEHALFM1_CJ] ; xmm1=[PD_ONEHALFM1_CJ]
398
399
	paddd     xmm7,xmm3
400
	paddd     xmm5,xmm4
401
	paddd     xmm7,xmm1
402
	paddd     xmm5,xmm1
403
	psrld     xmm7,SCALEBITS	; xmm7=CrOL
404
	psrld     xmm5,SCALEBITS	; xmm5=CrOH
405
	packssdw  xmm7,xmm5		; xmm7=CrO
406
407
	movdqa    xmm3, XMMWORD [wk(0)]	; xmm3=RE
408
409
	movdqa    xmm4,xmm6
410
	punpcklwd xmm6,xmm2
411
	punpckhwd xmm4,xmm2
412
	movdqa    xmm1,xmm6
413
	movdqa    xmm5,xmm4
414
	pmaddwd   xmm6,[rel PW_F0114_F0250] ; xmm6=BEL*FIX(0.114)+GEL*FIX(0.250)
415
	pmaddwd   xmm4,[rel PW_F0114_F0250] ; xmm4=BEH*FIX(0.114)+GEH*FIX(0.250)
416
	pmaddwd   xmm1,[rel PW_MF008_MF041] ; xmm1=BEL*-FIX(0.081)+GEL*-FIX(0.418)
417
	pmaddwd   xmm5,[rel PW_MF008_MF041] ; xmm5=BEH*-FIX(0.081)+GEH*-FIX(0.418)
418
419
	movdqa    xmm2,[rel PD_ONEHALF]	; xmm2=[PD_ONEHALF]
420
421
	paddd     xmm6, XMMWORD [wk(6)]
422
	paddd     xmm4, XMMWORD [wk(7)]
423
	paddd     xmm6,xmm2
424
	paddd     xmm4,xmm2
425
	psrld     xmm6,SCALEBITS	; xmm6=YEL
426
	psrld     xmm4,SCALEBITS	; xmm4=YEH
427
	packssdw  xmm6,xmm4		; xmm6=YE
428
429
	psllw     xmm0,BYTE_BIT
430
	por       xmm6,xmm0		; xmm6=Y
431
	movdqa    XMMWORD [rdi], xmm6	; Save Y
432
433
	pxor      xmm2,xmm2
434
	pxor      xmm4,xmm4
435
	punpcklwd xmm2,xmm3		; xmm2=REL
436
	punpckhwd xmm4,xmm3		; xmm4=REH
437
	psrld     xmm2,1		; xmm2=REL*FIX(0.500)
438
	psrld     xmm4,1		; xmm4=REH*FIX(0.500)
439
440
	movdqa    xmm0,[rel PD_ONEHALFM1_CJ] ; xmm0=[PD_ONEHALFM1_CJ]
441
442
	paddd     xmm1,xmm2
443
	paddd     xmm5,xmm4
444
	paddd     xmm1,xmm0
445
	paddd     xmm5,xmm0
446
	psrld     xmm1,SCALEBITS	; xmm1=CrEL
447
	psrld     xmm5,SCALEBITS	; xmm5=CrEH
448
	packssdw  xmm1,xmm5		; xmm1=CrE
449
450
	psllw     xmm7,BYTE_BIT
451
	por       xmm1,xmm7		; xmm1=Cr
452
	movdqa    XMMWORD [rdx], xmm1	; Save Cr
453
454
	sub	rcx, byte SIZEOF_XMMWORD
455
	add	rsi, byte RGB_PIXELSIZE*SIZEOF_XMMWORD	; inptr
456
	add	rdi, byte SIZEOF_XMMWORD		; outptr0
457
	add	rbx, byte SIZEOF_XMMWORD		; outptr1
458
	add	rdx, byte SIZEOF_XMMWORD		; outptr2
459
	cmp	rcx, byte SIZEOF_XMMWORD
460
	jae	near .columnloop
461
	test	rcx,rcx
462
	jnz	near .column_ld1
463
464
	pop	rcx			; col
465
	pop	rsi
466
	pop	rdi
467
	pop	rbx
468
	pop	rdx
469
470
	add	rsi, byte SIZEOF_JSAMPROW	; input_buf
471
	add	rdi, byte SIZEOF_JSAMPROW
472
	add	rbx, byte SIZEOF_JSAMPROW
473
	add	rdx, byte SIZEOF_JSAMPROW
474
	dec	rax				; num_rows
475
	jg	near .rowloop
476
477
.return:
478
	pop	rbx
479
	uncollect_args
480
	mov	rsp,rbp		; rsp <- aligned rbp
481
	pop	rsp		; rsp <- original rbp
482
	pop	rbp
483
	ret
484
485
; For some reason, the OS X linker does not honor the request to align the
486
; segment unless we do this.
487
	align	16
(-)a/jpeg/simd/jcclrss2.asm (+505 lines)
Line     Link Here 
Line 0    Link Here 
1
;
2
; jcclrss2.asm - colorspace conversion (SSE2)
3
;
4
; x86 SIMD extension for IJG JPEG library
5
; Copyright (C) 1999-2006, MIYASAKA Masaru.
6
; For conditions of distribution and use, see copyright notice in jsimdext.inc
7
;
8
; This file should be assembled with NASM (Netwide Assembler),
9
; can *not* be assembled with Microsoft's MASM or any compatible
10
; assembler (including Borland's Turbo Assembler).
11
; NASM is available from http://nasm.sourceforge.net/ or
12
; http://sourceforge.net/project/showfiles.php?group_id=6208
13
;
14
; [TAB8]
15
16
%include "jcolsamp.inc"
17
18
; --------------------------------------------------------------------------
19
	SECTION	SEG_TEXT
20
	BITS	32
21
;
22
; Convert some rows of samples to the output colorspace.
23
;
24
; GLOBAL(void)
25
; jsimd_rgb_ycc_convert_sse2 (JDIMENSION img_width,
26
;                             JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
27
;                             JDIMENSION output_row, int num_rows);
28
;
29
30
%define img_width(b)	(b)+8			; JDIMENSION img_width
31
%define input_buf(b)	(b)+12		; JSAMPARRAY input_buf
32
%define output_buf(b)	(b)+16		; JSAMPIMAGE output_buf
33
%define output_row(b)	(b)+20		; JDIMENSION output_row
34
%define num_rows(b)	(b)+24		; int num_rows
35
36
%define original_ebp	ebp+0
37
%define wk(i)		ebp-(WK_NUM-(i))*SIZEOF_XMMWORD	; xmmword wk[WK_NUM]
38
%define WK_NUM		8
39
%define gotptr		wk(0)-SIZEOF_POINTER	; void * gotptr
40
41
	align	16
42
43
	global	EXTN(jsimd_rgb_ycc_convert_sse2)
44
45
EXTN(jsimd_rgb_ycc_convert_sse2):
46
	push	ebp
47
	mov	eax,esp				; eax = original ebp
48
	sub	esp, byte 4
49
	and	esp, byte (-SIZEOF_XMMWORD)	; align to 128 bits
50
	mov	[esp],eax
51
	mov	ebp,esp				; ebp = aligned ebp
52
	lea	esp, [wk(0)]
53
	pushpic	eax		; make a room for GOT address
54
	push	ebx
55
;	push	ecx		; need not be preserved
56
;	push	edx		; need not be preserved
57
	push	esi
58
	push	edi
59
60
	get_GOT	ebx			; get GOT address
61
	movpic	POINTER [gotptr], ebx	; save GOT address
62
63
	mov	ecx, JDIMENSION [img_width(eax)]
64
	test	ecx,ecx
65
	jz	near .return
66
67
	push	ecx
68
69
	mov	esi, JSAMPIMAGE [output_buf(eax)]
70
	mov	ecx, JDIMENSION [output_row(eax)]
71
	mov	edi, JSAMPARRAY [esi+0*SIZEOF_JSAMPARRAY]
72
	mov	ebx, JSAMPARRAY [esi+1*SIZEOF_JSAMPARRAY]
73
	mov	edx, JSAMPARRAY [esi+2*SIZEOF_JSAMPARRAY]
74
	lea	edi, [edi+ecx*SIZEOF_JSAMPROW]
75
	lea	ebx, [ebx+ecx*SIZEOF_JSAMPROW]
76
	lea	edx, [edx+ecx*SIZEOF_JSAMPROW]
77
78
	pop	ecx
79
80
	mov	esi, JSAMPARRAY [input_buf(eax)]
81
	mov	eax, INT [num_rows(eax)]
82
	test	eax,eax
83
	jle	near .return
84
	alignx	16,7
85
.rowloop:
86
	pushpic	eax
87
	push	edx
88
	push	ebx
89
	push	edi
90
	push	esi
91
	push	ecx			; col
92
93
	mov	esi, JSAMPROW [esi]	; inptr
94
	mov	edi, JSAMPROW [edi]	; outptr0
95
	mov	ebx, JSAMPROW [ebx]	; outptr1
96
	mov	edx, JSAMPROW [edx]	; outptr2
97
	movpic	eax, POINTER [gotptr]	; load GOT address (eax)
98
99
	cmp	ecx, byte SIZEOF_XMMWORD
100
	jae	near .columnloop
101
	alignx	16,7
102
103
%if RGB_PIXELSIZE == 3 ; ---------------
104
105
.column_ld1:
106
	push	eax
107
	push	edx
108
	lea	ecx,[ecx+ecx*2]		; imul ecx,RGB_PIXELSIZE
109
	test	cl, SIZEOF_BYTE
110
	jz	short .column_ld2
111
	sub	ecx, byte SIZEOF_BYTE
112
	movzx	eax, BYTE [esi+ecx]
113
.column_ld2:
114
	test	cl, SIZEOF_WORD
115
	jz	short .column_ld4
116
	sub	ecx, byte SIZEOF_WORD
117
	movzx	edx, WORD [esi+ecx]
118
	shl	eax, WORD_BIT
119
	or	eax,edx
120
.column_ld4:
121
	movd	xmmA,eax
122
	pop	edx
123
	pop	eax
124
	test	cl, SIZEOF_DWORD
125
	jz	short .column_ld8
126
	sub	ecx, byte SIZEOF_DWORD
127
	movd	xmmF, XMM_DWORD [esi+ecx]
128
	pslldq	xmmA, SIZEOF_DWORD
129
	por	xmmA,xmmF
130
.column_ld8:
131
	test	cl, SIZEOF_MMWORD
132
	jz	short .column_ld16
133
	sub	ecx, byte SIZEOF_MMWORD
134
	movq	xmmB, XMM_MMWORD [esi+ecx]
135
	pslldq	xmmA, SIZEOF_MMWORD
136
	por	xmmA,xmmB
137
.column_ld16:
138
	test	cl, SIZEOF_XMMWORD
139
	jz	short .column_ld32
140
	movdqa	xmmF,xmmA
141
	movdqu	xmmA, XMMWORD [esi+0*SIZEOF_XMMWORD]
142
	mov	ecx, SIZEOF_XMMWORD
143
	jmp	short .rgb_ycc_cnv
144
.column_ld32:
145
	test	cl, 2*SIZEOF_XMMWORD
146
	mov	ecx, SIZEOF_XMMWORD
147
	jz	short .rgb_ycc_cnv
148
	movdqa	xmmB,xmmA
149
	movdqu	xmmA, XMMWORD [esi+0*SIZEOF_XMMWORD]
150
	movdqu	xmmF, XMMWORD [esi+1*SIZEOF_XMMWORD]
151
	jmp	short .rgb_ycc_cnv
152
	alignx	16,7
153
154
.columnloop:
155
	movdqu	xmmA, XMMWORD [esi+0*SIZEOF_XMMWORD]
156
	movdqu	xmmF, XMMWORD [esi+1*SIZEOF_XMMWORD]
157
	movdqu	xmmB, XMMWORD [esi+2*SIZEOF_XMMWORD]
158
159
.rgb_ycc_cnv:
160
	; xmmA=(00 10 20 01 11 21 02 12 22 03 13 23 04 14 24 05)
161
	; xmmF=(15 25 06 16 26 07 17 27 08 18 28 09 19 29 0A 1A)
162
	; xmmB=(2A 0B 1B 2B 0C 1C 2C 0D 1D 2D 0E 1E 2E 0F 1F 2F)
163
164
	movdqa    xmmG,xmmA
165
	pslldq    xmmA,8	; xmmA=(-- -- -- -- -- -- -- -- 00 10 20 01 11 21 02 12)
166
	psrldq    xmmG,8	; xmmG=(22 03 13 23 04 14 24 05 -- -- -- -- -- -- -- --)
167
168
	punpckhbw xmmA,xmmF	; xmmA=(00 08 10 18 20 28 01 09 11 19 21 29 02 0A 12 1A)
169
	pslldq    xmmF,8	; xmmF=(-- -- -- -- -- -- -- -- 15 25 06 16 26 07 17 27)
170
171
	punpcklbw xmmG,xmmB	; xmmG=(22 2A 03 0B 13 1B 23 2B 04 0C 14 1C 24 2C 05 0D)
172
	punpckhbw xmmF,xmmB	; xmmF=(15 1D 25 2D 06 0E 16 1E 26 2E 07 0F 17 1F 27 2F)
173
174
	movdqa    xmmD,xmmA
175
	pslldq    xmmA,8	; xmmA=(-- -- -- -- -- -- -- -- 00 08 10 18 20 28 01 09)
176
	psrldq    xmmD,8	; xmmD=(11 19 21 29 02 0A 12 1A -- -- -- -- -- -- -- --)
177
178
	punpckhbw xmmA,xmmG	; xmmA=(00 04 08 0C 10 14 18 1C 20 24 28 2C 01 05 09 0D)
179
	pslldq    xmmG,8	; xmmG=(-- -- -- -- -- -- -- -- 22 2A 03 0B 13 1B 23 2B)
180
181
	punpcklbw xmmD,xmmF	; xmmD=(11 15 19 1D 21 25 29 2D 02 06 0A 0E 12 16 1A 1E)
182
	punpckhbw xmmG,xmmF	; xmmG=(22 26 2A 2E 03 07 0B 0F 13 17 1B 1F 23 27 2B 2F)
183
184
	movdqa    xmmE,xmmA
185
	pslldq    xmmA,8	; xmmA=(-- -- -- -- -- -- -- -- 00 04 08 0C 10 14 18 1C)
186
	psrldq    xmmE,8	; xmmE=(20 24 28 2C 01 05 09 0D -- -- -- -- -- -- -- --)
187
188
	punpckhbw xmmA,xmmD	; xmmA=(00 02 04 06 08 0A 0C 0E 10 12 14 16 18 1A 1C 1E)
189
	pslldq    xmmD,8	; xmmD=(-- -- -- -- -- -- -- -- 11 15 19 1D 21 25 29 2D)
190
191
	punpcklbw xmmE,xmmG	; xmmE=(20 22 24 26 28 2A 2C 2E 01 03 05 07 09 0B 0D 0F)
192
	punpckhbw xmmD,xmmG	; xmmD=(11 13 15 17 19 1B 1D 1F 21 23 25 27 29 2B 2D 2F)
193
194
	pxor      xmmH,xmmH
195
196
	movdqa    xmmC,xmmA
197
	punpcklbw xmmA,xmmH	; xmmA=(00 02 04 06 08 0A 0C 0E)
198
	punpckhbw xmmC,xmmH	; xmmC=(10 12 14 16 18 1A 1C 1E)
199
200
	movdqa    xmmB,xmmE
201
	punpcklbw xmmE,xmmH	; xmmE=(20 22 24 26 28 2A 2C 2E)
202
	punpckhbw xmmB,xmmH	; xmmB=(01 03 05 07 09 0B 0D 0F)
203
204
	movdqa    xmmF,xmmD
205
	punpcklbw xmmD,xmmH	; xmmD=(11 13 15 17 19 1B 1D 1F)
206
	punpckhbw xmmF,xmmH	; xmmF=(21 23 25 27 29 2B 2D 2F)
207
208
%else ; RGB_PIXELSIZE == 4 ; -----------
209
210
.column_ld1:
211
	test	cl, SIZEOF_XMMWORD/16
212
	jz	short .column_ld2
213
	sub	ecx, byte SIZEOF_XMMWORD/16
214
	movd	xmmA, XMM_DWORD [esi+ecx*RGB_PIXELSIZE]
215
.column_ld2:
216
	test	cl, SIZEOF_XMMWORD/8
217
	jz	short .column_ld4
218
	sub	ecx, byte SIZEOF_XMMWORD/8
219
	movq	xmmE, XMM_MMWORD [esi+ecx*RGB_PIXELSIZE]
220
	pslldq	xmmA, SIZEOF_MMWORD
221
	por	xmmA,xmmE
222
.column_ld4:
223
	test	cl, SIZEOF_XMMWORD/4
224
	jz	short .column_ld8
225
	sub	ecx, byte SIZEOF_XMMWORD/4
226
	movdqa	xmmE,xmmA
227
	movdqu	xmmA, XMMWORD [esi+ecx*RGB_PIXELSIZE]
228
.column_ld8:
229
	test	cl, SIZEOF_XMMWORD/2
230
	mov	ecx, SIZEOF_XMMWORD
231
	jz	short .rgb_ycc_cnv
232
	movdqa	xmmF,xmmA
233
	movdqa	xmmH,xmmE
234
	movdqu	xmmA, XMMWORD [esi+0*SIZEOF_XMMWORD]
235
	movdqu	xmmE, XMMWORD [esi+1*SIZEOF_XMMWORD]
236
	jmp	short .rgb_ycc_cnv
237
	alignx	16,7
238
239
.columnloop:
240
	movdqu	xmmA, XMMWORD [esi+0*SIZEOF_XMMWORD]
241
	movdqu	xmmE, XMMWORD [esi+1*SIZEOF_XMMWORD]
242
	movdqu	xmmF, XMMWORD [esi+2*SIZEOF_XMMWORD]
243
	movdqu	xmmH, XMMWORD [esi+3*SIZEOF_XMMWORD]
244
245
.rgb_ycc_cnv:
246
	; xmmA=(00 10 20 30 01 11 21 31 02 12 22 32 03 13 23 33)
247
	; xmmE=(04 14 24 34 05 15 25 35 06 16 26 36 07 17 27 37)
248
	; xmmF=(08 18 28 38 09 19 29 39 0A 1A 2A 3A 0B 1B 2B 3B)
249
	; xmmH=(0C 1C 2C 3C 0D 1D 2D 3D 0E 1E 2E 3E 0F 1F 2F 3F)
250
251
	movdqa    xmmD,xmmA
252
	punpcklbw xmmA,xmmE	; xmmA=(00 04 10 14 20 24 30 34 01 05 11 15 21 25 31 35)
253
	punpckhbw xmmD,xmmE	; xmmD=(02 06 12 16 22 26 32 36 03 07 13 17 23 27 33 37)
254
255
	movdqa    xmmC,xmmF
256
	punpcklbw xmmF,xmmH	; xmmF=(08 0C 18 1C 28 2C 38 3C 09 0D 19 1D 29 2D 39 3D)
257
	punpckhbw xmmC,xmmH	; xmmC=(0A 0E 1A 1E 2A 2E 3A 3E 0B 0F 1B 1F 2B 2F 3B 3F)
258
259
	movdqa    xmmB,xmmA
260
	punpcklwd xmmA,xmmF	; xmmA=(00 04 08 0C 10 14 18 1C 20 24 28 2C 30 34 38 3C)
261
	punpckhwd xmmB,xmmF	; xmmB=(01 05 09 0D 11 15 19 1D 21 25 29 2D 31 35 39 3D)
262
263
	movdqa    xmmG,xmmD
264
	punpcklwd xmmD,xmmC	; xmmD=(02 06 0A 0E 12 16 1A 1E 22 26 2A 2E 32 36 3A 3E)
265
	punpckhwd xmmG,xmmC	; xmmG=(03 07 0B 0F 13 17 1B 1F 23 27 2B 2F 33 37 3B 3F)
266
267
	movdqa    xmmE,xmmA
268
	punpcklbw xmmA,xmmD	; xmmA=(00 02 04 06 08 0A 0C 0E 10 12 14 16 18 1A 1C 1E)
269
	punpckhbw xmmE,xmmD	; xmmE=(20 22 24 26 28 2A 2C 2E 30 32 34 36 38 3A 3C 3E)
270
271
	movdqa    xmmH,xmmB
272
	punpcklbw xmmB,xmmG	; xmmB=(01 03 05 07 09 0B 0D 0F 11 13 15 17 19 1B 1D 1F)
273
	punpckhbw xmmH,xmmG	; xmmH=(21 23 25 27 29 2B 2D 2F 31 33 35 37 39 3B 3D 3F)
274
275
	pxor      xmmF,xmmF
276
277
	movdqa    xmmC,xmmA
278
	punpcklbw xmmA,xmmF	; xmmA=(00 02 04 06 08 0A 0C 0E)
279
	punpckhbw xmmC,xmmF	; xmmC=(10 12 14 16 18 1A 1C 1E)
280
281
	movdqa    xmmD,xmmB
282
	punpcklbw xmmB,xmmF	; xmmB=(01 03 05 07 09 0B 0D 0F)
283
	punpckhbw xmmD,xmmF	; xmmD=(11 13 15 17 19 1B 1D 1F)
284
285
	movdqa    xmmG,xmmE
286
	punpcklbw xmmE,xmmF	; xmmE=(20 22 24 26 28 2A 2C 2E)
287
	punpckhbw xmmG,xmmF	; xmmG=(30 32 34 36 38 3A 3C 3E)
288
289
	punpcklbw xmmF,xmmH
290
	punpckhbw xmmH,xmmH
291
	psrlw     xmmF,BYTE_BIT	; xmmF=(21 23 25 27 29 2B 2D 2F)
292
	psrlw     xmmH,BYTE_BIT	; xmmH=(31 33 35 37 39 3B 3D 3F)
293
294
%endif ; RGB_PIXELSIZE ; ---------------
295
296
	; xmm0=R(02468ACE)=RE, xmm2=G(02468ACE)=GE, xmm4=B(02468ACE)=BE
297
	; xmm1=R(13579BDF)=RO, xmm3=G(13579BDF)=GO, xmm5=B(13579BDF)=BO
298
299
	; (Original)
300
	; Y  =  0.29900 * R + 0.58700 * G + 0.11400 * B
301
	; Cb = -0.16874 * R - 0.33126 * G + 0.50000 * B + CENTERJSAMPLE
302
	; Cr =  0.50000 * R - 0.41869 * G - 0.08131 * B + CENTERJSAMPLE
303
	;
304
	; (This implementation)
305
	; Y  =  0.29900 * R + 0.33700 * G + 0.11400 * B + 0.25000 * G
306
	; Cb = -0.16874 * R - 0.33126 * G + 0.50000 * B + CENTERJSAMPLE
307
	; Cr =  0.50000 * R - 0.41869 * G - 0.08131 * B + CENTERJSAMPLE
308
309
	movdqa    XMMWORD [wk(0)], xmm0	; wk(0)=RE
310
	movdqa    XMMWORD [wk(1)], xmm1	; wk(1)=RO
311
	movdqa    XMMWORD [wk(2)], xmm4	; wk(2)=BE
312
	movdqa    XMMWORD [wk(3)], xmm5	; wk(3)=BO
313
314
	movdqa    xmm6,xmm1
315
	punpcklwd xmm1,xmm3
316
	punpckhwd xmm6,xmm3
317
	movdqa    xmm7,xmm1
318
	movdqa    xmm4,xmm6
319
	pmaddwd   xmm1,[GOTOFF(eax,PW_F0299_F0337)] ; xmm1=ROL*FIX(0.299)+GOL*FIX(0.337)
320
	pmaddwd   xmm6,[GOTOFF(eax,PW_F0299_F0337)] ; xmm6=ROH*FIX(0.299)+GOH*FIX(0.337)
321
	pmaddwd   xmm7,[GOTOFF(eax,PW_MF016_MF033)] ; xmm7=ROL*-FIX(0.168)+GOL*-FIX(0.331)
322
	pmaddwd   xmm4,[GOTOFF(eax,PW_MF016_MF033)] ; xmm4=ROH*-FIX(0.168)+GOH*-FIX(0.331)
323
324
	movdqa    XMMWORD [wk(4)], xmm1	; wk(4)=ROL*FIX(0.299)+GOL*FIX(0.337)
325
	movdqa    XMMWORD [wk(5)], xmm6	; wk(5)=ROH*FIX(0.299)+GOH*FIX(0.337)
326
327
	pxor      xmm1,xmm1
328
	pxor      xmm6,xmm6
329
	punpcklwd xmm1,xmm5		; xmm1=BOL
330
	punpckhwd xmm6,xmm5		; xmm6=BOH
331
	psrld     xmm1,1		; xmm1=BOL*FIX(0.500)
332
	psrld     xmm6,1		; xmm6=BOH*FIX(0.500)
333
334
	movdqa    xmm5,[GOTOFF(eax,PD_ONEHALFM1_CJ)] ; xmm5=[PD_ONEHALFM1_CJ]
335
336
	paddd     xmm7,xmm1
337
	paddd     xmm4,xmm6
338
	paddd     xmm7,xmm5
339
	paddd     xmm4,xmm5
340
	psrld     xmm7,SCALEBITS	; xmm7=CbOL
341
	psrld     xmm4,SCALEBITS	; xmm4=CbOH
342
	packssdw  xmm7,xmm4		; xmm7=CbO
343
344
	movdqa    xmm1, XMMWORD [wk(2)]	; xmm1=BE
345
346
	movdqa    xmm6,xmm0
347
	punpcklwd xmm0,xmm2
348
	punpckhwd xmm6,xmm2
349
	movdqa    xmm5,xmm0
350
	movdqa    xmm4,xmm6
351
	pmaddwd   xmm0,[GOTOFF(eax,PW_F0299_F0337)] ; xmm0=REL*FIX(0.299)+GEL*FIX(0.337)
352
	pmaddwd   xmm6,[GOTOFF(eax,PW_F0299_F0337)] ; xmm6=REH*FIX(0.299)+GEH*FIX(0.337)
353
	pmaddwd   xmm5,[GOTOFF(eax,PW_MF016_MF033)] ; xmm5=REL*-FIX(0.168)+GEL*-FIX(0.331)
354
	pmaddwd   xmm4,[GOTOFF(eax,PW_MF016_MF033)] ; xmm4=REH*-FIX(0.168)+GEH*-FIX(0.331)
355
356
	movdqa    XMMWORD [wk(6)], xmm0	; wk(6)=REL*FIX(0.299)+GEL*FIX(0.337)
357
	movdqa    XMMWORD [wk(7)], xmm6	; wk(7)=REH*FIX(0.299)+GEH*FIX(0.337)
358
359
	pxor      xmm0,xmm0
360
	pxor      xmm6,xmm6
361
	punpcklwd xmm0,xmm1		; xmm0=BEL
362
	punpckhwd xmm6,xmm1		; xmm6=BEH
363
	psrld     xmm0,1		; xmm0=BEL*FIX(0.500)
364
	psrld     xmm6,1		; xmm6=BEH*FIX(0.500)
365
366
	movdqa    xmm1,[GOTOFF(eax,PD_ONEHALFM1_CJ)] ; xmm1=[PD_ONEHALFM1_CJ]
367
368
	paddd     xmm5,xmm0
369
	paddd     xmm4,xmm6
370
	paddd     xmm5,xmm1
371
	paddd     xmm4,xmm1
372
	psrld     xmm5,SCALEBITS	; xmm5=CbEL
373
	psrld     xmm4,SCALEBITS	; xmm4=CbEH
374
	packssdw  xmm5,xmm4		; xmm5=CbE
375
376
	psllw     xmm7,BYTE_BIT
377
	por       xmm5,xmm7		; xmm5=Cb
378
	movdqa    XMMWORD [ebx], xmm5	; Save Cb
379
380
	movdqa    xmm0, XMMWORD [wk(3)]	; xmm0=BO
381
	movdqa    xmm6, XMMWORD [wk(2)]	; xmm6=BE
382
	movdqa    xmm1, XMMWORD [wk(1)]	; xmm1=RO
383
384
	movdqa    xmm4,xmm0
385
	punpcklwd xmm0,xmm3
386
	punpckhwd xmm4,xmm3
387
	movdqa    xmm7,xmm0
388
	movdqa    xmm5,xmm4
389
	pmaddwd   xmm0,[GOTOFF(eax,PW_F0114_F0250)] ; xmm0=BOL*FIX(0.114)+GOL*FIX(0.250)
390
	pmaddwd   xmm4,[GOTOFF(eax,PW_F0114_F0250)] ; xmm4=BOH*FIX(0.114)+GOH*FIX(0.250)
391
	pmaddwd   xmm7,[GOTOFF(eax,PW_MF008_MF041)] ; xmm7=BOL*-FIX(0.081)+GOL*-FIX(0.418)
392
	pmaddwd   xmm5,[GOTOFF(eax,PW_MF008_MF041)] ; xmm5=BOH*-FIX(0.081)+GOH*-FIX(0.418)
393
394
	movdqa    xmm3,[GOTOFF(eax,PD_ONEHALF)]	; xmm3=[PD_ONEHALF]
395
396
	paddd     xmm0, XMMWORD [wk(4)]
397
	paddd     xmm4, XMMWORD [wk(5)]
398
	paddd     xmm0,xmm3
399
	paddd     xmm4,xmm3
400
	psrld     xmm0,SCALEBITS	; xmm0=YOL
401
	psrld     xmm4,SCALEBITS	; xmm4=YOH
402
	packssdw  xmm0,xmm4		; xmm0=YO
403
404
	pxor      xmm3,xmm3
405
	pxor      xmm4,xmm4
406
	punpcklwd xmm3,xmm1		; xmm3=ROL
407
	punpckhwd xmm4,xmm1		; xmm4=ROH
408
	psrld     xmm3,1		; xmm3=ROL*FIX(0.500)
409
	psrld     xmm4,1		; xmm4=ROH*FIX(0.500)
410
411
	movdqa    xmm1,[GOTOFF(eax,PD_ONEHALFM1_CJ)] ; xmm1=[PD_ONEHALFM1_CJ]
412
413
	paddd     xmm7,xmm3
414
	paddd     xmm5,xmm4
415
	paddd     xmm7,xmm1
416
	paddd     xmm5,xmm1
417
	psrld     xmm7,SCALEBITS	; xmm7=CrOL
418
	psrld     xmm5,SCALEBITS	; xmm5=CrOH
419
	packssdw  xmm7,xmm5		; xmm7=CrO
420
421
	movdqa    xmm3, XMMWORD [wk(0)]	; xmm3=RE
422
423
	movdqa    xmm4,xmm6
424
	punpcklwd xmm6,xmm2
425
	punpckhwd xmm4,xmm2
426
	movdqa    xmm1,xmm6
427
	movdqa    xmm5,xmm4
428
	pmaddwd   xmm6,[GOTOFF(eax,PW_F0114_F0250)] ; xmm6=BEL*FIX(0.114)+GEL*FIX(0.250)
429
	pmaddwd   xmm4,[GOTOFF(eax,PW_F0114_F0250)] ; xmm4=BEH*FIX(0.114)+GEH*FIX(0.250)
430
	pmaddwd   xmm1,[GOTOFF(eax,PW_MF008_MF041)] ; xmm1=BEL*-FIX(0.081)+GEL*-FIX(0.418)
431
	pmaddwd   xmm5,[GOTOFF(eax,PW_MF008_MF041)] ; xmm5=BEH*-FIX(0.081)+GEH*-FIX(0.418)
432
433
	movdqa    xmm2,[GOTOFF(eax,PD_ONEHALF)]	; xmm2=[PD_ONEHALF]
434
435
	paddd     xmm6, XMMWORD [wk(6)]
436
	paddd     xmm4, XMMWORD [wk(7)]
437
	paddd     xmm6,xmm2
438
	paddd     xmm4,xmm2
439
	psrld     xmm6,SCALEBITS	; xmm6=YEL
440
	psrld     xmm4,SCALEBITS	; xmm4=YEH
441
	packssdw  xmm6,xmm4		; xmm6=YE
442
443
	psllw     xmm0,BYTE_BIT
444
	por       xmm6,xmm0		; xmm6=Y
445
	movdqa    XMMWORD [edi], xmm6	; Save Y
446
447
	pxor      xmm2,xmm2
448
	pxor      xmm4,xmm4
449
	punpcklwd xmm2,xmm3		; xmm2=REL
450
	punpckhwd xmm4,xmm3		; xmm4=REH
451
	psrld     xmm2,1		; xmm2=REL*FIX(0.500)
452
	psrld     xmm4,1		; xmm4=REH*FIX(0.500)
453
454
	movdqa    xmm0,[GOTOFF(eax,PD_ONEHALFM1_CJ)] ; xmm0=[PD_ONEHALFM1_CJ]
455
456
	paddd     xmm1,xmm2
457
	paddd     xmm5,xmm4
458
	paddd     xmm1,xmm0
459
	paddd     xmm5,xmm0
460
	psrld     xmm1,SCALEBITS	; xmm1=CrEL
461
	psrld     xmm5,SCALEBITS	; xmm5=CrEH
462
	packssdw  xmm1,xmm5		; xmm1=CrE
463
464
	psllw     xmm7,BYTE_BIT
465
	por       xmm1,xmm7		; xmm1=Cr
466
	movdqa    XMMWORD [edx], xmm1	; Save Cr
467
468
	sub	ecx, byte SIZEOF_XMMWORD
469
	add	esi, byte RGB_PIXELSIZE*SIZEOF_XMMWORD	; inptr
470
	add	edi, byte SIZEOF_XMMWORD		; outptr0
471
	add	ebx, byte SIZEOF_XMMWORD		; outptr1
472
	add	edx, byte SIZEOF_XMMWORD		; outptr2
473
	cmp	ecx, byte SIZEOF_XMMWORD
474
	jae	near .columnloop
475
	test	ecx,ecx
476
	jnz	near .column_ld1
477
478
	pop	ecx			; col
479
	pop	esi
480
	pop	edi
481
	pop	ebx
482
	pop	edx
483
	poppic	eax
484
485
	add	esi, byte SIZEOF_JSAMPROW	; input_buf
486
	add	edi, byte SIZEOF_JSAMPROW
487
	add	ebx, byte SIZEOF_JSAMPROW
488
	add	edx, byte SIZEOF_JSAMPROW
489
	dec	eax				; num_rows
490
	jg	near .rowloop
491
492
.return:
493
	pop	edi
494
	pop	esi
495
;	pop	edx		; need not be preserved
496
;	pop	ecx		; need not be preserved
497
	pop	ebx
498
	mov	esp,ebp		; esp <- aligned ebp
499
	pop	esp		; esp <- original ebp
500
	pop	ebp
501
	ret
502
503
; For some reason, the OS X linker does not honor the request to align the
504
; segment unless we do this.
505
	align	16
(-)a/jpeg/simd/jccolmmx.asm (+120 lines)
Line     Link Here 
Line 0    Link Here 
1
;
2
; jccolmmx.asm - colorspace conversion (MMX)
3
;
4
; Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
5
; Copyright 2009 D. R. Commander
6
;
7
; Based on
8
; x86 SIMD extension for IJG JPEG library
9
; Copyright (C) 1999-2006, MIYASAKA Masaru.
10
; For conditions of distribution and use, see copyright notice in jsimdext.inc
11
;
12
; This file should be assembled with NASM (Netwide Assembler),
13
; can *not* be assembled with Microsoft's MASM or any compatible
14
; assembler (including Borland's Turbo Assembler).
15
; NASM is available from http://nasm.sourceforge.net/ or
16
; http://sourceforge.net/project/showfiles.php?group_id=6208
17
;
18
; [TAB8]
19
20
%include "jsimdext.inc"
21
22
; --------------------------------------------------------------------------
23
24
%define SCALEBITS	16
25
26
F_0_081	equ	 5329			; FIX(0.08131)
27
F_0_114	equ	 7471			; FIX(0.11400)
28
F_0_168	equ	11059			; FIX(0.16874)
29
F_0_250	equ	16384			; FIX(0.25000)
30
F_0_299	equ	19595			; FIX(0.29900)
31
F_0_331	equ	21709			; FIX(0.33126)
32
F_0_418	equ	27439			; FIX(0.41869)
33
F_0_587	equ	38470			; FIX(0.58700)
34
F_0_337	equ	(F_0_587 - F_0_250)	; FIX(0.58700) - FIX(0.25000)
35
36
; --------------------------------------------------------------------------
37
	SECTION	SEG_CONST
38
39
	alignz	16
40
	global	EXTN(jconst_rgb_ycc_convert_mmx)
41
42
EXTN(jconst_rgb_ycc_convert_mmx):
43
44
PW_F0299_F0337	times 2 dw  F_0_299, F_0_337
45
PW_F0114_F0250	times 2 dw  F_0_114, F_0_250
46
PW_MF016_MF033	times 2 dw -F_0_168,-F_0_331
47
PW_MF008_MF041	times 2 dw -F_0_081,-F_0_418
48
PD_ONEHALFM1_CJ	times 2 dd  (1 << (SCALEBITS-1)) - 1 + (CENTERJSAMPLE << SCALEBITS)
49
PD_ONEHALF	times 2 dd  (1 << (SCALEBITS-1))
50
51
	alignz	16
52
53
; --------------------------------------------------------------------------
54
%include "jcclrmmx.asm"
55
56
%undef RGB_RED
57
%undef RGB_GREEN
58
%undef RGB_BLUE
59
%undef RGB_PIXELSIZE
60
%define RGB_RED 0
61
%define RGB_GREEN 1
62
%define RGB_BLUE 2
63
%define RGB_PIXELSIZE 3
64
%define jsimd_rgb_ycc_convert_mmx jsimd_extrgb_ycc_convert_mmx
65
%include "jcclrmmx.asm"
66
67
%undef RGB_RED
68
%undef RGB_GREEN
69
%undef RGB_BLUE
70
%undef RGB_PIXELSIZE
71
%define RGB_RED 0
72
%define RGB_GREEN 1
73
%define RGB_BLUE 2
74
%define RGB_PIXELSIZE 4
75
%define jsimd_rgb_ycc_convert_mmx jsimd_extrgbx_ycc_convert_mmx
76
%include "jcclrmmx.asm"
77
78
%undef RGB_RED
79
%undef RGB_GREEN
80
%undef RGB_BLUE
81
%undef RGB_PIXELSIZE
82
%define RGB_RED 2
83
%define RGB_GREEN 1
84
%define RGB_BLUE 0
85
%define RGB_PIXELSIZE 3
86
%define jsimd_rgb_ycc_convert_mmx jsimd_extbgr_ycc_convert_mmx
87
%include "jcclrmmx.asm"
88
89
%undef RGB_RED
90
%undef RGB_GREEN
91
%undef RGB_BLUE
92
%undef RGB_PIXELSIZE
93
%define RGB_RED 2
94
%define RGB_GREEN 1
95
%define RGB_BLUE 0
96
%define RGB_PIXELSIZE 4
97
%define jsimd_rgb_ycc_convert_mmx jsimd_extbgrx_ycc_convert_mmx
98
%include "jcclrmmx.asm"
99
100
%undef RGB_RED
101
%undef RGB_GREEN
102
%undef RGB_BLUE
103
%undef RGB_PIXELSIZE
104
%define RGB_RED 3
105
%define RGB_GREEN 2
106
%define RGB_BLUE 1
107
%define RGB_PIXELSIZE 4
108
%define jsimd_rgb_ycc_convert_mmx jsimd_extxbgr_ycc_convert_mmx
109
%include "jcclrmmx.asm"
110
111
%undef RGB_RED
112
%undef RGB_GREEN
113
%undef RGB_BLUE
114
%undef RGB_PIXELSIZE
115
%define RGB_RED 1
116
%define RGB_GREEN 2
117
%define RGB_BLUE 3
118
%define RGB_PIXELSIZE 4
119
%define jsimd_rgb_ycc_convert_mmx jsimd_extxrgb_ycc_convert_mmx
120
%include "jcclrmmx.asm"
(-)a/jpeg/simd/jccolss2-64.asm (+117 lines)
Line     Link Here 
Line 0    Link Here 
1
;
2
; jccolss2-64.asm - colorspace conversion (64-bit SSE2)
3
;
4
; x86 SIMD extension for IJG JPEG library
5
; Copyright (C) 1999-2006, MIYASAKA Masaru.
6
; Copyright (C) 2009, D. R. Commander.
7
; For conditions of distribution and use, see copyright notice in jsimdext.inc
8
;
9
; This file should be assembled with NASM (Netwide Assembler),
10
; can *not* be assembled with Microsoft's MASM or any compatible
11
; assembler (including Borland's Turbo Assembler).
12
; NASM is available from http://nasm.sourceforge.net/ or
13
; http://sourceforge.net/project/showfiles.php?group_id=6208
14
;
15
; [TAB8]
16
17
%include "jsimdext.inc"
18
19
; --------------------------------------------------------------------------
20
21
%define SCALEBITS	16
22
23
F_0_081	equ	 5329			; FIX(0.08131)
24
F_0_114	equ	 7471			; FIX(0.11400)
25
F_0_168	equ	11059			; FIX(0.16874)
26
F_0_250	equ	16384			; FIX(0.25000)
27
F_0_299	equ	19595			; FIX(0.29900)
28
F_0_331	equ	21709			; FIX(0.33126)
29
F_0_418	equ	27439			; FIX(0.41869)
30
F_0_587	equ	38470			; FIX(0.58700)
31
F_0_337	equ	(F_0_587 - F_0_250)	; FIX(0.58700) - FIX(0.25000)
32
33
; --------------------------------------------------------------------------
34
	SECTION	SEG_CONST
35
36
	alignz	16
37
	global	EXTN(jconst_rgb_ycc_convert_sse2)
38
39
EXTN(jconst_rgb_ycc_convert_sse2):
40
41
PW_F0299_F0337	times 4 dw  F_0_299, F_0_337
42
PW_F0114_F0250	times 4 dw  F_0_114, F_0_250
43
PW_MF016_MF033	times 4 dw -F_0_168,-F_0_331
44
PW_MF008_MF041	times 4 dw -F_0_081,-F_0_418
45
PD_ONEHALFM1_CJ	times 4 dd  (1 << (SCALEBITS-1)) - 1 + (CENTERJSAMPLE << SCALEBITS)
46
PD_ONEHALF	times 4 dd  (1 << (SCALEBITS-1))
47
48
	alignz	16
49
50
; --------------------------------------------------------------------------
51
%include "jcclrss2-64.asm"
52
53
%undef RGB_RED
54
%undef RGB_GREEN
55
%undef RGB_BLUE
56
%undef RGB_PIXELSIZE
57
%define RGB_RED 0
58
%define RGB_GREEN 1
59
%define RGB_BLUE 2
60
%define RGB_PIXELSIZE 3
61
%define jsimd_rgb_ycc_convert_sse2 jsimd_extrgb_ycc_convert_sse2
62
%include "jcclrss2-64.asm"
63
64
%undef RGB_RED
65
%undef RGB_GREEN
66
%undef RGB_BLUE
67
%undef RGB_PIXELSIZE
68
%define RGB_RED 0
69
%define RGB_GREEN 1
70
%define RGB_BLUE 2
71
%define RGB_PIXELSIZE 4
72
%define jsimd_rgb_ycc_convert_sse2 jsimd_extrgbx_ycc_convert_sse2
73
%include "jcclrss2-64.asm"
74
75
%undef RGB_RED
76
%undef RGB_GREEN
77
%undef RGB_BLUE
78
%undef RGB_PIXELSIZE
79
%define RGB_RED 2
80
%define RGB_GREEN 1
81
%define RGB_BLUE 0
82
%define RGB_PIXELSIZE 3
83
%define jsimd_rgb_ycc_convert_sse2 jsimd_extbgr_ycc_convert_sse2
84
%include "jcclrss2-64.asm"
85
86
%undef RGB_RED
87
%undef RGB_GREEN
88
%undef RGB_BLUE
89
%undef RGB_PIXELSIZE
90
%define RGB_RED 2
91
%define RGB_GREEN 1
92
%define RGB_BLUE 0
93
%define RGB_PIXELSIZE 4
94
%define jsimd_rgb_ycc_convert_sse2 jsimd_extbgrx_ycc_convert_sse2
95
%include "jcclrss2-64.asm"
96
97
%undef RGB_RED
98
%undef RGB_GREEN
99
%undef RGB_BLUE
100
%undef RGB_PIXELSIZE
101
%define RGB_RED 3
102
%define RGB_GREEN 2
103
%define RGB_BLUE 1
104
%define RGB_PIXELSIZE 4
105
%define jsimd_rgb_ycc_convert_sse2 jsimd_extxbgr_ycc_convert_sse2
106
%include "jcclrss2-64.asm"
107
108
%undef RGB_RED
109
%undef RGB_GREEN
110
%undef RGB_BLUE
111
%undef RGB_PIXELSIZE
112
%define RGB_RED 1
113
%define RGB_GREEN 2
114
%define RGB_BLUE 3
115
%define RGB_PIXELSIZE 4
116
%define jsimd_rgb_ycc_convert_sse2 jsimd_extxrgb_ycc_convert_sse2
117
%include "jcclrss2-64.asm"
(-)a/jpeg/simd/jccolss2.asm (+117 lines)
Line     Link Here 
Line 0    Link Here 
1
;
2
; jccolss2.asm - colorspace conversion (SSE2)
3
;
4
; x86 SIMD extension for IJG JPEG library
5
; Copyright (C) 1999-2006, MIYASAKA Masaru.
6
; Copyright (C) 2009, D. R. Commander.
7
; For conditions of distribution and use, see copyright notice in jsimdext.inc
8
;
9
; This file should be assembled with NASM (Netwide Assembler),
10
; can *not* be assembled with Microsoft's MASM or any compatible
11
; assembler (including Borland's Turbo Assembler).
12
; NASM is available from http://nasm.sourceforge.net/ or
13
; http://sourceforge.net/project/showfiles.php?group_id=6208
14
;
15
; [TAB8]
16
17
%include "jsimdext.inc"
18
19
; --------------------------------------------------------------------------
20
21
%define SCALEBITS	16
22
23
F_0_081	equ	 5329			; FIX(0.08131)
24
F_0_114	equ	 7471			; FIX(0.11400)
25
F_0_168	equ	11059			; FIX(0.16874)
26
F_0_250	equ	16384			; FIX(0.25000)
27
F_0_299	equ	19595			; FIX(0.29900)
28
F_0_331	equ	21709			; FIX(0.33126)
29
F_0_418	equ	27439			; FIX(0.41869)
30
F_0_587	equ	38470			; FIX(0.58700)
31
F_0_337	equ	(F_0_587 - F_0_250)	; FIX(0.58700) - FIX(0.25000)
32
33
; --------------------------------------------------------------------------
34
	SECTION	SEG_CONST
35
36
	alignz	16
37
	global	EXTN(jconst_rgb_ycc_convert_sse2)
38
39
EXTN(jconst_rgb_ycc_convert_sse2):
40
41
PW_F0299_F0337	times 4 dw  F_0_299, F_0_337
42
PW_F0114_F0250	times 4 dw  F_0_114, F_0_250
43
PW_MF016_MF033	times 4 dw -F_0_168,-F_0_331
44
PW_MF008_MF041	times 4 dw -F_0_081,-F_0_418
45
PD_ONEHALFM1_CJ	times 4 dd  (1 << (SCALEBITS-1)) - 1 + (CENTERJSAMPLE << SCALEBITS)
46
PD_ONEHALF	times 4 dd  (1 << (SCALEBITS-1))
47
48
	alignz	16
49
50
; --------------------------------------------------------------------------
51
%include "jcclrss2.asm"
52
53
%undef RGB_RED
54
%undef RGB_GREEN
55
%undef RGB_BLUE
56
%undef RGB_PIXELSIZE
57
%define RGB_RED 0
58
%define RGB_GREEN 1
59
%define RGB_BLUE 2
60
%define RGB_PIXELSIZE 3
61
%define jsimd_rgb_ycc_convert_sse2 jsimd_extrgb_ycc_convert_sse2
62
%include "jcclrss2.asm"
63
64
%undef RGB_RED
65
%undef RGB_GREEN
66
%undef RGB_BLUE
67
%undef RGB_PIXELSIZE
68
%define RGB_RED 0
69
%define RGB_GREEN 1
70
%define RGB_BLUE 2
71
%define RGB_PIXELSIZE 4
72
%define jsimd_rgb_ycc_convert_sse2 jsimd_extrgbx_ycc_convert_sse2
73
%include "jcclrss2.asm"
74
75
%undef RGB_RED
76
%undef RGB_GREEN
77
%undef RGB_BLUE
78
%undef RGB_PIXELSIZE
79
%define RGB_RED 2
80
%define RGB_GREEN 1
81
%define RGB_BLUE 0
82
%define RGB_PIXELSIZE 3
83
%define jsimd_rgb_ycc_convert_sse2 jsimd_extbgr_ycc_convert_sse2
84
%include "jcclrss2.asm"
85
86
%undef RGB_RED
87
%undef RGB_GREEN
88
%undef RGB_BLUE
89
%undef RGB_PIXELSIZE
90
%define RGB_RED 2
91
%define RGB_GREEN 1
92
%define RGB_BLUE 0
93
%define RGB_PIXELSIZE 4
94
%define jsimd_rgb_ycc_convert_sse2 jsimd_extbgrx_ycc_convert_sse2
95
%include "jcclrss2.asm"
96
97
%undef RGB_RED
98
%undef RGB_GREEN
99
%undef RGB_BLUE
100
%undef RGB_PIXELSIZE
101
%define RGB_RED 3
102
%define RGB_GREEN 2
103
%define RGB_BLUE 1
104
%define RGB_PIXELSIZE 4
105
%define jsimd_rgb_ycc_convert_sse2 jsimd_extxbgr_ycc_convert_sse2
106
%include "jcclrss2.asm"
107
108
%undef RGB_RED
109
%undef RGB_GREEN
110
%undef RGB_BLUE
111
%undef RGB_PIXELSIZE
112
%define RGB_RED 1
113
%define RGB_GREEN 2
114
%define RGB_BLUE 3
115
%define RGB_PIXELSIZE 4
116
%define jsimd_rgb_ycc_convert_sse2 jsimd_extxrgb_ycc_convert_sse2
117
%include "jcclrss2.asm"
(-)a/jpeg/simd/jcolsamp.inc (+105 lines)
Line     Link Here 
Line 0    Link Here 
1
;
2
; jcolsamp.inc - private declarations for color conversion & up/downsampling
3
;
4
; Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
5
;
6
; Based on
7
; x86 SIMD extension for IJG JPEG library
8
; Copyright (C) 1999-2006, MIYASAKA Masaru.
9
; For conditions of distribution and use, see copyright notice in jsimdext.inc
10
;
11
; [TAB8]
12
13
; --------------------------------------------------------------------------
14
15
; pseudo-resisters to make ordering of RGB configurable
16
;
17
%if RGB_RED == 0
18
%define  mmA  mm0
19
%define  mmB  mm1
20
%define xmmA xmm0
21
%define xmmB xmm1
22
%elif RGB_GREEN == 0
23
%define  mmA  mm2
24
%define  mmB  mm3
25
%define xmmA xmm2
26
%define xmmB xmm3
27
%elif RGB_BLUE == 0
28
%define  mmA  mm4
29
%define  mmB  mm5
30
%define xmmA xmm4
31
%define xmmB xmm5
32
%else
33
%define  mmA  mm6
34
%define  mmB  mm7
35
%define xmmA xmm6
36
%define xmmB xmm7
37
%endif
38
39
%if RGB_RED == 1
40
%define  mmC  mm0
41
%define  mmD  mm1
42
%define xmmC xmm0
43
%define xmmD xmm1
44
%elif RGB_GREEN == 1
45
%define  mmC  mm2
46
%define  mmD  mm3
47
%define xmmC xmm2
48
%define xmmD xmm3
49
%elif RGB_BLUE == 1
50
%define  mmC  mm4
51
%define  mmD  mm5
52
%define xmmC xmm4
53
%define xmmD xmm5
54
%else
55
%define  mmC  mm6
56
%define  mmD  mm7
57
%define xmmC xmm6
58
%define xmmD xmm7
59
%endif
60
61
%if RGB_RED == 2
62
%define  mmE  mm0
63
%define  mmF  mm1
64
%define xmmE xmm0
65
%define xmmF xmm1
66
%elif RGB_GREEN == 2
67
%define  mmE  mm2
68
%define  mmF  mm3
69
%define xmmE xmm2
70
%define xmmF xmm3
71
%elif RGB_BLUE == 2
72
%define  mmE  mm4
73
%define  mmF  mm5
74
%define xmmE xmm4
75
%define xmmF xmm5
76
%else
77
%define  mmE  mm6
78
%define  mmF  mm7
79
%define xmmE xmm6
80
%define xmmF xmm7
81
%endif
82
83
%if RGB_RED == 3
84
%define  mmG  mm0
85
%define  mmH  mm1
86
%define xmmG xmm0
87
%define xmmH xmm1
88
%elif RGB_GREEN == 3
89
%define  mmG  mm2
90
%define  mmH  mm3
91
%define xmmG xmm2
92
%define xmmH xmm3
93
%elif RGB_BLUE == 3
94
%define  mmG  mm4
95
%define  mmH  mm5
96
%define xmmG xmm4
97
%define xmmH xmm5
98
%else
99
%define  mmG  mm6
100
%define  mmH  mm7
101
%define xmmG xmm6
102
%define xmmH xmm7
103
%endif
104
105
; --------------------------------------------------------------------------
(-)a/jpeg/simd/jcqnt3dn.asm (+233 lines)
Line     Link Here 
Line 0    Link Here 
1
;
2
; jcqnt3dn.asm - sample data conversion and quantization (3DNow! & MMX)
3
;
4
; Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
5
;
6
; Based on
7
; x86 SIMD extension for IJG JPEG library
8
; Copyright (C) 1999-2006, MIYASAKA Masaru.
9
; For conditions of distribution and use, see copyright notice in jsimdext.inc
10
;
11
; This file should be assembled with NASM (Netwide Assembler),
12
; can *not* be assembled with Microsoft's MASM or any compatible
13
; assembler (including Borland's Turbo Assembler).
14
; NASM is available from http://nasm.sourceforge.net/ or
15
; http://sourceforge.net/project/showfiles.php?group_id=6208
16
;
17
; [TAB8]
18
19
%include "jsimdext.inc"
20
%include "jdct.inc"
21
22
; --------------------------------------------------------------------------
23
	SECTION	SEG_TEXT
24
	BITS	32
25
;
26
; Load data into workspace, applying unsigned->signed conversion
27
;
28
; GLOBAL(void)
29
; jsimd_convsamp_float_3dnow (JSAMPARRAY sample_data, JDIMENSION start_col,
30
;                             FAST_FLOAT * workspace);
31
;
32
33
%define sample_data	ebp+8		; JSAMPARRAY sample_data
34
%define start_col	ebp+12		; JDIMENSION start_col
35
%define workspace	ebp+16		; FAST_FLOAT * workspace
36
37
	align	16
38
	global	EXTN(jsimd_convsamp_float_3dnow)
39
40
EXTN(jsimd_convsamp_float_3dnow):
41
	push	ebp
42
	mov	ebp,esp
43
	push	ebx
44
;	push	ecx		; need not be preserved
45
;	push	edx		; need not be preserved
46
	push	esi
47
	push	edi
48
49
	pcmpeqw  mm7,mm7
50
	psllw    mm7,7
51
	packsswb mm7,mm7		; mm7 = PB_CENTERJSAMPLE (0x808080..)
52
53
	mov	esi, JSAMPARRAY [sample_data]	; (JSAMPROW *)
54
	mov	eax, JDIMENSION [start_col]
55
	mov	edi, POINTER [workspace]	; (DCTELEM *)
56
	mov	ecx, DCTSIZE/2
57
	alignx	16,7
58
.convloop:
59
	mov	ebx, JSAMPROW [esi+0*SIZEOF_JSAMPROW]	; (JSAMPLE *)
60
	mov	edx, JSAMPROW [esi+1*SIZEOF_JSAMPROW]	; (JSAMPLE *)
61
62
	movq	mm0, MMWORD [ebx+eax*SIZEOF_JSAMPLE]
63
	movq	mm1, MMWORD [edx+eax*SIZEOF_JSAMPLE]
64
65
	psubb	mm0,mm7				; mm0=(01234567)
66
	psubb	mm1,mm7				; mm1=(89ABCDEF)
67
68
	punpcklbw mm2,mm0			; mm2=(*0*1*2*3)
69
	punpckhbw mm0,mm0			; mm0=(*4*5*6*7)
70
	punpcklbw mm3,mm1			; mm3=(*8*9*A*B)
71
	punpckhbw mm1,mm1			; mm1=(*C*D*E*F)
72
73
	punpcklwd mm4,mm2			; mm4=(***0***1)
74
	punpckhwd mm2,mm2			; mm2=(***2***3)
75
	punpcklwd mm5,mm0			; mm5=(***4***5)
76
	punpckhwd mm0,mm0			; mm0=(***6***7)
77
78
	psrad	mm4,(DWORD_BIT-BYTE_BIT)	; mm4=(01)
79
	psrad	mm2,(DWORD_BIT-BYTE_BIT)	; mm2=(23)
80
	pi2fd	mm4,mm4
81
	pi2fd	mm2,mm2
82
	psrad	mm5,(DWORD_BIT-BYTE_BIT)	; mm5=(45)
83
	psrad	mm0,(DWORD_BIT-BYTE_BIT)	; mm0=(67)
84
	pi2fd	mm5,mm5
85
	pi2fd	mm0,mm0
86
87
	movq	MMWORD [MMBLOCK(0,0,edi,SIZEOF_FAST_FLOAT)], mm4
88
	movq	MMWORD [MMBLOCK(0,1,edi,SIZEOF_FAST_FLOAT)], mm2
89
	movq	MMWORD [MMBLOCK(0,2,edi,SIZEOF_FAST_FLOAT)], mm5
90
	movq	MMWORD [MMBLOCK(0,3,edi,SIZEOF_FAST_FLOAT)], mm0
91
92
	punpcklwd mm6,mm3			; mm6=(***8***9)
93
	punpckhwd mm3,mm3			; mm3=(***A***B)
94
	punpcklwd mm4,mm1			; mm4=(***C***D)
95
	punpckhwd mm1,mm1			; mm1=(***E***F)
96
97
	psrad	mm6,(DWORD_BIT-BYTE_BIT)	; mm6=(89)
98
	psrad	mm3,(DWORD_BIT-BYTE_BIT)	; mm3=(AB)
99
	pi2fd	mm6,mm6
100
	pi2fd	mm3,mm3
101
	psrad	mm4,(DWORD_BIT-BYTE_BIT)	; mm4=(CD)
102
	psrad	mm1,(DWORD_BIT-BYTE_BIT)	; mm1=(EF)
103
	pi2fd	mm4,mm4
104
	pi2fd	mm1,mm1
105
106
	movq	MMWORD [MMBLOCK(1,0,edi,SIZEOF_FAST_FLOAT)], mm6
107
	movq	MMWORD [MMBLOCK(1,1,edi,SIZEOF_FAST_FLOAT)], mm3
108
	movq	MMWORD [MMBLOCK(1,2,edi,SIZEOF_FAST_FLOAT)], mm4
109
	movq	MMWORD [MMBLOCK(1,3,edi,SIZEOF_FAST_FLOAT)], mm1
110
111
	add	esi, byte 2*SIZEOF_JSAMPROW
112
	add	edi, byte 2*DCTSIZE*SIZEOF_FAST_FLOAT
113
	dec	ecx
114
	jnz	near .convloop
115
116
	femms		; empty MMX/3DNow! state
117
118
	pop	edi
119
	pop	esi
120
;	pop	edx		; need not be preserved
121
;	pop	ecx		; need not be preserved
122
	pop	ebx
123
	pop	ebp
124
	ret
125
126
127
; --------------------------------------------------------------------------
128
;
129
; Quantize/descale the coefficients, and store into coef_block
130
;
131
; GLOBAL(void)
132
; jsimd_quantize_float_3dnow (JCOEFPTR coef_block, FAST_FLOAT * divisors,
133
;                             FAST_FLOAT * workspace);
134
;
135
136
%define coef_block	ebp+8		; JCOEFPTR coef_block
137
%define divisors	ebp+12		; FAST_FLOAT * divisors
138
%define workspace	ebp+16		; FAST_FLOAT * workspace
139
140
	align	16
141
	global	EXTN(jsimd_quantize_float_3dnow)
142
143
EXTN(jsimd_quantize_float_3dnow):
144
	push	ebp
145
	mov	ebp,esp
146
;	push	ebx		; unused
147
;	push	ecx		; unused
148
;	push	edx		; need not be preserved
149
	push	esi
150
	push	edi
151
152
	mov       eax, 0x4B400000	; (float)0x00C00000 (rndint_magic)
153
	movd      mm7,eax
154
	punpckldq mm7,mm7		; mm7={12582912.0F 12582912.0F}
155
156
	mov	esi, POINTER [workspace]
157
	mov	edx, POINTER [divisors]
158
	mov	edi, JCOEFPTR [coef_block]
159
	mov	eax, DCTSIZE2/16
160
	alignx	16,7
161
.quantloop:
162
	movq	mm0, MMWORD [MMBLOCK(0,0,esi,SIZEOF_FAST_FLOAT)]
163
	movq	mm1, MMWORD [MMBLOCK(0,1,esi,SIZEOF_FAST_FLOAT)]
164
	pfmul	mm0, MMWORD [MMBLOCK(0,0,edx,SIZEOF_FAST_FLOAT)]
165
	pfmul	mm1, MMWORD [MMBLOCK(0,1,edx,SIZEOF_FAST_FLOAT)]
166
	movq	mm2, MMWORD [MMBLOCK(0,2,esi,SIZEOF_FAST_FLOAT)]
167
	movq	mm3, MMWORD [MMBLOCK(0,3,esi,SIZEOF_FAST_FLOAT)]
168
	pfmul	mm2, MMWORD [MMBLOCK(0,2,edx,SIZEOF_FAST_FLOAT)]
169
	pfmul	mm3, MMWORD [MMBLOCK(0,3,edx,SIZEOF_FAST_FLOAT)]
170
171
	pfadd	mm0,mm7			; mm0=(00 ** 01 **)
172
	pfadd	mm1,mm7			; mm1=(02 ** 03 **)
173
	pfadd	mm2,mm7			; mm0=(04 ** 05 **)
174
	pfadd	mm3,mm7			; mm1=(06 ** 07 **)
175
176
	movq      mm4,mm0
177
	punpcklwd mm0,mm1		; mm0=(00 02 ** **)
178
	punpckhwd mm4,mm1		; mm4=(01 03 ** **)
179
	movq      mm5,mm2
180
	punpcklwd mm2,mm3		; mm2=(04 06 ** **)
181
	punpckhwd mm5,mm3		; mm5=(05 07 ** **)
182
183
	punpcklwd mm0,mm4		; mm0=(00 01 02 03)
184
	punpcklwd mm2,mm5		; mm2=(04 05 06 07)
185
186
	movq	mm6, MMWORD [MMBLOCK(1,0,esi,SIZEOF_FAST_FLOAT)]
187
	movq	mm1, MMWORD [MMBLOCK(1,1,esi,SIZEOF_FAST_FLOAT)]
188
	pfmul	mm6, MMWORD [MMBLOCK(1,0,edx,SIZEOF_FAST_FLOAT)]
189
	pfmul	mm1, MMWORD [MMBLOCK(1,1,edx,SIZEOF_FAST_FLOAT)]
190
	movq	mm3, MMWORD [MMBLOCK(1,2,esi,SIZEOF_FAST_FLOAT)]
191
	movq	mm4, MMWORD [MMBLOCK(1,3,esi,SIZEOF_FAST_FLOAT)]
192
	pfmul	mm3, MMWORD [MMBLOCK(1,2,edx,SIZEOF_FAST_FLOAT)]
193
	pfmul	mm4, MMWORD [MMBLOCK(1,3,edx,SIZEOF_FAST_FLOAT)]
194
195
	pfadd	mm6,mm7			; mm0=(10 ** 11 **)
196
	pfadd	mm1,mm7			; mm4=(12 ** 13 **)
197
	pfadd	mm3,mm7			; mm0=(14 ** 15 **)
198
	pfadd	mm4,mm7			; mm4=(16 ** 17 **)
199
200
	movq      mm5,mm6
201
	punpcklwd mm6,mm1		; mm6=(10 12 ** **)
202
	punpckhwd mm5,mm1		; mm5=(11 13 ** **)
203
	movq      mm1,mm3
204
	punpcklwd mm3,mm4		; mm3=(14 16 ** **)
205
	punpckhwd mm1,mm4		; mm1=(15 17 ** **)
206
207
	punpcklwd mm6,mm5		; mm6=(10 11 12 13)
208
	punpcklwd mm3,mm1		; mm3=(14 15 16 17)
209
210
	movq	MMWORD [MMBLOCK(0,0,edi,SIZEOF_JCOEF)], mm0
211
	movq	MMWORD [MMBLOCK(0,1,edi,SIZEOF_JCOEF)], mm2
212
	movq	MMWORD [MMBLOCK(1,0,edi,SIZEOF_JCOEF)], mm6
213
	movq	MMWORD [MMBLOCK(1,1,edi,SIZEOF_JCOEF)], mm3
214
215
	add	esi, byte 16*SIZEOF_FAST_FLOAT
216
	add	edx, byte 16*SIZEOF_FAST_FLOAT
217
	add	edi, byte 16*SIZEOF_JCOEF
218
	dec	eax
219
	jnz	near .quantloop
220
221
	femms		; empty MMX/3DNow! state
222
223
	pop	edi
224
	pop	esi
225
;	pop	edx		; need not be preserved
226
;	pop	ecx		; unused
227
;	pop	ebx		; unused
228
	pop	ebp
229
	ret
230
231
; For some reason, the OS X linker does not honor the request to align the
232
; segment unless we do this.
233
	align	16
(-)a/jpeg/simd/jcqntmmx.asm (+274 lines)
Line     Link Here 
Line 0    Link Here 
1
;
2
; jcqntmmx.asm - sample data conversion and quantization (MMX)
3
;
4
; Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
5
;
6
; Based on
7
; x86 SIMD extension for IJG JPEG library
8
; Copyright (C) 1999-2006, MIYASAKA Masaru.
9
; For conditions of distribution and use, see copyright notice in jsimdext.inc
10
;
11
; This file should be assembled with NASM (Netwide Assembler),
12
; can *not* be assembled with Microsoft's MASM or any compatible
13
; assembler (including Borland's Turbo Assembler).
14
; NASM is available from http://nasm.sourceforge.net/ or
15
; http://sourceforge.net/project/showfiles.php?group_id=6208
16
;
17
; [TAB8]
18
19
%include "jsimdext.inc"
20
%include "jdct.inc"
21
22
; --------------------------------------------------------------------------
23
	SECTION	SEG_TEXT
24
	BITS	32
25
;
26
; Load data into workspace, applying unsigned->signed conversion
27
;
28
; GLOBAL(void)
29
; jsimd_convsamp_mmx (JSAMPARRAY sample_data, JDIMENSION start_col,
30
;                     DCTELEM * workspace);
31
;
32
33
%define sample_data	ebp+8		; JSAMPARRAY sample_data
34
%define start_col	ebp+12		; JDIMENSION start_col
35
%define workspace	ebp+16		; DCTELEM * workspace
36
37
	align	16
38
	global	EXTN(jsimd_convsamp_mmx)
39
40
EXTN(jsimd_convsamp_mmx):
41
	push	ebp
42
	mov	ebp,esp
43
	push	ebx
44
;	push	ecx		; need not be preserved
45
;	push	edx		; need not be preserved
46
	push	esi
47
	push	edi
48
49
	pxor	mm6,mm6			; mm6=(all 0's)
50
	pcmpeqw	mm7,mm7
51
	psllw	mm7,7			; mm7={0xFF80 0xFF80 0xFF80 0xFF80}
52
53
	mov	esi, JSAMPARRAY [sample_data]	; (JSAMPROW *)
54
	mov	eax, JDIMENSION [start_col]
55
	mov	edi, POINTER [workspace]	; (DCTELEM *)
56
	mov	ecx, DCTSIZE/4
57
	alignx	16,7
58
.convloop:
59
	mov	ebx, JSAMPROW [esi+0*SIZEOF_JSAMPROW]	; (JSAMPLE *)
60
	mov	edx, JSAMPROW [esi+1*SIZEOF_JSAMPROW]	; (JSAMPLE *)
61
62
	movq	mm0, MMWORD [ebx+eax*SIZEOF_JSAMPLE]	; mm0=(01234567)
63
	movq	mm1, MMWORD [edx+eax*SIZEOF_JSAMPLE]	; mm1=(89ABCDEF)
64
65
	mov	ebx, JSAMPROW [esi+2*SIZEOF_JSAMPROW]	; (JSAMPLE *)
66
	mov	edx, JSAMPROW [esi+3*SIZEOF_JSAMPROW]	; (JSAMPLE *)
67
68
	movq	mm2, MMWORD [ebx+eax*SIZEOF_JSAMPLE]	; mm2=(GHIJKLMN)
69
	movq	mm3, MMWORD [edx+eax*SIZEOF_JSAMPLE]	; mm3=(OPQRSTUV)
70
71
	movq      mm4,mm0
72
	punpcklbw mm0,mm6		; mm0=(0123)
73
	punpckhbw mm4,mm6		; mm4=(4567)
74
	movq      mm5,mm1
75
	punpcklbw mm1,mm6		; mm1=(89AB)
76
	punpckhbw mm5,mm6		; mm5=(CDEF)
77
78
	paddw	mm0,mm7
79
	paddw	mm4,mm7
80
	paddw	mm1,mm7
81
	paddw	mm5,mm7
82
83
	movq	MMWORD [MMBLOCK(0,0,edi,SIZEOF_DCTELEM)], mm0
84
	movq	MMWORD [MMBLOCK(0,1,edi,SIZEOF_DCTELEM)], mm4
85
	movq	MMWORD [MMBLOCK(1,0,edi,SIZEOF_DCTELEM)], mm1
86
	movq	MMWORD [MMBLOCK(1,1,edi,SIZEOF_DCTELEM)], mm5
87
88
	movq      mm0,mm2
89
	punpcklbw mm2,mm6		; mm2=(GHIJ)
90
	punpckhbw mm0,mm6		; mm0=(KLMN)
91
	movq      mm4,mm3
92
	punpcklbw mm3,mm6		; mm3=(OPQR)
93
	punpckhbw mm4,mm6		; mm4=(STUV)
94
95
	paddw	mm2,mm7
96
	paddw	mm0,mm7
97
	paddw	mm3,mm7
98
	paddw	mm4,mm7
99
100
	movq	MMWORD [MMBLOCK(2,0,edi,SIZEOF_DCTELEM)], mm2
101
	movq	MMWORD [MMBLOCK(2,1,edi,SIZEOF_DCTELEM)], mm0
102
	movq	MMWORD [MMBLOCK(3,0,edi,SIZEOF_DCTELEM)], mm3
103
	movq	MMWORD [MMBLOCK(3,1,edi,SIZEOF_DCTELEM)], mm4
104
105
	add	esi, byte 4*SIZEOF_JSAMPROW
106
	add	edi, byte 4*DCTSIZE*SIZEOF_DCTELEM
107
	dec	ecx
108
	jnz	short .convloop
109
110
	emms		; empty MMX state
111
112
	pop	edi
113
	pop	esi
114
;	pop	edx		; need not be preserved
115
;	pop	ecx		; need not be preserved
116
	pop	ebx
117
	pop	ebp
118
	ret
119
120
; --------------------------------------------------------------------------
121
;
122
; Quantize/descale the coefficients, and store into coef_block
123
;
124
; This implementation is based on an algorithm described in
125
;   "How to optimize for the Pentium family of microprocessors"
126
;   (http://www.agner.org/assem/).
127
;
128
; GLOBAL(void)
129
; jsimd_quantize_mmx (JCOEFPTR coef_block, DCTELEM * divisors,
130
;                     DCTELEM * workspace);
131
;
132
133
%define RECIPROCAL(m,n,b) MMBLOCK(DCTSIZE*0+(m),(n),(b),SIZEOF_DCTELEM)
134
%define CORRECTION(m,n,b) MMBLOCK(DCTSIZE*1+(m),(n),(b),SIZEOF_DCTELEM)
135
%define SCALE(m,n,b)      MMBLOCK(DCTSIZE*2+(m),(n),(b),SIZEOF_DCTELEM)
136
%define SHIFT(m,n,b)      MMBLOCK(DCTSIZE*3+(m),(n),(b),SIZEOF_DCTELEM)
137
138
%define coef_block	ebp+8		; JCOEFPTR coef_block
139
%define divisors	ebp+12		; DCTELEM * divisors
140
%define workspace	ebp+16		; DCTELEM * workspace
141
142
	align	16
143
	global	EXTN(jsimd_quantize_mmx)
144
145
EXTN(jsimd_quantize_mmx):
146
	push	ebp
147
	mov	ebp,esp
148
;	push	ebx		; unused
149
;	push	ecx		; unused
150
;	push	edx		; need not be preserved
151
	push	esi
152
	push	edi
153
154
	mov	esi, POINTER [workspace]
155
	mov	edx, POINTER [divisors]
156
	mov	edi, JCOEFPTR [coef_block]
157
	mov	ah, 2
158
	alignx	16,7
159
.quantloop1:
160
	mov	al, DCTSIZE2/8/2
161
	alignx	16,7
162
.quantloop2:
163
	movq	mm2, MMWORD [MMBLOCK(0,0,esi,SIZEOF_DCTELEM)]
164
	movq	mm3, MMWORD [MMBLOCK(0,1,esi,SIZEOF_DCTELEM)]
165
166
	movq	mm0,mm2
167
	movq	mm1,mm3
168
169
	psraw	mm2,(WORD_BIT-1)  ; -1 if value < 0, 0 otherwise
170
	psraw	mm3,(WORD_BIT-1)
171
172
	pxor	mm0,mm2   ; val = -val
173
	pxor	mm1,mm3
174
	psubw	mm0,mm2
175
	psubw	mm1,mm3
176
177
	;
178
	; MMX is an annoyingly crappy instruction set. It has two
179
	; misfeatures that are causing problems here:
180
	;
181
	; - All multiplications are signed.
182
	;
183
	; - The second operand for the shifts is not treated as packed.
184
	;
185
	;
186
	; We work around the first problem by implementing this algorithm:
187
	;
188
	; unsigned long unsigned_multiply(unsigned short x, unsigned short y)
189
	; {
190
	;   enum { SHORT_BIT = 16 };
191
	;   signed short sx = (signed short) x;
192
	;   signed short sy = (signed short) y;
193
	;   signed long sz;
194
	; 
195
	;   sz = (long) sx * (long) sy;     /* signed multiply */
196
	; 
197
	;   if (sx < 0) sz += (long) sy << SHORT_BIT;
198
	;   if (sy < 0) sz += (long) sx << SHORT_BIT;
199
	; 
200
	;   return (unsigned long) sz;
201
	; }
202
	;
203
	; (note that a negative sx adds _sy_ and vice versa)
204
	;
205
	; For the second problem, we replace the shift by a multiplication.
206
	; Unfortunately that means we have to deal with the signed issue again.
207
	;
208
209
	paddw	mm0, MMWORD [CORRECTION(0,0,edx)]   ; correction + roundfactor
210
	paddw	mm1, MMWORD [CORRECTION(0,1,edx)]
211
212
	movq	mm4,mm0   ; store current value for later
213
	movq	mm5,mm1
214
	pmulhw	mm0, MMWORD [RECIPROCAL(0,0,edx)]   ; reciprocal
215
	pmulhw	mm1, MMWORD [RECIPROCAL(0,1,edx)]
216
	paddw	mm0,mm4		; reciprocal is always negative (MSB=1),
217
	paddw	mm1,mm5   ; so we always need to add the initial value
218
	                ; (input value is never negative as we
219
	                ; inverted it at the start of this routine)
220
221
	; here it gets a bit tricky as both scale
222
	; and mm0/mm1 can be negative
223
	movq	mm6, MMWORD [SCALE(0,0,edx)]	; scale
224
	movq	mm7, MMWORD [SCALE(0,1,edx)]
225
	movq	mm4,mm0
226
	movq	mm5,mm1
227
	pmulhw	mm0,mm6
228
	pmulhw	mm1,mm7
229
230
	psraw	mm6,(WORD_BIT-1)    ; determine if scale is negative
231
	psraw	mm7,(WORD_BIT-1)
232
233
	pand	mm6,mm4             ; and add input if it is
234
	pand	mm7,mm5
235
	paddw	mm0,mm6
236
	paddw	mm1,mm7
237
238
	psraw	mm4,(WORD_BIT-1)    ; then check if negative input 
239
	psraw	mm5,(WORD_BIT-1)
240
241
	pand	mm4, MMWORD [SCALE(0,0,edx)]	; and add scale if it is
242
	pand	mm5, MMWORD [SCALE(0,1,edx)]
243
	paddw	mm0,mm4
244
	paddw	mm1,mm5
245
246
	pxor	mm0,mm2   ; val = -val
247
	pxor	mm1,mm3
248
	psubw	mm0,mm2
249
	psubw	mm1,mm3
250
251
	movq	MMWORD [MMBLOCK(0,0,edi,SIZEOF_DCTELEM)], mm0
252
	movq	MMWORD [MMBLOCK(0,1,edi,SIZEOF_DCTELEM)], mm1
253
254
	add	esi, byte 8*SIZEOF_DCTELEM
255
	add	edx, byte 8*SIZEOF_DCTELEM
256
	add	edi, byte 8*SIZEOF_JCOEF
257
	dec	al
258
	jnz	near .quantloop2
259
	dec	ah
260
	jnz	near .quantloop1	; to avoid branch misprediction
261
262
	emms		; empty MMX state
263
264
	pop	edi
265
	pop	esi
266
;	pop	edx		; need not be preserved
267
;	pop	ecx		; unused
268
;	pop	ebx		; unused
269
	pop	ebp
270
	ret
271
272
; For some reason, the OS X linker does not honor the request to align the
273
; segment unless we do this.
274
	align	16
(-)a/jpeg/simd/jcqnts2f-64.asm (+158 lines)
Line     Link Here 
Line 0    Link Here 
1
;
2
; jcqnts2f-64.asm - sample data conversion and quantization (64-bit SSE & SSE2)
3
;
4
; Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
5
; Copyright 2009 D. R. Commander
6
;
7
; Based on
8
; x86 SIMD extension for IJG JPEG library
9
; Copyright (C) 1999-2006, MIYASAKA Masaru.
10
; For conditions of distribution and use, see copyright notice in jsimdext.inc
11
;
12
; This file should be assembled with NASM (Netwide Assembler),
13
; can *not* be assembled with Microsoft's MASM or any compatible
14
; assembler (including Borland's Turbo Assembler).
15
; NASM is available from http://nasm.sourceforge.net/ or
16
; http://sourceforge.net/project/showfiles.php?group_id=6208
17
;
18
; [TAB8]
19
20
%include "jsimdext.inc"
21
%include "jdct.inc"
22
23
; --------------------------------------------------------------------------
24
	SECTION	SEG_TEXT
25
	BITS	64
26
;
27
; Load data into workspace, applying unsigned->signed conversion
28
;
29
; GLOBAL(void)
30
; jsimd_convsamp_float_sse2 (JSAMPARRAY sample_data, JDIMENSION start_col,
31
;                            FAST_FLOAT * workspace);
32
;
33
34
; r10 = JSAMPARRAY sample_data
35
; r11 = JDIMENSION start_col
36
; r12 = FAST_FLOAT * workspace
37
38
	align	16
39
	global	EXTN(jsimd_convsamp_float_sse2)
40
41
EXTN(jsimd_convsamp_float_sse2):
42
	push	rbp
43
	mov	rax,rsp
44
	mov	rbp,rsp
45
	collect_args
46
	push	rbx
47
48
	pcmpeqw  xmm7,xmm7
49
	psllw    xmm7,7
50
	packsswb xmm7,xmm7		; xmm7 = PB_CENTERJSAMPLE (0x808080..)
51
52
	mov rsi, r10
53
	mov	rax, r11
54
	mov rdi, r12
55
	mov	rcx, DCTSIZE/2
56
.convloop:
57
	mov	rbx, JSAMPROW [rsi+0*SIZEOF_JSAMPROW]	; (JSAMPLE *)
58
	mov rdx, JSAMPROW [rsi+1*SIZEOF_JSAMPROW]	; (JSAMPLE *)
59
60
	movq	xmm0, XMM_MMWORD [rbx+rax*SIZEOF_JSAMPLE]
61
	movq	xmm1, XMM_MMWORD [rdx+rax*SIZEOF_JSAMPLE]
62
63
	psubb	xmm0,xmm7			; xmm0=(01234567)
64
	psubb	xmm1,xmm7			; xmm1=(89ABCDEF)
65
66
	punpcklbw xmm0,xmm0			; xmm0=(*0*1*2*3*4*5*6*7)
67
	punpcklbw xmm1,xmm1			; xmm1=(*8*9*A*B*C*D*E*F)
68
69
	punpcklwd xmm2,xmm0			; xmm2=(***0***1***2***3)
70
	punpckhwd xmm0,xmm0			; xmm0=(***4***5***6***7)
71
	punpcklwd xmm3,xmm1			; xmm3=(***8***9***A***B)
72
	punpckhwd xmm1,xmm1			; xmm1=(***C***D***E***F)
73
74
	psrad     xmm2,(DWORD_BIT-BYTE_BIT)	; xmm2=(0123)
75
	psrad     xmm0,(DWORD_BIT-BYTE_BIT)	; xmm0=(4567)
76
	cvtdq2ps  xmm2,xmm2			; xmm2=(0123)
77
	cvtdq2ps  xmm0,xmm0			; xmm0=(4567)
78
	psrad     xmm3,(DWORD_BIT-BYTE_BIT)	; xmm3=(89AB)
79
	psrad     xmm1,(DWORD_BIT-BYTE_BIT)	; xmm1=(CDEF)
80
	cvtdq2ps  xmm3,xmm3			; xmm3=(89AB)
81
	cvtdq2ps  xmm1,xmm1			; xmm1=(CDEF)
82
83
	movaps	XMMWORD [XMMBLOCK(0,0,rdi,SIZEOF_FAST_FLOAT)], xmm2
84
	movaps	XMMWORD [XMMBLOCK(0,1,rdi,SIZEOF_FAST_FLOAT)], xmm0
85
	movaps	XMMWORD [XMMBLOCK(1,0,rdi,SIZEOF_FAST_FLOAT)], xmm3
86
	movaps	XMMWORD [XMMBLOCK(1,1,rdi,SIZEOF_FAST_FLOAT)], xmm1
87
88
	add	rsi, byte 2*SIZEOF_JSAMPROW
89
	add	rdi, byte 2*DCTSIZE*SIZEOF_FAST_FLOAT
90
	dec	rcx
91
	jnz	short .convloop
92
93
	pop	rbx
94
	uncollect_args
95
	pop	rbp
96
	ret
97
98
99
; --------------------------------------------------------------------------
100
;
101
; Quantize/descale the coefficients, and store into coef_block
102
;
103
; GLOBAL(void)
104
; jsimd_quantize_float_sse2 (JCOEFPTR coef_block, FAST_FLOAT * divisors,
105
;                         FAST_FLOAT * workspace);
106
;
107
108
; r10 = JCOEFPTR coef_block
109
; r11 = FAST_FLOAT * divisors
110
; r12 = FAST_FLOAT * workspace
111
112
	align	16
113
	global	EXTN(jsimd_quantize_float_sse2)
114
115
EXTN(jsimd_quantize_float_sse2):
116
	push	rbp
117
	mov	rax,rsp
118
	mov	rbp,rsp
119
	collect_args
120
121
	mov rsi, r12
122
	mov rdx, r11
123
	mov rdi, r10
124
	mov	rax, DCTSIZE2/16
125
.quantloop:
126
	movaps	xmm0, XMMWORD [XMMBLOCK(0,0,rsi,SIZEOF_FAST_FLOAT)]
127
	movaps	xmm1, XMMWORD [XMMBLOCK(0,1,rsi,SIZEOF_FAST_FLOAT)]
128
	mulps	xmm0, XMMWORD [XMMBLOCK(0,0,rdx,SIZEOF_FAST_FLOAT)]
129
	mulps	xmm1, XMMWORD [XMMBLOCK(0,1,rdx,SIZEOF_FAST_FLOAT)]
130
	movaps	xmm2, XMMWORD [XMMBLOCK(1,0,rsi,SIZEOF_FAST_FLOAT)]
131
	movaps	xmm3, XMMWORD [XMMBLOCK(1,1,rsi,SIZEOF_FAST_FLOAT)]
132
	mulps	xmm2, XMMWORD [XMMBLOCK(1,0,rdx,SIZEOF_FAST_FLOAT)]
133
	mulps	xmm3, XMMWORD [XMMBLOCK(1,1,rdx,SIZEOF_FAST_FLOAT)]
134
135
	cvtps2dq xmm0,xmm0
136
	cvtps2dq xmm1,xmm1
137
	cvtps2dq xmm2,xmm2
138
	cvtps2dq xmm3,xmm3
139
140
	packssdw xmm0,xmm1
141
	packssdw xmm2,xmm3
142
143
	movdqa	XMMWORD [XMMBLOCK(0,0,rdi,SIZEOF_JCOEF)], xmm0
144
	movdqa	XMMWORD [XMMBLOCK(1,0,rdi,SIZEOF_JCOEF)], xmm2
145
146
	add	rsi, byte 16*SIZEOF_FAST_FLOAT
147
	add	rdx, byte 16*SIZEOF_FAST_FLOAT
148
	add	rdi, byte 16*SIZEOF_JCOEF
149
	dec	rax
150
	jnz	short .quantloop
151
152
	uncollect_args
153
	pop	rbp
154
	ret
155
156
; For some reason, the OS X linker does not honor the request to align the
157
; segment unless we do this.
158
	align	16
(-)a/jpeg/simd/jcqnts2f.asm (+171 lines)
Line     Link Here 
Line 0    Link Here 
1
;
2
; jcqnts2f.asm - sample data conversion and quantization (SSE & SSE2)
3
;
4
; Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
5
;
6
; Based on
7
; x86 SIMD extension for IJG JPEG library
8
; Copyright (C) 1999-2006, MIYASAKA Masaru.
9
; For conditions of distribution and use, see copyright notice in jsimdext.inc
10
;
11
; This file should be assembled with NASM (Netwide Assembler),
12
; can *not* be assembled with Microsoft's MASM or any compatible
13
; assembler (including Borland's Turbo Assembler).
14
; NASM is available from http://nasm.sourceforge.net/ or
15
; http://sourceforge.net/project/showfiles.php?group_id=6208
16
;
17
; [TAB8]
18
19
%include "jsimdext.inc"
20
%include "jdct.inc"
21
22
; --------------------------------------------------------------------------
23
	SECTION	SEG_TEXT
24
	BITS	32
25
;
26
; Load data into workspace, applying unsigned->signed conversion
27
;
28
; GLOBAL(void)
29
; jsimd_convsamp_float_sse2 (JSAMPARRAY sample_data, JDIMENSION start_col,
30
;                            FAST_FLOAT * workspace);
31
;
32
33
%define sample_data	ebp+8		; JSAMPARRAY sample_data
34
%define start_col	ebp+12		; JDIMENSION start_col
35
%define workspace	ebp+16		; FAST_FLOAT * workspace
36
37
	align	16
38
	global	EXTN(jsimd_convsamp_float_sse2)
39
40
EXTN(jsimd_convsamp_float_sse2):
41
	push	ebp
42
	mov	ebp,esp
43
	push	ebx
44
;	push	ecx		; need not be preserved
45
;	push	edx		; need not be preserved
46
	push	esi
47
	push	edi
48
49
	pcmpeqw  xmm7,xmm7
50
	psllw    xmm7,7
51
	packsswb xmm7,xmm7		; xmm7 = PB_CENTERJSAMPLE (0x808080..)
52
53
	mov	esi, JSAMPARRAY [sample_data]	; (JSAMPROW *)
54
	mov	eax, JDIMENSION [start_col]
55
	mov	edi, POINTER [workspace]	; (DCTELEM *)
56
	mov	ecx, DCTSIZE/2
57
	alignx	16,7
58
.convloop:
59
	mov	ebx, JSAMPROW [esi+0*SIZEOF_JSAMPROW]	; (JSAMPLE *)
60
	mov	edx, JSAMPROW [esi+1*SIZEOF_JSAMPROW]	; (JSAMPLE *)
61
62
	movq	xmm0, XMM_MMWORD [ebx+eax*SIZEOF_JSAMPLE]
63
	movq	xmm1, XMM_MMWORD [edx+eax*SIZEOF_JSAMPLE]
64
65
	psubb	xmm0,xmm7			; xmm0=(01234567)
66
	psubb	xmm1,xmm7			; xmm1=(89ABCDEF)
67
68
	punpcklbw xmm0,xmm0			; xmm0=(*0*1*2*3*4*5*6*7)
69
	punpcklbw xmm1,xmm1			; xmm1=(*8*9*A*B*C*D*E*F)
70
71
	punpcklwd xmm2,xmm0			; xmm2=(***0***1***2***3)
72
	punpckhwd xmm0,xmm0			; xmm0=(***4***5***6***7)
73
	punpcklwd xmm3,xmm1			; xmm3=(***8***9***A***B)
74
	punpckhwd xmm1,xmm1			; xmm1=(***C***D***E***F)
75
76
	psrad     xmm2,(DWORD_BIT-BYTE_BIT)	; xmm2=(0123)
77
	psrad     xmm0,(DWORD_BIT-BYTE_BIT)	; xmm0=(4567)
78
	cvtdq2ps  xmm2,xmm2			; xmm2=(0123)
79
	cvtdq2ps  xmm0,xmm0			; xmm0=(4567)
80
	psrad     xmm3,(DWORD_BIT-BYTE_BIT)	; xmm3=(89AB)
81
	psrad     xmm1,(DWORD_BIT-BYTE_BIT)	; xmm1=(CDEF)
82
	cvtdq2ps  xmm3,xmm3			; xmm3=(89AB)
83
	cvtdq2ps  xmm1,xmm1			; xmm1=(CDEF)
84
85
	movaps	XMMWORD [XMMBLOCK(0,0,edi,SIZEOF_FAST_FLOAT)], xmm2
86
	movaps	XMMWORD [XMMBLOCK(0,1,edi,SIZEOF_FAST_FLOAT)], xmm0
87
	movaps	XMMWORD [XMMBLOCK(1,0,edi,SIZEOF_FAST_FLOAT)], xmm3
88
	movaps	XMMWORD [XMMBLOCK(1,1,edi,SIZEOF_FAST_FLOAT)], xmm1
89
90
	add	esi, byte 2*SIZEOF_JSAMPROW
91
	add	edi, byte 2*DCTSIZE*SIZEOF_FAST_FLOAT
92
	dec	ecx
93
	jnz	short .convloop
94
95
	pop	edi
96
	pop	esi
97
;	pop	edx		; need not be preserved
98
;	pop	ecx		; need not be preserved
99
	pop	ebx
100
	pop	ebp
101
	ret
102
103
104
; --------------------------------------------------------------------------
105
;
106
; Quantize/descale the coefficients, and store into coef_block
107
;
108
; GLOBAL(void)
109
; jsimd_quantize_float_sse2 (JCOEFPTR coef_block, FAST_FLOAT * divisors,
110
;                         FAST_FLOAT * workspace);
111
;
112
113
%define coef_block	ebp+8		; JCOEFPTR coef_block
114
%define divisors	ebp+12		; FAST_FLOAT * divisors
115
%define workspace	ebp+16		; FAST_FLOAT * workspace
116
117
	align	16
118
	global	EXTN(jsimd_quantize_float_sse2)
119
120
EXTN(jsimd_quantize_float_sse2):
121
	push	ebp
122
	mov	ebp,esp
123
;	push	ebx		; unused
124
;	push	ecx		; unused
125
;	push	edx		; need not be preserved
126
	push	esi
127
	push	edi
128
129
	mov	esi, POINTER [workspace]
130
	mov	edx, POINTER [divisors]
131
	mov	edi, JCOEFPTR [coef_block]
132
	mov	eax, DCTSIZE2/16
133
	alignx	16,7
134
.quantloop:
135
	movaps	xmm0, XMMWORD [XMMBLOCK(0,0,esi,SIZEOF_FAST_FLOAT)]
136
	movaps	xmm1, XMMWORD [XMMBLOCK(0,1,esi,SIZEOF_FAST_FLOAT)]
137
	mulps	xmm0, XMMWORD [XMMBLOCK(0,0,edx,SIZEOF_FAST_FLOAT)]
138
	mulps	xmm1, XMMWORD [XMMBLOCK(0,1,edx,SIZEOF_FAST_FLOAT)]
139
	movaps	xmm2, XMMWORD [XMMBLOCK(1,0,esi,SIZEOF_FAST_FLOAT)]
140
	movaps	xmm3, XMMWORD [XMMBLOCK(1,1,esi,SIZEOF_FAST_FLOAT)]
141
	mulps	xmm2, XMMWORD [XMMBLOCK(1,0,edx,SIZEOF_FAST_FLOAT)]
142
	mulps	xmm3, XMMWORD [XMMBLOCK(1,1,edx,SIZEOF_FAST_FLOAT)]
143
144
	cvtps2dq xmm0,xmm0
145
	cvtps2dq xmm1,xmm1
146
	cvtps2dq xmm2,xmm2
147
	cvtps2dq xmm3,xmm3
148
149
	packssdw xmm0,xmm1
150
	packssdw xmm2,xmm3
151
152
	movdqa	XMMWORD [XMMBLOCK(0,0,edi,SIZEOF_JCOEF)], xmm0
153
	movdqa	XMMWORD [XMMBLOCK(1,0,edi,SIZEOF_JCOEF)], xmm2
154
155
	add	esi, byte 16*SIZEOF_FAST_FLOAT
156
	add	edx, byte 16*SIZEOF_FAST_FLOAT
157
	add	edi, byte 16*SIZEOF_JCOEF
158
	dec	eax
159
	jnz	short .quantloop
160
161
	pop	edi
162
	pop	esi
163
;	pop	edx		; need not be preserved
164
;	pop	ecx		; unused
165
;	pop	ebx		; unused
166
	pop	ebp
167
	ret
168
169
; For some reason, the OS X linker does not honor the request to align the
170
; segment unless we do this.
171
	align	16
(-)a/jpeg/simd/jcqnts2i-64.asm (+187 lines)
Line     Link Here 
Line 0    Link Here 
1
;
2
; jcqnts2i-64.asm - sample data conversion and quantization (64-bit SSE2)
3
;
4
; Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
5
; Copyright 2009 D. R. Commander
6
;
7
; Based on
8
; x86 SIMD extension for IJG JPEG library
9
; Copyright (C) 1999-2006, MIYASAKA Masaru.
10
; For conditions of distribution and use, see copyright notice in jsimdext.inc
11
;
12
; This file should be assembled with NASM (Netwide Assembler),
13
; can *not* be assembled with Microsoft's MASM or any compatible
14
; assembler (including Borland's Turbo Assembler).
15
; NASM is available from http://nasm.sourceforge.net/ or
16
; http://sourceforge.net/project/showfiles.php?group_id=6208
17
;
18
; [TAB8]
19
20
%include "jsimdext.inc"
21
%include "jdct.inc"
22
23
; --------------------------------------------------------------------------
24
	SECTION	SEG_TEXT
25
	BITS	64
26
;
27
; Load data into workspace, applying unsigned->signed conversion
28
;
29
; GLOBAL(void)
30
; jsimd_convsamp_sse2 (JSAMPARRAY sample_data, JDIMENSION start_col,
31
;                      DCTELEM * workspace);
32
;
33
34
; r10 = JSAMPARRAY sample_data
35
; r11 = JDIMENSION start_col
36
; r12 = DCTELEM * workspace
37
38
	align	16
39
	global	EXTN(jsimd_convsamp_sse2)
40
41
EXTN(jsimd_convsamp_sse2):
42
	push	rbp
43
	mov	rax,rsp
44
	mov	rbp,rsp
45
	collect_args
46
	push	rbx
47
48
	pxor	xmm6,xmm6		; xmm6=(all 0's)
49
	pcmpeqw	xmm7,xmm7
50
	psllw	xmm7,7			; xmm7={0xFF80 0xFF80 0xFF80 0xFF80 ..}
51
52
	mov rsi, r10
53
	mov rax, r11
54
	mov rdi, r12
55
	mov	rcx, DCTSIZE/4
56
.convloop:
57
	mov	rbx, JSAMPROW [rsi+0*SIZEOF_JSAMPROW]	; (JSAMPLE *)
58
	mov rdx, JSAMPROW [rsi+1*SIZEOF_JSAMPROW]	; (JSAMPLE *)
59
60
	movq	xmm0, XMM_MMWORD [rbx+rax*SIZEOF_JSAMPLE]	; xmm0=(01234567)
61
	movq	xmm1, XMM_MMWORD [rdx+rax*SIZEOF_JSAMPLE]	; xmm1=(89ABCDEF)
62
63
	mov	rbx, JSAMPROW [rsi+2*SIZEOF_JSAMPROW]	; (JSAMPLE *)
64
	mov	rdx, JSAMPROW [rsi+3*SIZEOF_JSAMPROW]	; (JSAMPLE *)
65
66
	movq	xmm2, XMM_MMWORD [rbx+rax*SIZEOF_JSAMPLE]	; xmm2=(GHIJKLMN)
67
	movq	xmm3, XMM_MMWORD [rdx+rax*SIZEOF_JSAMPLE]	; xmm3=(OPQRSTUV)
68
69
	punpcklbw xmm0,xmm6		; xmm0=(01234567)
70
	punpcklbw xmm1,xmm6		; xmm1=(89ABCDEF)
71
	paddw     xmm0,xmm7
72
	paddw     xmm1,xmm7
73
	punpcklbw xmm2,xmm6		; xmm2=(GHIJKLMN)
74
	punpcklbw xmm3,xmm6		; xmm3=(OPQRSTUV)
75
	paddw     xmm2,xmm7
76
	paddw     xmm3,xmm7
77
78
	movdqa	XMMWORD [XMMBLOCK(0,0,rdi,SIZEOF_DCTELEM)], xmm0
79
	movdqa	XMMWORD [XMMBLOCK(1,0,rdi,SIZEOF_DCTELEM)], xmm1
80
	movdqa	XMMWORD [XMMBLOCK(2,0,rdi,SIZEOF_DCTELEM)], xmm2
81
	movdqa	XMMWORD [XMMBLOCK(3,0,rdi,SIZEOF_DCTELEM)], xmm3
82
83
	add	rsi, byte 4*SIZEOF_JSAMPROW
84
	add	rdi, byte 4*DCTSIZE*SIZEOF_DCTELEM
85
	dec	rcx
86
	jnz	short .convloop
87
88
	pop	rbx
89
	uncollect_args
90
	pop	rbp
91
	ret
92
93
; --------------------------------------------------------------------------
94
;
95
; Quantize/descale the coefficients, and store into coef_block
96
;
97
; This implementation is based on an algorithm described in
98
;   "How to optimize for the Pentium family of microprocessors"
99
;   (http://www.agner.org/assem/).
100
;
101
; GLOBAL(void)
102
; jsimd_quantize_sse2 (JCOEFPTR coef_block, DCTELEM * divisors,
103
;                      DCTELEM * workspace);
104
;
105
106
%define RECIPROCAL(m,n,b) XMMBLOCK(DCTSIZE*0+(m),(n),(b),SIZEOF_DCTELEM)
107
%define CORRECTION(m,n,b) XMMBLOCK(DCTSIZE*1+(m),(n),(b),SIZEOF_DCTELEM)
108
%define SCALE(m,n,b)      XMMBLOCK(DCTSIZE*2+(m),(n),(b),SIZEOF_DCTELEM)
109
110
; r10 = JCOEFPTR coef_block
111
; r11 = DCTELEM * divisors
112
; r12 = DCTELEM * workspace
113
114
	align	16
115
	global	EXTN(jsimd_quantize_sse2)
116
117
EXTN(jsimd_quantize_sse2):
118
	push	rbp
119
	mov	rax,rsp
120
	mov	rbp,rsp
121
	collect_args
122
123
	mov rsi, r12
124
	mov rdx, r11
125
	mov rdi, r10
126
	mov	rax, DCTSIZE2/32
127
.quantloop:
128
	movdqa	xmm4, XMMWORD [XMMBLOCK(0,0,rsi,SIZEOF_DCTELEM)]
129
	movdqa	xmm5, XMMWORD [XMMBLOCK(1,0,rsi,SIZEOF_DCTELEM)]
130
	movdqa	xmm6, XMMWORD [XMMBLOCK(2,0,rsi,SIZEOF_DCTELEM)]
131
	movdqa	xmm7, XMMWORD [XMMBLOCK(3,0,rsi,SIZEOF_DCTELEM)]
132
	movdqa	xmm0,xmm4
133
	movdqa	xmm1,xmm5
134
	movdqa	xmm2,xmm6
135
	movdqa	xmm3,xmm7
136
	psraw	xmm4,(WORD_BIT-1)
137
	psraw	xmm5,(WORD_BIT-1)
138
	psraw	xmm6,(WORD_BIT-1)
139
	psraw	xmm7,(WORD_BIT-1)
140
	pxor	xmm0,xmm4
141
	pxor	xmm1,xmm5
142
	pxor	xmm2,xmm6
143
	pxor	xmm3,xmm7
144
	psubw	xmm0,xmm4		; if (xmm0 < 0) xmm0 = -xmm0;
145
	psubw	xmm1,xmm5		; if (xmm1 < 0) xmm1 = -xmm1;
146
	psubw	xmm2,xmm6		; if (xmm2 < 0) xmm2 = -xmm2;
147
	psubw	xmm3,xmm7		; if (xmm3 < 0) xmm3 = -xmm3;
148
149
	paddw	xmm0, XMMWORD [CORRECTION(0,0,rdx)]  ; correction + roundfactor
150
	paddw	xmm1, XMMWORD [CORRECTION(1,0,rdx)]
151
	paddw	xmm2, XMMWORD [CORRECTION(2,0,rdx)]
152
	paddw	xmm3, XMMWORD [CORRECTION(3,0,rdx)]
153
	pmulhuw	xmm0, XMMWORD [RECIPROCAL(0,0,rdx)]  ; reciprocal
154
	pmulhuw	xmm1, XMMWORD [RECIPROCAL(1,0,rdx)]
155
	pmulhuw	xmm2, XMMWORD [RECIPROCAL(2,0,rdx)]
156
	pmulhuw	xmm3, XMMWORD [RECIPROCAL(3,0,rdx)]
157
	pmulhuw	xmm0, XMMWORD [SCALE(0,0,rdx)]	; scale
158
	pmulhuw	xmm1, XMMWORD [SCALE(1,0,rdx)]
159
	pmulhuw	xmm2, XMMWORD [SCALE(2,0,rdx)]
160
	pmulhuw	xmm3, XMMWORD [SCALE(3,0,rdx)]
161
162
	pxor	xmm0,xmm4
163
	pxor	xmm1,xmm5
164
	pxor	xmm2,xmm6
165
	pxor	xmm3,xmm7
166
	psubw	xmm0,xmm4
167
	psubw	xmm1,xmm5
168
	psubw	xmm2,xmm6
169
	psubw	xmm3,xmm7
170
	movdqa	XMMWORD [XMMBLOCK(0,0,rdi,SIZEOF_DCTELEM)], xmm0
171
	movdqa	XMMWORD [XMMBLOCK(1,0,rdi,SIZEOF_DCTELEM)], xmm1
172
	movdqa	XMMWORD [XMMBLOCK(2,0,rdi,SIZEOF_DCTELEM)], xmm2
173
	movdqa	XMMWORD [XMMBLOCK(3,0,rdi,SIZEOF_DCTELEM)], xmm3
174
175
	add	rsi, byte 32*SIZEOF_DCTELEM
176
	add	rdx, byte 32*SIZEOF_DCTELEM
177
	add	rdi, byte 32*SIZEOF_JCOEF
178
	dec	rax
179
	jnz	near .quantloop
180
181
	uncollect_args
182
	pop	rbp
183
	ret
184
185
; For some reason, the OS X linker does not honor the request to align the
186
; segment unless we do this.
187
	align	16
(-)a/jpeg/simd/jcqnts2i.asm (+200 lines)
Line     Link Here 
Line 0    Link Here 
1
;
2
; jcqnts2i.asm - sample data conversion and quantization (SSE2)
3
;
4
; Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
5
;
6
; Based on
7
; x86 SIMD extension for IJG JPEG library
8
; Copyright (C) 1999-2006, MIYASAKA Masaru.
9
; For conditions of distribution and use, see copyright notice in jsimdext.inc
10
;
11
; This file should be assembled with NASM (Netwide Assembler),
12
; can *not* be assembled with Microsoft's MASM or any compatible
13
; assembler (including Borland's Turbo Assembler).
14
; NASM is available from http://nasm.sourceforge.net/ or
15
; http://sourceforge.net/project/showfiles.php?group_id=6208
16
;
17
; [TAB8]
18
19
%include "jsimdext.inc"
20
%include "jdct.inc"
21
22
; --------------------------------------------------------------------------
23
	SECTION	SEG_TEXT
24
	BITS	32
25
;
26
; Load data into workspace, applying unsigned->signed conversion
27
;
28
; GLOBAL(void)
29
; jsimd_convsamp_sse2 (JSAMPARRAY sample_data, JDIMENSION start_col,
30
;                      DCTELEM * workspace);
31
;
32
33
%define sample_data	ebp+8		; JSAMPARRAY sample_data
34
%define start_col	ebp+12		; JDIMENSION start_col
35
%define workspace	ebp+16		; DCTELEM * workspace
36
37
	align	16
38
	global	EXTN(jsimd_convsamp_sse2)
39
40
EXTN(jsimd_convsamp_sse2):
41
	push	ebp
42
	mov	ebp,esp
43
	push	ebx
44
;	push	ecx		; need not be preserved
45
;	push	edx		; need not be preserved
46
	push	esi
47
	push	edi
48
49
	pxor	xmm6,xmm6		; xmm6=(all 0's)
50
	pcmpeqw	xmm7,xmm7
51
	psllw	xmm7,7			; xmm7={0xFF80 0xFF80 0xFF80 0xFF80 ..}
52
53
	mov	esi, JSAMPARRAY [sample_data]	; (JSAMPROW *)
54
	mov	eax, JDIMENSION [start_col]
55
	mov	edi, POINTER [workspace]	; (DCTELEM *)
56
	mov	ecx, DCTSIZE/4
57
	alignx	16,7
58
.convloop:
59
	mov	ebx, JSAMPROW [esi+0*SIZEOF_JSAMPROW]	; (JSAMPLE *)
60
	mov	edx, JSAMPROW [esi+1*SIZEOF_JSAMPROW]	; (JSAMPLE *)
61
62
	movq	xmm0, XMM_MMWORD [ebx+eax*SIZEOF_JSAMPLE]	; xmm0=(01234567)
63
	movq	xmm1, XMM_MMWORD [edx+eax*SIZEOF_JSAMPLE]	; xmm1=(89ABCDEF)
64
65
	mov	ebx, JSAMPROW [esi+2*SIZEOF_JSAMPROW]	; (JSAMPLE *)
66
	mov	edx, JSAMPROW [esi+3*SIZEOF_JSAMPROW]	; (JSAMPLE *)
67
68
	movq	xmm2, XMM_MMWORD [ebx+eax*SIZEOF_JSAMPLE]	; xmm2=(GHIJKLMN)
69
	movq	xmm3, XMM_MMWORD [edx+eax*SIZEOF_JSAMPLE]	; xmm3=(OPQRSTUV)
70
71
	punpcklbw xmm0,xmm6		; xmm0=(01234567)
72
	punpcklbw xmm1,xmm6		; xmm1=(89ABCDEF)
73
	paddw     xmm0,xmm7
74
	paddw     xmm1,xmm7
75
	punpcklbw xmm2,xmm6		; xmm2=(GHIJKLMN)
76
	punpcklbw xmm3,xmm6		; xmm3=(OPQRSTUV)
77
	paddw     xmm2,xmm7
78
	paddw     xmm3,xmm7
79
80
	movdqa	XMMWORD [XMMBLOCK(0,0,edi,SIZEOF_DCTELEM)], xmm0
81
	movdqa	XMMWORD [XMMBLOCK(1,0,edi,SIZEOF_DCTELEM)], xmm1
82
	movdqa	XMMWORD [XMMBLOCK(2,0,edi,SIZEOF_DCTELEM)], xmm2
83
	movdqa	XMMWORD [XMMBLOCK(3,0,edi,SIZEOF_DCTELEM)], xmm3
84
85
	add	esi, byte 4*SIZEOF_JSAMPROW
86
	add	edi, byte 4*DCTSIZE*SIZEOF_DCTELEM
87
	dec	ecx
88
	jnz	short .convloop
89
90
	pop	edi
91
	pop	esi
92
;	pop	edx		; need not be preserved
93
;	pop	ecx		; need not be preserved
94
	pop	ebx
95
	pop	ebp
96
	ret
97
98
; --------------------------------------------------------------------------
99
;
100
; Quantize/descale the coefficients, and store into coef_block
101
;
102
; This implementation is based on an algorithm described in
103
;   "How to optimize for the Pentium family of microprocessors"
104
;   (http://www.agner.org/assem/).
105
;
106
; GLOBAL(void)
107
; jsimd_quantize_sse2 (JCOEFPTR coef_block, DCTELEM * divisors,
108
;                      DCTELEM * workspace);
109
;
110
111
%define RECIPROCAL(m,n,b) XMMBLOCK(DCTSIZE*0+(m),(n),(b),SIZEOF_DCTELEM)
112
%define CORRECTION(m,n,b) XMMBLOCK(DCTSIZE*1+(m),(n),(b),SIZEOF_DCTELEM)
113
%define SCALE(m,n,b)      XMMBLOCK(DCTSIZE*2+(m),(n),(b),SIZEOF_DCTELEM)
114
115
%define coef_block	ebp+8		; JCOEFPTR coef_block
116
%define divisors	ebp+12		; DCTELEM * divisors
117
%define workspace	ebp+16		; DCTELEM * workspace
118
119
	align	16
120
	global	EXTN(jsimd_quantize_sse2)
121
122
EXTN(jsimd_quantize_sse2):
123
	push	ebp
124
	mov	ebp,esp
125
;	push	ebx		; unused
126
;	push	ecx		; unused
127
;	push	edx		; need not be preserved
128
	push	esi
129
	push	edi
130
131
	mov	esi, POINTER [workspace]
132
	mov	edx, POINTER [divisors]
133
	mov	edi, JCOEFPTR [coef_block]
134
	mov	eax, DCTSIZE2/32
135
	alignx	16,7
136
.quantloop:
137
	movdqa	xmm4, XMMWORD [XMMBLOCK(0,0,esi,SIZEOF_DCTELEM)]
138
	movdqa	xmm5, XMMWORD [XMMBLOCK(1,0,esi,SIZEOF_DCTELEM)]
139
	movdqa	xmm6, XMMWORD [XMMBLOCK(2,0,esi,SIZEOF_DCTELEM)]
140
	movdqa	xmm7, XMMWORD [XMMBLOCK(3,0,esi,SIZEOF_DCTELEM)]
141
	movdqa	xmm0,xmm4
142
	movdqa	xmm1,xmm5
143
	movdqa	xmm2,xmm6
144
	movdqa	xmm3,xmm7
145
	psraw	xmm4,(WORD_BIT-1)
146
	psraw	xmm5,(WORD_BIT-1)
147
	psraw	xmm6,(WORD_BIT-1)
148
	psraw	xmm7,(WORD_BIT-1)
149
	pxor	xmm0,xmm4
150
	pxor	xmm1,xmm5
151
	pxor	xmm2,xmm6
152
	pxor	xmm3,xmm7
153
	psubw	xmm0,xmm4		; if (xmm0 < 0) xmm0 = -xmm0;
154
	psubw	xmm1,xmm5		; if (xmm1 < 0) xmm1 = -xmm1;
155
	psubw	xmm2,xmm6		; if (xmm2 < 0) xmm2 = -xmm2;
156
	psubw	xmm3,xmm7		; if (xmm3 < 0) xmm3 = -xmm3;
157
158
	paddw	xmm0, XMMWORD [CORRECTION(0,0,edx)]  ; correction + roundfactor
159
	paddw	xmm1, XMMWORD [CORRECTION(1,0,edx)]
160
	paddw	xmm2, XMMWORD [CORRECTION(2,0,edx)]
161
	paddw	xmm3, XMMWORD [CORRECTION(3,0,edx)]
162
	pmulhuw	xmm0, XMMWORD [RECIPROCAL(0,0,edx)]  ; reciprocal
163
	pmulhuw	xmm1, XMMWORD [RECIPROCAL(1,0,edx)]
164
	pmulhuw	xmm2, XMMWORD [RECIPROCAL(2,0,edx)]
165
	pmulhuw	xmm3, XMMWORD [RECIPROCAL(3,0,edx)]
166
	pmulhuw	xmm0, XMMWORD [SCALE(0,0,edx)]	; scale
167
	pmulhuw	xmm1, XMMWORD [SCALE(1,0,edx)]
168
	pmulhuw	xmm2, XMMWORD [SCALE(2,0,edx)]
169
	pmulhuw	xmm3, XMMWORD [SCALE(3,0,edx)]
170
171
	pxor	xmm0,xmm4
172
	pxor	xmm1,xmm5
173
	pxor	xmm2,xmm6
174
	pxor	xmm3,xmm7
175
	psubw	xmm0,xmm4
176
	psubw	xmm1,xmm5
177
	psubw	xmm2,xmm6
178
	psubw	xmm3,xmm7
179
	movdqa	XMMWORD [XMMBLOCK(0,0,edi,SIZEOF_DCTELEM)], xmm0
180
	movdqa	XMMWORD [XMMBLOCK(1,0,edi,SIZEOF_DCTELEM)], xmm1
181
	movdqa	XMMWORD [XMMBLOCK(2,0,edi,SIZEOF_DCTELEM)], xmm2
182
	movdqa	XMMWORD [XMMBLOCK(3,0,edi,SIZEOF_DCTELEM)], xmm3
183
184
	add	esi, byte 32*SIZEOF_DCTELEM
185
	add	edx, byte 32*SIZEOF_DCTELEM
186
	add	edi, byte 32*SIZEOF_JCOEF
187
	dec	eax
188
	jnz	near .quantloop
189
190
	pop	edi
191
	pop	esi
192
;	pop	edx		; need not be preserved
193
;	pop	ecx		; unused
194
;	pop	ebx		; unused
195
	pop	ebp
196
	ret
197
198
; For some reason, the OS X linker does not honor the request to align the
199
; segment unless we do this.
200
	align	16
(-)a/jpeg/simd/jcqntsse.asm (+211 lines)
Line     Link Here 
Line 0    Link Here 
1
;
2
; jcqntsse.asm - sample data conversion and quantization (SSE & MMX)
3
;
4
; Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
5
;
6
; Based on
7
; x86 SIMD extension for IJG JPEG library
8
; Copyright (C) 1999-2006, MIYASAKA Masaru.
9
; For conditions of distribution and use, see copyright notice in jsimdext.inc
10
;
11
; This file should be assembled with NASM (Netwide Assembler),
12
; can *not* be assembled with Microsoft's MASM or any compatible
13
; assembler (including Borland's Turbo Assembler).
14
; NASM is available from http://nasm.sourceforge.net/ or
15
; http://sourceforge.net/project/showfiles.php?group_id=6208
16
;
17
; [TAB8]
18
19
%include "jsimdext.inc"
20
%include "jdct.inc"
21
22
; --------------------------------------------------------------------------
23
	SECTION	SEG_TEXT
24
	BITS	32
25
;
26
; Load data into workspace, applying unsigned->signed conversion
27
;
28
; GLOBAL(void)
29
; jsimd_convsamp_float_sse (JSAMPARRAY sample_data, JDIMENSION start_col,
30
;                           FAST_FLOAT * workspace);
31
;
32
33
%define sample_data	ebp+8		; JSAMPARRAY sample_data
34
%define start_col	ebp+12		; JDIMENSION start_col
35
%define workspace	ebp+16		; FAST_FLOAT * workspace
36
37
	align	16
38
	global	EXTN(jsimd_convsamp_float_sse)
39
40
EXTN(jsimd_convsamp_float_sse):
41
	push	ebp
42
	mov	ebp,esp
43
	push	ebx
44
;	push	ecx		; need not be preserved
45
;	push	edx		; need not be preserved
46
	push	esi
47
	push	edi
48
49
	pcmpeqw  mm7,mm7
50
	psllw    mm7,7
51
	packsswb mm7,mm7		; mm7 = PB_CENTERJSAMPLE (0x808080..)
52
53
	mov	esi, JSAMPARRAY [sample_data]	; (JSAMPROW *)
54
	mov	eax, JDIMENSION [start_col]
55
	mov	edi, POINTER [workspace]	; (DCTELEM *)
56
	mov	ecx, DCTSIZE/2
57
	alignx	16,7
58
.convloop:
59
	mov	ebx, JSAMPROW [esi+0*SIZEOF_JSAMPROW]	; (JSAMPLE *)
60
	mov	edx, JSAMPROW [esi+1*SIZEOF_JSAMPROW]	; (JSAMPLE *)
61
62
	movq	mm0, MMWORD [ebx+eax*SIZEOF_JSAMPLE]
63
	movq	mm1, MMWORD [edx+eax*SIZEOF_JSAMPLE]
64
65
	psubb	mm0,mm7				; mm0=(01234567)
66
	psubb	mm1,mm7				; mm1=(89ABCDEF)
67
68
	punpcklbw mm2,mm0			; mm2=(*0*1*2*3)
69
	punpckhbw mm0,mm0			; mm0=(*4*5*6*7)
70
	punpcklbw mm3,mm1			; mm3=(*8*9*A*B)
71
	punpckhbw mm1,mm1			; mm1=(*C*D*E*F)
72
73
	punpcklwd mm4,mm2			; mm4=(***0***1)
74
	punpckhwd mm2,mm2			; mm2=(***2***3)
75
	punpcklwd mm5,mm0			; mm5=(***4***5)
76
	punpckhwd mm0,mm0			; mm0=(***6***7)
77
78
	psrad     mm4,(DWORD_BIT-BYTE_BIT)	; mm4=(01)
79
	psrad     mm2,(DWORD_BIT-BYTE_BIT)	; mm2=(23)
80
	cvtpi2ps  xmm0,mm4			; xmm0=(01**)
81
	cvtpi2ps  xmm1,mm2			; xmm1=(23**)
82
	psrad     mm5,(DWORD_BIT-BYTE_BIT)	; mm5=(45)
83
	psrad     mm0,(DWORD_BIT-BYTE_BIT)	; mm0=(67)
84
	cvtpi2ps  xmm2,mm5			; xmm2=(45**)
85
	cvtpi2ps  xmm3,mm0			; xmm3=(67**)
86
87
	punpcklwd mm6,mm3			; mm6=(***8***9)
88
	punpckhwd mm3,mm3			; mm3=(***A***B)
89
	punpcklwd mm4,mm1			; mm4=(***C***D)
90
	punpckhwd mm1,mm1			; mm1=(***E***F)
91
92
	psrad     mm6,(DWORD_BIT-BYTE_BIT)	; mm6=(89)
93
	psrad     mm3,(DWORD_BIT-BYTE_BIT)	; mm3=(AB)
94
	cvtpi2ps  xmm4,mm6			; xmm4=(89**)
95
	cvtpi2ps  xmm5,mm3			; xmm5=(AB**)
96
	psrad     mm4,(DWORD_BIT-BYTE_BIT)	; mm4=(CD)
97
	psrad     mm1,(DWORD_BIT-BYTE_BIT)	; mm1=(EF)
98
	cvtpi2ps  xmm6,mm4			; xmm6=(CD**)
99
	cvtpi2ps  xmm7,mm1			; xmm7=(EF**)
100
101
	movlhps   xmm0,xmm1			; xmm0=(0123)
102
	movlhps   xmm2,xmm3			; xmm2=(4567)
103
	movlhps   xmm4,xmm5			; xmm4=(89AB)
104
	movlhps   xmm6,xmm7			; xmm6=(CDEF)
105
106
	movaps	XMMWORD [XMMBLOCK(0,0,edi,SIZEOF_FAST_FLOAT)], xmm0
107
	movaps	XMMWORD [XMMBLOCK(0,1,edi,SIZEOF_FAST_FLOAT)], xmm2
108
	movaps	XMMWORD [XMMBLOCK(1,0,edi,SIZEOF_FAST_FLOAT)], xmm4
109
	movaps	XMMWORD [XMMBLOCK(1,1,edi,SIZEOF_FAST_FLOAT)], xmm6
110
111
	add	esi, byte 2*SIZEOF_JSAMPROW
112
	add	edi, byte 2*DCTSIZE*SIZEOF_FAST_FLOAT
113
	dec	ecx
114
	jnz	near .convloop
115
116
	emms		; empty MMX state
117
118
	pop	edi
119
	pop	esi
120
;	pop	edx		; need not be preserved
121
;	pop	ecx		; need not be preserved
122
	pop	ebx
123
	pop	ebp
124
	ret
125
126
127
; --------------------------------------------------------------------------
128
;
129
; Quantize/descale the coefficients, and store into coef_block
130
;
131
; GLOBAL(void)
132
; jsimd_quantize_float_sse (JCOEFPTR coef_block, FAST_FLOAT * divisors,
133
;                           FAST_FLOAT * workspace);
134
;
135
136
%define coef_block	ebp+8		; JCOEFPTR coef_block
137
%define divisors	ebp+12		; FAST_FLOAT * divisors
138
%define workspace	ebp+16		; FAST_FLOAT * workspace
139
140
	align	16
141
	global	EXTN(jsimd_quantize_float_sse)
142
143
EXTN(jsimd_quantize_float_sse):
144
	push	ebp
145
	mov	ebp,esp
146
;	push	ebx		; unused
147
;	push	ecx		; unused
148
;	push	edx		; need not be preserved
149
	push	esi
150
	push	edi
151
152
	mov	esi, POINTER [workspace]
153
	mov	edx, POINTER [divisors]
154
	mov	edi, JCOEFPTR [coef_block]
155
	mov	eax, DCTSIZE2/16
156
	alignx	16,7
157
.quantloop:
158
	movaps	xmm0, XMMWORD [XMMBLOCK(0,0,esi,SIZEOF_FAST_FLOAT)]
159
	movaps	xmm1, XMMWORD [XMMBLOCK(0,1,esi,SIZEOF_FAST_FLOAT)]
160
	mulps	xmm0, XMMWORD [XMMBLOCK(0,0,edx,SIZEOF_FAST_FLOAT)]
161
	mulps	xmm1, XMMWORD [XMMBLOCK(0,1,edx,SIZEOF_FAST_FLOAT)]
162
	movaps	xmm2, XMMWORD [XMMBLOCK(1,0,esi,SIZEOF_FAST_FLOAT)]
163
	movaps	xmm3, XMMWORD [XMMBLOCK(1,1,esi,SIZEOF_FAST_FLOAT)]
164
	mulps	xmm2, XMMWORD [XMMBLOCK(1,0,edx,SIZEOF_FAST_FLOAT)]
165
	mulps	xmm3, XMMWORD [XMMBLOCK(1,1,edx,SIZEOF_FAST_FLOAT)]
166
167
	movhlps  xmm4,xmm0
168
	movhlps  xmm5,xmm1
169
170
	cvtps2pi mm0,xmm0
171
	cvtps2pi mm1,xmm1
172
	cvtps2pi mm4,xmm4
173
	cvtps2pi mm5,xmm5
174
175
	movhlps  xmm6,xmm2
176
	movhlps  xmm7,xmm3
177
178
	cvtps2pi mm2,xmm2
179
	cvtps2pi mm3,xmm3
180
	cvtps2pi mm6,xmm6
181
	cvtps2pi mm7,xmm7
182
183
	packssdw mm0,mm4
184
	packssdw mm1,mm5
185
	packssdw mm2,mm6
186
	packssdw mm3,mm7
187
188
	movq	MMWORD [MMBLOCK(0,0,edi,SIZEOF_JCOEF)], mm0
189
	movq	MMWORD [MMBLOCK(0,1,edi,SIZEOF_JCOEF)], mm1
190
	movq	MMWORD [MMBLOCK(1,0,edi,SIZEOF_JCOEF)], mm2
191
	movq	MMWORD [MMBLOCK(1,1,edi,SIZEOF_JCOEF)], mm3
192
193
	add	esi, byte 16*SIZEOF_FAST_FLOAT
194
	add	edx, byte 16*SIZEOF_FAST_FLOAT
195
	add	edi, byte 16*SIZEOF_JCOEF
196
	dec	eax
197
	jnz	short .quantloop
198
199
	emms		; empty MMX state
200
201
	pop	edi
202
	pop	esi
203
;	pop	edx		; need not be preserved
204
;	pop	ecx		; unused
205
;	pop	ebx		; unused
206
	pop	ebp
207
	ret
208
209
; For some reason, the OS X linker does not honor the request to align the
210
; segment unless we do this.
211
	align	16
(-)a/jpeg/simd/jcsammmx.asm (+324 lines)
Line     Link Here 
Line 0    Link Here 
1
;
2
; jcsammmx.asm - downsampling (MMX)
3
;
4
; Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
5
;
6
; Based on
7
; x86 SIMD extension for IJG JPEG library
8
; Copyright (C) 1999-2006, MIYASAKA Masaru.
9
; For conditions of distribution and use, see copyright notice in jsimdext.inc
10
;
11
; This file should be assembled with NASM (Netwide Assembler),
12
; can *not* be assembled with Microsoft's MASM or any compatible
13
; assembler (including Borland's Turbo Assembler).
14
; NASM is available from http://nasm.sourceforge.net/ or
15
; http://sourceforge.net/project/showfiles.php?group_id=6208
16
;
17
; [TAB8]
18
19
%include "jsimdext.inc"
20
21
; --------------------------------------------------------------------------
22
	SECTION	SEG_TEXT
23
	BITS	32
24
;
25
; Downsample pixel values of a single component.
26
; This version handles the common case of 2:1 horizontal and 1:1 vertical,
27
; without smoothing.
28
;
29
; GLOBAL(void)
30
; jsimd_h2v1_downsample_mmx (JDIMENSION image_width, int max_v_samp_factor,
31
;                            JDIMENSION v_samp_factor, JDIMENSION width_blocks,
32
;                            JSAMPARRAY input_data, JSAMPARRAY output_data);
33
;
34
35
%define img_width(b)	(b)+8			; JDIMENSION image_width
36
%define max_v_samp(b)	(b)+12		; int max_v_samp_factor
37
%define v_samp(b)			(b)+16		; JDIMENSION v_samp_factor
38
%define width_blks(b)	(b)+20		; JDIMENSION width_blocks
39
%define input_data(b)	(b)+24		; JSAMPARRAY input_data
40
%define output_data(b)	(b)+28	; JSAMPARRAY output_data
41
42
	align	16
43
	global	EXTN(jsimd_h2v1_downsample_mmx)
44
45
EXTN(jsimd_h2v1_downsample_mmx):
46
	push	ebp
47
	mov	ebp,esp
48
;	push	ebx		; unused
49
;	push	ecx		; need not be preserved
50
;	push	edx		; need not be preserved
51
	push	esi
52
	push	edi
53
54
	mov	ecx, JDIMENSION [width_blks(ebp)]
55
	shl	ecx,3			; imul ecx,DCTSIZE (ecx = output_cols)
56
	jz	near .return
57
58
	mov	edx, JDIMENSION [img_width(ebp)]
59
60
	; -- expand_right_edge
61
62
	push	ecx
63
	shl	ecx,1				; output_cols * 2
64
	sub	ecx,edx
65
	jle	short .expand_end
66
67
	mov	eax, INT [max_v_samp(ebp)]
68
	test	eax,eax
69
	jle	short .expand_end
70
71
	cld
72
	mov	esi, JSAMPARRAY [input_data(ebp)]	; input_data
73
	alignx	16,7
74
.expandloop:
75
	push	eax
76
	push	ecx
77
78
	mov	edi, JSAMPROW [esi]
79
	add	edi,edx
80
	mov	al, JSAMPLE [edi-1]
81
82
	rep stosb
83
84
	pop	ecx
85
	pop	eax
86
87
	add	esi, byte SIZEOF_JSAMPROW
88
	dec	eax
89
	jg	short .expandloop
90
91
.expand_end:
92
	pop	ecx				; output_cols
93
94
	; -- h2v1_downsample
95
96
	mov	eax, JDIMENSION [v_samp(ebp)]	; rowctr
97
	test	eax,eax
98
	jle	near .return
99
100
	mov       edx, 0x00010000	; bias pattern
101
	movd      mm7,edx
102
	pcmpeqw   mm6,mm6
103
	punpckldq mm7,mm7		; mm7={0, 1, 0, 1}
104
	psrlw     mm6,BYTE_BIT		; mm6={0xFF 0x00 0xFF 0x00 ..}
105
106
	mov	esi, JSAMPARRAY [input_data(ebp)]	; input_data
107
	mov	edi, JSAMPARRAY [output_data(ebp)]	; output_data
108
	alignx	16,7
109
.rowloop:
110
	push	ecx
111
	push	edi
112
	push	esi
113
114
	mov	esi, JSAMPROW [esi]		; inptr
115
	mov	edi, JSAMPROW [edi]		; outptr
116
	alignx	16,7
117
.columnloop:
118
119
	movq	mm0, MMWORD [esi+0*SIZEOF_MMWORD]
120
	movq	mm1, MMWORD [esi+1*SIZEOF_MMWORD]
121
	movq	mm2,mm0
122
	movq	mm3,mm1
123
124
	pand	mm0,mm6
125
	psrlw	mm2,BYTE_BIT
126
	pand	mm1,mm6
127
	psrlw	mm3,BYTE_BIT
128
129
	paddw	mm0,mm2
130
	paddw	mm1,mm3
131
	paddw	mm0,mm7
132
	paddw	mm1,mm7
133
	psrlw	mm0,1
134
	psrlw	mm1,1
135
136
	packuswb mm0,mm1
137
138
	movq	MMWORD [edi+0*SIZEOF_MMWORD], mm0
139
140
	add	esi, byte 2*SIZEOF_MMWORD	; inptr
141
	add	edi, byte 1*SIZEOF_MMWORD	; outptr
142
	sub	ecx, byte SIZEOF_MMWORD		; outcol
143
	jnz	short .columnloop
144
145
	pop	esi
146
	pop	edi
147
	pop	ecx
148
149
	add	esi, byte SIZEOF_JSAMPROW	; input_data
150
	add	edi, byte SIZEOF_JSAMPROW	; output_data
151
	dec	eax				; rowctr
152
	jg	short .rowloop
153
154
	emms		; empty MMX state
155
156
.return:
157
	pop	edi
158
	pop	esi
159
;	pop	edx		; need not be preserved
160
;	pop	ecx		; need not be preserved
161
;	pop	ebx		; unused
162
	pop	ebp
163
	ret
164
165
; --------------------------------------------------------------------------
166
;
167
; Downsample pixel values of a single component.
168
; This version handles the standard case of 2:1 horizontal and 2:1 vertical,
169
; without smoothing.
170
;
171
; GLOBAL(void)
172
; jsimd_h2v2_downsample_mmx (JDIMENSION image_width, int max_v_samp_factor,
173
;                            JDIMENSION v_samp_factor, JDIMENSION width_blocks,
174
;                            JSAMPARRAY input_data, JSAMPARRAY output_data);
175
;
176
177
%define img_width(b)	(b)+8			; JDIMENSION image_width
178
%define max_v_samp(b)	(b)+12		; int max_v_samp_factor
179
%define v_samp(b)			(b)+16		; JDIMENSION v_samp_factor
180
%define width_blks(b)	(b)+20		; JDIMENSION width_blocks
181
%define input_data(b)	(b)+24		; JSAMPARRAY input_data
182
%define output_data(b)	(b)+28	; JSAMPARRAY output_data
183
184
	align	16
185
	global	EXTN(jsimd_h2v2_downsample_mmx)
186
187
EXTN(jsimd_h2v2_downsample_mmx):
188
	push	ebp
189
	mov	ebp,esp
190
;	push	ebx		; unused
191
;	push	ecx		; need not be preserved
192
;	push	edx		; need not be preserved
193
	push	esi
194
	push	edi
195
196
	mov	ecx, JDIMENSION [width_blks(ebp)]
197
	shl	ecx,3			; imul ecx,DCTSIZE (ecx = output_cols)
198
	jz	near .return
199
200
	mov	edx, JDIMENSION [img_width(ebp)]
201
202
	; -- expand_right_edge
203
204
	push	ecx
205
	shl	ecx,1				; output_cols * 2
206
	sub	ecx,edx
207
	jle	short .expand_end
208
209
	mov	eax, INT [max_v_samp(ebp)]
210
	test	eax,eax
211
	jle	short .expand_end
212
213
	cld
214
	mov	esi, JSAMPARRAY [input_data(ebp)]	; input_data
215
	alignx	16,7
216
.expandloop:
217
	push	eax
218
	push	ecx
219
220
	mov	edi, JSAMPROW [esi]
221
	add	edi,edx
222
	mov	al, JSAMPLE [edi-1]
223
224
	rep stosb
225
226
	pop	ecx
227
	pop	eax
228
229
	add	esi, byte SIZEOF_JSAMPROW
230
	dec	eax
231
	jg	short .expandloop
232
233
.expand_end:
234
	pop	ecx				; output_cols
235
236
	; -- h2v2_downsample
237
238
	mov	eax, JDIMENSION [v_samp(ebp)]	; rowctr
239
	test	eax,eax
240
	jle	near .return
241
242
	mov       edx, 0x00020001	; bias pattern
243
	movd      mm7,edx
244
	pcmpeqw   mm6,mm6
245
	punpckldq mm7,mm7		; mm7={1, 2, 1, 2}
246
	psrlw     mm6,BYTE_BIT		; mm6={0xFF 0x00 0xFF 0x00 ..}
247
248
	mov	esi, JSAMPARRAY [input_data(ebp)]	; input_data
249
	mov	edi, JSAMPARRAY [output_data(ebp)]	; output_data
250
	alignx	16,7
251
.rowloop:
252
	push	ecx
253
	push	edi
254
	push	esi
255
256
	mov	edx, JSAMPROW [esi+0*SIZEOF_JSAMPROW]	; inptr0
257
	mov	esi, JSAMPROW [esi+1*SIZEOF_JSAMPROW]	; inptr1
258
	mov	edi, JSAMPROW [edi]			; outptr
259
	alignx	16,7
260
.columnloop:
261
262
	movq	mm0, MMWORD [edx+0*SIZEOF_MMWORD]
263
	movq	mm1, MMWORD [esi+0*SIZEOF_MMWORD]
264
	movq	mm2, MMWORD [edx+1*SIZEOF_MMWORD]
265
	movq	mm3, MMWORD [esi+1*SIZEOF_MMWORD]
266
267
	movq	mm4,mm0
268
	movq	mm5,mm1
269
	pand	mm0,mm6
270
	psrlw	mm4,BYTE_BIT
271
	pand	mm1,mm6
272
	psrlw	mm5,BYTE_BIT
273
	paddw	mm0,mm4
274
	paddw	mm1,mm5
275
276
	movq	mm4,mm2
277
	movq	mm5,mm3
278
	pand	mm2,mm6
279
	psrlw	mm4,BYTE_BIT
280
	pand	mm3,mm6
281
	psrlw	mm5,BYTE_BIT
282
	paddw	mm2,mm4
283
	paddw	mm3,mm5
284
285
	paddw	mm0,mm1
286
	paddw	mm2,mm3
287
	paddw	mm0,mm7
288
	paddw	mm2,mm7
289
	psrlw	mm0,2
290
	psrlw	mm2,2
291
292
	packuswb mm0,mm2
293
294
	movq	MMWORD [edi+0*SIZEOF_MMWORD], mm0
295
296
	add	edx, byte 2*SIZEOF_MMWORD	; inptr0
297
	add	esi, byte 2*SIZEOF_MMWORD	; inptr1
298
	add	edi, byte 1*SIZEOF_MMWORD	; outptr
299
	sub	ecx, byte SIZEOF_MMWORD		; outcol
300
	jnz	near .columnloop
301
302
	pop	esi
303
	pop	edi
304
	pop	ecx
305
306
	add	esi, byte 2*SIZEOF_JSAMPROW	; input_data
307
	add	edi, byte 1*SIZEOF_JSAMPROW	; output_data
308
	dec	eax				; rowctr
309
	jg	near .rowloop
310
311
	emms		; empty MMX state
312
313
.return:
314
	pop	edi
315
	pop	esi
316
;	pop	edx		; need not be preserved
317
;	pop	ecx		; need not be preserved
318
;	pop	ebx		; unused
319
	pop	ebp
320
	ret
321
322
; For some reason, the OS X linker does not honor the request to align the
323
; segment unless we do this.
324
	align	16
(-)a/jpeg/simd/jcsamss2-64.asm (+330 lines)
Line     Link Here 
Line 0    Link Here 
1
;
2
; jcsamss2-64.asm - downsampling (64-bit SSE2)
3
;
4
; Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
5
; Copyright 2009 D. R. Commander
6
;
7
; Based on
8
; x86 SIMD extension for IJG JPEG library
9
; Copyright (C) 1999-2006, MIYASAKA Masaru.
10
; For conditions of distribution and use, see copyright notice in jsimdext.inc
11
;
12
; This file should be assembled with NASM (Netwide Assembler),
13
; can *not* be assembled with Microsoft's MASM or any compatible
14
; assembler (including Borland's Turbo Assembler).
15
; NASM is available from http://nasm.sourceforge.net/ or
16
; http://sourceforge.net/project/showfiles.php?group_id=6208
17
;
18
; [TAB8]
19
20
%include "jsimdext.inc"
21
22
; --------------------------------------------------------------------------
23
	SECTION	SEG_TEXT
24
	BITS	64
25
;
26
; Downsample pixel values of a single component.
27
; This version handles the common case of 2:1 horizontal and 1:1 vertical,
28
; without smoothing.
29
;
30
; GLOBAL(void)
31
; jsimd_h2v1_downsample_sse2 (JDIMENSION image_width, int max_v_samp_factor,
32
;                             JDIMENSION v_samp_factor, JDIMENSION width_blocks,
33
;                             JSAMPARRAY input_data, JSAMPARRAY output_data);
34
;
35
36
; r10 = JDIMENSION image_width
37
; r11 = int max_v_samp_factor
38
; r12 = JDIMENSION v_samp_factor
39
; r13 = JDIMENSION width_blocks
40
; r14 = JSAMPARRAY input_data
41
; r15 = JSAMPARRAY output_data
42
43
	align	16
44
	global	EXTN(jsimd_h2v1_downsample_sse2)
45
46
EXTN(jsimd_h2v1_downsample_sse2):
47
	push	rbp
48
	mov	rax,rsp
49
	mov	rbp,rsp
50
	collect_args
51
52
	mov rcx, r13
53
	shl	rcx,3			; imul rcx,DCTSIZE (rcx = output_cols)
54
	jz	near .return
55
56
	mov rdx, r10
57
58
	; -- expand_right_edge
59
60
	push	rcx
61
	shl	rcx,1				; output_cols * 2
62
	sub	rcx,rdx
63
	jle	short .expand_end
64
65
	mov	rax, r11
66
	test	rax,rax
67
	jle	short .expand_end
68
69
	cld
70
	mov	rsi, r14	; input_data
71
.expandloop:
72
	push	rax
73
	push	rcx
74
75
	mov	rdi, JSAMPROW [rsi]
76
	add	rdi,rdx
77
	mov	al, JSAMPLE [rdi-1]
78
79
	rep stosb
80
81
	pop	rcx
82
	pop	rax
83
84
	add	rsi, byte SIZEOF_JSAMPROW
85
	dec	rax
86
	jg	short .expandloop
87
88
.expand_end:
89
	pop	rcx				; output_cols
90
91
	; -- h2v1_downsample
92
93
	mov	rax, r12	; rowctr
94
	test	eax,eax
95
	jle	near .return
96
97
	mov	rdx, 0x00010000		; bias pattern
98
	movd	xmm7,edx
99
	pcmpeqw	xmm6,xmm6
100
	pshufd	xmm7,xmm7,0x00		; xmm7={0, 1, 0, 1, 0, 1, 0, 1}
101
	psrlw	xmm6,BYTE_BIT		; xmm6={0xFF 0x00 0xFF 0x00 ..}
102
103
	mov	rsi, r14	; input_data
104
	mov	rdi, r15	; output_data
105
.rowloop:
106
	push	rcx
107
	push	rdi
108
	push	rsi
109
110
	mov	rsi, JSAMPROW [rsi]		; inptr
111
	mov rdi, JSAMPROW [rdi]		; outptr
112
113
	cmp	rcx, byte SIZEOF_XMMWORD
114
	jae	short .columnloop
115
116
.columnloop_r8:
117
	movdqa	xmm0, XMMWORD [rsi+0*SIZEOF_XMMWORD]
118
	pxor	xmm1,xmm1
119
	mov	rcx, SIZEOF_XMMWORD
120
	jmp	short .downsample
121
122
.columnloop:
123
	movdqa	xmm0, XMMWORD [rsi+0*SIZEOF_XMMWORD]
124
	movdqa	xmm1, XMMWORD [rsi+1*SIZEOF_XMMWORD]
125
126
.downsample:
127
	movdqa	xmm2,xmm0
128
	movdqa	xmm3,xmm1
129
130
	pand	xmm0,xmm6
131
	psrlw	xmm2,BYTE_BIT
132
	pand	xmm1,xmm6
133
	psrlw	xmm3,BYTE_BIT
134
135
	paddw	xmm0,xmm2
136
	paddw	xmm1,xmm3
137
	paddw	xmm0,xmm7
138
	paddw	xmm1,xmm7
139
	psrlw	xmm0,1
140
	psrlw	xmm1,1
141
142
	packuswb xmm0,xmm1
143
144
	movdqa	XMMWORD [rdi+0*SIZEOF_XMMWORD], xmm0
145
146
	sub	rcx, byte SIZEOF_XMMWORD	; outcol
147
	add	rsi, byte 2*SIZEOF_XMMWORD	; inptr
148
	add	rdi, byte 1*SIZEOF_XMMWORD	; outptr
149
	cmp	rcx, byte SIZEOF_XMMWORD
150
	jae	short .columnloop
151
	test	rcx,rcx
152
	jnz	short .columnloop_r8
153
154
	pop	rsi
155
	pop	rdi
156
	pop	rcx
157
158
	add	rsi, byte SIZEOF_JSAMPROW	; input_data
159
	add	rdi, byte SIZEOF_JSAMPROW	; output_data
160
	dec	rax				; rowctr
161
	jg	near .rowloop
162
163
.return:
164
	uncollect_args
165
	pop	rbp
166
	ret
167
168
; --------------------------------------------------------------------------
169
;
170
; Downsample pixel values of a single component.
171
; This version handles the standard case of 2:1 horizontal and 2:1 vertical,
172
; without smoothing.
173
;
174
; GLOBAL(void)
175
; jsimd_h2v2_downsample_sse2 (JDIMENSION image_width, int max_v_samp_factor,
176
;                             JDIMENSION v_samp_factor, JDIMENSION width_blocks,
177
;                             JSAMPARRAY input_data, JSAMPARRAY output_data);
178
;
179
180
; r10 = JDIMENSION image_width
181
; r11 = int max_v_samp_factor
182
; r12 = JDIMENSION v_samp_factor
183
; r13 = JDIMENSION width_blocks
184
; r14 = JSAMPARRAY input_data
185
; r15 = JSAMPARRAY output_data
186
187
	align	16
188
	global	EXTN(jsimd_h2v2_downsample_sse2)
189
190
EXTN(jsimd_h2v2_downsample_sse2):
191
	push	rbp
192
	mov	rax,rsp
193
	mov	rbp,rsp
194
	collect_args
195
196
	mov	rcx, r13
197
	shl	rcx,3			; imul rcx,DCTSIZE (rcx = output_cols)
198
	jz	near .return
199
200
	mov	rdx, r10
201
202
	; -- expand_right_edge
203
204
	push	rcx
205
	shl	rcx,1				; output_cols * 2
206
	sub	rcx,rdx
207
	jle	short .expand_end
208
209
	mov	rax, r11
210
	test	rax,rax
211
	jle	short .expand_end
212
213
	cld
214
	mov	rsi, r14	; input_data
215
.expandloop:
216
	push	rax
217
	push	rcx
218
219
	mov	rdi, JSAMPROW [rsi]
220
	add	rdi,rdx
221
	mov	al, JSAMPLE [rdi-1]
222
223
	rep stosb
224
225
	pop	rcx
226
	pop	rax
227
228
	add	rsi, byte SIZEOF_JSAMPROW
229
	dec	rax
230
	jg	short .expandloop
231
232
.expand_end:
233
	pop	rcx				; output_cols
234
235
	; -- h2v2_downsample
236
237
	mov	rax, r12	; rowctr
238
	test	rax,rax
239
	jle	near .return
240
241
	mov	rdx, 0x00020001		; bias pattern
242
	movd	xmm7,edx
243
	pcmpeqw	xmm6,xmm6
244
	pshufd	xmm7,xmm7,0x00		; xmm7={1, 2, 1, 2, 1, 2, 1, 2}
245
	psrlw	xmm6,BYTE_BIT		; xmm6={0xFF 0x00 0xFF 0x00 ..}
246
247
	mov	rsi, r14	; input_data
248
	mov	rdi, r15	; output_data
249
.rowloop:
250
	push	rcx
251
	push	rdi
252
	push	rsi
253
254
	mov	rdx, JSAMPROW [rsi+0*SIZEOF_JSAMPROW]	; inptr0
255
	mov	rsi, JSAMPROW [rsi+1*SIZEOF_JSAMPROW]	; inptr1
256
	mov	rdi, JSAMPROW [rdi]			; outptr
257
258
	cmp	rcx, byte SIZEOF_XMMWORD
259
	jae	short .columnloop
260
261
.columnloop_r8:
262
	movdqa	xmm0, XMMWORD [rdx+0*SIZEOF_XMMWORD]
263
	movdqa	xmm1, XMMWORD [rsi+0*SIZEOF_XMMWORD]
264
	pxor	xmm2,xmm2
265
	pxor	xmm3,xmm3
266
	mov	rcx, SIZEOF_XMMWORD
267
	jmp	short .downsample
268
269
.columnloop:
270
	movdqa	xmm0, XMMWORD [rdx+0*SIZEOF_XMMWORD]
271
	movdqa	xmm1, XMMWORD [rsi+0*SIZEOF_XMMWORD]
272
	movdqa	xmm2, XMMWORD [rdx+1*SIZEOF_XMMWORD]
273
	movdqa	xmm3, XMMWORD [rsi+1*SIZEOF_XMMWORD]
274
275
.downsample:
276
	movdqa	xmm4,xmm0
277
	movdqa	xmm5,xmm1
278
	pand	xmm0,xmm6
279
	psrlw	xmm4,BYTE_BIT
280
	pand	xmm1,xmm6
281
	psrlw	xmm5,BYTE_BIT
282
	paddw	xmm0,xmm4
283
	paddw	xmm1,xmm5
284
285
	movdqa	xmm4,xmm2
286
	movdqa	xmm5,xmm3
287
	pand	xmm2,xmm6
288
	psrlw	xmm4,BYTE_BIT
289
	pand	xmm3,xmm6
290
	psrlw	xmm5,BYTE_BIT
291
	paddw	xmm2,xmm4
292
	paddw	xmm3,xmm5
293
294
	paddw	xmm0,xmm1
295
	paddw	xmm2,xmm3
296
	paddw	xmm0,xmm7
297
	paddw	xmm2,xmm7
298
	psrlw	xmm0,2
299
	psrlw	xmm2,2
300
301
	packuswb xmm0,xmm2
302
303
	movdqa	XMMWORD [rdi+0*SIZEOF_XMMWORD], xmm0
304
305
	sub	rcx, byte SIZEOF_XMMWORD	; outcol
306
	add	rdx, byte 2*SIZEOF_XMMWORD	; inptr0
307
	add	rsi, byte 2*SIZEOF_XMMWORD	; inptr1
308
	add	rdi, byte 1*SIZEOF_XMMWORD	; outptr
309
	cmp	rcx, byte SIZEOF_XMMWORD
310
	jae	near .columnloop
311
	test	rcx,rcx
312
	jnz	near .columnloop_r8
313
314
	pop	rsi
315
	pop	rdi
316
	pop	rcx
317
318
	add	rsi, byte 2*SIZEOF_JSAMPROW	; input_data
319
	add	rdi, byte 1*SIZEOF_JSAMPROW	; output_data
320
	dec	rax				; rowctr
321
	jg	near .rowloop
322
323
.return:
324
	uncollect_args
325
	pop	rbp
326
	ret
327
328
; For some reason, the OS X linker does not honor the request to align the
329
; segment unless we do this.
330
	align	16
(-)a/jpeg/simd/jcsamss2.asm (+351 lines)
Line     Link Here 
Line 0    Link Here 
1
;
2
; jcsamss2.asm - downsampling (SSE2)
3
;
4
; Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
5
;
6
; Based on
7
; x86 SIMD extension for IJG JPEG library
8
; Copyright (C) 1999-2006, MIYASAKA Masaru.
9
; For conditions of distribution and use, see copyright notice in jsimdext.inc
10
;
11
; This file should be assembled with NASM (Netwide Assembler),
12
; can *not* be assembled with Microsoft's MASM or any compatible
13
; assembler (including Borland's Turbo Assembler).
14
; NASM is available from http://nasm.sourceforge.net/ or
15
; http://sourceforge.net/project/showfiles.php?group_id=6208
16
;
17
; [TAB8]
18
19
%include "jsimdext.inc"
20
21
; --------------------------------------------------------------------------
22
	SECTION	SEG_TEXT
23
	BITS	32
24
;
25
; Downsample pixel values of a single component.
26
; This version handles the common case of 2:1 horizontal and 1:1 vertical,
27
; without smoothing.
28
;
29
; GLOBAL(void)
30
; jsimd_h2v1_downsample_sse2 (JDIMENSION image_width, int max_v_samp_factor,
31
;                             JDIMENSION v_samp_factor, JDIMENSION width_blocks,
32
;                             JSAMPARRAY input_data, JSAMPARRAY output_data);
33
;
34
35
%define img_width(b)	(b)+8			; JDIMENSION image_width
36
%define max_v_samp(b)	(b)+12		; int max_v_samp_factor
37
%define v_samp(b)			(b)+16		; JDIMENSION v_samp_factor
38
%define width_blks(b)	(b)+20		; JDIMENSION width_blocks
39
%define input_data(b)	(b)+24		; JSAMPARRAY input_data
40
%define output_data(b)	(b)+28		; JSAMPARRAY output_data
41
42
	align	16
43
	global	EXTN(jsimd_h2v1_downsample_sse2)
44
45
EXTN(jsimd_h2v1_downsample_sse2):
46
	push	ebp
47
	mov	ebp,esp
48
;	push	ebx		; unused
49
;	push	ecx		; need not be preserved
50
;	push	edx		; need not be preserved
51
	push	esi
52
	push	edi
53
54
	mov	ecx, JDIMENSION [width_blks(ebp)]
55
	shl	ecx,3			; imul ecx,DCTSIZE (ecx = output_cols)
56
	jz	near .return
57
58
	mov	edx, JDIMENSION [img_width(ebp)]
59
60
	; -- expand_right_edge
61
62
	push	ecx
63
	shl	ecx,1				; output_cols * 2
64
	sub	ecx,edx
65
	jle	short .expand_end
66
67
	mov	eax, INT [max_v_samp(ebp)]
68
	test	eax,eax
69
	jle	short .expand_end
70
71
	cld
72
	mov	esi, JSAMPARRAY [input_data(ebp)]	; input_data
73
	alignx	16,7
74
.expandloop:
75
	push	eax
76
	push	ecx
77
78
	mov	edi, JSAMPROW [esi]
79
	add	edi,edx
80
	mov	al, JSAMPLE [edi-1]
81
82
	rep stosb
83
84
	pop	ecx
85
	pop	eax
86
87
	add	esi, byte SIZEOF_JSAMPROW
88
	dec	eax
89
	jg	short .expandloop
90
91
.expand_end:
92
	pop	ecx				; output_cols
93
94
	; -- h2v1_downsample
95
96
	mov	eax, JDIMENSION [v_samp(ebp)]	; rowctr
97
	test	eax,eax
98
	jle	near .return
99
100
	mov	edx, 0x00010000		; bias pattern
101
	movd	xmm7,edx
102
	pcmpeqw	xmm6,xmm6
103
	pshufd	xmm7,xmm7,0x00		; xmm7={0, 1, 0, 1, 0, 1, 0, 1}
104
	psrlw	xmm6,BYTE_BIT		; xmm6={0xFF 0x00 0xFF 0x00 ..}
105
106
	mov	esi, JSAMPARRAY [input_data(ebp)]	; input_data
107
	mov	edi, JSAMPARRAY [output_data(ebp)]	; output_data
108
	alignx	16,7
109
.rowloop:
110
	push	ecx
111
	push	edi
112
	push	esi
113
114
	mov	esi, JSAMPROW [esi]		; inptr
115
	mov	edi, JSAMPROW [edi]		; outptr
116
117
	cmp	ecx, byte SIZEOF_XMMWORD
118
	jae	short .columnloop
119
	alignx	16,7
120
121
.columnloop_r8:
122
	movdqa	xmm0, XMMWORD [esi+0*SIZEOF_XMMWORD]
123
	pxor	xmm1,xmm1
124
	mov	ecx, SIZEOF_XMMWORD
125
	jmp	short .downsample
126
	alignx	16,7
127
128
.columnloop:
129
	movdqa	xmm0, XMMWORD [esi+0*SIZEOF_XMMWORD]
130
	movdqa	xmm1, XMMWORD [esi+1*SIZEOF_XMMWORD]
131
132
.downsample:
133
	movdqa	xmm2,xmm0
134
	movdqa	xmm3,xmm1
135
136
	pand	xmm0,xmm6
137
	psrlw	xmm2,BYTE_BIT
138
	pand	xmm1,xmm6
139
	psrlw	xmm3,BYTE_BIT
140
141
	paddw	xmm0,xmm2
142
	paddw	xmm1,xmm3
143
	paddw	xmm0,xmm7
144
	paddw	xmm1,xmm7
145
	psrlw	xmm0,1
146
	psrlw	xmm1,1
147
148
	packuswb xmm0,xmm1
149
150
	movdqa	XMMWORD [edi+0*SIZEOF_XMMWORD], xmm0
151
152
	sub	ecx, byte SIZEOF_XMMWORD	; outcol
153
	add	esi, byte 2*SIZEOF_XMMWORD	; inptr
154
	add	edi, byte 1*SIZEOF_XMMWORD	; outptr
155
	cmp	ecx, byte SIZEOF_XMMWORD
156
	jae	short .columnloop
157
	test	ecx,ecx
158
	jnz	short .columnloop_r8
159
160
	pop	esi
161
	pop	edi
162
	pop	ecx
163
164
	add	esi, byte SIZEOF_JSAMPROW	; input_data
165
	add	edi, byte SIZEOF_JSAMPROW	; output_data
166
	dec	eax				; rowctr
167
	jg	near .rowloop
168
169
.return:
170
	pop	edi
171
	pop	esi
172
;	pop	edx		; need not be preserved
173
;	pop	ecx		; need not be preserved
174
;	pop	ebx		; unused
175
	pop	ebp
176
	ret
177
178
; --------------------------------------------------------------------------
179
;
180
; Downsample pixel values of a single component.
181
; This version handles the standard case of 2:1 horizontal and 2:1 vertical,
182
; without smoothing.
183
;
184
; GLOBAL(void)
185
; jsimd_h2v2_downsample_sse2 (JDIMENSION image_width, int max_v_samp_factor,
186
;                             JDIMENSION v_samp_factor, JDIMENSION width_blocks,
187
;                             JSAMPARRAY input_data, JSAMPARRAY output_data);
188
;
189
190
%define img_width(b)	(b)+8			; JDIMENSION image_width
191
%define max_v_samp(b)	(b)+12		; int max_v_samp_factor
192
%define v_samp(b)			(b)+16		; JDIMENSION v_samp_factor
193
%define width_blks(b)	(b)+20		; JDIMENSION width_blocks
194
%define input_data(b)	(b)+24		; JSAMPARRAY input_data
195
%define output_data(b)	(b)+28	; JSAMPARRAY output_data
196
197
	align	16
198
	global	EXTN(jsimd_h2v2_downsample_sse2)
199
200
EXTN(jsimd_h2v2_downsample_sse2):
201
	push	ebp
202
	mov	ebp,esp
203
;	push	ebx		; unused
204
;	push	ecx		; need not be preserved
205
;	push	edx		; need not be preserved
206
	push	esi
207
	push	edi
208
209
	mov	ecx, JDIMENSION [width_blks(ebp)]
210
	shl	ecx,3			; imul ecx,DCTSIZE (ecx = output_cols)
211
	jz	near .return
212
213
	mov	edx, JDIMENSION [img_width(ebp)]
214
215
	; -- expand_right_edge
216
217
	push	ecx
218
	shl	ecx,1				; output_cols * 2
219
	sub	ecx,edx
220
	jle	short .expand_end
221
222
	mov	eax, INT [max_v_samp(ebp)]
223
	test	eax,eax
224
	jle	short .expand_end
225
226
	cld
227
	mov	esi, JSAMPARRAY [input_data(ebp)]	; input_data
228
	alignx	16,7
229
.expandloop:
230
	push	eax
231
	push	ecx
232
233
	mov	edi, JSAMPROW [esi]
234
	add	edi,edx
235
	mov	al, JSAMPLE [edi-1]
236
237
	rep stosb
238
239
	pop	ecx
240
	pop	eax
241
242
	add	esi, byte SIZEOF_JSAMPROW
243
	dec	eax
244
	jg	short .expandloop
245
246
.expand_end:
247
	pop	ecx				; output_cols
248
249
	; -- h2v2_downsample
250
251
	mov	eax, JDIMENSION [v_samp(ebp)]	; rowctr
252
	test	eax,eax
253
	jle	near .return
254
255
	mov	edx, 0x00020001		; bias pattern
256
	movd	xmm7,edx
257
	pcmpeqw	xmm6,xmm6
258
	pshufd	xmm7,xmm7,0x00		; xmm7={1, 2, 1, 2, 1, 2, 1, 2}
259
	psrlw	xmm6,BYTE_BIT		; xmm6={0xFF 0x00 0xFF 0x00 ..}
260
261
	mov	esi, JSAMPARRAY [input_data(ebp)]	; input_data
262
	mov	edi, JSAMPARRAY [output_data(ebp)]	; output_data
263
	alignx	16,7
264
.rowloop:
265
	push	ecx
266
	push	edi
267
	push	esi
268
269
	mov	edx, JSAMPROW [esi+0*SIZEOF_JSAMPROW]	; inptr0
270
	mov	esi, JSAMPROW [esi+1*SIZEOF_JSAMPROW]	; inptr1
271
	mov	edi, JSAMPROW [edi]			; outptr
272
273
	cmp	ecx, byte SIZEOF_XMMWORD
274
	jae	short .columnloop
275
	alignx	16,7
276
277
.columnloop_r8:
278
	movdqa	xmm0, XMMWORD [edx+0*SIZEOF_XMMWORD]
279
	movdqa	xmm1, XMMWORD [esi+0*SIZEOF_XMMWORD]
280
	pxor	xmm2,xmm2
281
	pxor	xmm3,xmm3
282
	mov	ecx, SIZEOF_XMMWORD
283
	jmp	short .downsample
284
	alignx	16,7
285
286
.columnloop:
287
	movdqa	xmm0, XMMWORD [edx+0*SIZEOF_XMMWORD]
288
	movdqa	xmm1, XMMWORD [esi+0*SIZEOF_XMMWORD]
289
	movdqa	xmm2, XMMWORD [edx+1*SIZEOF_XMMWORD]
290
	movdqa	xmm3, XMMWORD [esi+1*SIZEOF_XMMWORD]
291
292
.downsample:
293
	movdqa	xmm4,xmm0
294
	movdqa	xmm5,xmm1
295
	pand	xmm0,xmm6
296
	psrlw	xmm4,BYTE_BIT
297
	pand	xmm1,xmm6
298
	psrlw	xmm5,BYTE_BIT
299
	paddw	xmm0,xmm4
300
	paddw	xmm1,xmm5
301
302
	movdqa	xmm4,xmm2
303
	movdqa	xmm5,xmm3
304
	pand	xmm2,xmm6
305
	psrlw	xmm4,BYTE_BIT
306
	pand	xmm3,xmm6
307
	psrlw	xmm5,BYTE_BIT
308
	paddw	xmm2,xmm4
309
	paddw	xmm3,xmm5
310
311
	paddw	xmm0,xmm1
312
	paddw	xmm2,xmm3
313
	paddw	xmm0,xmm7
314
	paddw	xmm2,xmm7
315
	psrlw	xmm0,2
316
	psrlw	xmm2,2
317
318
	packuswb xmm0,xmm2
319
320
	movdqa	XMMWORD [edi+0*SIZEOF_XMMWORD], xmm0
321
322
	sub	ecx, byte SIZEOF_XMMWORD	; outcol
323
	add	edx, byte 2*SIZEOF_XMMWORD	; inptr0
324
	add	esi, byte 2*SIZEOF_XMMWORD	; inptr1
325
	add	edi, byte 1*SIZEOF_XMMWORD	; outptr
326
	cmp	ecx, byte SIZEOF_XMMWORD
327
	jae	near .columnloop
328
	test	ecx,ecx
329
	jnz	near .columnloop_r8
330
331
	pop	esi
332
	pop	edi
333
	pop	ecx
334
335
	add	esi, byte 2*SIZEOF_JSAMPROW	; input_data
336
	add	edi, byte 1*SIZEOF_JSAMPROW	; output_data
337
	dec	eax				; rowctr
338
	jg	near .rowloop
339
340
.return:
341
	pop	edi
342
	pop	esi
343
;	pop	edx		; need not be preserved
344
;	pop	ecx		; need not be preserved
345
;	pop	ebx		; unused
346
	pop	ebp
347
	ret
348
349
; For some reason, the OS X linker does not honor the request to align the
350
; segment unless we do this.
351
	align	16
(-)a/jpeg/simd/jdclrmmx.asm (+407 lines)
Line     Link Here 
Line 0    Link Here 
1
;
2
; jdclrmmx.asm - colorspace conversion (MMX)
3
;
4
; Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
5
;
6
; Based on
7
; x86 SIMD extension for IJG JPEG library
8
; Copyright (C) 1999-2006, MIYASAKA Masaru.
9
; For conditions of distribution and use, see copyright notice in jsimdext.inc
10
;
11
; This file should be assembled with NASM (Netwide Assembler),
12
; can *not* be assembled with Microsoft's MASM or any compatible
13
; assembler (including Borland's Turbo Assembler).
14
; NASM is available from http://nasm.sourceforge.net/ or
15
; http://sourceforge.net/project/showfiles.php?group_id=6208
16
;
17
; [TAB8]
18
19
%include "jcolsamp.inc"
20
21
; --------------------------------------------------------------------------
22
	SECTION	SEG_TEXT
23
	BITS	32
24
;
25
; Convert some rows of samples to the output colorspace.
26
;
27
; GLOBAL(void)
28
; jsimd_ycc_rgb_convert_mmx (JDIMENSION out_width,
29
;                            JSAMPIMAGE input_buf, JDIMENSION input_row,
30
;                            JSAMPARRAY output_buf, int num_rows)
31
;
32
33
%define out_width(b)	(b)+8			; JDIMENSION out_width
34
%define input_buf(b)	(b)+12		; JSAMPIMAGE input_buf
35
%define input_row(b)	(b)+16		; JDIMENSION input_row
36
%define output_buf(b)	(b)+20		; JSAMPARRAY output_buf
37
%define num_rows(b)	(b)+24		; int num_rows
38
39
%define original_ebp	ebp+0
40
%define wk(i)		ebp-(WK_NUM-(i))*SIZEOF_MMWORD	; mmword wk[WK_NUM]
41
%define WK_NUM		2
42
%define gotptr		wk(0)-SIZEOF_POINTER	; void * gotptr
43
44
	align	16
45
	global	EXTN(jsimd_ycc_rgb_convert_mmx)
46
47
EXTN(jsimd_ycc_rgb_convert_mmx):
48
	push	ebp
49
	mov	eax,esp				; eax = original ebp
50
	sub	esp, byte 4
51
	and	esp, byte (-SIZEOF_MMWORD)	; align to 64 bits
52
	mov	[esp],eax
53
	mov	ebp,esp				; ebp = aligned ebp
54
	lea	esp, [wk(0)]
55
	pushpic	eax		; make a room for GOT address
56
	push	ebx
57
;	push	ecx		; need not be preserved
58
;	push	edx		; need not be preserved
59
	push	esi
60
	push	edi
61
62
	get_GOT	ebx			; get GOT address
63
	movpic	POINTER [gotptr], ebx	; save GOT address
64
65
	mov	ecx, JDIMENSION [out_width(eax)]	; num_cols
66
	test	ecx,ecx
67
	jz	near .return
68
69
	push	ecx
70
71
	mov	edi, JSAMPIMAGE [input_buf(eax)]
72
	mov	ecx, JDIMENSION [input_row(eax)]
73
	mov	esi, JSAMPARRAY [edi+0*SIZEOF_JSAMPARRAY]
74
	mov	ebx, JSAMPARRAY [edi+1*SIZEOF_JSAMPARRAY]
75
	mov	edx, JSAMPARRAY [edi+2*SIZEOF_JSAMPARRAY]
76
	lea	esi, [esi+ecx*SIZEOF_JSAMPROW]
77
	lea	ebx, [ebx+ecx*SIZEOF_JSAMPROW]
78
	lea	edx, [edx+ecx*SIZEOF_JSAMPROW]
79
80
	pop	ecx
81
82
	mov	edi, JSAMPARRAY [output_buf(eax)]
83
	mov	eax, INT [num_rows(eax)]
84
	test	eax,eax
85
	jle	near .return
86
	alignx	16,7
87
.rowloop:
88
	push	eax
89
	push	edi
90
	push	edx
91
	push	ebx
92
	push	esi
93
	push	ecx			; col
94
95
	mov	esi, JSAMPROW [esi]	; inptr0
96
	mov	ebx, JSAMPROW [ebx]	; inptr1
97
	mov	edx, JSAMPROW [edx]	; inptr2
98
	mov	edi, JSAMPROW [edi]	; outptr
99
	movpic	eax, POINTER [gotptr]	; load GOT address (eax)
100
	alignx	16,7
101
.columnloop:
102
103
	movq	mm5, MMWORD [ebx]	; mm5=Cb(01234567)
104
	movq	mm1, MMWORD [edx]	; mm1=Cr(01234567)
105
106
	pcmpeqw	mm4,mm4
107
	pcmpeqw	mm7,mm7
108
	psrlw	mm4,BYTE_BIT
109
	psllw	mm7,7			; mm7={0xFF80 0xFF80 0xFF80 0xFF80}
110
	movq	mm0,mm4			; mm0=mm4={0xFF 0x00 0xFF 0x00 ..}
111
112
	pand	mm4,mm5			; mm4=Cb(0246)=CbE
113
	psrlw	mm5,BYTE_BIT		; mm5=Cb(1357)=CbO
114
	pand	mm0,mm1			; mm0=Cr(0246)=CrE
115
	psrlw	mm1,BYTE_BIT		; mm1=Cr(1357)=CrO
116
117
	paddw	mm4,mm7
118
	paddw	mm5,mm7
119
	paddw	mm0,mm7
120
	paddw	mm1,mm7
121
122
	; (Original)
123
	; R = Y                + 1.40200 * Cr
124
	; G = Y - 0.34414 * Cb - 0.71414 * Cr
125
	; B = Y + 1.77200 * Cb
126
	;
127
	; (This implementation)
128
	; R = Y                + 0.40200 * Cr + Cr
129
	; G = Y - 0.34414 * Cb + 0.28586 * Cr - Cr
130
	; B = Y - 0.22800 * Cb + Cb + Cb
131
132
	movq	mm2,mm4			; mm2=CbE
133
	movq	mm3,mm5			; mm3=CbO
134
	paddw	mm4,mm4			; mm4=2*CbE
135
	paddw	mm5,mm5			; mm5=2*CbO
136
	movq	mm6,mm0			; mm6=CrE
137
	movq	mm7,mm1			; mm7=CrO
138
	paddw	mm0,mm0			; mm0=2*CrE
139
	paddw	mm1,mm1			; mm1=2*CrO
140
141
	pmulhw	mm4,[GOTOFF(eax,PW_MF0228)]	; mm4=(2*CbE * -FIX(0.22800))
142
	pmulhw	mm5,[GOTOFF(eax,PW_MF0228)]	; mm5=(2*CbO * -FIX(0.22800))
143
	pmulhw	mm0,[GOTOFF(eax,PW_F0402)]	; mm0=(2*CrE * FIX(0.40200))
144
	pmulhw	mm1,[GOTOFF(eax,PW_F0402)]	; mm1=(2*CrO * FIX(0.40200))
145
146
	paddw	mm4,[GOTOFF(eax,PW_ONE)]
147
	paddw	mm5,[GOTOFF(eax,PW_ONE)]
148
	psraw	mm4,1			; mm4=(CbE * -FIX(0.22800))
149
	psraw	mm5,1			; mm5=(CbO * -FIX(0.22800))
150
	paddw	mm0,[GOTOFF(eax,PW_ONE)]
151
	paddw	mm1,[GOTOFF(eax,PW_ONE)]
152
	psraw	mm0,1			; mm0=(CrE * FIX(0.40200))
153
	psraw	mm1,1			; mm1=(CrO * FIX(0.40200))
154
155
	paddw	mm4,mm2
156
	paddw	mm5,mm3
157
	paddw	mm4,mm2			; mm4=(CbE * FIX(1.77200))=(B-Y)E
158
	paddw	mm5,mm3			; mm5=(CbO * FIX(1.77200))=(B-Y)O
159
	paddw	mm0,mm6			; mm0=(CrE * FIX(1.40200))=(R-Y)E
160
	paddw	mm1,mm7			; mm1=(CrO * FIX(1.40200))=(R-Y)O
161
162
	movq	MMWORD [wk(0)], mm4	; wk(0)=(B-Y)E
163
	movq	MMWORD [wk(1)], mm5	; wk(1)=(B-Y)O
164
165
	movq      mm4,mm2
166
	movq      mm5,mm3
167
	punpcklwd mm2,mm6
168
	punpckhwd mm4,mm6
169
	pmaddwd   mm2,[GOTOFF(eax,PW_MF0344_F0285)]
170
	pmaddwd   mm4,[GOTOFF(eax,PW_MF0344_F0285)]
171
	punpcklwd mm3,mm7
172
	punpckhwd mm5,mm7
173
	pmaddwd   mm3,[GOTOFF(eax,PW_MF0344_F0285)]
174
	pmaddwd   mm5,[GOTOFF(eax,PW_MF0344_F0285)]
175
176
	paddd     mm2,[GOTOFF(eax,PD_ONEHALF)]
177
	paddd     mm4,[GOTOFF(eax,PD_ONEHALF)]
178
	psrad     mm2,SCALEBITS
179
	psrad     mm4,SCALEBITS
180
	paddd     mm3,[GOTOFF(eax,PD_ONEHALF)]
181
	paddd     mm5,[GOTOFF(eax,PD_ONEHALF)]
182
	psrad     mm3,SCALEBITS
183
	psrad     mm5,SCALEBITS
184
185
	packssdw  mm2,mm4	; mm2=CbE*-FIX(0.344)+CrE*FIX(0.285)
186
	packssdw  mm3,mm5	; mm3=CbO*-FIX(0.344)+CrO*FIX(0.285)
187
	psubw     mm2,mm6	; mm2=CbE*-FIX(0.344)+CrE*-FIX(0.714)=(G-Y)E
188
	psubw     mm3,mm7	; mm3=CbO*-FIX(0.344)+CrO*-FIX(0.714)=(G-Y)O
189
190
	movq      mm5, MMWORD [esi]	; mm5=Y(01234567)
191
192
	pcmpeqw   mm4,mm4
193
	psrlw     mm4,BYTE_BIT		; mm4={0xFF 0x00 0xFF 0x00 ..}
194
	pand      mm4,mm5		; mm4=Y(0246)=YE
195
	psrlw     mm5,BYTE_BIT		; mm5=Y(1357)=YO
196
197
	paddw     mm0,mm4		; mm0=((R-Y)E+YE)=RE=(R0 R2 R4 R6)
198
	paddw     mm1,mm5		; mm1=((R-Y)O+YO)=RO=(R1 R3 R5 R7)
199
	packuswb  mm0,mm0		; mm0=(R0 R2 R4 R6 ** ** ** **)
200
	packuswb  mm1,mm1		; mm1=(R1 R3 R5 R7 ** ** ** **)
201
202
	paddw     mm2,mm4		; mm2=((G-Y)E+YE)=GE=(G0 G2 G4 G6)
203
	paddw     mm3,mm5		; mm3=((G-Y)O+YO)=GO=(G1 G3 G5 G7)
204
	packuswb  mm2,mm2		; mm2=(G0 G2 G4 G6 ** ** ** **)
205
	packuswb  mm3,mm3		; mm3=(G1 G3 G5 G7 ** ** ** **)
206
207
	paddw     mm4, MMWORD [wk(0)]	; mm4=(YE+(B-Y)E)=BE=(B0 B2 B4 B6)
208
	paddw     mm5, MMWORD [wk(1)]	; mm5=(YO+(B-Y)O)=BO=(B1 B3 B5 B7)
209
	packuswb  mm4,mm4		; mm4=(B0 B2 B4 B6 ** ** ** **)
210
	packuswb  mm5,mm5		; mm5=(B1 B3 B5 B7 ** ** ** **)
211
212
%if RGB_PIXELSIZE == 3 ; ---------------
213
214
	; mmA=(00 02 04 06 ** ** ** **), mmB=(01 03 05 07 ** ** ** **)
215
	; mmC=(10 12 14 16 ** ** ** **), mmD=(11 13 15 17 ** ** ** **)
216
	; mmE=(20 22 24 26 ** ** ** **), mmF=(21 23 25 27 ** ** ** **)
217
	; mmG=(** ** ** ** ** ** ** **), mmH=(** ** ** ** ** ** ** **)
218
219
	punpcklbw mmA,mmC		; mmA=(00 10 02 12 04 14 06 16)
220
	punpcklbw mmE,mmB		; mmE=(20 01 22 03 24 05 26 07)
221
	punpcklbw mmD,mmF		; mmD=(11 21 13 23 15 25 17 27)
222
223
	movq      mmG,mmA
224
	movq      mmH,mmA
225
	punpcklwd mmA,mmE		; mmA=(00 10 20 01 02 12 22 03)
226
	punpckhwd mmG,mmE		; mmG=(04 14 24 05 06 16 26 07)
227
228
	psrlq     mmH,2*BYTE_BIT	; mmH=(02 12 04 14 06 16 -- --)
229
	psrlq     mmE,2*BYTE_BIT	; mmE=(22 03 24 05 26 07 -- --)
230
231
	movq      mmC,mmD
232
	movq      mmB,mmD
233
	punpcklwd mmD,mmH		; mmD=(11 21 02 12 13 23 04 14)
234
	punpckhwd mmC,mmH		; mmC=(15 25 06 16 17 27 -- --)
235
236
	psrlq     mmB,2*BYTE_BIT	; mmB=(13 23 15 25 17 27 -- --)
237
238
	movq      mmF,mmE
239
	punpcklwd mmE,mmB		; mmE=(22 03 13 23 24 05 15 25)
240
	punpckhwd mmF,mmB		; mmF=(26 07 17 27 -- -- -- --)
241
242
	punpckldq mmA,mmD		; mmA=(00 10 20 01 11 21 02 12)
243
	punpckldq mmE,mmG		; mmE=(22 03 13 23 04 14 24 05)
244
	punpckldq mmC,mmF		; mmC=(15 25 06 16 26 07 17 27)
245
246
	cmp	ecx, byte SIZEOF_MMWORD
247
	jb	short .column_st16
248
249
	movq	MMWORD [edi+0*SIZEOF_MMWORD], mmA
250
	movq	MMWORD [edi+1*SIZEOF_MMWORD], mmE
251
	movq	MMWORD [edi+2*SIZEOF_MMWORD], mmC
252
253
	sub	ecx, byte SIZEOF_MMWORD
254
	jz	short .nextrow
255
256
	add	esi, byte SIZEOF_MMWORD			; inptr0
257
	add	ebx, byte SIZEOF_MMWORD			; inptr1
258
	add	edx, byte SIZEOF_MMWORD			; inptr2
259
	add	edi, byte RGB_PIXELSIZE*SIZEOF_MMWORD	; outptr
260
	jmp	near .columnloop
261
	alignx	16,7
262
263
.column_st16:
264
	lea	ecx, [ecx+ecx*2]	; imul ecx, RGB_PIXELSIZE
265
	cmp	ecx, byte 2*SIZEOF_MMWORD
266
	jb	short .column_st8
267
	movq	MMWORD [edi+0*SIZEOF_MMWORD], mmA
268
	movq	MMWORD [edi+1*SIZEOF_MMWORD], mmE
269
	movq	mmA,mmC
270
	sub	ecx, byte 2*SIZEOF_MMWORD
271
	add	edi, byte 2*SIZEOF_MMWORD
272
	jmp	short .column_st4
273
.column_st8:
274
	cmp	ecx, byte SIZEOF_MMWORD
275
	jb	short .column_st4
276
	movq	MMWORD [edi+0*SIZEOF_MMWORD], mmA
277
	movq	mmA,mmE
278
	sub	ecx, byte SIZEOF_MMWORD
279
	add	edi, byte SIZEOF_MMWORD
280
.column_st4:
281
	movd	eax,mmA
282
	cmp	ecx, byte SIZEOF_DWORD
283
	jb	short .column_st2
284
	mov	DWORD [edi+0*SIZEOF_DWORD], eax
285
	psrlq	mmA,DWORD_BIT
286
	movd	eax,mmA
287
	sub	ecx, byte SIZEOF_DWORD
288
	add	edi, byte SIZEOF_DWORD
289
.column_st2:
290
	cmp	ecx, byte SIZEOF_WORD
291
	jb	short .column_st1
292
	mov	WORD [edi+0*SIZEOF_WORD], ax
293
	shr	eax,WORD_BIT
294
	sub	ecx, byte SIZEOF_WORD
295
	add	edi, byte SIZEOF_WORD
296
.column_st1:
297
	cmp	ecx, byte SIZEOF_BYTE
298
	jb	short .nextrow
299
	mov	BYTE [edi+0*SIZEOF_BYTE], al
300
301
%else ; RGB_PIXELSIZE == 4 ; -----------
302
303
%ifdef RGBX_FILLER_0XFF
304
	pcmpeqb   mm6,mm6		; mm6=(X0 X2 X4 X6 ** ** ** **)
305
	pcmpeqb   mm7,mm7		; mm7=(X1 X3 X5 X7 ** ** ** **)
306
%else
307
	pxor      mm6,mm6		; mm6=(X0 X2 X4 X6 ** ** ** **)
308
	pxor      mm7,mm7		; mm7=(X1 X3 X5 X7 ** ** ** **)
309
%endif
310
	; mmA=(00 02 04 06 ** ** ** **), mmB=(01 03 05 07 ** ** ** **)
311
	; mmC=(10 12 14 16 ** ** ** **), mmD=(11 13 15 17 ** ** ** **)
312
	; mmE=(20 22 24 26 ** ** ** **), mmF=(21 23 25 27 ** ** ** **)
313
	; mmG=(30 32 34 36 ** ** ** **), mmH=(31 33 35 37 ** ** ** **)
314
315
	punpcklbw mmA,mmC		; mmA=(00 10 02 12 04 14 06 16)
316
	punpcklbw mmE,mmG		; mmE=(20 30 22 32 24 34 26 36)
317
	punpcklbw mmB,mmD		; mmB=(01 11 03 13 05 15 07 17)
318
	punpcklbw mmF,mmH		; mmF=(21 31 23 33 25 35 27 37)
319
320
	movq      mmC,mmA
321
	punpcklwd mmA,mmE		; mmA=(00 10 20 30 02 12 22 32)
322
	punpckhwd mmC,mmE		; mmC=(04 14 24 34 06 16 26 36)
323
	movq      mmG,mmB
324
	punpcklwd mmB,mmF		; mmB=(01 11 21 31 03 13 23 33)
325
	punpckhwd mmG,mmF		; mmG=(05 15 25 35 07 17 27 37)
326
327
	movq      mmD,mmA
328
	punpckldq mmA,mmB		; mmA=(00 10 20 30 01 11 21 31)
329
	punpckhdq mmD,mmB		; mmD=(02 12 22 32 03 13 23 33)
330
	movq      mmH,mmC
331
	punpckldq mmC,mmG		; mmC=(04 14 24 34 05 15 25 35)
332
	punpckhdq mmH,mmG		; mmH=(06 16 26 36 07 17 27 37)
333
334
	cmp	ecx, byte SIZEOF_MMWORD
335
	jb	short .column_st16
336
337
	movq	MMWORD [edi+0*SIZEOF_MMWORD], mmA
338
	movq	MMWORD [edi+1*SIZEOF_MMWORD], mmD
339
	movq	MMWORD [edi+2*SIZEOF_MMWORD], mmC
340
	movq	MMWORD [edi+3*SIZEOF_MMWORD], mmH
341
342
	sub	ecx, byte SIZEOF_MMWORD
343
	jz	short .nextrow
344
345
	add	esi, byte SIZEOF_MMWORD			; inptr0
346
	add	ebx, byte SIZEOF_MMWORD			; inptr1
347
	add	edx, byte SIZEOF_MMWORD			; inptr2
348
	add	edi, byte RGB_PIXELSIZE*SIZEOF_MMWORD	; outptr
349
	jmp	near .columnloop
350
	alignx	16,7
351
352
.column_st16:
353
	cmp	ecx, byte SIZEOF_MMWORD/2
354
	jb	short .column_st8
355
	movq	MMWORD [edi+0*SIZEOF_MMWORD], mmA
356
	movq	MMWORD [edi+1*SIZEOF_MMWORD], mmD
357
	movq	mmA,mmC
358
	movq	mmD,mmH
359
	sub	ecx, byte SIZEOF_MMWORD/2
360
	add	edi, byte 2*SIZEOF_MMWORD
361
.column_st8:
362
	cmp	ecx, byte SIZEOF_MMWORD/4
363
	jb	short .column_st4
364
	movq	MMWORD [edi+0*SIZEOF_MMWORD], mmA
365
	movq	mmA,mmD
366
	sub	ecx, byte SIZEOF_MMWORD/4
367
	add	edi, byte 1*SIZEOF_MMWORD
368
.column_st4:
369
	cmp	ecx, byte SIZEOF_MMWORD/8
370
	jb	short .nextrow
371
	movd	DWORD [edi+0*SIZEOF_DWORD], mmA
372
373
%endif ; RGB_PIXELSIZE ; ---------------
374
375
	alignx	16,7
376
377
.nextrow:
378
	pop	ecx
379
	pop	esi
380
	pop	ebx
381
	pop	edx
382
	pop	edi
383
	pop	eax
384
385
	add	esi, byte SIZEOF_JSAMPROW
386
	add	ebx, byte SIZEOF_JSAMPROW
387
	add	edx, byte SIZEOF_JSAMPROW
388
	add	edi, byte SIZEOF_JSAMPROW	; output_buf
389
	dec	eax				; num_rows
390
	jg	near .rowloop
391
392
	emms		; empty MMX state
393
394
.return:
395
	pop	edi
396
	pop	esi
397
;	pop	edx		; need not be preserved
398
;	pop	ecx		; need not be preserved
399
	pop	ebx
400
	mov	esp,ebp		; esp <- aligned ebp
401
	pop	esp		; esp <- original ebp
402
	pop	ebp
403
	ret
404
405
; For some reason, the OS X linker does not honor the request to align the
406
; segment unless we do this.
407
	align	16
(-)a/jpeg/simd/jdclrss2-64.asm (+487 lines)
Line     Link Here 
Line 0    Link Here 
1
;
2
; jdclrss2-64.asm - colorspace conversion (64-bit SSE2)
3
;
4
; Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
5
; Copyright 2009 D. R. Commander
6
;
7
; Based on
8
; x86 SIMD extension for IJG JPEG library
9
; Copyright (C) 1999-2006, MIYASAKA Masaru.
10
; For conditions of distribution and use, see copyright notice in jsimdext.inc
11
;
12
; This file should be assembled with NASM (Netwide Assembler),
13
; can *not* be assembled with Microsoft's MASM or any compatible
14
; assembler (including Borland's Turbo Assembler).
15
; NASM is available from http://nasm.sourceforge.net/ or
16
; http://sourceforge.net/project/showfiles.php?group_id=6208
17
;
18
; [TAB8]
19
20
%include "jcolsamp.inc"
21
				
22
; --------------------------------------------------------------------------
23
	SECTION	SEG_TEXT
24
	BITS	64
25
;
26
; Convert some rows of samples to the output colorspace.
27
;
28
; GLOBAL(void)
29
; jsimd_ycc_rgb_convert_sse2 (JDIMENSION out_width,
30
;                             JSAMPIMAGE input_buf, JDIMENSION input_row,
31
;                             JSAMPARRAY output_buf, int num_rows)
32
;
33
34
; r10 = JDIMENSION out_width
35
; r11 = JSAMPIMAGE input_buf
36
; r12 = JDIMENSION input_row
37
; r13 = JSAMPARRAY output_buf
38
; r14 = int num_rows
39
40
%define wk(i)		rbp-(WK_NUM-(i))*SIZEOF_XMMWORD	; xmmword wk[WK_NUM]
41
%define WK_NUM		2
42
43
	align	16
44
	global	EXTN(jsimd_ycc_rgb_convert_sse2)
45
46
EXTN(jsimd_ycc_rgb_convert_sse2):
47
	push	rbp
48
	mov	rax,rsp				; rax = original rbp
49
	sub	rsp, byte 4
50
	and	rsp, byte (-SIZEOF_XMMWORD)	; align to 128 bits
51
	mov	[rsp],rax
52
	mov	rbp,rsp				; rbp = aligned rbp
53
	lea	rsp, [wk(0)]
54
	collect_args
55
	push	rbx
56
57
	mov	rcx, r10	; num_cols
58
	test	rcx,rcx
59
	jz	near .return
60
61
	push	rcx
62
63
	mov	rdi, r11
64
	mov	rcx, r12
65
	mov	rsi, JSAMPARRAY [rdi+0*SIZEOF_JSAMPARRAY]
66
	mov	rbx, JSAMPARRAY [rdi+1*SIZEOF_JSAMPARRAY]
67
	mov	rdx, JSAMPARRAY [rdi+2*SIZEOF_JSAMPARRAY]
68
	lea	rsi, [rsi+rcx*SIZEOF_JSAMPROW]
69
	lea	rbx, [rbx+rcx*SIZEOF_JSAMPROW]
70
	lea	rdx, [rdx+rcx*SIZEOF_JSAMPROW]
71
72
	pop	rcx
73
74
	mov	rdi, r13
75
	mov	eax, r14d
76
	test	rax,rax
77
	jle	near .return
78
.rowloop:
79
	push	rax
80
	push	rdi
81
	push	rdx
82
	push	rbx
83
	push	rsi
84
	push	rcx			; col
85
86
	mov	rsi, JSAMPROW [rsi]	; inptr0
87
	mov	rbx, JSAMPROW [rbx]	; inptr1
88
	mov	rdx, JSAMPROW [rdx]	; inptr2
89
	mov	rdi, JSAMPROW [rdi]	; outptr
90
.columnloop:
91
92
	movdqa	xmm5, XMMWORD [rbx]	; xmm5=Cb(0123456789ABCDEF)
93
	movdqa	xmm1, XMMWORD [rdx]	; xmm1=Cr(0123456789ABCDEF)
94
95
	pcmpeqw	xmm4,xmm4
96
	pcmpeqw	xmm7,xmm7
97
	psrlw	xmm4,BYTE_BIT
98
	psllw	xmm7,7			; xmm7={0xFF80 0xFF80 0xFF80 0xFF80 ..}
99
	movdqa	xmm0,xmm4		; xmm0=xmm4={0xFF 0x00 0xFF 0x00 ..}
100
101
	pand	xmm4,xmm5		; xmm4=Cb(02468ACE)=CbE
102
	psrlw	xmm5,BYTE_BIT		; xmm5=Cb(13579BDF)=CbO
103
	pand	xmm0,xmm1		; xmm0=Cr(02468ACE)=CrE
104
	psrlw	xmm1,BYTE_BIT		; xmm1=Cr(13579BDF)=CrO
105
106
	paddw	xmm4,xmm7
107
	paddw	xmm5,xmm7
108
	paddw	xmm0,xmm7
109
	paddw	xmm1,xmm7
110
111
	; (Original)
112
	; R = Y                + 1.40200 * Cr
113
	; G = Y - 0.34414 * Cb - 0.71414 * Cr
114
	; B = Y + 1.77200 * Cb
115
	;
116
	; (This implementation)
117
	; R = Y                + 0.40200 * Cr + Cr
118
	; G = Y - 0.34414 * Cb + 0.28586 * Cr - Cr
119
	; B = Y - 0.22800 * Cb + Cb + Cb
120
121
	movdqa	xmm2,xmm4		; xmm2=CbE
122
	movdqa	xmm3,xmm5		; xmm3=CbO
123
	paddw	xmm4,xmm4		; xmm4=2*CbE
124
	paddw	xmm5,xmm5		; xmm5=2*CbO
125
	movdqa	xmm6,xmm0		; xmm6=CrE
126
	movdqa	xmm7,xmm1		; xmm7=CrO
127
	paddw	xmm0,xmm0		; xmm0=2*CrE
128
	paddw	xmm1,xmm1		; xmm1=2*CrO
129
130
	pmulhw	xmm4,[rel PW_MF0228]	; xmm4=(2*CbE * -FIX(0.22800))
131
	pmulhw	xmm5,[rel PW_MF0228]	; xmm5=(2*CbO * -FIX(0.22800))
132
	pmulhw	xmm0,[rel PW_F0402]	; xmm0=(2*CrE * FIX(0.40200))
133
	pmulhw	xmm1,[rel PW_F0402]	; xmm1=(2*CrO * FIX(0.40200))
134
135
	paddw	xmm4,[rel PW_ONE]
136
	paddw	xmm5,[rel PW_ONE]
137
	psraw	xmm4,1			; xmm4=(CbE * -FIX(0.22800))
138
	psraw	xmm5,1			; xmm5=(CbO * -FIX(0.22800))
139
	paddw	xmm0,[rel PW_ONE]
140
	paddw	xmm1,[rel PW_ONE]
141
	psraw	xmm0,1			; xmm0=(CrE * FIX(0.40200))
142
	psraw	xmm1,1			; xmm1=(CrO * FIX(0.40200))
143
144
	paddw	xmm4,xmm2
145
	paddw	xmm5,xmm3
146
	paddw	xmm4,xmm2		; xmm4=(CbE * FIX(1.77200))=(B-Y)E
147
	paddw	xmm5,xmm3		; xmm5=(CbO * FIX(1.77200))=(B-Y)O
148
	paddw	xmm0,xmm6		; xmm0=(CrE * FIX(1.40200))=(R-Y)E
149
	paddw	xmm1,xmm7		; xmm1=(CrO * FIX(1.40200))=(R-Y)O
150
151
	movdqa	XMMWORD [wk(0)], xmm4	; wk(0)=(B-Y)E
152
	movdqa	XMMWORD [wk(1)], xmm5	; wk(1)=(B-Y)O
153
154
	movdqa    xmm4,xmm2
155
	movdqa    xmm5,xmm3
156
	punpcklwd xmm2,xmm6
157
	punpckhwd xmm4,xmm6
158
	pmaddwd   xmm2,[rel PW_MF0344_F0285]
159
	pmaddwd   xmm4,[rel PW_MF0344_F0285]
160
	punpcklwd xmm3,xmm7
161
	punpckhwd xmm5,xmm7
162
	pmaddwd   xmm3,[rel PW_MF0344_F0285]
163
	pmaddwd   xmm5,[rel PW_MF0344_F0285]
164
165
	paddd     xmm2,[rel PD_ONEHALF]
166
	paddd     xmm4,[rel PD_ONEHALF]
167
	psrad     xmm2,SCALEBITS
168
	psrad     xmm4,SCALEBITS
169
	paddd     xmm3,[rel PD_ONEHALF]
170
	paddd     xmm5,[rel PD_ONEHALF]
171
	psrad     xmm3,SCALEBITS
172
	psrad     xmm5,SCALEBITS
173
174
	packssdw  xmm2,xmm4	; xmm2=CbE*-FIX(0.344)+CrE*FIX(0.285)
175
	packssdw  xmm3,xmm5	; xmm3=CbO*-FIX(0.344)+CrO*FIX(0.285)
176
	psubw     xmm2,xmm6	; xmm2=CbE*-FIX(0.344)+CrE*-FIX(0.714)=(G-Y)E
177
	psubw     xmm3,xmm7	; xmm3=CbO*-FIX(0.344)+CrO*-FIX(0.714)=(G-Y)O
178
179
	movdqa    xmm5, XMMWORD [rsi]	; xmm5=Y(0123456789ABCDEF)
180
181
	pcmpeqw   xmm4,xmm4
182
	psrlw     xmm4,BYTE_BIT		; xmm4={0xFF 0x00 0xFF 0x00 ..}
183
	pand      xmm4,xmm5		; xmm4=Y(02468ACE)=YE
184
	psrlw     xmm5,BYTE_BIT		; xmm5=Y(13579BDF)=YO
185
186
	paddw     xmm0,xmm4		; xmm0=((R-Y)E+YE)=RE=R(02468ACE)
187
	paddw     xmm1,xmm5		; xmm1=((R-Y)O+YO)=RO=R(13579BDF)
188
	packuswb  xmm0,xmm0		; xmm0=R(02468ACE********)
189
	packuswb  xmm1,xmm1		; xmm1=R(13579BDF********)
190
191
	paddw     xmm2,xmm4		; xmm2=((G-Y)E+YE)=GE=G(02468ACE)
192
	paddw     xmm3,xmm5		; xmm3=((G-Y)O+YO)=GO=G(13579BDF)
193
	packuswb  xmm2,xmm2		; xmm2=G(02468ACE********)
194
	packuswb  xmm3,xmm3		; xmm3=G(13579BDF********)
195
196
	paddw     xmm4, XMMWORD [wk(0)]	; xmm4=(YE+(B-Y)E)=BE=B(02468ACE)
197
	paddw     xmm5, XMMWORD [wk(1)]	; xmm5=(YO+(B-Y)O)=BO=B(13579BDF)
198
	packuswb  xmm4,xmm4		; xmm4=B(02468ACE********)
199
	packuswb  xmm5,xmm5		; xmm5=B(13579BDF********)
200
201
%if RGB_PIXELSIZE == 3 ; ---------------
202
203
	; xmmA=(00 02 04 06 08 0A 0C 0E **), xmmB=(01 03 05 07 09 0B 0D 0F **)
204
	; xmmC=(10 12 14 16 18 1A 1C 1E **), xmmD=(11 13 15 17 19 1B 1D 1F **)
205
	; xmmE=(20 22 24 26 28 2A 2C 2E **), xmmF=(21 23 25 27 29 2B 2D 2F **)
206
	; xmmG=(** ** ** ** ** ** ** ** **), xmmH=(** ** ** ** ** ** ** ** **)
207
208
	punpcklbw xmmA,xmmC	; xmmA=(00 10 02 12 04 14 06 16 08 18 0A 1A 0C 1C 0E 1E)
209
	punpcklbw xmmE,xmmB	; xmmE=(20 01 22 03 24 05 26 07 28 09 2A 0B 2C 0D 2E 0F)
210
	punpcklbw xmmD,xmmF	; xmmD=(11 21 13 23 15 25 17 27 19 29 1B 2B 1D 2D 1F 2F)
211
212
	movdqa    xmmG,xmmA
213
	movdqa    xmmH,xmmA
214
	punpcklwd xmmA,xmmE	; xmmA=(00 10 20 01 02 12 22 03 04 14 24 05 06 16 26 07)
215
	punpckhwd xmmG,xmmE	; xmmG=(08 18 28 09 0A 1A 2A 0B 0C 1C 2C 0D 0E 1E 2E 0F)
216
217
	psrldq    xmmH,2	; xmmH=(02 12 04 14 06 16 08 18 0A 1A 0C 1C 0E 1E -- --)
218
	psrldq    xmmE,2	; xmmE=(22 03 24 05 26 07 28 09 2A 0B 2C 0D 2E 0F -- --)
219
220
	movdqa    xmmC,xmmD
221
	movdqa    xmmB,xmmD
222
	punpcklwd xmmD,xmmH	; xmmD=(11 21 02 12 13 23 04 14 15 25 06 16 17 27 08 18)
223
	punpckhwd xmmC,xmmH	; xmmC=(19 29 0A 1A 1B 2B 0C 1C 1D 2D 0E 1E 1F 2F -- --)
224
225
	psrldq    xmmB,2	; xmmB=(13 23 15 25 17 27 19 29 1B 2B 1D 2D 1F 2F -- --)
226
227
	movdqa    xmmF,xmmE
228
	punpcklwd xmmE,xmmB	; xmmE=(22 03 13 23 24 05 15 25 26 07 17 27 28 09 19 29)
229
	punpckhwd xmmF,xmmB	; xmmF=(2A 0B 1B 2B 2C 0D 1D 2D 2E 0F 1F 2F -- -- -- --)
230
231
	pshufd    xmmH,xmmA,0x4E; xmmH=(04 14 24 05 06 16 26 07 00 10 20 01 02 12 22 03)
232
	movdqa    xmmB,xmmE
233
	punpckldq xmmA,xmmD	; xmmA=(00 10 20 01 11 21 02 12 02 12 22 03 13 23 04 14)
234
	punpckldq xmmE,xmmH	; xmmE=(22 03 13 23 04 14 24 05 24 05 15 25 06 16 26 07)
235
	punpckhdq xmmD,xmmB	; xmmD=(15 25 06 16 26 07 17 27 17 27 08 18 28 09 19 29)
236
237
	pshufd    xmmH,xmmG,0x4E; xmmH=(0C 1C 2C 0D 0E 1E 2E 0F 08 18 28 09 0A 1A 2A 0B)
238
	movdqa    xmmB,xmmF
239
	punpckldq xmmG,xmmC	; xmmG=(08 18 28 09 19 29 0A 1A 0A 1A 2A 0B 1B 2B 0C 1C)
240
	punpckldq xmmF,xmmH	; xmmF=(2A 0B 1B 2B 0C 1C 2C 0D 2C 0D 1D 2D 0E 1E 2E 0F)
241
	punpckhdq xmmC,xmmB	; xmmC=(1D 2D 0E 1E 2E 0F 1F 2F 1F 2F -- -- -- -- -- --)
242
243
	punpcklqdq xmmA,xmmE	; xmmA=(00 10 20 01 11 21 02 12 22 03 13 23 04 14 24 05)
244
	punpcklqdq xmmD,xmmG	; xmmD=(15 25 06 16 26 07 17 27 08 18 28 09 19 29 0A 1A)
245
	punpcklqdq xmmF,xmmC	; xmmF=(2A 0B 1B 2B 0C 1C 2C 0D 1D 2D 0E 1E 2E 0F 1F 2F)
246
247
	cmp	rcx, byte SIZEOF_XMMWORD
248
	jb	short .column_st32
249
250
	test	rdi, SIZEOF_XMMWORD-1
251
	jnz	short .out1
252
	; --(aligned)-------------------
253
	movntdq	XMMWORD [rdi+0*SIZEOF_XMMWORD], xmmA
254
	movntdq	XMMWORD [rdi+1*SIZEOF_XMMWORD], xmmD
255
	movntdq	XMMWORD [rdi+2*SIZEOF_XMMWORD], xmmF
256
	add	rdi, byte RGB_PIXELSIZE*SIZEOF_XMMWORD	; outptr
257
	jmp	short .out0
258
.out1:	; --(unaligned)-----------------
259
	pcmpeqb    xmmH,xmmH			; xmmH=(all 1's)
260
	maskmovdqu xmmA,xmmH			; movntdqu XMMWORD [rdi], xmmA
261
	add	rdi, byte SIZEOF_XMMWORD	; outptr
262
	maskmovdqu xmmD,xmmH			; movntdqu XMMWORD [rdi], xmmD
263
	add	rdi, byte SIZEOF_XMMWORD	; outptr
264
	maskmovdqu xmmF,xmmH			; movntdqu XMMWORD [rdi], xmmF
265
	add	rdi, byte SIZEOF_XMMWORD	; outptr
266
.out0:
267
	sub	rcx, byte SIZEOF_XMMWORD
268
	jz	near .nextrow
269
270
	add	rsi, byte SIZEOF_XMMWORD	; inptr0
271
	add	rbx, byte SIZEOF_XMMWORD	; inptr1
272
	add	rdx, byte SIZEOF_XMMWORD	; inptr2
273
	jmp	near .columnloop
274
275
.column_st32:
276
	pcmpeqb	xmmH,xmmH			; xmmH=(all 1's)
277
	lea	rcx, [rcx+rcx*2]		; imul ecx, RGB_PIXELSIZE
278
	cmp	rcx, byte 2*SIZEOF_XMMWORD
279
	jb	short .column_st16
280
	maskmovdqu xmmA,xmmH			; movntdqu XMMWORD [rdi], xmmA
281
	add	rdi, byte SIZEOF_XMMWORD	; outptr
282
	maskmovdqu xmmD,xmmH			; movntdqu XMMWORD [rdi], xmmD
283
	add	rdi, byte SIZEOF_XMMWORD	; outptr
284
	movdqa	xmmA,xmmF
285
	sub	rcx, byte 2*SIZEOF_XMMWORD
286
	jmp	short .column_st15
287
.column_st16:
288
	cmp	rcx, byte SIZEOF_XMMWORD
289
	jb	short .column_st15
290
	maskmovdqu xmmA,xmmH			; movntdqu XMMWORD [rdi], xmmA
291
	add	rdi, byte SIZEOF_XMMWORD	; outptr
292
	movdqa	xmmA,xmmD
293
	sub	rcx, byte SIZEOF_XMMWORD
294
.column_st15:
295
	mov	rax,rcx
296
	xor	rcx, byte 0x0F
297
	shl	rcx, 2
298
	movd	xmmB,ecx
299
	psrlq	xmmH,4
300
	pcmpeqb	xmmE,xmmE
301
	psrlq	xmmH,xmmB
302
	psrlq	xmmE,xmmB
303
	punpcklbw xmmE,xmmH
304
	; ----------------
305
	mov	rcx,rdi
306
	and	rcx, byte SIZEOF_XMMWORD-1
307
	jz	short .adj0
308
	add	rax,rcx
309
	cmp	rax, byte SIZEOF_XMMWORD
310
	ja	short .adj0
311
	and	rdi, byte (-SIZEOF_XMMWORD)	; align to 16-byte boundary
312
	shl	rcx, 3			; pslldq xmmA,ecx & pslldq xmmE,rcx
313
	movdqa	xmmG,xmmA
314
	movdqa	xmmC,xmmE
315
	pslldq	xmmA, SIZEOF_XMMWORD/2
316
	pslldq	xmmE, SIZEOF_XMMWORD/2
317
	movd	xmmD,ecx
318
	sub	rcx, byte (SIZEOF_XMMWORD/2)*BYTE_BIT
319
	jb	short .adj1
320
	movd	xmmF,ecx
321
	psllq	xmmA,xmmF
322
	psllq	xmmE,xmmF
323
	jmp	short .adj0
324
.adj1:	neg	ecx
325
	movd	xmmF,ecx
326
	psrlq	xmmA,xmmF
327
	psrlq	xmmE,xmmF
328
	psllq	xmmG,xmmD
329
	psllq	xmmC,xmmD
330
	por	xmmA,xmmG
331
	por	xmmE,xmmC
332
.adj0:	; ----------------
333
	maskmovdqu xmmA,xmmE			; movntdqu XMMWORD [rdi], xmmA
334
335
%else ; RGB_PIXELSIZE == 4 ; -----------
336
337
%ifdef RGBX_FILLER_0XFF
338
	pcmpeqb   xmm6,xmm6		; xmm6=XE=X(02468ACE********)
339
	pcmpeqb   xmm7,xmm7		; xmm7=XO=X(13579BDF********)
340
%else
341
	pxor      xmm6,xmm6		; xmm6=XE=X(02468ACE********)
342
	pxor      xmm7,xmm7		; xmm7=XO=X(13579BDF********)
343
%endif
344
	; xmmA=(00 02 04 06 08 0A 0C 0E **), xmmB=(01 03 05 07 09 0B 0D 0F **)
345
	; xmmC=(10 12 14 16 18 1A 1C 1E **), xmmD=(11 13 15 17 19 1B 1D 1F **)
346
	; xmmE=(20 22 24 26 28 2A 2C 2E **), xmmF=(21 23 25 27 29 2B 2D 2F **)
347
	; xmmG=(30 32 34 36 38 3A 3C 3E **), xmmH=(31 33 35 37 39 3B 3D 3F **)
348
349
	punpcklbw xmmA,xmmC	; xmmA=(00 10 02 12 04 14 06 16 08 18 0A 1A 0C 1C 0E 1E)
350
	punpcklbw xmmE,xmmG	; xmmE=(20 30 22 32 24 34 26 36 28 38 2A 3A 2C 3C 2E 3E)
351
	punpcklbw xmmB,xmmD	; xmmB=(01 11 03 13 05 15 07 17 09 19 0B 1B 0D 1D 0F 1F)
352
	punpcklbw xmmF,xmmH	; xmmF=(21 31 23 33 25 35 27 37 29 39 2B 3B 2D 3D 2F 3F)
353
354
	movdqa    xmmC,xmmA
355
	punpcklwd xmmA,xmmE	; xmmA=(00 10 20 30 02 12 22 32 04 14 24 34 06 16 26 36)
356
	punpckhwd xmmC,xmmE	; xmmC=(08 18 28 38 0A 1A 2A 3A 0C 1C 2C 3C 0E 1E 2E 3E)
357
	movdqa    xmmG,xmmB
358
	punpcklwd xmmB,xmmF	; xmmB=(01 11 21 31 03 13 23 33 05 15 25 35 07 17 27 37)
359
	punpckhwd xmmG,xmmF	; xmmG=(09 19 29 39 0B 1B 2B 3B 0D 1D 2D 3D 0F 1F 2F 3F)
360
361
	movdqa    xmmD,xmmA
362
	punpckldq xmmA,xmmB	; xmmA=(00 10 20 30 01 11 21 31 02 12 22 32 03 13 23 33)
363
	punpckhdq xmmD,xmmB	; xmmD=(04 14 24 34 05 15 25 35 06 16 26 36 07 17 27 37)
364
	movdqa    xmmH,xmmC
365
	punpckldq xmmC,xmmG	; xmmC=(08 18 28 38 09 19 29 39 0A 1A 2A 3A 0B 1B 2B 3B)
366
	punpckhdq xmmH,xmmG	; xmmH=(0C 1C 2C 3C 0D 1D 2D 3D 0E 1E 2E 3E 0F 1F 2F 3F)
367
368
	cmp	rcx, byte SIZEOF_XMMWORD
369
	jb	short .column_st32
370
371
	test	rdi, SIZEOF_XMMWORD-1
372
	jnz	short .out1
373
	; --(aligned)-------------------
374
	movntdq	XMMWORD [rdi+0*SIZEOF_XMMWORD], xmmA
375
	movntdq	XMMWORD [rdi+1*SIZEOF_XMMWORD], xmmD
376
	movntdq	XMMWORD [rdi+2*SIZEOF_XMMWORD], xmmC
377
	movntdq	XMMWORD [rdi+3*SIZEOF_XMMWORD], xmmH
378
	add	rdi, byte RGB_PIXELSIZE*SIZEOF_XMMWORD	; outptr
379
	jmp	short .out0
380
.out1:	; --(unaligned)-----------------
381
	pcmpeqb    xmmE,xmmE			; xmmE=(all 1's)
382
	maskmovdqu xmmA,xmmE			; movntdqu XMMWORD [rdi], xmmA
383
	add	rdi, byte SIZEOF_XMMWORD	; outptr
384
	maskmovdqu xmmD,xmmE			; movntdqu XMMWORD [rdi], xmmD
385
	add	rdi, byte SIZEOF_XMMWORD	; outptr
386
	maskmovdqu xmmC,xmmE			; movntdqu XMMWORD [rdi], xmmC
387
	add	rdi, byte SIZEOF_XMMWORD	; outptr
388
	maskmovdqu xmmH,xmmE			; movntdqu XMMWORD [rdi], xmmH
389
	add	rdi, byte SIZEOF_XMMWORD	; outptr
390
.out0:
391
	sub	rcx, byte SIZEOF_XMMWORD
392
	jz	near .nextrow
393
394
	add	rsi, byte SIZEOF_XMMWORD	; inptr0
395
	add	rbx, byte SIZEOF_XMMWORD	; inptr1
396
	add	rdx, byte SIZEOF_XMMWORD	; inptr2
397
	jmp	near .columnloop
398
399
.column_st32:
400
	pcmpeqb	xmmE,xmmE			; xmmE=(all 1's)
401
	cmp	rcx, byte SIZEOF_XMMWORD/2
402
	jb	short .column_st16
403
	maskmovdqu xmmA,xmmE			; movntdqu XMMWORD [rdi], xmmA
404
	add	rdi, byte SIZEOF_XMMWORD	; outptr
405
	maskmovdqu xmmD,xmmE			; movntdqu XMMWORD [rdi], xmmD
406
	add	rdi, byte SIZEOF_XMMWORD	; outptr
407
	movdqa	xmmA,xmmC
408
	movdqa	xmmD,xmmH
409
	sub	rcx, byte SIZEOF_XMMWORD/2
410
.column_st16:
411
	cmp	rcx, byte SIZEOF_XMMWORD/4
412
	jb	short .column_st15
413
	maskmovdqu xmmA,xmmE			; movntdqu XMMWORD [rdi], xmmA
414
	add	rdi, byte SIZEOF_XMMWORD	; outptr
415
	movdqa	xmmA,xmmD
416
	sub	rcx, byte SIZEOF_XMMWORD/4
417
.column_st15:
418
	cmp	rcx, byte SIZEOF_XMMWORD/16
419
	jb	near .nextrow
420
	mov	rax,rcx
421
	xor	rcx, byte 0x03
422
	inc	rcx
423
	shl	rcx, 4
424
	movd	xmmF,ecx
425
	psrlq	xmmE,xmmF
426
	punpcklbw xmmE,xmmE
427
	; ----------------
428
	mov	rcx,rdi
429
	and	rcx, byte SIZEOF_XMMWORD-1
430
	jz	short .adj0
431
	lea	rax, [rcx+rax*4]	; RGB_PIXELSIZE
432
	cmp	rax, byte SIZEOF_XMMWORD
433
	ja	short .adj0
434
	and	rdi, byte (-SIZEOF_XMMWORD)	; align to 16-byte boundary
435
	shl	rcx, 3			; pslldq xmmA,ecx & pslldq xmmE,ecx
436
	movdqa	xmmB,xmmA
437
	movdqa	xmmG,xmmE
438
	pslldq	xmmA, SIZEOF_XMMWORD/2
439
	pslldq	xmmE, SIZEOF_XMMWORD/2
440
	movd	xmmC,ecx
441
	sub	rcx, byte (SIZEOF_XMMWORD/2)*BYTE_BIT
442
	jb	short .adj1
443
	movd	xmmH,ecx
444
	psllq	xmmA,xmmH
445
	psllq	xmmE,xmmH
446
	jmp	short .adj0
447
.adj1:	neg	rcx
448
	movd	xmmH,ecx
449
	psrlq	xmmA,xmmH
450
	psrlq	xmmE,xmmH
451
	psllq	xmmB,xmmC
452
	psllq	xmmG,xmmC
453
	por	xmmA,xmmB
454
	por	xmmE,xmmG
455
.adj0:	; ----------------
456
	maskmovdqu xmmA,xmmE			; movntdqu XMMWORD [rdi], xmmA
457
458
%endif ; RGB_PIXELSIZE ; ---------------
459
460
.nextrow:
461
	pop	rcx
462
	pop	rsi
463
	pop	rbx
464
	pop	rdx
465
	pop	rdi
466
	pop	rax
467
468
	add	rsi, byte SIZEOF_JSAMPROW
469
	add	rbx, byte SIZEOF_JSAMPROW
470
	add	rdx, byte SIZEOF_JSAMPROW
471
	add	rdi, byte SIZEOF_JSAMPROW	; output_buf
472
	dec	rax				; num_rows
473
	jg	near .rowloop
474
475
	sfence		; flush the write buffer
476
477
.return:
478
	pop	rbx
479
	uncollect_args
480
	mov	rsp,rbp		; rsp <- aligned rbp
481
	pop	rsp		; rsp <- original rbp
482
	pop	rbp
483
	ret
484
485
; For some reason, the OS X linker does not honor the request to align the
486
; segment unless we do this.
487
	align	16
(-)a/jpeg/simd/jdclrss2.asm (+505 lines)
Line     Link Here 
Line 0    Link Here 
1
;
2
; jdclrss2.asm - colorspace conversion (SSE2)
3
;
4
; Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
5
;
6
; Based on
7
; x86 SIMD extension for IJG JPEG library
8
; Copyright (C) 1999-2006, MIYASAKA Masaru.
9
; For conditions of distribution and use, see copyright notice in jsimdext.inc
10
;
11
; This file should be assembled with NASM (Netwide Assembler),
12
; can *not* be assembled with Microsoft's MASM or any compatible
13
; assembler (including Borland's Turbo Assembler).
14
; NASM is available from http://nasm.sourceforge.net/ or
15
; http://sourceforge.net/project/showfiles.php?group_id=6208
16
;
17
; [TAB8]
18
19
%include "jcolsamp.inc"
20
				
21
; --------------------------------------------------------------------------
22
	SECTION	SEG_TEXT
23
	BITS	32
24
;
25
; Convert some rows of samples to the output colorspace.
26
;
27
; GLOBAL(void)
28
; jsimd_ycc_rgb_convert_sse2 (JDIMENSION out_width,
29
;                             JSAMPIMAGE input_buf, JDIMENSION input_row,
30
;                             JSAMPARRAY output_buf, int num_rows)
31
;
32
33
%define out_width(b)	(b)+8			; JDIMENSION out_width
34
%define input_buf(b)	(b)+12		; JSAMPIMAGE input_buf
35
%define input_row(b)	(b)+16		; JDIMENSION input_row
36
%define output_buf(b)	(b)+20		; JSAMPARRAY output_buf
37
%define num_rows(b)	(b)+24		; int num_rows
38
39
%define original_ebp	ebp+0
40
%define wk(i)		ebp-(WK_NUM-(i))*SIZEOF_XMMWORD	; xmmword wk[WK_NUM]
41
%define WK_NUM		2
42
%define gotptr		wk(0)-SIZEOF_POINTER	; void * gotptr
43
44
	align	16
45
	global	EXTN(jsimd_ycc_rgb_convert_sse2)
46
47
EXTN(jsimd_ycc_rgb_convert_sse2):
48
	push	ebp
49
	mov	eax,esp				; eax = original ebp
50
	sub	esp, byte 4
51
	and	esp, byte (-SIZEOF_XMMWORD)	; align to 128 bits
52
	mov	[esp],eax
53
	mov	ebp,esp				; ebp = aligned ebp
54
	lea	esp, [wk(0)]
55
	pushpic	eax		; make a room for GOT address
56
	push	ebx
57
;	push	ecx		; need not be preserved
58
;	push	edx		; need not be preserved
59
	push	esi
60
	push	edi
61
62
	get_GOT	ebx			; get GOT address
63
	movpic	POINTER [gotptr], ebx	; save GOT address
64
65
	mov	ecx, JDIMENSION [out_width(eax)]	; num_cols
66
	test	ecx,ecx
67
	jz	near .return
68
69
	push	ecx
70
71
	mov	edi, JSAMPIMAGE [input_buf(eax)]
72
	mov	ecx, JDIMENSION [input_row(eax)]
73
	mov	esi, JSAMPARRAY [edi+0*SIZEOF_JSAMPARRAY]
74
	mov	ebx, JSAMPARRAY [edi+1*SIZEOF_JSAMPARRAY]
75
	mov	edx, JSAMPARRAY [edi+2*SIZEOF_JSAMPARRAY]
76
	lea	esi, [esi+ecx*SIZEOF_JSAMPROW]
77
	lea	ebx, [ebx+ecx*SIZEOF_JSAMPROW]
78
	lea	edx, [edx+ecx*SIZEOF_JSAMPROW]
79
80
	pop	ecx
81
82
	mov	edi, JSAMPARRAY [output_buf(eax)]
83
	mov	eax, INT [num_rows(eax)]
84
	test	eax,eax
85
	jle	near .return
86
	alignx	16,7
87
.rowloop:
88
	push	eax
89
	push	edi
90
	push	edx
91
	push	ebx
92
	push	esi
93
	push	ecx			; col
94
95
	mov	esi, JSAMPROW [esi]	; inptr0
96
	mov	ebx, JSAMPROW [ebx]	; inptr1
97
	mov	edx, JSAMPROW [edx]	; inptr2
98
	mov	edi, JSAMPROW [edi]	; outptr
99
	movpic	eax, POINTER [gotptr]	; load GOT address (eax)
100
	alignx	16,7
101
.columnloop:
102
103
	movdqa	xmm5, XMMWORD [ebx]	; xmm5=Cb(0123456789ABCDEF)
104
	movdqa	xmm1, XMMWORD [edx]	; xmm1=Cr(0123456789ABCDEF)
105
106
	pcmpeqw	xmm4,xmm4
107
	pcmpeqw	xmm7,xmm7
108
	psrlw	xmm4,BYTE_BIT
109
	psllw	xmm7,7			; xmm7={0xFF80 0xFF80 0xFF80 0xFF80 ..}
110
	movdqa	xmm0,xmm4		; xmm0=xmm4={0xFF 0x00 0xFF 0x00 ..}
111
112
	pand	xmm4,xmm5		; xmm4=Cb(02468ACE)=CbE
113
	psrlw	xmm5,BYTE_BIT		; xmm5=Cb(13579BDF)=CbO
114
	pand	xmm0,xmm1		; xmm0=Cr(02468ACE)=CrE
115
	psrlw	xmm1,BYTE_BIT		; xmm1=Cr(13579BDF)=CrO
116
117
	paddw	xmm4,xmm7
118
	paddw	xmm5,xmm7
119
	paddw	xmm0,xmm7
120
	paddw	xmm1,xmm7
121
122
	; (Original)
123
	; R = Y                + 1.40200 * Cr
124
	; G = Y - 0.34414 * Cb - 0.71414 * Cr
125
	; B = Y + 1.77200 * Cb
126
	;
127
	; (This implementation)
128
	; R = Y                + 0.40200 * Cr + Cr
129
	; G = Y - 0.34414 * Cb + 0.28586 * Cr - Cr
130
	; B = Y - 0.22800 * Cb + Cb + Cb
131
132
	movdqa	xmm2,xmm4		; xmm2=CbE
133
	movdqa	xmm3,xmm5		; xmm3=CbO
134
	paddw	xmm4,xmm4		; xmm4=2*CbE
135
	paddw	xmm5,xmm5		; xmm5=2*CbO
136
	movdqa	xmm6,xmm0		; xmm6=CrE
137
	movdqa	xmm7,xmm1		; xmm7=CrO
138
	paddw	xmm0,xmm0		; xmm0=2*CrE
139
	paddw	xmm1,xmm1		; xmm1=2*CrO
140
141
	pmulhw	xmm4,[GOTOFF(eax,PW_MF0228)]	; xmm4=(2*CbE * -FIX(0.22800))
142
	pmulhw	xmm5,[GOTOFF(eax,PW_MF0228)]	; xmm5=(2*CbO * -FIX(0.22800))
143
	pmulhw	xmm0,[GOTOFF(eax,PW_F0402)]	; xmm0=(2*CrE * FIX(0.40200))
144
	pmulhw	xmm1,[GOTOFF(eax,PW_F0402)]	; xmm1=(2*CrO * FIX(0.40200))
145
146
	paddw	xmm4,[GOTOFF(eax,PW_ONE)]
147
	paddw	xmm5,[GOTOFF(eax,PW_ONE)]
148
	psraw	xmm4,1			; xmm4=(CbE * -FIX(0.22800))
149
	psraw	xmm5,1			; xmm5=(CbO * -FIX(0.22800))
150
	paddw	xmm0,[GOTOFF(eax,PW_ONE)]
151
	paddw	xmm1,[GOTOFF(eax,PW_ONE)]
152
	psraw	xmm0,1			; xmm0=(CrE * FIX(0.40200))
153
	psraw	xmm1,1			; xmm1=(CrO * FIX(0.40200))
154
155
	paddw	xmm4,xmm2
156
	paddw	xmm5,xmm3
157
	paddw	xmm4,xmm2		; xmm4=(CbE * FIX(1.77200))=(B-Y)E
158
	paddw	xmm5,xmm3		; xmm5=(CbO * FIX(1.77200))=(B-Y)O
159
	paddw	xmm0,xmm6		; xmm0=(CrE * FIX(1.40200))=(R-Y)E
160
	paddw	xmm1,xmm7		; xmm1=(CrO * FIX(1.40200))=(R-Y)O
161
162
	movdqa	XMMWORD [wk(0)], xmm4	; wk(0)=(B-Y)E
163
	movdqa	XMMWORD [wk(1)], xmm5	; wk(1)=(B-Y)O
164
165
	movdqa    xmm4,xmm2
166
	movdqa    xmm5,xmm3
167
	punpcklwd xmm2,xmm6
168
	punpckhwd xmm4,xmm6
169
	pmaddwd   xmm2,[GOTOFF(eax,PW_MF0344_F0285)]
170
	pmaddwd   xmm4,[GOTOFF(eax,PW_MF0344_F0285)]
171
	punpcklwd xmm3,xmm7
172
	punpckhwd xmm5,xmm7
173
	pmaddwd   xmm3,[GOTOFF(eax,PW_MF0344_F0285)]
174
	pmaddwd   xmm5,[GOTOFF(eax,PW_MF0344_F0285)]
175
176
	paddd     xmm2,[GOTOFF(eax,PD_ONEHALF)]
177
	paddd     xmm4,[GOTOFF(eax,PD_ONEHALF)]
178
	psrad     xmm2,SCALEBITS
179
	psrad     xmm4,SCALEBITS
180
	paddd     xmm3,[GOTOFF(eax,PD_ONEHALF)]
181
	paddd     xmm5,[GOTOFF(eax,PD_ONEHALF)]
182
	psrad     xmm3,SCALEBITS
183
	psrad     xmm5,SCALEBITS
184
185
	packssdw  xmm2,xmm4	; xmm2=CbE*-FIX(0.344)+CrE*FIX(0.285)
186
	packssdw  xmm3,xmm5	; xmm3=CbO*-FIX(0.344)+CrO*FIX(0.285)
187
	psubw     xmm2,xmm6	; xmm2=CbE*-FIX(0.344)+CrE*-FIX(0.714)=(G-Y)E
188
	psubw     xmm3,xmm7	; xmm3=CbO*-FIX(0.344)+CrO*-FIX(0.714)=(G-Y)O
189
190
	movdqa    xmm5, XMMWORD [esi]	; xmm5=Y(0123456789ABCDEF)
191
192
	pcmpeqw   xmm4,xmm4
193
	psrlw     xmm4,BYTE_BIT		; xmm4={0xFF 0x00 0xFF 0x00 ..}
194
	pand      xmm4,xmm5		; xmm4=Y(02468ACE)=YE
195
	psrlw     xmm5,BYTE_BIT		; xmm5=Y(13579BDF)=YO
196
197
	paddw     xmm0,xmm4		; xmm0=((R-Y)E+YE)=RE=R(02468ACE)
198
	paddw     xmm1,xmm5		; xmm1=((R-Y)O+YO)=RO=R(13579BDF)
199
	packuswb  xmm0,xmm0		; xmm0=R(02468ACE********)
200
	packuswb  xmm1,xmm1		; xmm1=R(13579BDF********)
201
202
	paddw     xmm2,xmm4		; xmm2=((G-Y)E+YE)=GE=G(02468ACE)
203
	paddw     xmm3,xmm5		; xmm3=((G-Y)O+YO)=GO=G(13579BDF)
204
	packuswb  xmm2,xmm2		; xmm2=G(02468ACE********)
205
	packuswb  xmm3,xmm3		; xmm3=G(13579BDF********)
206
207
	paddw     xmm4, XMMWORD [wk(0)]	; xmm4=(YE+(B-Y)E)=BE=B(02468ACE)
208
	paddw     xmm5, XMMWORD [wk(1)]	; xmm5=(YO+(B-Y)O)=BO=B(13579BDF)
209
	packuswb  xmm4,xmm4		; xmm4=B(02468ACE********)
210
	packuswb  xmm5,xmm5		; xmm5=B(13579BDF********)
211
212
%if RGB_PIXELSIZE == 3 ; ---------------
213
214
	; xmmA=(00 02 04 06 08 0A 0C 0E **), xmmB=(01 03 05 07 09 0B 0D 0F **)
215
	; xmmC=(10 12 14 16 18 1A 1C 1E **), xmmD=(11 13 15 17 19 1B 1D 1F **)
216
	; xmmE=(20 22 24 26 28 2A 2C 2E **), xmmF=(21 23 25 27 29 2B 2D 2F **)
217
	; xmmG=(** ** ** ** ** ** ** ** **), xmmH=(** ** ** ** ** ** ** ** **)
218
219
	punpcklbw xmmA,xmmC	; xmmA=(00 10 02 12 04 14 06 16 08 18 0A 1A 0C 1C 0E 1E)
220
	punpcklbw xmmE,xmmB	; xmmE=(20 01 22 03 24 05 26 07 28 09 2A 0B 2C 0D 2E 0F)
221
	punpcklbw xmmD,xmmF	; xmmD=(11 21 13 23 15 25 17 27 19 29 1B 2B 1D 2D 1F 2F)
222
223
	movdqa    xmmG,xmmA
224
	movdqa    xmmH,xmmA
225
	punpcklwd xmmA,xmmE	; xmmA=(00 10 20 01 02 12 22 03 04 14 24 05 06 16 26 07)
226
	punpckhwd xmmG,xmmE	; xmmG=(08 18 28 09 0A 1A 2A 0B 0C 1C 2C 0D 0E 1E 2E 0F)
227
228
	psrldq    xmmH,2	; xmmH=(02 12 04 14 06 16 08 18 0A 1A 0C 1C 0E 1E -- --)
229
	psrldq    xmmE,2	; xmmE=(22 03 24 05 26 07 28 09 2A 0B 2C 0D 2E 0F -- --)
230
231
	movdqa    xmmC,xmmD
232
	movdqa    xmmB,xmmD
233
	punpcklwd xmmD,xmmH	; xmmD=(11 21 02 12 13 23 04 14 15 25 06 16 17 27 08 18)
234
	punpckhwd xmmC,xmmH	; xmmC=(19 29 0A 1A 1B 2B 0C 1C 1D 2D 0E 1E 1F 2F -- --)
235
236
	psrldq    xmmB,2	; xmmB=(13 23 15 25 17 27 19 29 1B 2B 1D 2D 1F 2F -- --)
237
238
	movdqa    xmmF,xmmE
239
	punpcklwd xmmE,xmmB	; xmmE=(22 03 13 23 24 05 15 25 26 07 17 27 28 09 19 29)
240
	punpckhwd xmmF,xmmB	; xmmF=(2A 0B 1B 2B 2C 0D 1D 2D 2E 0F 1F 2F -- -- -- --)
241
242
	pshufd    xmmH,xmmA,0x4E; xmmH=(04 14 24 05 06 16 26 07 00 10 20 01 02 12 22 03)
243
	movdqa    xmmB,xmmE
244
	punpckldq xmmA,xmmD	; xmmA=(00 10 20 01 11 21 02 12 02 12 22 03 13 23 04 14)
245
	punpckldq xmmE,xmmH	; xmmE=(22 03 13 23 04 14 24 05 24 05 15 25 06 16 26 07)
246
	punpckhdq xmmD,xmmB	; xmmD=(15 25 06 16 26 07 17 27 17 27 08 18 28 09 19 29)
247
248
	pshufd    xmmH,xmmG,0x4E; xmmH=(0C 1C 2C 0D 0E 1E 2E 0F 08 18 28 09 0A 1A 2A 0B)
249
	movdqa    xmmB,xmmF
250
	punpckldq xmmG,xmmC	; xmmG=(08 18 28 09 19 29 0A 1A 0A 1A 2A 0B 1B 2B 0C 1C)
251
	punpckldq xmmF,xmmH	; xmmF=(2A 0B 1B 2B 0C 1C 2C 0D 2C 0D 1D 2D 0E 1E 2E 0F)
252
	punpckhdq xmmC,xmmB	; xmmC=(1D 2D 0E 1E 2E 0F 1F 2F 1F 2F -- -- -- -- -- --)
253
254
	punpcklqdq xmmA,xmmE	; xmmA=(00 10 20 01 11 21 02 12 22 03 13 23 04 14 24 05)
255
	punpcklqdq xmmD,xmmG	; xmmD=(15 25 06 16 26 07 17 27 08 18 28 09 19 29 0A 1A)
256
	punpcklqdq xmmF,xmmC	; xmmF=(2A 0B 1B 2B 0C 1C 2C 0D 1D 2D 0E 1E 2E 0F 1F 2F)
257
258
	cmp	ecx, byte SIZEOF_XMMWORD
259
	jb	short .column_st32
260
261
	test	edi, SIZEOF_XMMWORD-1
262
	jnz	short .out1
263
	; --(aligned)-------------------
264
	movntdq	XMMWORD [edi+0*SIZEOF_XMMWORD], xmmA
265
	movntdq	XMMWORD [edi+1*SIZEOF_XMMWORD], xmmD
266
	movntdq	XMMWORD [edi+2*SIZEOF_XMMWORD], xmmF
267
	add	edi, byte RGB_PIXELSIZE*SIZEOF_XMMWORD	; outptr
268
	jmp	short .out0
269
.out1:	; --(unaligned)-----------------
270
	pcmpeqb    xmmH,xmmH			; xmmH=(all 1's)
271
	maskmovdqu xmmA,xmmH			; movntdqu XMMWORD [edi], xmmA
272
	add	edi, byte SIZEOF_XMMWORD	; outptr
273
	maskmovdqu xmmD,xmmH			; movntdqu XMMWORD [edi], xmmD
274
	add	edi, byte SIZEOF_XMMWORD	; outptr
275
	maskmovdqu xmmF,xmmH			; movntdqu XMMWORD [edi], xmmF
276
	add	edi, byte SIZEOF_XMMWORD	; outptr
277
.out0:
278
	sub	ecx, byte SIZEOF_XMMWORD
279
	jz	near .nextrow
280
281
	add	esi, byte SIZEOF_XMMWORD	; inptr0
282
	add	ebx, byte SIZEOF_XMMWORD	; inptr1
283
	add	edx, byte SIZEOF_XMMWORD	; inptr2
284
	jmp	near .columnloop
285
	alignx	16,7
286
287
.column_st32:
288
	pcmpeqb	xmmH,xmmH			; xmmH=(all 1's)
289
	lea	ecx, [ecx+ecx*2]		; imul ecx, RGB_PIXELSIZE
290
	cmp	ecx, byte 2*SIZEOF_XMMWORD
291
	jb	short .column_st16
292
	maskmovdqu xmmA,xmmH			; movntdqu XMMWORD [edi], xmmA
293
	add	edi, byte SIZEOF_XMMWORD	; outptr
294
	maskmovdqu xmmD,xmmH			; movntdqu XMMWORD [edi], xmmD
295
	add	edi, byte SIZEOF_XMMWORD	; outptr
296
	movdqa	xmmA,xmmF
297
	sub	ecx, byte 2*SIZEOF_XMMWORD
298
	jmp	short .column_st15
299
.column_st16:
300
	cmp	ecx, byte SIZEOF_XMMWORD
301
	jb	short .column_st15
302
	maskmovdqu xmmA,xmmH			; movntdqu XMMWORD [edi], xmmA
303
	add	edi, byte SIZEOF_XMMWORD	; outptr
304
	movdqa	xmmA,xmmD
305
	sub	ecx, byte SIZEOF_XMMWORD
306
.column_st15:
307
	mov	eax,ecx
308
	xor	ecx, byte 0x0F
309
	shl	ecx, 2
310
	movd	xmmB,ecx
311
	psrlq	xmmH,4
312
	pcmpeqb	xmmE,xmmE
313
	psrlq	xmmH,xmmB
314
	psrlq	xmmE,xmmB
315
	punpcklbw xmmE,xmmH
316
	; ----------------
317
	mov	ecx,edi
318
	and	ecx, byte SIZEOF_XMMWORD-1
319
	jz	short .adj0
320
	add	eax,ecx
321
	cmp	eax, byte SIZEOF_XMMWORD
322
	ja	short .adj0
323
	and	edi, byte (-SIZEOF_XMMWORD)	; align to 16-byte boundary
324
	shl	ecx, 3			; pslldq xmmA,ecx & pslldq xmmE,ecx
325
	movdqa	xmmG,xmmA
326
	movdqa	xmmC,xmmE
327
	pslldq	xmmA, SIZEOF_XMMWORD/2
328
	pslldq	xmmE, SIZEOF_XMMWORD/2
329
	movd	xmmD,ecx
330
	sub	ecx, byte (SIZEOF_XMMWORD/2)*BYTE_BIT
331
	jb	short .adj1
332
	movd	xmmF,ecx
333
	psllq	xmmA,xmmF
334
	psllq	xmmE,xmmF
335
	jmp	short .adj0
336
.adj1:	neg	ecx
337
	movd	xmmF,ecx
338
	psrlq	xmmA,xmmF
339
	psrlq	xmmE,xmmF
340
	psllq	xmmG,xmmD
341
	psllq	xmmC,xmmD
342
	por	xmmA,xmmG
343
	por	xmmE,xmmC
344
.adj0:	; ----------------
345
	maskmovdqu xmmA,xmmE			; movntdqu XMMWORD [edi], xmmA
346
347
%else ; RGB_PIXELSIZE == 4 ; -----------
348
349
%ifdef RGBX_FILLER_0XFF
350
	pcmpeqb   xmm6,xmm6		; xmm6=XE=X(02468ACE********)
351
	pcmpeqb   xmm7,xmm7		; xmm7=XO=X(13579BDF********)
352
%else
353
	pxor      xmm6,xmm6		; xmm6=XE=X(02468ACE********)
354
	pxor      xmm7,xmm7		; xmm7=XO=X(13579BDF********)
355
%endif
356
	; xmmA=(00 02 04 06 08 0A 0C 0E **), xmmB=(01 03 05 07 09 0B 0D 0F **)
357
	; xmmC=(10 12 14 16 18 1A 1C 1E **), xmmD=(11 13 15 17 19 1B 1D 1F **)
358
	; xmmE=(20 22 24 26 28 2A 2C 2E **), xmmF=(21 23 25 27 29 2B 2D 2F **)
359
	; xmmG=(30 32 34 36 38 3A 3C 3E **), xmmH=(31 33 35 37 39 3B 3D 3F **)
360
361
	punpcklbw xmmA,xmmC	; xmmA=(00 10 02 12 04 14 06 16 08 18 0A 1A 0C 1C 0E 1E)
362
	punpcklbw xmmE,xmmG	; xmmE=(20 30 22 32 24 34 26 36 28 38 2A 3A 2C 3C 2E 3E)
363
	punpcklbw xmmB,xmmD	; xmmB=(01 11 03 13 05 15 07 17 09 19 0B 1B 0D 1D 0F 1F)
364
	punpcklbw xmmF,xmmH	; xmmF=(21 31 23 33 25 35 27 37 29 39 2B 3B 2D 3D 2F 3F)
365
366
	movdqa    xmmC,xmmA
367
	punpcklwd xmmA,xmmE	; xmmA=(00 10 20 30 02 12 22 32 04 14 24 34 06 16 26 36)
368
	punpckhwd xmmC,xmmE	; xmmC=(08 18 28 38 0A 1A 2A 3A 0C 1C 2C 3C 0E 1E 2E 3E)
369
	movdqa    xmmG,xmmB
370
	punpcklwd xmmB,xmmF	; xmmB=(01 11 21 31 03 13 23 33 05 15 25 35 07 17 27 37)
371
	punpckhwd xmmG,xmmF	; xmmG=(09 19 29 39 0B 1B 2B 3B 0D 1D 2D 3D 0F 1F 2F 3F)
372
373
	movdqa    xmmD,xmmA
374
	punpckldq xmmA,xmmB	; xmmA=(00 10 20 30 01 11 21 31 02 12 22 32 03 13 23 33)
375
	punpckhdq xmmD,xmmB	; xmmD=(04 14 24 34 05 15 25 35 06 16 26 36 07 17 27 37)
376
	movdqa    xmmH,xmmC
377
	punpckldq xmmC,xmmG	; xmmC=(08 18 28 38 09 19 29 39 0A 1A 2A 3A 0B 1B 2B 3B)
378
	punpckhdq xmmH,xmmG	; xmmH=(0C 1C 2C 3C 0D 1D 2D 3D 0E 1E 2E 3E 0F 1F 2F 3F)
379
380
	cmp	ecx, byte SIZEOF_XMMWORD
381
	jb	short .column_st32
382
383
	test	edi, SIZEOF_XMMWORD-1
384
	jnz	short .out1
385
	; --(aligned)-------------------
386
	movntdq	XMMWORD [edi+0*SIZEOF_XMMWORD], xmmA
387
	movntdq	XMMWORD [edi+1*SIZEOF_XMMWORD], xmmD
388
	movntdq	XMMWORD [edi+2*SIZEOF_XMMWORD], xmmC
389
	movntdq	XMMWORD [edi+3*SIZEOF_XMMWORD], xmmH
390
	add	edi, byte RGB_PIXELSIZE*SIZEOF_XMMWORD	; outptr
391
	jmp	short .out0
392
.out1:	; --(unaligned)-----------------
393
	pcmpeqb    xmmE,xmmE			; xmmE=(all 1's)
394
	maskmovdqu xmmA,xmmE			; movntdqu XMMWORD [edi], xmmA
395
	add	edi, byte SIZEOF_XMMWORD	; outptr
396
	maskmovdqu xmmD,xmmE			; movntdqu XMMWORD [edi], xmmD
397
	add	edi, byte SIZEOF_XMMWORD	; outptr
398
	maskmovdqu xmmC,xmmE			; movntdqu XMMWORD [edi], xmmC
399
	add	edi, byte SIZEOF_XMMWORD	; outptr
400
	maskmovdqu xmmH,xmmE			; movntdqu XMMWORD [edi], xmmH
401
	add	edi, byte SIZEOF_XMMWORD	; outptr
402
.out0:
403
	sub	ecx, byte SIZEOF_XMMWORD
404
	jz	near .nextrow
405
406
	add	esi, byte SIZEOF_XMMWORD	; inptr0
407
	add	ebx, byte SIZEOF_XMMWORD	; inptr1
408
	add	edx, byte SIZEOF_XMMWORD	; inptr2
409
	jmp	near .columnloop
410
	alignx	16,7
411
412
.column_st32:
413
	pcmpeqb	xmmE,xmmE			; xmmE=(all 1's)
414
	cmp	ecx, byte SIZEOF_XMMWORD/2
415
	jb	short .column_st16
416
	maskmovdqu xmmA,xmmE			; movntdqu XMMWORD [edi], xmmA
417
	add	edi, byte SIZEOF_XMMWORD	; outptr
418
	maskmovdqu xmmD,xmmE			; movntdqu XMMWORD [edi], xmmD
419
	add	edi, byte SIZEOF_XMMWORD	; outptr
420
	movdqa	xmmA,xmmC
421
	movdqa	xmmD,xmmH
422
	sub	ecx, byte SIZEOF_XMMWORD/2
423
.column_st16:
424
	cmp	ecx, byte SIZEOF_XMMWORD/4
425
	jb	short .column_st15
426
	maskmovdqu xmmA,xmmE			; movntdqu XMMWORD [edi], xmmA
427
	add	edi, byte SIZEOF_XMMWORD	; outptr
428
	movdqa	xmmA,xmmD
429
	sub	ecx, byte SIZEOF_XMMWORD/4
430
.column_st15:
431
	cmp	ecx, byte SIZEOF_XMMWORD/16
432
	jb	short .nextrow
433
	mov	eax,ecx
434
	xor	ecx, byte 0x03
435
	inc	ecx
436
	shl	ecx, 4
437
	movd	xmmF,ecx
438
	psrlq	xmmE,xmmF
439
	punpcklbw xmmE,xmmE
440
	; ----------------
441
	mov	ecx,edi
442
	and	ecx, byte SIZEOF_XMMWORD-1
443
	jz	short .adj0
444
	lea	eax, [ecx+eax*4]	; RGB_PIXELSIZE
445
	cmp	eax, byte SIZEOF_XMMWORD
446
	ja	short .adj0
447
	and	edi, byte (-SIZEOF_XMMWORD)	; align to 16-byte boundary
448
	shl	ecx, 3			; pslldq xmmA,ecx & pslldq xmmE,ecx
449
	movdqa	xmmB,xmmA
450
	movdqa	xmmG,xmmE
451
	pslldq	xmmA, SIZEOF_XMMWORD/2
452
	pslldq	xmmE, SIZEOF_XMMWORD/2
453
	movd	xmmC,ecx
454
	sub	ecx, byte (SIZEOF_XMMWORD/2)*BYTE_BIT
455
	jb	short .adj1
456
	movd	xmmH,ecx
457
	psllq	xmmA,xmmH
458
	psllq	xmmE,xmmH
459
	jmp	short .adj0
460
.adj1:	neg	ecx
461
	movd	xmmH,ecx
462
	psrlq	xmmA,xmmH
463
	psrlq	xmmE,xmmH
464
	psllq	xmmB,xmmC
465
	psllq	xmmG,xmmC
466
	por	xmmA,xmmB
467
	por	xmmE,xmmG
468
.adj0:	; ----------------
469
	maskmovdqu xmmA,xmmE			; movntdqu XMMWORD [edi], xmmA
470
471
%endif ; RGB_PIXELSIZE ; ---------------
472
473
	alignx	16,7
474
475
.nextrow:
476
	pop	ecx
477
	pop	esi
478
	pop	ebx
479
	pop	edx
480
	pop	edi
481
	pop	eax
482
483
	add	esi, byte SIZEOF_JSAMPROW
484
	add	ebx, byte SIZEOF_JSAMPROW
485
	add	edx, byte SIZEOF_JSAMPROW
486
	add	edi, byte SIZEOF_JSAMPROW	; output_buf
487
	dec	eax				; num_rows
488
	jg	near .rowloop
489
490
	sfence		; flush the write buffer
491
492
.return:
493
	pop	edi
494
	pop	esi
495
;	pop	edx		; need not be preserved
496
;	pop	ecx		; need not be preserved
497
	pop	ebx
498
	mov	esp,ebp		; esp <- aligned ebp
499
	pop	esp		; esp <- original ebp
500
	pop	ebp
501
	ret
502
503
; For some reason, the OS X linker does not honor the request to align the
504
; segment unless we do this.
505
	align	16
(-)a/jpeg/simd/jdcolmmx.asm (+117 lines)
Line     Link Here 
Line 0    Link Here 
1
;
2
; jdcolmmx.asm - colorspace conversion (MMX)
3
;
4
; Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
5
; Copyright 2009 D. R. Commander
6
;
7
; Based on
8
; x86 SIMD extension for IJG JPEG library
9
; Copyright (C) 1999-2006, MIYASAKA Masaru.
10
; For conditions of distribution and use, see copyright notice in jsimdext.inc
11
;
12
; This file should be assembled with NASM (Netwide Assembler),
13
; can *not* be assembled with Microsoft's MASM or any compatible
14
; assembler (including Borland's Turbo Assembler).
15
; NASM is available from http://nasm.sourceforge.net/ or
16
; http://sourceforge.net/project/showfiles.php?group_id=6208
17
;
18
; [TAB8]
19
20
%include "jsimdext.inc"
21
22
; --------------------------------------------------------------------------
23
24
%define SCALEBITS	16
25
26
F_0_344	equ	 22554			; FIX(0.34414)
27
F_0_714	equ	 46802			; FIX(0.71414)
28
F_1_402	equ	 91881			; FIX(1.40200)
29
F_1_772	equ	116130			; FIX(1.77200)
30
F_0_402	equ	(F_1_402 - 65536)	; FIX(1.40200) - FIX(1)
31
F_0_285	equ	( 65536 - F_0_714)	; FIX(1) - FIX(0.71414)
32
F_0_228	equ	(131072 - F_1_772)	; FIX(2) - FIX(1.77200)
33
34
; --------------------------------------------------------------------------
35
	SECTION	SEG_CONST
36
37
	alignz	16
38
	global	EXTN(jconst_ycc_rgb_convert_mmx)
39
40
EXTN(jconst_ycc_rgb_convert_mmx):
41
42
PW_F0402	times 4 dw  F_0_402
43
PW_MF0228	times 4 dw -F_0_228
44
PW_MF0344_F0285	times 2 dw -F_0_344, F_0_285
45
PW_ONE		times 4 dw  1
46
PD_ONEHALF	times 2 dd  1 << (SCALEBITS-1)
47
48
	alignz	16
49
50
; --------------------------------------------------------------------------
51
%include "jdclrmmx.asm"
52
53
%undef RGB_RED
54
%undef RGB_GREEN
55
%undef RGB_BLUE
56
%undef RGB_PIXELSIZE
57
%define RGB_RED 0
58
%define RGB_GREEN 1
59
%define RGB_BLUE 2
60
%define RGB_PIXELSIZE 3
61
%define jsimd_ycc_rgb_convert_mmx jsimd_ycc_extrgb_convert_mmx
62
%include "jdclrmmx.asm"
63
64
%undef RGB_RED
65
%undef RGB_GREEN
66
%undef RGB_BLUE
67
%undef RGB_PIXELSIZE
68
%define RGB_RED 0
69
%define RGB_GREEN 1
70
%define RGB_BLUE 2
71
%define RGB_PIXELSIZE 4
72
%define jsimd_ycc_rgb_convert_mmx jsimd_ycc_extrgbx_convert_mmx
73
%include "jdclrmmx.asm"
74
75
%undef RGB_RED
76
%undef RGB_GREEN
77
%undef RGB_BLUE
78
%undef RGB_PIXELSIZE
79
%define RGB_RED 2
80
%define RGB_GREEN 1
81
%define RGB_BLUE 0
82
%define RGB_PIXELSIZE 3
83
%define jsimd_ycc_rgb_convert_mmx jsimd_ycc_extbgr_convert_mmx
84
%include "jdclrmmx.asm"
85
86
%undef RGB_RED
87
%undef RGB_GREEN
88
%undef RGB_BLUE
89
%undef RGB_PIXELSIZE
90
%define RGB_RED 2
91
%define RGB_GREEN 1
92
%define RGB_BLUE 0
93
%define RGB_PIXELSIZE 4
94
%define jsimd_ycc_rgb_convert_mmx jsimd_ycc_extbgrx_convert_mmx
95
%include "jdclrmmx.asm"
96
97
%undef RGB_RED
98
%undef RGB_GREEN
99
%undef RGB_BLUE
100
%undef RGB_PIXELSIZE
101
%define RGB_RED 3
102
%define RGB_GREEN 2
103
%define RGB_BLUE 1
104
%define RGB_PIXELSIZE 4
105
%define jsimd_ycc_rgb_convert_mmx jsimd_ycc_extxbgr_convert_mmx
106
%include "jdclrmmx.asm"
107
108
%undef RGB_RED
109
%undef RGB_GREEN
110
%undef RGB_BLUE
111
%undef RGB_PIXELSIZE
112
%define RGB_RED 1
113
%define RGB_GREEN 2
114
%define RGB_BLUE 3
115
%define RGB_PIXELSIZE 4
116
%define jsimd_ycc_rgb_convert_mmx jsimd_ycc_extxrgb_convert_mmx
117
%include "jdclrmmx.asm"
(-)a/jpeg/simd/jdcolss2-64.asm (+117 lines)
Line     Link Here 
Line 0    Link Here 
1
;
2
; jdcolss2-64.asm - colorspace conversion (64-bit SSE2)
3
;
4
; Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
5
; Copyright 2009 D. R. Commander
6
;
7
; Based on
8
; x86 SIMD extension for IJG JPEG library
9
; Copyright (C) 1999-2006, MIYASAKA Masaru.
10
; For conditions of distribution and use, see copyright notice in jsimdext.inc
11
;
12
; This file should be assembled with NASM (Netwide Assembler),
13
; can *not* be assembled with Microsoft's MASM or any compatible
14
; assembler (including Borland's Turbo Assembler).
15
; NASM is available from http://nasm.sourceforge.net/ or
16
; http://sourceforge.net/project/showfiles.php?group_id=6208
17
;
18
; [TAB8]
19
20
%include "jsimdext.inc"
21
22
; --------------------------------------------------------------------------
23
24
%define SCALEBITS	16
25
26
F_0_344	equ	 22554			; FIX(0.34414)
27
F_0_714	equ	 46802			; FIX(0.71414)
28
F_1_402	equ	 91881			; FIX(1.40200)
29
F_1_772	equ	116130			; FIX(1.77200)
30
F_0_402	equ	(F_1_402 - 65536)	; FIX(1.40200) - FIX(1)
31
F_0_285	equ	( 65536 - F_0_714)	; FIX(1) - FIX(0.71414)
32
F_0_228	equ	(131072 - F_1_772)	; FIX(2) - FIX(1.77200)
33
34
; --------------------------------------------------------------------------
35
	SECTION	SEG_CONST
36
37
	alignz	16
38
	global	EXTN(jconst_ycc_rgb_convert_sse2)
39
40
EXTN(jconst_ycc_rgb_convert_sse2):
41
42
PW_F0402	times 8 dw  F_0_402
43
PW_MF0228	times 8 dw -F_0_228
44
PW_MF0344_F0285	times 4 dw -F_0_344, F_0_285
45
PW_ONE		times 8 dw  1
46
PD_ONEHALF	times 4 dd  1 << (SCALEBITS-1)
47
48
	alignz	16
49
50
; --------------------------------------------------------------------------
51
%include "jdclrss2-64.asm"
52
53
%undef RGB_RED
54
%undef RGB_GREEN
55
%undef RGB_BLUE
56
%undef RGB_PIXELSIZE
57
%define RGB_RED 0
58
%define RGB_GREEN 1
59
%define RGB_BLUE 2
60
%define RGB_PIXELSIZE 3
61
%define jsimd_ycc_rgb_convert_sse2 jsimd_ycc_extrgb_convert_sse2
62
%include "jdclrss2-64.asm"
63
64
%undef RGB_RED
65
%undef RGB_GREEN
66
%undef RGB_BLUE
67
%undef RGB_PIXELSIZE
68
%define RGB_RED 0
69
%define RGB_GREEN 1
70
%define RGB_BLUE 2
71
%define RGB_PIXELSIZE 4
72
%define jsimd_ycc_rgb_convert_sse2 jsimd_ycc_extrgbx_convert_sse2
73
%include "jdclrss2-64.asm"
74
75
%undef RGB_RED
76
%undef RGB_GREEN
77
%undef RGB_BLUE
78
%undef RGB_PIXELSIZE
79
%define RGB_RED 2
80
%define RGB_GREEN 1
81
%define RGB_BLUE 0
82
%define RGB_PIXELSIZE 3
83
%define jsimd_ycc_rgb_convert_sse2 jsimd_ycc_extbgr_convert_sse2
84
%include "jdclrss2-64.asm"
85
86
%undef RGB_RED
87
%undef RGB_GREEN
88
%undef RGB_BLUE
89
%undef RGB_PIXELSIZE
90
%define RGB_RED 2
91
%define RGB_GREEN 1
92
%define RGB_BLUE 0
93
%define RGB_PIXELSIZE 4
94
%define jsimd_ycc_rgb_convert_sse2 jsimd_ycc_extbgrx_convert_sse2
95
%include "jdclrss2-64.asm"
96
97
%undef RGB_RED
98
%undef RGB_GREEN
99
%undef RGB_BLUE
100
%undef RGB_PIXELSIZE
101
%define RGB_RED 3
102
%define RGB_GREEN 2
103
%define RGB_BLUE 1
104
%define RGB_PIXELSIZE 4
105
%define jsimd_ycc_rgb_convert_sse2 jsimd_ycc_extxbgr_convert_sse2
106
%include "jdclrss2-64.asm"
107
108
%undef RGB_RED
109
%undef RGB_GREEN
110
%undef RGB_BLUE
111
%undef RGB_PIXELSIZE
112
%define RGB_RED 1
113
%define RGB_GREEN 2
114
%define RGB_BLUE 3
115
%define RGB_PIXELSIZE 4
116
%define jsimd_ycc_rgb_convert_sse2 jsimd_ycc_extxrgb_convert_sse2
117
%include "jdclrss2-64.asm"
(-)a/jpeg/simd/jdcolss2.asm (+117 lines)
Line     Link Here 
Line 0    Link Here 
1
;
2
; jdcolss2.asm - colorspace conversion (SSE2)
3
;
4
; Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
5
; Copyright 2009 D. R. Commander
6
;
7
; Based on
8
; x86 SIMD extension for IJG JPEG library
9
; Copyright (C) 1999-2006, MIYASAKA Masaru.
10
; For conditions of distribution and use, see copyright notice in jsimdext.inc
11
;
12
; This file should be assembled with NASM (Netwide Assembler),
13
; can *not* be assembled with Microsoft's MASM or any compatible
14
; assembler (including Borland's Turbo Assembler).
15
; NASM is available from http://nasm.sourceforge.net/ or
16
; http://sourceforge.net/project/showfiles.php?group_id=6208
17
;
18
; [TAB8]
19
20
%include "jsimdext.inc"
21
22
; --------------------------------------------------------------------------
23
24
%define SCALEBITS	16
25
26
F_0_344	equ	 22554			; FIX(0.34414)
27
F_0_714	equ	 46802			; FIX(0.71414)
28
F_1_402	equ	 91881			; FIX(1.40200)
29
F_1_772	equ	116130			; FIX(1.77200)
30
F_0_402	equ	(F_1_402 - 65536)	; FIX(1.40200) - FIX(1)
31
F_0_285	equ	( 65536 - F_0_714)	; FIX(1) - FIX(0.71414)
32
F_0_228	equ	(131072 - F_1_772)	; FIX(2) - FIX(1.77200)
33
34
; --------------------------------------------------------------------------
35
	SECTION	SEG_CONST
36
37
	alignz	16
38
	global	EXTN(jconst_ycc_rgb_convert_sse2)
39
40
EXTN(jconst_ycc_rgb_convert_sse2):
41
42
PW_F0402	times 8 dw  F_0_402
43
PW_MF0228	times 8 dw -F_0_228
44
PW_MF0344_F0285	times 4 dw -F_0_344, F_0_285
45
PW_ONE		times 8 dw  1
46
PD_ONEHALF	times 4 dd  1 << (SCALEBITS-1)
47
48
	alignz	16
49
50
; --------------------------------------------------------------------------
51
%include "jdclrss2.asm"
52
53
%undef RGB_RED
54
%undef RGB_GREEN
55
%undef RGB_BLUE
56
%undef RGB_PIXELSIZE
57
%define RGB_RED 0
58
%define RGB_GREEN 1
59
%define RGB_BLUE 2
60
%define RGB_PIXELSIZE 3
61
%define jsimd_ycc_rgb_convert_sse2 jsimd_ycc_extrgb_convert_sse2
62
%include "jdclrss2.asm"
63
64
%undef RGB_RED
65
%undef RGB_GREEN
66
%undef RGB_BLUE
67
%undef RGB_PIXELSIZE
68
%define RGB_RED 0
69
%define RGB_GREEN 1
70
%define RGB_BLUE 2
71
%define RGB_PIXELSIZE 4
72
%define jsimd_ycc_rgb_convert_sse2 jsimd_ycc_extrgbx_convert_sse2
73
%include "jdclrss2.asm"
74
75
%undef RGB_RED
76
%undef RGB_GREEN
77
%undef RGB_BLUE
78
%undef RGB_PIXELSIZE
79
%define RGB_RED 2
80
%define RGB_GREEN 1
81
%define RGB_BLUE 0
82
%define RGB_PIXELSIZE 3
83
%define jsimd_ycc_rgb_convert_sse2 jsimd_ycc_extbgr_convert_sse2
84
%include "jdclrss2.asm"
85
86
%undef RGB_RED
87
%undef RGB_GREEN
88
%undef RGB_BLUE
89
%undef RGB_PIXELSIZE
90
%define RGB_RED 2
91
%define RGB_GREEN 1
92
%define RGB_BLUE 0
93
%define RGB_PIXELSIZE 4
94
%define jsimd_ycc_rgb_convert_sse2 jsimd_ycc_extbgrx_convert_sse2
95
%include "jdclrss2.asm"
96
97
%undef RGB_RED
98
%undef RGB_GREEN
99
%undef RGB_BLUE
100
%undef RGB_PIXELSIZE
101
%define RGB_RED 3
102
%define RGB_GREEN 2
103
%define RGB_BLUE 1
104
%define RGB_PIXELSIZE 4
105
%define jsimd_ycc_rgb_convert_sse2 jsimd_ycc_extxbgr_convert_sse2
106
%include "jdclrss2.asm"
107
108
%undef RGB_RED
109
%undef RGB_GREEN
110
%undef RGB_BLUE
111
%undef RGB_PIXELSIZE
112
%define RGB_RED 1
113
%define RGB_GREEN 2
114
%define RGB_BLUE 3
115
%define RGB_PIXELSIZE 4
116
%define jsimd_ycc_rgb_convert_sse2 jsimd_ycc_extxrgb_convert_sse2
117
%include "jdclrss2.asm"
(-)a/jpeg/simd/jdct.inc (+28 lines)
Line     Link Here 
Line 0    Link Here 
1
;
2
; jdct.inc - private declarations for forward & reverse DCT subsystems
3
;
4
; Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
5
;
6
; Based on
7
; x86 SIMD extension for IJG JPEG library
8
; Copyright (C) 1999-2006, MIYASAKA Masaru.
9
; For conditions of distribution and use, see copyright notice in jsimdext.inc
10
;
11
; [TAB8]
12
13
; Each IDCT routine is responsible for range-limiting its results and
14
; converting them to unsigned form (0..MAXJSAMPLE).  The raw outputs could
15
; be quite far out of range if the input data is corrupt, so a bulletproof
16
; range-limiting step is required.  We use a mask-and-table-lookup method
17
; to do the combined operations quickly.
18
;
19
%define RANGE_MASK  (MAXJSAMPLE * 4 + 3)  ; 2 bits wider than legal samples
20
21
%define ROW(n,b,s)		((b)+(n)*(s))
22
%define COL(n,b,s)		((b)+(n)*(s)*DCTSIZE)
23
24
%define DWBLOCK(m,n,b,s)	((b)+(m)*DCTSIZE*(s)+(n)*SIZEOF_DWORD)
25
%define MMBLOCK(m,n,b,s)	((b)+(m)*DCTSIZE*(s)+(n)*SIZEOF_MMWORD)
26
%define XMMBLOCK(m,n,b,s)	((b)+(m)*DCTSIZE*(s)+(n)*SIZEOF_XMMWORD)
27
28
; --------------------------------------------------------------------------
(-)a/jpeg/simd/jdmermmx.asm (+123 lines)
Line     Link Here 
Line 0    Link Here 
1
;
2
; jdmermmx.asm - merged upsampling/color conversion (MMX)
3
;
4
; Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
5
; Copyright 2009 D. R. Commander
6
;
7
; Based on
8
; x86 SIMD extension for IJG JPEG library
9
; Copyright (C) 1999-2006, MIYASAKA Masaru.
10
; For conditions of distribution and use, see copyright notice in jsimdext.inc
11
;
12
; This file should be assembled with NASM (Netwide Assembler),
13
; can *not* be assembled with Microsoft's MASM or any compatible
14
; assembler (including Borland's Turbo Assembler).
15
; NASM is available from http://nasm.sourceforge.net/ or
16
; http://sourceforge.net/project/showfiles.php?group_id=6208
17
;
18
; [TAB8]
19
20
%include "jsimdext.inc"
21
22
; --------------------------------------------------------------------------
23
24
%define SCALEBITS	16
25
26
F_0_344	equ	 22554			; FIX(0.34414)
27
F_0_714	equ	 46802			; FIX(0.71414)
28
F_1_402	equ	 91881			; FIX(1.40200)
29
F_1_772	equ	116130			; FIX(1.77200)
30
F_0_402	equ	(F_1_402 - 65536)	; FIX(1.40200) - FIX(1)
31
F_0_285	equ	( 65536 - F_0_714)	; FIX(1) - FIX(0.71414)
32
F_0_228	equ	(131072 - F_1_772)	; FIX(2) - FIX(1.77200)
33
34
; --------------------------------------------------------------------------
35
	SECTION	SEG_CONST
36
37
	alignz	16
38
	global	EXTN(jconst_merged_upsample_mmx)
39
40
EXTN(jconst_merged_upsample_mmx):
41
42
PW_F0402	times 4 dw  F_0_402
43
PW_MF0228	times 4 dw -F_0_228
44
PW_MF0344_F0285	times 2 dw -F_0_344, F_0_285
45
PW_ONE		times 4 dw  1
46
PD_ONEHALF	times 2 dd  1 << (SCALEBITS-1)
47
48
	alignz	16
49
50
; --------------------------------------------------------------------------
51
%include "jdmrgmmx.asm"
52
53
%undef RGB_RED
54
%undef RGB_GREEN
55
%undef RGB_BLUE
56
%undef RGB_PIXELSIZE
57
%define RGB_RED 0
58
%define RGB_GREEN 1
59
%define RGB_BLUE 2
60
%define RGB_PIXELSIZE 3
61
%define jsimd_h2v1_merged_upsample_mmx jsimd_h2v1_extrgb_merged_upsample_mmx
62
%define jsimd_h2v2_merged_upsample_mmx jsimd_h2v2_extrgb_merged_upsample_mmx
63
%include "jdmrgmmx.asm"
64
65
%undef RGB_RED
66
%undef RGB_GREEN
67
%undef RGB_BLUE
68
%undef RGB_PIXELSIZE
69
%define RGB_RED 0
70
%define RGB_GREEN 1
71
%define RGB_BLUE 2
72
%define RGB_PIXELSIZE 4
73
%define jsimd_h2v1_merged_upsample_mmx jsimd_h2v1_extrgbx_merged_upsample_mmx
74
%define jsimd_h2v2_merged_upsample_mmx jsimd_h2v2_extrgbx_merged_upsample_mmx
75
%include "jdmrgmmx.asm"
76
77
%undef RGB_RED
78
%undef RGB_GREEN
79
%undef RGB_BLUE
80
%undef RGB_PIXELSIZE
81
%define RGB_RED 2
82
%define RGB_GREEN 1
83
%define RGB_BLUE 0
84
%define RGB_PIXELSIZE 3
85
%define jsimd_h2v1_merged_upsample_mmx jsimd_h2v1_extbgr_merged_upsample_mmx
86
%define jsimd_h2v2_merged_upsample_mmx jsimd_h2v2_extbgr_merged_upsample_mmx
87
%include "jdmrgmmx.asm"
88
89
%undef RGB_RED
90
%undef RGB_GREEN
91
%undef RGB_BLUE
92
%undef RGB_PIXELSIZE
93
%define RGB_RED 2
94
%define RGB_GREEN 1
95
%define RGB_BLUE 0
96
%define RGB_PIXELSIZE 4
97
%define jsimd_h2v1_merged_upsample_mmx jsimd_h2v1_extbgrx_merged_upsample_mmx
98
%define jsimd_h2v2_merged_upsample_mmx jsimd_h2v2_extbgrx_merged_upsample_mmx
99
%include "jdmrgmmx.asm"
100
101
%undef RGB_RED
102
%undef RGB_GREEN
103
%undef RGB_BLUE
104
%undef RGB_PIXELSIZE
105
%define RGB_RED 3
106
%define RGB_GREEN 2
107
%define RGB_BLUE 1
108
%define RGB_PIXELSIZE 4
109
%define jsimd_h2v1_merged_upsample_mmx jsimd_h2v1_extxbgr_merged_upsample_mmx
110
%define jsimd_h2v2_merged_upsample_mmx jsimd_h2v2_extxbgr_merged_upsample_mmx
111
%include "jdmrgmmx.asm"
112
113
%undef RGB_RED
114
%undef RGB_GREEN
115
%undef RGB_BLUE
116
%undef RGB_PIXELSIZE
117
%define RGB_RED 1
118
%define RGB_GREEN 2
119
%define RGB_BLUE 3
120
%define RGB_PIXELSIZE 4
121
%define jsimd_h2v1_merged_upsample_mmx jsimd_h2v1_extxrgb_merged_upsample_mmx
122
%define jsimd_h2v2_merged_upsample_mmx jsimd_h2v2_extxrgb_merged_upsample_mmx
123
%include "jdmrgmmx.asm"
(-)a/jpeg/simd/jdmerss2-64.asm (+123 lines)
Line     Link Here 
Line 0    Link Here 
1
;
2
; jdmerss2-64.asm - merged upsampling/color conversion (64-bit SSE2)
3
;
4
; Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
5
; Copyright 2009 D. R. Commander
6
;
7
; Based on
8
; x86 SIMD extension for IJG JPEG library
9
; Copyright (C) 1999-2006, MIYASAKA Masaru.
10
; For conditions of distribution and use, see copyright notice in jsimdext.inc
11
;
12
; This file should be assembled with NASM (Netwide Assembler),
13
; can *not* be assembled with Microsoft's MASM or any compatible
14
; assembler (including Borland's Turbo Assembler).
15
; NASM is available from http://nasm.sourceforge.net/ or
16
; http://sourceforge.net/project/showfiles.php?group_id=6208
17
;
18
; [TAB8]
19
20
%include "jsimdext.inc"
21
22
; --------------------------------------------------------------------------
23
24
%define SCALEBITS	16
25
26
F_0_344	equ	 22554			; FIX(0.34414)
27
F_0_714	equ	 46802			; FIX(0.71414)
28
F_1_402	equ	 91881			; FIX(1.40200)
29
F_1_772	equ	116130			; FIX(1.77200)
30
F_0_402	equ	(F_1_402 - 65536)	; FIX(1.40200) - FIX(1)
31
F_0_285	equ	( 65536 - F_0_714)	; FIX(1) - FIX(0.71414)
32
F_0_228	equ	(131072 - F_1_772)	; FIX(2) - FIX(1.77200)
33
34
; --------------------------------------------------------------------------
35
	SECTION	SEG_CONST
36
37
	alignz	16
38
	global	EXTN(jconst_merged_upsample_sse2)
39
40
EXTN(jconst_merged_upsample_sse2):
41
42
PW_F0402	times 8 dw  F_0_402
43
PW_MF0228	times 8 dw -F_0_228
44
PW_MF0344_F0285	times 4 dw -F_0_344, F_0_285
45
PW_ONE		times 8 dw  1
46
PD_ONEHALF	times 4 dd  1 << (SCALEBITS-1)
47
48
	alignz	16
49
50
; --------------------------------------------------------------------------
51
%include "jdmrgss2-64.asm"
52
53
%undef RGB_RED
54
%undef RGB_GREEN
55
%undef RGB_BLUE
56
%undef RGB_PIXELSIZE
57
%define RGB_RED 0
58
%define RGB_GREEN 1
59
%define RGB_BLUE 2
60
%define RGB_PIXELSIZE 3
61
%define jsimd_h2v1_merged_upsample_sse2 jsimd_h2v1_extrgb_merged_upsample_sse2
62
%define jsimd_h2v2_merged_upsample_sse2 jsimd_h2v2_extrgb_merged_upsample_sse2
63
%include "jdmrgss2-64.asm"
64
65
%undef RGB_RED
66
%undef RGB_GREEN
67
%undef RGB_BLUE
68
%undef RGB_PIXELSIZE
69
%define RGB_RED 0
70
%define RGB_GREEN 1
71
%define RGB_BLUE 2
72
%define RGB_PIXELSIZE 4
73
%define jsimd_h2v1_merged_upsample_sse2 jsimd_h2v1_extrgbx_merged_upsample_sse2
74
%define jsimd_h2v2_merged_upsample_sse2 jsimd_h2v2_extrgbx_merged_upsample_sse2
75
%include "jdmrgss2-64.asm"
76
77
%undef RGB_RED
78
%undef RGB_GREEN
79
%undef RGB_BLUE
80
%undef RGB_PIXELSIZE
81
%define RGB_RED 2
82
%define RGB_GREEN 1
83
%define RGB_BLUE 0
84
%define RGB_PIXELSIZE 3
85
%define jsimd_h2v1_merged_upsample_sse2 jsimd_h2v1_extbgr_merged_upsample_sse2
86
%define jsimd_h2v2_merged_upsample_sse2 jsimd_h2v2_extbgr_merged_upsample_sse2
87
%include "jdmrgss2-64.asm"
88
89
%undef RGB_RED
90
%undef RGB_GREEN
91
%undef RGB_BLUE
92
%undef RGB_PIXELSIZE
93
%define RGB_RED 2
94
%define RGB_GREEN 1
95
%define RGB_BLUE 0
96
%define RGB_PIXELSIZE 4
97
%define jsimd_h2v1_merged_upsample_sse2 jsimd_h2v1_extbgrx_merged_upsample_sse2
98
%define jsimd_h2v2_merged_upsample_sse2 jsimd_h2v2_extbgrx_merged_upsample_sse2
99
%include "jdmrgss2-64.asm"
100
101
%undef RGB_RED
102
%undef RGB_GREEN
103
%undef RGB_BLUE
104
%undef RGB_PIXELSIZE
105
%define RGB_RED 3
106
%define RGB_GREEN 2
107
%define RGB_BLUE 1
108
%define RGB_PIXELSIZE 4
109
%define jsimd_h2v1_merged_upsample_sse2 jsimd_h2v1_extxbgr_merged_upsample_sse2
110
%define jsimd_h2v2_merged_upsample_sse2 jsimd_h2v2_extxbgr_merged_upsample_sse2
111
%include "jdmrgss2-64.asm"
112
113
%undef RGB_RED
114
%undef RGB_GREEN
115
%undef RGB_BLUE
116
%undef RGB_PIXELSIZE
117
%define RGB_RED 1
118
%define RGB_GREEN 2
119
%define RGB_BLUE 3
120
%define RGB_PIXELSIZE 4
121
%define jsimd_h2v1_merged_upsample_sse2 jsimd_h2v1_extxrgb_merged_upsample_sse2
122
%define jsimd_h2v2_merged_upsample_sse2 jsimd_h2v2_extxrgb_merged_upsample_sse2
123
%include "jdmrgss2-64.asm"
(-)a/jpeg/simd/jdmerss2.asm (+123 lines)
Line     Link Here 
Line 0    Link Here 
1
;
2
; jdmerss2.asm - merged upsampling/color conversion (SSE2)
3
;
4
; Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
5
; Copyright 2009 D. R. Commander
6
;
7
; Based on
8
; x86 SIMD extension for IJG JPEG library
9
; Copyright (C) 1999-2006, MIYASAKA Masaru.
10
; For conditions of distribution and use, see copyright notice in jsimdext.inc
11
;
12
; This file should be assembled with NASM (Netwide Assembler),
13
; can *not* be assembled with Microsoft's MASM or any compatible
14
; assembler (including Borland's Turbo Assembler).
15
; NASM is available from http://nasm.sourceforge.net/ or
16
; http://sourceforge.net/project/showfiles.php?group_id=6208
17
;
18
; [TAB8]
19
20
%include "jsimdext.inc"
21
22
; --------------------------------------------------------------------------
23
24
%define SCALEBITS	16
25
26
F_0_344	equ	 22554			; FIX(0.34414)
27
F_0_714	equ	 46802			; FIX(0.71414)
28
F_1_402	equ	 91881			; FIX(1.40200)
29
F_1_772	equ	116130			; FIX(1.77200)
30
F_0_402	equ	(F_1_402 - 65536)	; FIX(1.40200) - FIX(1)
31
F_0_285	equ	( 65536 - F_0_714)	; FIX(1) - FIX(0.71414)
32
F_0_228	equ	(131072 - F_1_772)	; FIX(2) - FIX(1.77200)
33
34
; --------------------------------------------------------------------------
35
	SECTION	SEG_CONST
36
37
	alignz	16
38
	global	EXTN(jconst_merged_upsample_sse2)
39
40
EXTN(jconst_merged_upsample_sse2):
41
42
PW_F0402	times 8 dw  F_0_402
43
PW_MF0228	times 8 dw -F_0_228
44
PW_MF0344_F0285	times 4 dw -F_0_344, F_0_285
45
PW_ONE		times 8 dw  1
46
PD_ONEHALF	times 4 dd  1 << (SCALEBITS-1)
47
48
	alignz	16
49
50
; --------------------------------------------------------------------------
51
%include "jdmrgss2.asm"
52
53
%undef RGB_RED
54
%undef RGB_GREEN
55
%undef RGB_BLUE
56
%undef RGB_PIXELSIZE
57
%define RGB_RED 0
58
%define RGB_GREEN 1
59
%define RGB_BLUE 2
60
%define RGB_PIXELSIZE 3
61
%define jsimd_h2v1_merged_upsample_sse2 jsimd_h2v1_extrgb_merged_upsample_sse2
62
%define jsimd_h2v2_merged_upsample_sse2 jsimd_h2v2_extrgb_merged_upsample_sse2
63
%include "jdmrgss2.asm"
64
65
%undef RGB_RED
66
%undef RGB_GREEN
67
%undef RGB_BLUE
68
%undef RGB_PIXELSIZE
69
%define RGB_RED 0
70
%define RGB_GREEN 1
71
%define RGB_BLUE 2
72
%define RGB_PIXELSIZE 4
73
%define jsimd_h2v1_merged_upsample_sse2 jsimd_h2v1_extrgbx_merged_upsample_sse2
74
%define jsimd_h2v2_merged_upsample_sse2 jsimd_h2v2_extrgbx_merged_upsample_sse2
75
%include "jdmrgss2.asm"
76
77
%undef RGB_RED
78
%undef RGB_GREEN
79
%undef RGB_BLUE
80
%undef RGB_PIXELSIZE
81
%define RGB_RED 2
82
%define RGB_GREEN 1
83
%define RGB_BLUE 0
84
%define RGB_PIXELSIZE 3
85
%define jsimd_h2v1_merged_upsample_sse2 jsimd_h2v1_extbgr_merged_upsample_sse2
86
%define jsimd_h2v2_merged_upsample_sse2 jsimd_h2v2_extbgr_merged_upsample_sse2
87
%include "jdmrgss2.asm"
88
89
%undef RGB_RED
90
%undef RGB_GREEN
91
%undef RGB_BLUE
92
%undef RGB_PIXELSIZE
93
%define RGB_RED 2
94
%define RGB_GREEN 1
95
%define RGB_BLUE 0
96
%define RGB_PIXELSIZE 4
97
%define jsimd_h2v1_merged_upsample_sse2 jsimd_h2v1_extbgrx_merged_upsample_sse2
98
%define jsimd_h2v2_merged_upsample_sse2 jsimd_h2v2_extbgrx_merged_upsample_sse2
99
%include "jdmrgss2.asm"
100
101
%undef RGB_RED
102
%undef RGB_GREEN
103
%undef RGB_BLUE
104
%undef RGB_PIXELSIZE
105
%define RGB_RED 3
106
%define RGB_GREEN 2
107
%define RGB_BLUE 1
108
%define RGB_PIXELSIZE 4
109
%define jsimd_h2v1_merged_upsample_sse2 jsimd_h2v1_extxbgr_merged_upsample_sse2
110
%define jsimd_h2v2_merged_upsample_sse2 jsimd_h2v2_extxbgr_merged_upsample_sse2
111
%include "jdmrgss2.asm"
112
113
%undef RGB_RED
114
%undef RGB_GREEN
115
%undef RGB_BLUE
116
%undef RGB_PIXELSIZE
117
%define RGB_RED 1
118
%define RGB_GREEN 2
119
%define RGB_BLUE 3
120
%define RGB_PIXELSIZE 4
121
%define jsimd_h2v1_merged_upsample_sse2 jsimd_h2v1_extxrgb_merged_upsample_sse2
122
%define jsimd_h2v2_merged_upsample_sse2 jsimd_h2v2_extxrgb_merged_upsample_sse2
123
%include "jdmrgss2.asm"
(-)a/jpeg/simd/jdmrgmmx.asm (+466 lines)
Line     Link Here 
Line 0    Link Here 
1
;
2
; jdmrgmmx.asm - merged upsampling/color conversion (MMX)
3
;
4
; Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
5
;
6
; Based on
7
; x86 SIMD extension for IJG JPEG library
8
; Copyright (C) 1999-2006, MIYASAKA Masaru.
9
; For conditions of distribution and use, see copyright notice in jsimdext.inc
10
;
11
; This file should be assembled with NASM (Netwide Assembler),
12
; can *not* be assembled with Microsoft's MASM or any compatible
13
; assembler (including Borland's Turbo Assembler).
14
; NASM is available from http://nasm.sourceforge.net/ or
15
; http://sourceforge.net/project/showfiles.php?group_id=6208
16
;
17
; [TAB8]
18
19
%include "jcolsamp.inc"
20
21
; --------------------------------------------------------------------------
22
	SECTION	SEG_TEXT
23
	BITS	32
24
;
25
; Upsample and color convert for the case of 2:1 horizontal and 1:1 vertical.
26
;
27
; GLOBAL(void)
28
; jsimd_h2v1_merged_upsample_mmx (JDIMENSION output_width,
29
;                                 JSAMPIMAGE input_buf,
30
;                                 JDIMENSION in_row_group_ctr,
31
;                                 JSAMPARRAY output_buf);
32
;
33
34
%define output_width(b)	(b)+8			; JDIMENSION output_width
35
%define input_buf(b)		(b)+12		; JSAMPIMAGE input_buf
36
%define in_row_group_ctr(b)	(b)+16		; JDIMENSION in_row_group_ctr
37
%define output_buf(b)		(b)+20		; JSAMPARRAY output_buf
38
39
%define original_ebp	ebp+0
40
%define wk(i)		ebp-(WK_NUM-(i))*SIZEOF_MMWORD	; mmword wk[WK_NUM]
41
%define WK_NUM		3
42
%define gotptr		wk(0)-SIZEOF_POINTER	; void * gotptr
43
44
	align	16
45
	global	EXTN(jsimd_h2v1_merged_upsample_mmx)
46
47
EXTN(jsimd_h2v1_merged_upsample_mmx):
48
	push	ebp
49
	mov	eax,esp				; eax = original ebp
50
	sub	esp, byte 4
51
	and	esp, byte (-SIZEOF_MMWORD)	; align to 64 bits
52
	mov	[esp],eax
53
	mov	ebp,esp				; ebp = aligned ebp
54
	lea	esp, [wk(0)]
55
	pushpic	eax		; make a room for GOT address
56
	push	ebx
57
;	push	ecx		; need not be preserved
58
;	push	edx		; need not be preserved
59
	push	esi
60
	push	edi
61
62
	get_GOT	ebx			; get GOT address
63
	movpic	POINTER [gotptr], ebx	; save GOT address
64
65
	mov	ecx, JDIMENSION [output_width(eax)]	; col
66
	test	ecx,ecx
67
	jz	near .return
68
69
	push	ecx
70
71
	mov	edi, JSAMPIMAGE [input_buf(eax)]
72
	mov	ecx, JDIMENSION [in_row_group_ctr(eax)]
73
	mov	esi, JSAMPARRAY [edi+0*SIZEOF_JSAMPARRAY]
74
	mov	ebx, JSAMPARRAY [edi+1*SIZEOF_JSAMPARRAY]
75
	mov	edx, JSAMPARRAY [edi+2*SIZEOF_JSAMPARRAY]
76
	mov	edi, JSAMPARRAY [output_buf(eax)]
77
	mov	esi, JSAMPROW [esi+ecx*SIZEOF_JSAMPROW]		; inptr0
78
	mov	ebx, JSAMPROW [ebx+ecx*SIZEOF_JSAMPROW]		; inptr1
79
	mov	edx, JSAMPROW [edx+ecx*SIZEOF_JSAMPROW]		; inptr2
80
	mov	edi, JSAMPROW [edi]				; outptr
81
82
	pop	ecx			; col
83
84
	alignx	16,7
85
.columnloop:
86
	movpic	eax, POINTER [gotptr]	; load GOT address (eax)
87
88
	movq      mm6, MMWORD [ebx]	; mm6=Cb(01234567)
89
	movq      mm7, MMWORD [edx]	; mm7=Cr(01234567)
90
91
	pxor      mm1,mm1		; mm1=(all 0's)
92
	pcmpeqw   mm3,mm3
93
	psllw     mm3,7			; mm3={0xFF80 0xFF80 0xFF80 0xFF80}
94
95
	movq      mm4,mm6
96
	punpckhbw mm6,mm1		; mm6=Cb(4567)=CbH
97
	punpcklbw mm4,mm1		; mm4=Cb(0123)=CbL
98
	movq      mm0,mm7
99
	punpckhbw mm7,mm1		; mm7=Cr(4567)=CrH
100
	punpcklbw mm0,mm1		; mm0=Cr(0123)=CrL
101
102
	paddw     mm6,mm3
103
	paddw     mm4,mm3
104
	paddw     mm7,mm3
105
	paddw     mm0,mm3
106
107
	; (Original)
108
	; R = Y                + 1.40200 * Cr
109
	; G = Y - 0.34414 * Cb - 0.71414 * Cr
110
	; B = Y + 1.77200 * Cb
111
	;
112
	; (This implementation)
113
	; R = Y                + 0.40200 * Cr + Cr
114
	; G = Y - 0.34414 * Cb + 0.28586 * Cr - Cr
115
	; B = Y - 0.22800 * Cb + Cb + Cb
116
117
	movq	mm5,mm6			; mm5=CbH
118
	movq	mm2,mm4			; mm2=CbL
119
	paddw	mm6,mm6			; mm6=2*CbH
120
	paddw	mm4,mm4			; mm4=2*CbL
121
	movq	mm1,mm7			; mm1=CrH
122
	movq	mm3,mm0			; mm3=CrL
123
	paddw	mm7,mm7			; mm7=2*CrH
124
	paddw	mm0,mm0			; mm0=2*CrL
125
126
	pmulhw	mm6,[GOTOFF(eax,PW_MF0228)]	; mm6=(2*CbH * -FIX(0.22800))
127
	pmulhw	mm4,[GOTOFF(eax,PW_MF0228)]	; mm4=(2*CbL * -FIX(0.22800))
128
	pmulhw	mm7,[GOTOFF(eax,PW_F0402)]	; mm7=(2*CrH * FIX(0.40200))
129
	pmulhw	mm0,[GOTOFF(eax,PW_F0402)]	; mm0=(2*CrL * FIX(0.40200))
130
131
	paddw	mm6,[GOTOFF(eax,PW_ONE)]
132
	paddw	mm4,[GOTOFF(eax,PW_ONE)]
133
	psraw	mm6,1			; mm6=(CbH * -FIX(0.22800))
134
	psraw	mm4,1			; mm4=(CbL * -FIX(0.22800))
135
	paddw	mm7,[GOTOFF(eax,PW_ONE)]
136
	paddw	mm0,[GOTOFF(eax,PW_ONE)]
137
	psraw	mm7,1			; mm7=(CrH * FIX(0.40200))
138
	psraw	mm0,1			; mm0=(CrL * FIX(0.40200))
139
140
	paddw	mm6,mm5
141
	paddw	mm4,mm2
142
	paddw	mm6,mm5			; mm6=(CbH * FIX(1.77200))=(B-Y)H
143
	paddw	mm4,mm2			; mm4=(CbL * FIX(1.77200))=(B-Y)L
144
	paddw	mm7,mm1			; mm7=(CrH * FIX(1.40200))=(R-Y)H
145
	paddw	mm0,mm3			; mm0=(CrL * FIX(1.40200))=(R-Y)L
146
147
	movq	MMWORD [wk(0)], mm6	; wk(0)=(B-Y)H
148
	movq	MMWORD [wk(1)], mm7	; wk(1)=(R-Y)H
149
150
	movq      mm6,mm5
151
	movq      mm7,mm2
152
	punpcklwd mm5,mm1
153
	punpckhwd mm6,mm1
154
	pmaddwd   mm5,[GOTOFF(eax,PW_MF0344_F0285)]
155
	pmaddwd   mm6,[GOTOFF(eax,PW_MF0344_F0285)]
156
	punpcklwd mm2,mm3
157
	punpckhwd mm7,mm3
158
	pmaddwd   mm2,[GOTOFF(eax,PW_MF0344_F0285)]
159
	pmaddwd   mm7,[GOTOFF(eax,PW_MF0344_F0285)]
160
161
	paddd     mm5,[GOTOFF(eax,PD_ONEHALF)]
162
	paddd     mm6,[GOTOFF(eax,PD_ONEHALF)]
163
	psrad     mm5,SCALEBITS
164
	psrad     mm6,SCALEBITS
165
	paddd     mm2,[GOTOFF(eax,PD_ONEHALF)]
166
	paddd     mm7,[GOTOFF(eax,PD_ONEHALF)]
167
	psrad     mm2,SCALEBITS
168
	psrad     mm7,SCALEBITS
169
170
	packssdw  mm5,mm6	; mm5=CbH*-FIX(0.344)+CrH*FIX(0.285)
171
	packssdw  mm2,mm7	; mm2=CbL*-FIX(0.344)+CrL*FIX(0.285)
172
	psubw     mm5,mm1	; mm5=CbH*-FIX(0.344)+CrH*-FIX(0.714)=(G-Y)H
173
	psubw     mm2,mm3	; mm2=CbL*-FIX(0.344)+CrL*-FIX(0.714)=(G-Y)L
174
175
	movq	MMWORD [wk(2)], mm5	; wk(2)=(G-Y)H
176
177
	mov	al,2			; Yctr
178
	jmp	short .Yloop_1st
179
	alignx	16,7
180
181
.Yloop_2nd:
182
	movq	mm0, MMWORD [wk(1)]	; mm0=(R-Y)H
183
	movq	mm2, MMWORD [wk(2)]	; mm2=(G-Y)H
184
	movq	mm4, MMWORD [wk(0)]	; mm4=(B-Y)H
185
	alignx	16,7
186
187
.Yloop_1st:
188
	movq	mm7, MMWORD [esi]	; mm7=Y(01234567)
189
190
	pcmpeqw	mm6,mm6
191
	psrlw	mm6,BYTE_BIT		; mm6={0xFF 0x00 0xFF 0x00 ..}
192
	pand	mm6,mm7			; mm6=Y(0246)=YE
193
	psrlw	mm7,BYTE_BIT		; mm7=Y(1357)=YO
194
195
	movq	mm1,mm0			; mm1=mm0=(R-Y)(L/H)
196
	movq	mm3,mm2			; mm3=mm2=(G-Y)(L/H)
197
	movq	mm5,mm4			; mm5=mm4=(B-Y)(L/H)
198
199
	paddw     mm0,mm6		; mm0=((R-Y)+YE)=RE=(R0 R2 R4 R6)
200
	paddw     mm1,mm7		; mm1=((R-Y)+YO)=RO=(R1 R3 R5 R7)
201
	packuswb  mm0,mm0		; mm0=(R0 R2 R4 R6 ** ** ** **)
202
	packuswb  mm1,mm1		; mm1=(R1 R3 R5 R7 ** ** ** **)
203
204
	paddw     mm2,mm6		; mm2=((G-Y)+YE)=GE=(G0 G2 G4 G6)
205
	paddw     mm3,mm7		; mm3=((G-Y)+YO)=GO=(G1 G3 G5 G7)
206
	packuswb  mm2,mm2		; mm2=(G0 G2 G4 G6 ** ** ** **)
207
	packuswb  mm3,mm3		; mm3=(G1 G3 G5 G7 ** ** ** **)
208
209
	paddw     mm4,mm6		; mm4=((B-Y)+YE)=BE=(B0 B2 B4 B6)
210
	paddw     mm5,mm7		; mm5=((B-Y)+YO)=BO=(B1 B3 B5 B7)
211
	packuswb  mm4,mm4		; mm4=(B0 B2 B4 B6 ** ** ** **)
212
	packuswb  mm5,mm5		; mm5=(B1 B3 B5 B7 ** ** ** **)
213
214
%if RGB_PIXELSIZE == 3 ; ---------------
215
216
	; mmA=(00 02 04 06 ** ** ** **), mmB=(01 03 05 07 ** ** ** **)
217
	; mmC=(10 12 14 16 ** ** ** **), mmD=(11 13 15 17 ** ** ** **)
218
	; mmE=(20 22 24 26 ** ** ** **), mmF=(21 23 25 27 ** ** ** **)
219
	; mmG=(** ** ** ** ** ** ** **), mmH=(** ** ** ** ** ** ** **)
220
221
	punpcklbw mmA,mmC		; mmA=(00 10 02 12 04 14 06 16)
222
	punpcklbw mmE,mmB		; mmE=(20 01 22 03 24 05 26 07)
223
	punpcklbw mmD,mmF		; mmD=(11 21 13 23 15 25 17 27)
224
225
	movq      mmG,mmA
226
	movq      mmH,mmA
227
	punpcklwd mmA,mmE		; mmA=(00 10 20 01 02 12 22 03)
228
	punpckhwd mmG,mmE		; mmG=(04 14 24 05 06 16 26 07)
229
230
	psrlq     mmH,2*BYTE_BIT	; mmH=(02 12 04 14 06 16 -- --)
231
	psrlq     mmE,2*BYTE_BIT	; mmE=(22 03 24 05 26 07 -- --)
232
233
	movq      mmC,mmD
234
	movq      mmB,mmD
235
	punpcklwd mmD,mmH		; mmD=(11 21 02 12 13 23 04 14)
236
	punpckhwd mmC,mmH		; mmC=(15 25 06 16 17 27 -- --)
237
238
	psrlq     mmB,2*BYTE_BIT	; mmB=(13 23 15 25 17 27 -- --)
239
240
	movq      mmF,mmE
241
	punpcklwd mmE,mmB		; mmE=(22 03 13 23 24 05 15 25)
242
	punpckhwd mmF,mmB		; mmF=(26 07 17 27 -- -- -- --)
243
244
	punpckldq mmA,mmD		; mmA=(00 10 20 01 11 21 02 12)
245
	punpckldq mmE,mmG		; mmE=(22 03 13 23 04 14 24 05)
246
	punpckldq mmC,mmF		; mmC=(15 25 06 16 26 07 17 27)
247
248
	cmp	ecx, byte SIZEOF_MMWORD
249
	jb	short .column_st16
250
251
	movq	MMWORD [edi+0*SIZEOF_MMWORD], mmA
252
	movq	MMWORD [edi+1*SIZEOF_MMWORD], mmE
253
	movq	MMWORD [edi+2*SIZEOF_MMWORD], mmC
254
255
	sub	ecx, byte SIZEOF_MMWORD
256
	jz	near .endcolumn
257
258
	add	edi, byte RGB_PIXELSIZE*SIZEOF_MMWORD	; outptr
259
	add	esi, byte SIZEOF_MMWORD			; inptr0
260
	dec	al			; Yctr
261
	jnz	near .Yloop_2nd
262
263
	add	ebx, byte SIZEOF_MMWORD			; inptr1
264
	add	edx, byte SIZEOF_MMWORD			; inptr2
265
	jmp	near .columnloop
266
	alignx	16,7
267
268
.column_st16:
269
	lea	ecx, [ecx+ecx*2]	; imul ecx, RGB_PIXELSIZE
270
	cmp	ecx, byte 2*SIZEOF_MMWORD
271
	jb	short .column_st8
272
	movq	MMWORD [edi+0*SIZEOF_MMWORD], mmA
273
	movq	MMWORD [edi+1*SIZEOF_MMWORD], mmE
274
	movq	mmA,mmC
275
	sub	ecx, byte 2*SIZEOF_MMWORD
276
	add	edi, byte 2*SIZEOF_MMWORD
277
	jmp	short .column_st4
278
.column_st8:
279
	cmp	ecx, byte SIZEOF_MMWORD
280
	jb	short .column_st4
281
	movq	MMWORD [edi+0*SIZEOF_MMWORD], mmA
282
	movq	mmA,mmE
283
	sub	ecx, byte SIZEOF_MMWORD
284
	add	edi, byte SIZEOF_MMWORD
285
.column_st4:
286
	movd	eax,mmA
287
	cmp	ecx, byte SIZEOF_DWORD
288
	jb	short .column_st2
289
	mov	DWORD [edi+0*SIZEOF_DWORD], eax
290
	psrlq	mmA,DWORD_BIT
291
	movd	eax,mmA
292
	sub	ecx, byte SIZEOF_DWORD
293
	add	edi, byte SIZEOF_DWORD
294
.column_st2:
295
	cmp	ecx, byte SIZEOF_WORD
296
	jb	short .column_st1
297
	mov	WORD [edi+0*SIZEOF_WORD], ax
298
	shr	eax,WORD_BIT
299
	sub	ecx, byte SIZEOF_WORD
300
	add	edi, byte SIZEOF_WORD
301
.column_st1:
302
	cmp	ecx, byte SIZEOF_BYTE
303
	jb	short .endcolumn
304
	mov	BYTE [edi+0*SIZEOF_BYTE], al
305
306
%else ; RGB_PIXELSIZE == 4 ; -----------
307
308
%ifdef RGBX_FILLER_0XFF
309
	pcmpeqb   mm6,mm6		; mm6=(X0 X2 X4 X6 ** ** ** **)
310
	pcmpeqb   mm7,mm7		; mm7=(X1 X3 X5 X7 ** ** ** **)
311
%else
312
	pxor      mm6,mm6		; mm6=(X0 X2 X4 X6 ** ** ** **)
313
	pxor      mm7,mm7		; mm7=(X1 X3 X5 X7 ** ** ** **)
314
%endif
315
	; mmA=(00 02 04 06 ** ** ** **), mmB=(01 03 05 07 ** ** ** **)
316
	; mmC=(10 12 14 16 ** ** ** **), mmD=(11 13 15 17 ** ** ** **)
317
	; mmE=(20 22 24 26 ** ** ** **), mmF=(21 23 25 27 ** ** ** **)
318
	; mmG=(30 32 34 36 ** ** ** **), mmH=(31 33 35 37 ** ** ** **)
319
320
	punpcklbw mmA,mmC		; mmA=(00 10 02 12 04 14 06 16)
321
	punpcklbw mmE,mmG		; mmE=(20 30 22 32 24 34 26 36)
322
	punpcklbw mmB,mmD		; mmB=(01 11 03 13 05 15 07 17)
323
	punpcklbw mmF,mmH		; mmF=(21 31 23 33 25 35 27 37)
324
325
	movq      mmC,mmA
326
	punpcklwd mmA,mmE		; mmA=(00 10 20 30 02 12 22 32)
327
	punpckhwd mmC,mmE		; mmC=(04 14 24 34 06 16 26 36)
328
	movq      mmG,mmB
329
	punpcklwd mmB,mmF		; mmB=(01 11 21 31 03 13 23 33)
330
	punpckhwd mmG,mmF		; mmG=(05 15 25 35 07 17 27 37)
331
332
	movq      mmD,mmA
333
	punpckldq mmA,mmB		; mmA=(00 10 20 30 01 11 21 31)
334
	punpckhdq mmD,mmB		; mmD=(02 12 22 32 03 13 23 33)
335
	movq      mmH,mmC
336
	punpckldq mmC,mmG		; mmC=(04 14 24 34 05 15 25 35)
337
	punpckhdq mmH,mmG		; mmH=(06 16 26 36 07 17 27 37)
338
339
	cmp	ecx, byte SIZEOF_MMWORD
340
	jb	short .column_st16
341
342
	movq	MMWORD [edi+0*SIZEOF_MMWORD], mmA
343
	movq	MMWORD [edi+1*SIZEOF_MMWORD], mmD
344
	movq	MMWORD [edi+2*SIZEOF_MMWORD], mmC
345
	movq	MMWORD [edi+3*SIZEOF_MMWORD], mmH
346
347
	sub	ecx, byte SIZEOF_MMWORD
348
	jz	short .endcolumn
349
350
	add	edi, byte RGB_PIXELSIZE*SIZEOF_MMWORD	; outptr
351
	add	esi, byte SIZEOF_MMWORD			; inptr0
352
	dec	al			; Yctr
353
	jnz	near .Yloop_2nd
354
355
	add	ebx, byte SIZEOF_MMWORD			; inptr1
356
	add	edx, byte SIZEOF_MMWORD			; inptr2
357
	jmp	near .columnloop
358
	alignx	16,7
359
360
.column_st16:
361
	cmp	ecx, byte SIZEOF_MMWORD/2
362
	jb	short .column_st8
363
	movq	MMWORD [edi+0*SIZEOF_MMWORD], mmA
364
	movq	MMWORD [edi+1*SIZEOF_MMWORD], mmD
365
	movq	mmA,mmC
366
	movq	mmD,mmH
367
	sub	ecx, byte SIZEOF_MMWORD/2
368
	add	edi, byte 2*SIZEOF_MMWORD
369
.column_st8:
370
	cmp	ecx, byte SIZEOF_MMWORD/4
371
	jb	short .column_st4
372
	movq	MMWORD [edi+0*SIZEOF_MMWORD], mmA
373
	movq	mmA,mmD
374
	sub	ecx, byte SIZEOF_MMWORD/4
375
	add	edi, byte 1*SIZEOF_MMWORD
376
.column_st4:
377
	cmp	ecx, byte SIZEOF_MMWORD/8
378
	jb	short .endcolumn
379
	movd	DWORD [edi+0*SIZEOF_DWORD], mmA
380
381
%endif ; RGB_PIXELSIZE ; ---------------
382
383
.endcolumn:
384
	emms		; empty MMX state
385
386
.return:
387
	pop	edi
388
	pop	esi
389
;	pop	edx		; need not be preserved
390
;	pop	ecx		; need not be preserved
391
	pop	ebx
392
	mov	esp,ebp		; esp <- aligned ebp
393
	pop	esp		; esp <- original ebp
394
	pop	ebp
395
	ret
396
397
; --------------------------------------------------------------------------
398
;
399
; Upsample and color convert for the case of 2:1 horizontal and 2:1 vertical.
400
;
401
; GLOBAL(void)
402
; jsimd_h2v2_merged_upsample_mmx (JDIMENSION output_width,
403
;                                 JSAMPIMAGE input_buf,
404
;                                 JDIMENSION in_row_group_ctr,
405
;                                 JSAMPARRAY output_buf);
406
;
407
408
%define output_width(b)	(b)+8			; JDIMENSION output_width
409
%define input_buf(b)		(b)+12		; JSAMPIMAGE input_buf
410
%define in_row_group_ctr(b)	(b)+16		; JDIMENSION in_row_group_ctr
411
%define output_buf(b)		(b)+20		; JSAMPARRAY output_buf
412
413
	align	16
414
	global	EXTN(jsimd_h2v2_merged_upsample_mmx)
415
416
EXTN(jsimd_h2v2_merged_upsample_mmx):
417
	push	ebp
418
	mov	ebp,esp
419
	push	ebx
420
;	push	ecx		; need not be preserved
421
;	push	edx		; need not be preserved
422
	push	esi
423
	push	edi
424
425
	mov	eax, JDIMENSION [output_width(ebp)]
426
427
	mov	edi, JSAMPIMAGE [input_buf(ebp)]
428
	mov	ecx, JDIMENSION [in_row_group_ctr(ebp)]
429
	mov	esi, JSAMPARRAY [edi+0*SIZEOF_JSAMPARRAY]
430
	mov	ebx, JSAMPARRAY [edi+1*SIZEOF_JSAMPARRAY]
431
	mov	edx, JSAMPARRAY [edi+2*SIZEOF_JSAMPARRAY]
432
	mov	edi, JSAMPARRAY [output_buf(ebp)]
433
	lea	esi, [esi+ecx*SIZEOF_JSAMPROW]
434
435
	push	edx			; inptr2
436
	push	ebx			; inptr1
437
	push	esi			; inptr00
438
	mov	ebx,esp
439
440
	push	edi			; output_buf (outptr0)
441
	push	ecx			; in_row_group_ctr
442
	push	ebx			; input_buf
443
	push	eax			; output_width
444
445
	call	near EXTN(jsimd_h2v1_merged_upsample_mmx)
446
447
	add	esi, byte SIZEOF_JSAMPROW	; inptr01
448
	add	edi, byte SIZEOF_JSAMPROW	; outptr1
449
	mov	POINTER [ebx+0*SIZEOF_POINTER], esi
450
	mov	POINTER [ebx-1*SIZEOF_POINTER], edi
451
452
	call	near EXTN(jsimd_h2v1_merged_upsample_mmx)
453
454
	add	esp, byte 7*SIZEOF_DWORD
455
456
	pop	edi
457
	pop	esi
458
;	pop	edx		; need not be preserved
459
;	pop	ecx		; need not be preserved
460
	pop	ebx
461
	pop	ebp
462
	ret
463
464
; For some reason, the OS X linker does not honor the request to align the
465
; segment unless we do this.
466
	align	16
(-)a/jpeg/simd/jdmrgss2-64.asm (+584 lines)
Line     Link Here 
Line 0    Link Here 
1
;
2
; jdmrgss2-64.asm - merged upsampling/color conversion (64-bit SSE2)
3
;
4
; Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
5
; Copyright 2009 D. R. Commander
6
;
7
; Based on
8
; x86 SIMD extension for IJG JPEG library
9
; Copyright (C) 1999-2006, MIYASAKA Masaru.
10
; For conditions of distribution and use, see copyright notice in jsimdext.inc
11
;
12
; This file should be assembled with NASM (Netwide Assembler),
13
; can *not* be assembled with Microsoft's MASM or any compatible
14
; assembler (including Borland's Turbo Assembler).
15
; NASM is available from http://nasm.sourceforge.net/ for
16
; http://sourceforge.net/project/showfiles.php?group_id=6208
17
;
18
; [TAB8]
19
20
%include "jcolsamp.inc"
21
				
22
; --------------------------------------------------------------------------
23
	SECTION	SEG_TEXT
24
	BITS	64
25
;
26
; Upsample and color convert for the case of 2:1 horizontal and 1:1 vertical.
27
;
28
; GLOBAL(void)
29
; jsimd_h2v1_merged_upsample_sse2 (JDIMENSION output_width,
30
;                                  JSAMPIMAGE input_buf,
31
;                                  JDIMENSION in_row_group_ctr,
32
;                                  JSAMPARRAY output_buf);
33
;
34
35
; r10 = JDIMENSION output_width
36
; r11 = JSAMPIMAGE input_buf
37
; r12 = JDIMENSION in_row_group_ctr
38
; r13 = JSAMPARRAY output_buf
39
40
%define wk(i)		rbp-(WK_NUM-(i))*SIZEOF_XMMWORD	; xmmword wk[WK_NUM]
41
%define WK_NUM		3
42
43
	align	16
44
	global	EXTN(jsimd_h2v1_merged_upsample_sse2)
45
46
EXTN(jsimd_h2v1_merged_upsample_sse2):
47
	push	rbp
48
	mov	rax,rsp				; rax = original rbp
49
	sub	rsp, byte 4
50
	and	rsp, byte (-SIZEOF_XMMWORD)	; align to 128 bits
51
	mov	[rsp],rax
52
	mov	rbp,rsp				; rbp = aligned rbp
53
	lea	rsp, [wk(0)]
54
	collect_args
55
	push	rbx
56
57
	mov	rcx, r10	; col
58
	test	rcx,rcx
59
	jz	near .return
60
61
	push	rcx
62
63
	mov	rdi, r11
64
	mov	rcx, r12
65
	mov	rsi, JSAMPARRAY [rdi+0*SIZEOF_JSAMPARRAY]
66
	mov	rbx, JSAMPARRAY [rdi+1*SIZEOF_JSAMPARRAY]
67
	mov	rdx, JSAMPARRAY [rdi+2*SIZEOF_JSAMPARRAY]
68
	mov	rdi, r13
69
	mov	rsi, JSAMPROW [rsi+rcx*SIZEOF_JSAMPROW]		; inptr0
70
	mov	rbx, JSAMPROW [rbx+rcx*SIZEOF_JSAMPROW]		; inptr1
71
	mov	rdx, JSAMPROW [rdx+rcx*SIZEOF_JSAMPROW]		; inptr2
72
	mov	rdi, JSAMPROW [rdi]				; outptr
73
74
	pop	rcx			; col
75
76
.columnloop:
77
78
	movdqa    xmm6, XMMWORD [rbx]	; xmm6=Cb(0123456789ABCDEF)
79
	movdqa    xmm7, XMMWORD [rdx]	; xmm7=Cr(0123456789ABCDEF)
80
81
	pxor      xmm1,xmm1		; xmm1=(all 0's)
82
	pcmpeqw   xmm3,xmm3
83
	psllw     xmm3,7		; xmm3={0xFF80 0xFF80 0xFF80 0xFF80 ..}
84
85
	movdqa    xmm4,xmm6
86
	punpckhbw xmm6,xmm1		; xmm6=Cb(89ABCDEF)=CbH
87
	punpcklbw xmm4,xmm1		; xmm4=Cb(01234567)=CbL
88
	movdqa    xmm0,xmm7
89
	punpckhbw xmm7,xmm1		; xmm7=Cr(89ABCDEF)=CrH
90
	punpcklbw xmm0,xmm1		; xmm0=Cr(01234567)=CrL
91
92
	paddw     xmm6,xmm3
93
	paddw     xmm4,xmm3
94
	paddw     xmm7,xmm3
95
	paddw     xmm0,xmm3
96
97
	; (Original)
98
	; R = Y                + 1.40200 * Cr
99
	; G = Y - 0.34414 * Cb - 0.71414 * Cr
100
	; B = Y + 1.77200 * Cb
101
	;
102
	; (This implementation)
103
	; R = Y                + 0.40200 * Cr + Cr
104
	; G = Y - 0.34414 * Cb + 0.28586 * Cr - Cr
105
	; B = Y - 0.22800 * Cb + Cb + Cb
106
107
	movdqa	xmm5,xmm6		; xmm5=CbH
108
	movdqa	xmm2,xmm4		; xmm2=CbL
109
	paddw	xmm6,xmm6		; xmm6=2*CbH
110
	paddw	xmm4,xmm4		; xmm4=2*CbL
111
	movdqa	xmm1,xmm7		; xmm1=CrH
112
	movdqa	xmm3,xmm0		; xmm3=CrL
113
	paddw	xmm7,xmm7		; xmm7=2*CrH
114
	paddw	xmm0,xmm0		; xmm0=2*CrL
115
116
	pmulhw	xmm6,[rel PW_MF0228]	; xmm6=(2*CbH * -FIX(0.22800))
117
	pmulhw	xmm4,[rel PW_MF0228]	; xmm4=(2*CbL * -FIX(0.22800))
118
	pmulhw	xmm7,[rel PW_F0402]	; xmm7=(2*CrH * FIX(0.40200))
119
	pmulhw	xmm0,[rel PW_F0402]	; xmm0=(2*CrL * FIX(0.40200))
120
121
	paddw	xmm6,[rel PW_ONE]
122
	paddw	xmm4,[rel PW_ONE]
123
	psraw	xmm6,1			; xmm6=(CbH * -FIX(0.22800))
124
	psraw	xmm4,1			; xmm4=(CbL * -FIX(0.22800))
125
	paddw	xmm7,[rel PW_ONE]
126
	paddw	xmm0,[rel PW_ONE]
127
	psraw	xmm7,1			; xmm7=(CrH * FIX(0.40200))
128
	psraw	xmm0,1			; xmm0=(CrL * FIX(0.40200))
129
130
	paddw	xmm6,xmm5
131
	paddw	xmm4,xmm2
132
	paddw	xmm6,xmm5		; xmm6=(CbH * FIX(1.77200))=(B-Y)H
133
	paddw	xmm4,xmm2		; xmm4=(CbL * FIX(1.77200))=(B-Y)L
134
	paddw	xmm7,xmm1		; xmm7=(CrH * FIX(1.40200))=(R-Y)H
135
	paddw	xmm0,xmm3		; xmm0=(CrL * FIX(1.40200))=(R-Y)L
136
137
	movdqa	XMMWORD [wk(0)], xmm6	; wk(0)=(B-Y)H
138
	movdqa	XMMWORD [wk(1)], xmm7	; wk(1)=(R-Y)H
139
140
	movdqa    xmm6,xmm5
141
	movdqa    xmm7,xmm2
142
	punpcklwd xmm5,xmm1
143
	punpckhwd xmm6,xmm1
144
	pmaddwd   xmm5,[rel PW_MF0344_F0285]
145
	pmaddwd   xmm6,[rel PW_MF0344_F0285]
146
	punpcklwd xmm2,xmm3
147
	punpckhwd xmm7,xmm3
148
	pmaddwd   xmm2,[rel PW_MF0344_F0285]
149
	pmaddwd   xmm7,[rel PW_MF0344_F0285]
150
151
	paddd     xmm5,[rel PD_ONEHALF]
152
	paddd     xmm6,[rel PD_ONEHALF]
153
	psrad     xmm5,SCALEBITS
154
	psrad     xmm6,SCALEBITS
155
	paddd     xmm2,[rel PD_ONEHALF]
156
	paddd     xmm7,[rel PD_ONEHALF]
157
	psrad     xmm2,SCALEBITS
158
	psrad     xmm7,SCALEBITS
159
160
	packssdw  xmm5,xmm6	; xmm5=CbH*-FIX(0.344)+CrH*FIX(0.285)
161
	packssdw  xmm2,xmm7	; xmm2=CbL*-FIX(0.344)+CrL*FIX(0.285)
162
	psubw     xmm5,xmm1	; xmm5=CbH*-FIX(0.344)+CrH*-FIX(0.714)=(G-Y)H
163
	psubw     xmm2,xmm3	; xmm2=CbL*-FIX(0.344)+CrL*-FIX(0.714)=(G-Y)L
164
165
	movdqa	XMMWORD [wk(2)], xmm5	; wk(2)=(G-Y)H
166
167
	mov	al,2			; Yctr
168
	jmp	short .Yloop_1st
169
170
.Yloop_2nd:
171
	movdqa	xmm0, XMMWORD [wk(1)]	; xmm0=(R-Y)H
172
	movdqa	xmm2, XMMWORD [wk(2)]	; xmm2=(G-Y)H
173
	movdqa	xmm4, XMMWORD [wk(0)]	; xmm4=(B-Y)H
174
175
.Yloop_1st:
176
	movdqa	xmm7, XMMWORD [rsi]	; xmm7=Y(0123456789ABCDEF)
177
178
	pcmpeqw	xmm6,xmm6
179
	psrlw	xmm6,BYTE_BIT		; xmm6={0xFF 0x00 0xFF 0x00 ..}
180
	pand	xmm6,xmm7		; xmm6=Y(02468ACE)=YE
181
	psrlw	xmm7,BYTE_BIT		; xmm7=Y(13579BDF)=YO
182
183
	movdqa	xmm1,xmm0		; xmm1=xmm0=(R-Y)(L/H)
184
	movdqa	xmm3,xmm2		; xmm3=xmm2=(G-Y)(L/H)
185
	movdqa	xmm5,xmm4		; xmm5=xmm4=(B-Y)(L/H)
186
187
	paddw     xmm0,xmm6		; xmm0=((R-Y)+YE)=RE=R(02468ACE)
188
	paddw     xmm1,xmm7		; xmm1=((R-Y)+YO)=RO=R(13579BDF)
189
	packuswb  xmm0,xmm0		; xmm0=R(02468ACE********)
190
	packuswb  xmm1,xmm1		; xmm1=R(13579BDF********)
191
192
	paddw     xmm2,xmm6		; xmm2=((G-Y)+YE)=GE=G(02468ACE)
193
	paddw     xmm3,xmm7		; xmm3=((G-Y)+YO)=GO=G(13579BDF)
194
	packuswb  xmm2,xmm2		; xmm2=G(02468ACE********)
195
	packuswb  xmm3,xmm3		; xmm3=G(13579BDF********)
196
197
	paddw     xmm4,xmm6		; xmm4=((B-Y)+YE)=BE=B(02468ACE)
198
	paddw     xmm5,xmm7		; xmm5=((B-Y)+YO)=BO=B(13579BDF)
199
	packuswb  xmm4,xmm4		; xmm4=B(02468ACE********)
200
	packuswb  xmm5,xmm5		; xmm5=B(13579BDF********)
201
202
%if RGB_PIXELSIZE == 3 ; ---------------
203
204
	; xmmA=(00 02 04 06 08 0A 0C 0E **), xmmB=(01 03 05 07 09 0B 0D 0F **)
205
	; xmmC=(10 12 14 16 18 1A 1C 1E **), xmmD=(11 13 15 17 19 1B 1D 1F **)
206
	; xmmE=(20 22 24 26 28 2A 2C 2E **), xmmF=(21 23 25 27 29 2B 2D 2F **)
207
	; xmmG=(** ** ** ** ** ** ** ** **), xmmH=(** ** ** ** ** ** ** ** **)
208
209
	punpcklbw xmmA,xmmC	; xmmA=(00 10 02 12 04 14 06 16 08 18 0A 1A 0C 1C 0E 1E)
210
	punpcklbw xmmE,xmmB	; xmmE=(20 01 22 03 24 05 26 07 28 09 2A 0B 2C 0D 2E 0F)
211
	punpcklbw xmmD,xmmF	; xmmD=(11 21 13 23 15 25 17 27 19 29 1B 2B 1D 2D 1F 2F)
212
213
	movdqa    xmmG,xmmA
214
	movdqa    xmmH,xmmA
215
	punpcklwd xmmA,xmmE	; xmmA=(00 10 20 01 02 12 22 03 04 14 24 05 06 16 26 07)
216
	punpckhwd xmmG,xmmE	; xmmG=(08 18 28 09 0A 1A 2A 0B 0C 1C 2C 0D 0E 1E 2E 0F)
217
218
	psrldq    xmmH,2	; xmmH=(02 12 04 14 06 16 08 18 0A 1A 0C 1C 0E 1E -- --)
219
	psrldq    xmmE,2	; xmmE=(22 03 24 05 26 07 28 09 2A 0B 2C 0D 2E 0F -- --)
220
221
	movdqa    xmmC,xmmD
222
	movdqa    xmmB,xmmD
223
	punpcklwd xmmD,xmmH	; xmmD=(11 21 02 12 13 23 04 14 15 25 06 16 17 27 08 18)
224
	punpckhwd xmmC,xmmH	; xmmC=(19 29 0A 1A 1B 2B 0C 1C 1D 2D 0E 1E 1F 2F -- --)
225
226
	psrldq    xmmB,2	; xmmB=(13 23 15 25 17 27 19 29 1B 2B 1D 2D 1F 2F -- --)
227
228
	movdqa    xmmF,xmmE
229
	punpcklwd xmmE,xmmB	; xmmE=(22 03 13 23 24 05 15 25 26 07 17 27 28 09 19 29)
230
	punpckhwd xmmF,xmmB	; xmmF=(2A 0B 1B 2B 2C 0D 1D 2D 2E 0F 1F 2F -- -- -- --)
231
232
	pshufd    xmmH,xmmA,0x4E; xmmH=(04 14 24 05 06 16 26 07 00 10 20 01 02 12 22 03)
233
	movdqa    xmmB,xmmE
234
	punpckldq xmmA,xmmD	; xmmA=(00 10 20 01 11 21 02 12 02 12 22 03 13 23 04 14)
235
	punpckldq xmmE,xmmH	; xmmE=(22 03 13 23 04 14 24 05 24 05 15 25 06 16 26 07)
236
	punpckhdq xmmD,xmmB	; xmmD=(15 25 06 16 26 07 17 27 17 27 08 18 28 09 19 29)
237
238
	pshufd    xmmH,xmmG,0x4E; xmmH=(0C 1C 2C 0D 0E 1E 2E 0F 08 18 28 09 0A 1A 2A 0B)
239
	movdqa    xmmB,xmmF
240
	punpckldq xmmG,xmmC	; xmmG=(08 18 28 09 19 29 0A 1A 0A 1A 2A 0B 1B 2B 0C 1C)
241
	punpckldq xmmF,xmmH	; xmmF=(2A 0B 1B 2B 0C 1C 2C 0D 2C 0D 1D 2D 0E 1E 2E 0F)
242
	punpckhdq xmmC,xmmB	; xmmC=(1D 2D 0E 1E 2E 0F 1F 2F 1F 2F -- -- -- -- -- --)
243
244
	punpcklqdq xmmA,xmmE	; xmmA=(00 10 20 01 11 21 02 12 22 03 13 23 04 14 24 05)
245
	punpcklqdq xmmD,xmmG	; xmmD=(15 25 06 16 26 07 17 27 08 18 28 09 19 29 0A 1A)
246
	punpcklqdq xmmF,xmmC	; xmmF=(2A 0B 1B 2B 0C 1C 2C 0D 1D 2D 0E 1E 2E 0F 1F 2F)
247
248
	cmp	rcx, byte SIZEOF_XMMWORD
249
	jb	short .column_st32
250
251
	test	rdi, SIZEOF_XMMWORD-1
252
	jnz	short .out1
253
	; --(aligned)-------------------
254
	movntdq	XMMWORD [rdi+0*SIZEOF_XMMWORD], xmmA
255
	movntdq	XMMWORD [rdi+1*SIZEOF_XMMWORD], xmmD
256
	movntdq	XMMWORD [rdi+2*SIZEOF_XMMWORD], xmmF
257
	add	rdi, byte RGB_PIXELSIZE*SIZEOF_XMMWORD	; outptr
258
	jmp	short .out0
259
.out1:	; --(unaligned)-----------------
260
	pcmpeqb    xmmH,xmmH			; xmmH=(all 1's)
261
	maskmovdqu xmmA,xmmH			; movntdqu XMMWORD [rdi], xmmA
262
	add	rdi, byte SIZEOF_XMMWORD	; outptr
263
	maskmovdqu xmmD,xmmH			; movntdqu XMMWORD [rdi], xmmD
264
	add	rdi, byte SIZEOF_XMMWORD	; outptr
265
	maskmovdqu xmmF,xmmH			; movntdqu XMMWORD [rdi], xmmF
266
	add	rdi, byte SIZEOF_XMMWORD	; outptr
267
.out0:
268
	sub	rcx, byte SIZEOF_XMMWORD
269
	jz	near .endcolumn
270
271
	add	rsi, byte SIZEOF_XMMWORD	; inptr0
272
	dec	al			; Yctr
273
	jnz	near .Yloop_2nd
274
275
	add	rbx, byte SIZEOF_XMMWORD	; inptr1
276
	add	rdx, byte SIZEOF_XMMWORD	; inptr2
277
	jmp	near .columnloop
278
279
.column_st32:
280
	pcmpeqb	xmmH,xmmH			; xmmH=(all 1's)
281
	lea	rcx, [rcx+rcx*2]		; imul ecx, RGB_PIXELSIZE
282
	cmp	rcx, byte 2*SIZEOF_XMMWORD
283
	jb	short .column_st16
284
	maskmovdqu xmmA,xmmH			; movntdqu XMMWORD [rdi], xmmA
285
	add	rdi, byte SIZEOF_XMMWORD	; outptr
286
	maskmovdqu xmmD,xmmH			; movntdqu XMMWORD [rdi], xmmD
287
	add	rdi, byte SIZEOF_XMMWORD	; outptr
288
	movdqa	xmmA,xmmF
289
	sub	rcx, byte 2*SIZEOF_XMMWORD
290
	jmp	short .column_st15
291
.column_st16:
292
	cmp	rcx, byte SIZEOF_XMMWORD
293
	jb	short .column_st15
294
	maskmovdqu xmmA,xmmH			; movntdqu XMMWORD [rdi], xmmA
295
	add	rdi, byte SIZEOF_XMMWORD	; outptr
296
	movdqa	xmmA,xmmD
297
	sub	rcx, byte SIZEOF_XMMWORD
298
.column_st15:
299
	mov	rax,rcx
300
	xor	rcx, byte 0x0F
301
	shl	rcx, 2
302
	movd	xmmB,ecx
303
	psrlq	xmmH,4
304
	pcmpeqb	xmmE,xmmE
305
	psrlq	xmmH,xmmB
306
	psrlq	xmmE,xmmB
307
	punpcklbw xmmE,xmmH
308
	; ----------------
309
	mov	rcx,rdi
310
	and	rcx, byte SIZEOF_XMMWORD-1
311
	jz	short .adj0
312
	add	rax,rcx
313
	cmp	rax, byte SIZEOF_XMMWORD
314
	ja	short .adj0
315
	and	rdi, byte (-SIZEOF_XMMWORD)	; align to 16-byte boundary
316
	shl	rcx, 3			; pslldq xmmA,ecx & pslldq xmmE,ecx
317
	movdqa	xmmG,xmmA
318
	movdqa	xmmC,xmmE
319
	pslldq	xmmA, SIZEOF_XMMWORD/2
320
	pslldq	xmmE, SIZEOF_XMMWORD/2
321
	movd	xmmD,ecx
322
	sub	rcx, byte (SIZEOF_XMMWORD/2)*BYTE_BIT
323
	jb	short .adj1
324
	movd	xmmF,ecx
325
	psllq	xmmA,xmmF
326
	psllq	xmmE,xmmF
327
	jmp	short .adj0
328
.adj1:	neg	rcx
329
	movd	xmmF,ecx
330
	psrlq	xmmA,xmmF
331
	psrlq	xmmE,xmmF
332
	psllq	xmmG,xmmD
333
	psllq	xmmC,xmmD
334
	por	xmmA,xmmG
335
	por	xmmE,xmmC
336
.adj0:	; ----------------
337
	maskmovdqu xmmA,xmmE			; movntdqu XMMWORD [edi], xmmA
338
339
%else ; RGB_PIXELSIZE == 4 ; -----------
340
341
%ifdef RGBX_FILLER_0XFF
342
	pcmpeqb   xmm6,xmm6		; xmm6=XE=X(02468ACE********)
343
	pcmpeqb   xmm7,xmm7		; xmm7=XO=X(13579BDF********)
344
%else
345
	pxor      xmm6,xmm6		; xmm6=XE=X(02468ACE********)
346
	pxor      xmm7,xmm7		; xmm7=XO=X(13579BDF********)
347
%endif
348
	; xmmA=(00 02 04 06 08 0A 0C 0E **), xmmB=(01 03 05 07 09 0B 0D 0F **)
349
	; xmmC=(10 12 14 16 18 1A 1C 1E **), xmmD=(11 13 15 17 19 1B 1D 1F **)
350
	; xmmE=(20 22 24 26 28 2A 2C 2E **), xmmF=(21 23 25 27 29 2B 2D 2F **)
351
	; xmmG=(30 32 34 36 38 3A 3C 3E **), xmmH=(31 33 35 37 39 3B 3D 3F **)
352
353
	punpcklbw xmmA,xmmC	; xmmA=(00 10 02 12 04 14 06 16 08 18 0A 1A 0C 1C 0E 1E)
354
	punpcklbw xmmE,xmmG	; xmmE=(20 30 22 32 24 34 26 36 28 38 2A 3A 2C 3C 2E 3E)
355
	punpcklbw xmmB,xmmD	; xmmB=(01 11 03 13 05 15 07 17 09 19 0B 1B 0D 1D 0F 1F)
356
	punpcklbw xmmF,xmmH	; xmmF=(21 31 23 33 25 35 27 37 29 39 2B 3B 2D 3D 2F 3F)
357
358
	movdqa    xmmC,xmmA
359
	punpcklwd xmmA,xmmE	; xmmA=(00 10 20 30 02 12 22 32 04 14 24 34 06 16 26 36)
360
	punpckhwd xmmC,xmmE	; xmmC=(08 18 28 38 0A 1A 2A 3A 0C 1C 2C 3C 0E 1E 2E 3E)
361
	movdqa    xmmG,xmmB
362
	punpcklwd xmmB,xmmF	; xmmB=(01 11 21 31 03 13 23 33 05 15 25 35 07 17 27 37)
363
	punpckhwd xmmG,xmmF	; xmmG=(09 19 29 39 0B 1B 2B 3B 0D 1D 2D 3D 0F 1F 2F 3F)
364
365
	movdqa    xmmD,xmmA
366
	punpckldq xmmA,xmmB	; xmmA=(00 10 20 30 01 11 21 31 02 12 22 32 03 13 23 33)
367
	punpckhdq xmmD,xmmB	; xmmD=(04 14 24 34 05 15 25 35 06 16 26 36 07 17 27 37)
368
	movdqa    xmmH,xmmC
369
	punpckldq xmmC,xmmG	; xmmC=(08 18 28 38 09 19 29 39 0A 1A 2A 3A 0B 1B 2B 3B)
370
	punpckhdq xmmH,xmmG	; xmmH=(0C 1C 2C 3C 0D 1D 2D 3D 0E 1E 2E 3E 0F 1F 2F 3F)
371
372
	cmp	rcx, byte SIZEOF_XMMWORD
373
	jb	short .column_st32
374
375
	test	rdi, SIZEOF_XMMWORD-1
376
	jnz	short .out1
377
	; --(aligned)-------------------
378
	movntdq	XMMWORD [rdi+0*SIZEOF_XMMWORD], xmmA
379
	movntdq	XMMWORD [rdi+1*SIZEOF_XMMWORD], xmmD
380
	movntdq	XMMWORD [rdi+2*SIZEOF_XMMWORD], xmmC
381
	movntdq	XMMWORD [rdi+3*SIZEOF_XMMWORD], xmmH
382
	add	rdi, byte RGB_PIXELSIZE*SIZEOF_XMMWORD	; outptr
383
	jmp	short .out0
384
.out1:	; --(unaligned)-----------------
385
	pcmpeqb    xmmE,xmmE			; xmmE=(all 1's)
386
	maskmovdqu xmmA,xmmE			; movntdqu XMMWORD [rdi], xmmA
387
	add	rdi, byte SIZEOF_XMMWORD	; outptr
388
	maskmovdqu xmmD,xmmE			; movntdqu XMMWORD [rdi], xmmD
389
	add	rdi, byte SIZEOF_XMMWORD	; outptr
390
	maskmovdqu xmmC,xmmE			; movntdqu XMMWORD [rdi], xmmC
391
	add	rdi, byte SIZEOF_XMMWORD	; outptr
392
	maskmovdqu xmmH,xmmE			; movntdqu XMMWORD [rdi], xmmH
393
	add	rdi, byte SIZEOF_XMMWORD	; outptr
394
.out0:
395
	sub	rcx, byte SIZEOF_XMMWORD
396
	jz	near .endcolumn
397
398
	add	rsi, byte SIZEOF_XMMWORD	; inptr0
399
	dec	al			; Yctr
400
	jnz	near .Yloop_2nd
401
402
	add	rbx, byte SIZEOF_XMMWORD	; inptr1
403
	add	rdx, byte SIZEOF_XMMWORD	; inptr2
404
	jmp	near .columnloop
405
406
.column_st32:
407
	pcmpeqb	xmmE,xmmE			; xmmE=(all 1's)
408
	cmp	rcx, byte SIZEOF_XMMWORD/2
409
	jb	short .column_st16
410
	maskmovdqu xmmA,xmmE			; movntdqu XMMWORD [rdi], xmmA
411
	add	rdi, byte SIZEOF_XMMWORD	; outptr
412
	maskmovdqu xmmD,xmmE			; movntdqu XMMWORD [rdi], xmmD
413
	add	rdi, byte SIZEOF_XMMWORD	; outptr
414
	movdqa	xmmA,xmmC
415
	movdqa	xmmD,xmmH
416
	sub	rcx, byte SIZEOF_XMMWORD/2
417
.column_st16:
418
	cmp	rcx, byte SIZEOF_XMMWORD/4
419
	jb	short .column_st15
420
	maskmovdqu xmmA,xmmE			; movntdqu XMMWORD [edi], xmmA
421
	add	rdi, byte SIZEOF_XMMWORD	; outptr
422
	movdqa	xmmA,xmmD
423
	sub	rcx, byte SIZEOF_XMMWORD/4
424
.column_st15:
425
	cmp	rcx, byte SIZEOF_XMMWORD/16
426
	jb	near .endcolumn
427
	mov	rax,rcx
428
	xor	rcx, byte 0x03
429
	inc	rcx
430
	shl	rcx, 4
431
	movd	xmmF,ecx
432
	psrlq	xmmE,xmmF
433
	punpcklbw xmmE,xmmE
434
	; ----------------
435
	mov	rcx,rdi
436
	and	rcx, byte SIZEOF_XMMWORD-1
437
	jz	short .adj0
438
	lea	rax, [rcx+rax*4]	; RGB_PIXELSIZE
439
	cmp	rax, byte SIZEOF_XMMWORD
440
	ja	short .adj0
441
	and	rdi, byte (-SIZEOF_XMMWORD)	; align to 16-byte boundary
442
	shl	rcx, 3			; pslldq xmmA,ecx & pslldq xmmE,ecx
443
	movdqa	xmmB,xmmA
444
	movdqa	xmmG,xmmE
445
	pslldq	xmmA, SIZEOF_XMMWORD/2
446
	pslldq	xmmE, SIZEOF_XMMWORD/2
447
	movd	xmmC,ecx
448
	sub	rcx, byte (SIZEOF_XMMWORD/2)*BYTE_BIT
449
	jb	short .adj1
450
	movd	xmmH,ecx
451
	psllq	xmmA,xmmH
452
	psllq	xmmE,xmmH
453
	jmp	short .adj0
454
.adj1:	neg	rcx
455
	movd	xmmH,ecx
456
	psrlq	xmmA,xmmH
457
	psrlq	xmmE,xmmH
458
	psllq	xmmB,xmmC
459
	psllq	xmmG,xmmC
460
	por	xmmA,xmmB
461
	por	xmmE,xmmG
462
.adj0:	; ----------------
463
	maskmovdqu xmmA,xmmE			; movntdqu XMMWORD [edi], xmmA
464
465
%endif ; RGB_PIXELSIZE ; ---------------
466
467
.endcolumn:
468
	sfence		; flush the write buffer
469
470
.return:
471
	pop	rbx
472
	uncollect_args
473
	mov	rsp,rbp		; rsp <- aligned rbp
474
	pop	rsp		; rsp <- original rbp
475
	pop	rbp
476
	ret
477
478
; --------------------------------------------------------------------------
479
;
480
; Upsample and color convert for the case of 2:1 horizontal and 2:1 vertical.
481
;
482
; GLOBAL(void)
483
; jsimd_h2v2_merged_upsample_sse2 (JDIMENSION output_width,
484
;                                  JSAMPIMAGE input_buf,
485
;                                  JDIMENSION in_row_group_ctr,
486
;                                  JSAMPARRAY output_buf);
487
;
488
489
; r10 = JDIMENSION output_width
490
; r11 = JSAMPIMAGE input_buf
491
; r12 = JDIMENSION in_row_group_ctr
492
; r13 = JSAMPARRAY output_buf
493
494
	align	16
495
	global	EXTN(jsimd_h2v2_merged_upsample_sse2)
496
497
EXTN(jsimd_h2v2_merged_upsample_sse2):
498
	push	rbp
499
	mov	rax,rsp
500
	mov	rbp,rsp
501
	collect_args
502
	push	rbx
503
504
	mov	rax, r10
505
506
	mov	rdi, r11
507
	mov	rcx, r12
508
	mov	rsi, JSAMPARRAY [rdi+0*SIZEOF_JSAMPARRAY]
509
	mov	rbx, JSAMPARRAY [rdi+1*SIZEOF_JSAMPARRAY]
510
	mov	rdx, JSAMPARRAY [rdi+2*SIZEOF_JSAMPARRAY]
511
	mov	rdi, r13
512
	lea	rsi, [rsi+rcx*SIZEOF_JSAMPROW]
513
514
	push	rdx			; inptr2
515
	push	rbx			; inptr1
516
	push	rsi			; inptr00
517
	mov	rbx,rsp
518
519
	push	rdi
520
	push	rcx
521
	push	rax
522
523
	%ifdef WIN64
524
	mov r8, rcx
525
	mov r9, rdi
526
	mov rcx, rax
527
	mov rdx, rbx
528
	%else
529
	mov rdx, rcx
530
	mov rcx, rdi
531
	mov	rdi, rax
532
	mov rsi, rbx
533
	%endif
534
535
	call	EXTN(jsimd_h2v1_merged_upsample_sse2)
536
537
	pop rax
538
	pop rcx
539
	pop rdi
540
	pop rsi
541
	pop rbx
542
	pop rdx
543
544
	add	rdi, byte SIZEOF_JSAMPROW	; outptr1
545
	add	rsi, byte SIZEOF_JSAMPROW	; inptr01
546
547
	push	rdx			; inptr2
548
	push	rbx			; inptr1
549
	push	rsi			; inptr00
550
	mov	rbx,rsp
551
552
	push	rdi
553
	push	rcx
554
	push	rax
555
556
	%ifdef WIN64
557
	mov r8, rcx
558
	mov r9, rdi
559
	mov rcx, rax
560
	mov rdx, rbx
561
	%else
562
	mov rdx, rcx
563
	mov rcx, rdi
564
	mov	rdi, rax
565
	mov rsi, rbx
566
	%endif
567
568
	call	EXTN(jsimd_h2v1_merged_upsample_sse2)
569
570
	pop rax
571
	pop rcx
572
	pop rdi
573
	pop rsi
574
	pop rbx
575
	pop rdx
576
577
	pop	rbx
578
	uncollect_args
579
	pop	rbp
580
	ret
581
582
; For some reason, the OS X linker does not honor the request to align the
583
; segment unless we do this.
584
	align	16
(-)a/jpeg/simd/jdmrgss2.asm (+564 lines)
Line     Link Here 
Line 0    Link Here 
1
;
2
; jdmrgss2.asm - merged upsampling/color conversion (SSE2)
3
;
4
; Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
5
;
6
; Based on
7
; x86 SIMD extension for IJG JPEG library
8
; Copyright (C) 1999-2006, MIYASAKA Masaru.
9
; For conditions of distribution and use, see copyright notice in jsimdext.inc
10
;
11
; This file should be assembled with NASM (Netwide Assembler),
12
; can *not* be assembled with Microsoft's MASM or any compatible
13
; assembler (including Borland's Turbo Assembler).
14
; NASM is available from http://nasm.sourceforge.net/ or
15
; http://sourceforge.net/project/showfiles.php?group_id=6208
16
;
17
; [TAB8]
18
19
%include "jcolsamp.inc"
20
				
21
; --------------------------------------------------------------------------
22
	SECTION	SEG_TEXT
23
	BITS	32
24
;
25
; Upsample and color convert for the case of 2:1 horizontal and 1:1 vertical.
26
;
27
; GLOBAL(void)
28
; jsimd_h2v1_merged_upsample_sse2 (JDIMENSION output_width,
29
;                                  JSAMPIMAGE input_buf,
30
;                                  JDIMENSION in_row_group_ctr,
31
;                                  JSAMPARRAY output_buf);
32
;
33
34
%define output_width(b)	(b)+8			; JDIMENSION output_width
35
%define input_buf(b)		(b)+12		; JSAMPIMAGE input_buf
36
%define in_row_group_ctr(b)	(b)+16		; JDIMENSION in_row_group_ctr
37
%define output_buf(b)		(b)+20		; JSAMPARRAY output_buf
38
39
%define original_ebp	ebp+0
40
%define wk(i)		ebp-(WK_NUM-(i))*SIZEOF_XMMWORD	; xmmword wk[WK_NUM]
41
%define WK_NUM		3
42
%define gotptr		wk(0)-SIZEOF_POINTER	; void * gotptr
43
44
	align	16
45
	global	EXTN(jsimd_h2v1_merged_upsample_sse2)
46
47
EXTN(jsimd_h2v1_merged_upsample_sse2):
48
	push	ebp
49
	mov	eax,esp				; eax = original ebp
50
	sub	esp, byte 4
51
	and	esp, byte (-SIZEOF_XMMWORD)	; align to 128 bits
52
	mov	[esp],eax
53
	mov	ebp,esp				; ebp = aligned ebp
54
	lea	esp, [wk(0)]
55
	pushpic	eax		; make a room for GOT address
56
	push	ebx
57
;	push	ecx		; need not be preserved
58
;	push	edx		; need not be preserved
59
	push	esi
60
	push	edi
61
62
	get_GOT	ebx			; get GOT address
63
	movpic	POINTER [gotptr], ebx	; save GOT address
64
65
	mov	ecx, JDIMENSION [output_width(eax)]	; col
66
	test	ecx,ecx
67
	jz	near .return
68
69
	push	ecx
70
71
	mov	edi, JSAMPIMAGE [input_buf(eax)]
72
	mov	ecx, JDIMENSION [in_row_group_ctr(eax)]
73
	mov	esi, JSAMPARRAY [edi+0*SIZEOF_JSAMPARRAY]
74
	mov	ebx, JSAMPARRAY [edi+1*SIZEOF_JSAMPARRAY]
75
	mov	edx, JSAMPARRAY [edi+2*SIZEOF_JSAMPARRAY]
76
	mov	edi, JSAMPARRAY [output_buf(eax)]
77
	mov	esi, JSAMPROW [esi+ecx*SIZEOF_JSAMPROW]		; inptr0
78
	mov	ebx, JSAMPROW [ebx+ecx*SIZEOF_JSAMPROW]		; inptr1
79
	mov	edx, JSAMPROW [edx+ecx*SIZEOF_JSAMPROW]		; inptr2
80
	mov	edi, JSAMPROW [edi]				; outptr
81
82
	pop	ecx			; col
83
84
	alignx	16,7
85
.columnloop:
86
	movpic	eax, POINTER [gotptr]	; load GOT address (eax)
87
88
	movdqa    xmm6, XMMWORD [ebx]	; xmm6=Cb(0123456789ABCDEF)
89
	movdqa    xmm7, XMMWORD [edx]	; xmm7=Cr(0123456789ABCDEF)
90
91
	pxor      xmm1,xmm1		; xmm1=(all 0's)
92
	pcmpeqw   xmm3,xmm3
93
	psllw     xmm3,7		; xmm3={0xFF80 0xFF80 0xFF80 0xFF80 ..}
94
95
	movdqa    xmm4,xmm6
96
	punpckhbw xmm6,xmm1		; xmm6=Cb(89ABCDEF)=CbH
97
	punpcklbw xmm4,xmm1		; xmm4=Cb(01234567)=CbL
98
	movdqa    xmm0,xmm7
99
	punpckhbw xmm7,xmm1		; xmm7=Cr(89ABCDEF)=CrH
100
	punpcklbw xmm0,xmm1		; xmm0=Cr(01234567)=CrL
101
102
	paddw     xmm6,xmm3
103
	paddw     xmm4,xmm3
104
	paddw     xmm7,xmm3
105
	paddw     xmm0,xmm3
106
107
	; (Original)
108
	; R = Y                + 1.40200 * Cr
109
	; G = Y - 0.34414 * Cb - 0.71414 * Cr
110
	; B = Y + 1.77200 * Cb
111
	;
112
	; (This implementation)
113
	; R = Y                + 0.40200 * Cr + Cr
114
	; G = Y - 0.34414 * Cb + 0.28586 * Cr - Cr
115
	; B = Y - 0.22800 * Cb + Cb + Cb
116
117
	movdqa	xmm5,xmm6		; xmm5=CbH
118
	movdqa	xmm2,xmm4		; xmm2=CbL
119
	paddw	xmm6,xmm6		; xmm6=2*CbH
120
	paddw	xmm4,xmm4		; xmm4=2*CbL
121
	movdqa	xmm1,xmm7		; xmm1=CrH
122
	movdqa	xmm3,xmm0		; xmm3=CrL
123
	paddw	xmm7,xmm7		; xmm7=2*CrH
124
	paddw	xmm0,xmm0		; xmm0=2*CrL
125
126
	pmulhw	xmm6,[GOTOFF(eax,PW_MF0228)]	; xmm6=(2*CbH * -FIX(0.22800))
127
	pmulhw	xmm4,[GOTOFF(eax,PW_MF0228)]	; xmm4=(2*CbL * -FIX(0.22800))
128
	pmulhw	xmm7,[GOTOFF(eax,PW_F0402)]	; xmm7=(2*CrH * FIX(0.40200))
129
	pmulhw	xmm0,[GOTOFF(eax,PW_F0402)]	; xmm0=(2*CrL * FIX(0.40200))
130
131
	paddw	xmm6,[GOTOFF(eax,PW_ONE)]
132
	paddw	xmm4,[GOTOFF(eax,PW_ONE)]
133
	psraw	xmm6,1			; xmm6=(CbH * -FIX(0.22800))
134
	psraw	xmm4,1			; xmm4=(CbL * -FIX(0.22800))
135
	paddw	xmm7,[GOTOFF(eax,PW_ONE)]
136
	paddw	xmm0,[GOTOFF(eax,PW_ONE)]
137
	psraw	xmm7,1			; xmm7=(CrH * FIX(0.40200))
138
	psraw	xmm0,1			; xmm0=(CrL * FIX(0.40200))
139
140
	paddw	xmm6,xmm5
141
	paddw	xmm4,xmm2
142
	paddw	xmm6,xmm5		; xmm6=(CbH * FIX(1.77200))=(B-Y)H
143
	paddw	xmm4,xmm2		; xmm4=(CbL * FIX(1.77200))=(B-Y)L
144
	paddw	xmm7,xmm1		; xmm7=(CrH * FIX(1.40200))=(R-Y)H
145
	paddw	xmm0,xmm3		; xmm0=(CrL * FIX(1.40200))=(R-Y)L
146
147
	movdqa	XMMWORD [wk(0)], xmm6	; wk(0)=(B-Y)H
148
	movdqa	XMMWORD [wk(1)], xmm7	; wk(1)=(R-Y)H
149
150
	movdqa    xmm6,xmm5
151
	movdqa    xmm7,xmm2
152
	punpcklwd xmm5,xmm1
153
	punpckhwd xmm6,xmm1
154
	pmaddwd   xmm5,[GOTOFF(eax,PW_MF0344_F0285)]
155
	pmaddwd   xmm6,[GOTOFF(eax,PW_MF0344_F0285)]
156
	punpcklwd xmm2,xmm3
157
	punpckhwd xmm7,xmm3
158
	pmaddwd   xmm2,[GOTOFF(eax,PW_MF0344_F0285)]
159
	pmaddwd   xmm7,[GOTOFF(eax,PW_MF0344_F0285)]
160
161
	paddd     xmm5,[GOTOFF(eax,PD_ONEHALF)]
162
	paddd     xmm6,[GOTOFF(eax,PD_ONEHALF)]
163
	psrad     xmm5,SCALEBITS
164
	psrad     xmm6,SCALEBITS
165
	paddd     xmm2,[GOTOFF(eax,PD_ONEHALF)]
166
	paddd     xmm7,[GOTOFF(eax,PD_ONEHALF)]
167
	psrad     xmm2,SCALEBITS
168
	psrad     xmm7,SCALEBITS
169
170
	packssdw  xmm5,xmm6	; xmm5=CbH*-FIX(0.344)+CrH*FIX(0.285)
171
	packssdw  xmm2,xmm7	; xmm2=CbL*-FIX(0.344)+CrL*FIX(0.285)
172
	psubw     xmm5,xmm1	; xmm5=CbH*-FIX(0.344)+CrH*-FIX(0.714)=(G-Y)H
173
	psubw     xmm2,xmm3	; xmm2=CbL*-FIX(0.344)+CrL*-FIX(0.714)=(G-Y)L
174
175
	movdqa	XMMWORD [wk(2)], xmm5	; wk(2)=(G-Y)H
176
177
	mov	al,2			; Yctr
178
	jmp	short .Yloop_1st
179
	alignx	16,7
180
181
.Yloop_2nd:
182
	movdqa	xmm0, XMMWORD [wk(1)]	; xmm0=(R-Y)H
183
	movdqa	xmm2, XMMWORD [wk(2)]	; xmm2=(G-Y)H
184
	movdqa	xmm4, XMMWORD [wk(0)]	; xmm4=(B-Y)H
185
	alignx	16,7
186
187
.Yloop_1st:
188
	movdqa	xmm7, XMMWORD [esi]	; xmm7=Y(0123456789ABCDEF)
189
190
	pcmpeqw	xmm6,xmm6
191
	psrlw	xmm6,BYTE_BIT		; xmm6={0xFF 0x00 0xFF 0x00 ..}
192
	pand	xmm6,xmm7		; xmm6=Y(02468ACE)=YE
193
	psrlw	xmm7,BYTE_BIT		; xmm7=Y(13579BDF)=YO
194
195
	movdqa	xmm1,xmm0		; xmm1=xmm0=(R-Y)(L/H)
196
	movdqa	xmm3,xmm2		; xmm3=xmm2=(G-Y)(L/H)
197
	movdqa	xmm5,xmm4		; xmm5=xmm4=(B-Y)(L/H)
198
199
	paddw     xmm0,xmm6		; xmm0=((R-Y)+YE)=RE=R(02468ACE)
200
	paddw     xmm1,xmm7		; xmm1=((R-Y)+YO)=RO=R(13579BDF)
201
	packuswb  xmm0,xmm0		; xmm0=R(02468ACE********)
202
	packuswb  xmm1,xmm1		; xmm1=R(13579BDF********)
203
204
	paddw     xmm2,xmm6		; xmm2=((G-Y)+YE)=GE=G(02468ACE)
205
	paddw     xmm3,xmm7		; xmm3=((G-Y)+YO)=GO=G(13579BDF)
206
	packuswb  xmm2,xmm2		; xmm2=G(02468ACE********)
207
	packuswb  xmm3,xmm3		; xmm3=G(13579BDF********)
208
209
	paddw     xmm4,xmm6		; xmm4=((B-Y)+YE)=BE=B(02468ACE)
210
	paddw     xmm5,xmm7		; xmm5=((B-Y)+YO)=BO=B(13579BDF)
211
	packuswb  xmm4,xmm4		; xmm4=B(02468ACE********)
212
	packuswb  xmm5,xmm5		; xmm5=B(13579BDF********)
213
214
%if RGB_PIXELSIZE == 3 ; ---------------
215
216
	; xmmA=(00 02 04 06 08 0A 0C 0E **), xmmB=(01 03 05 07 09 0B 0D 0F **)
217
	; xmmC=(10 12 14 16 18 1A 1C 1E **), xmmD=(11 13 15 17 19 1B 1D 1F **)
218
	; xmmE=(20 22 24 26 28 2A 2C 2E **), xmmF=(21 23 25 27 29 2B 2D 2F **)
219
	; xmmG=(** ** ** ** ** ** ** ** **), xmmH=(** ** ** ** ** ** ** ** **)
220
221
	punpcklbw xmmA,xmmC	; xmmA=(00 10 02 12 04 14 06 16 08 18 0A 1A 0C 1C 0E 1E)
222
	punpcklbw xmmE,xmmB	; xmmE=(20 01 22 03 24 05 26 07 28 09 2A 0B 2C 0D 2E 0F)
223
	punpcklbw xmmD,xmmF	; xmmD=(11 21 13 23 15 25 17 27 19 29 1B 2B 1D 2D 1F 2F)
224
225
	movdqa    xmmG,xmmA
226
	movdqa    xmmH,xmmA
227
	punpcklwd xmmA,xmmE	; xmmA=(00 10 20 01 02 12 22 03 04 14 24 05 06 16 26 07)
228
	punpckhwd xmmG,xmmE	; xmmG=(08 18 28 09 0A 1A 2A 0B 0C 1C 2C 0D 0E 1E 2E 0F)
229
230
	psrldq    xmmH,2	; xmmH=(02 12 04 14 06 16 08 18 0A 1A 0C 1C 0E 1E -- --)
231
	psrldq    xmmE,2	; xmmE=(22 03 24 05 26 07 28 09 2A 0B 2C 0D 2E 0F -- --)
232
233
	movdqa    xmmC,xmmD
234
	movdqa    xmmB,xmmD
235
	punpcklwd xmmD,xmmH	; xmmD=(11 21 02 12 13 23 04 14 15 25 06 16 17 27 08 18)
236
	punpckhwd xmmC,xmmH	; xmmC=(19 29 0A 1A 1B 2B 0C 1C 1D 2D 0E 1E 1F 2F -- --)
237
238
	psrldq    xmmB,2	; xmmB=(13 23 15 25 17 27 19 29 1B 2B 1D 2D 1F 2F -- --)
239
240
	movdqa    xmmF,xmmE
241
	punpcklwd xmmE,xmmB	; xmmE=(22 03 13 23 24 05 15 25 26 07 17 27 28 09 19 29)
242
	punpckhwd xmmF,xmmB	; xmmF=(2A 0B 1B 2B 2C 0D 1D 2D 2E 0F 1F 2F -- -- -- --)
243
244
	pshufd    xmmH,xmmA,0x4E; xmmH=(04 14 24 05 06 16 26 07 00 10 20 01 02 12 22 03)
245
	movdqa    xmmB,xmmE
246
	punpckldq xmmA,xmmD	; xmmA=(00 10 20 01 11 21 02 12 02 12 22 03 13 23 04 14)
247
	punpckldq xmmE,xmmH	; xmmE=(22 03 13 23 04 14 24 05 24 05 15 25 06 16 26 07)
248
	punpckhdq xmmD,xmmB	; xmmD=(15 25 06 16 26 07 17 27 17 27 08 18 28 09 19 29)
249
250
	pshufd    xmmH,xmmG,0x4E; xmmH=(0C 1C 2C 0D 0E 1E 2E 0F 08 18 28 09 0A 1A 2A 0B)
251
	movdqa    xmmB,xmmF
252
	punpckldq xmmG,xmmC	; xmmG=(08 18 28 09 19 29 0A 1A 0A 1A 2A 0B 1B 2B 0C 1C)
253
	punpckldq xmmF,xmmH	; xmmF=(2A 0B 1B 2B 0C 1C 2C 0D 2C 0D 1D 2D 0E 1E 2E 0F)
254
	punpckhdq xmmC,xmmB	; xmmC=(1D 2D 0E 1E 2E 0F 1F 2F 1F 2F -- -- -- -- -- --)
255
256
	punpcklqdq xmmA,xmmE	; xmmA=(00 10 20 01 11 21 02 12 22 03 13 23 04 14 24 05)
257
	punpcklqdq xmmD,xmmG	; xmmD=(15 25 06 16 26 07 17 27 08 18 28 09 19 29 0A 1A)
258
	punpcklqdq xmmF,xmmC	; xmmF=(2A 0B 1B 2B 0C 1C 2C 0D 1D 2D 0E 1E 2E 0F 1F 2F)
259
260
	cmp	ecx, byte SIZEOF_XMMWORD
261
	jb	short .column_st32
262
263
	test	edi, SIZEOF_XMMWORD-1
264
	jnz	short .out1
265
	; --(aligned)-------------------
266
	movntdq	XMMWORD [edi+0*SIZEOF_XMMWORD], xmmA
267
	movntdq	XMMWORD [edi+1*SIZEOF_XMMWORD], xmmD
268
	movntdq	XMMWORD [edi+2*SIZEOF_XMMWORD], xmmF
269
	add	edi, byte RGB_PIXELSIZE*SIZEOF_XMMWORD	; outptr
270
	jmp	short .out0
271
.out1:	; --(unaligned)-----------------
272
	pcmpeqb    xmmH,xmmH			; xmmH=(all 1's)
273
	maskmovdqu xmmA,xmmH			; movntdqu XMMWORD [edi], xmmA
274
	add	edi, byte SIZEOF_XMMWORD	; outptr
275
	maskmovdqu xmmD,xmmH			; movntdqu XMMWORD [edi], xmmD
276
	add	edi, byte SIZEOF_XMMWORD	; outptr
277
	maskmovdqu xmmF,xmmH			; movntdqu XMMWORD [edi], xmmF
278
	add	edi, byte SIZEOF_XMMWORD	; outptr
279
.out0:
280
	sub	ecx, byte SIZEOF_XMMWORD
281
	jz	near .endcolumn
282
283
	add	esi, byte SIZEOF_XMMWORD	; inptr0
284
	dec	al			; Yctr
285
	jnz	near .Yloop_2nd
286
287
	add	ebx, byte SIZEOF_XMMWORD	; inptr1
288
	add	edx, byte SIZEOF_XMMWORD	; inptr2
289
	jmp	near .columnloop
290
	alignx	16,7
291
292
.column_st32:
293
	pcmpeqb	xmmH,xmmH			; xmmH=(all 1's)
294
	lea	ecx, [ecx+ecx*2]		; imul ecx, RGB_PIXELSIZE
295
	cmp	ecx, byte 2*SIZEOF_XMMWORD
296
	jb	short .column_st16
297
	maskmovdqu xmmA,xmmH			; movntdqu XMMWORD [edi], xmmA
298
	add	edi, byte SIZEOF_XMMWORD	; outptr
299
	maskmovdqu xmmD,xmmH			; movntdqu XMMWORD [edi], xmmD
300
	add	edi, byte SIZEOF_XMMWORD	; outptr
301
	movdqa	xmmA,xmmF
302
	sub	ecx, byte 2*SIZEOF_XMMWORD
303
	jmp	short .column_st15
304
.column_st16:
305
	cmp	ecx, byte SIZEOF_XMMWORD
306
	jb	short .column_st15
307
	maskmovdqu xmmA,xmmH			; movntdqu XMMWORD [edi], xmmA
308
	add	edi, byte SIZEOF_XMMWORD	; outptr
309
	movdqa	xmmA,xmmD
310
	sub	ecx, byte SIZEOF_XMMWORD
311
.column_st15:
312
	mov	eax,ecx
313
	xor	ecx, byte 0x0F
314
	shl	ecx, 2
315
	movd	xmmB,ecx
316
	psrlq	xmmH,4
317
	pcmpeqb	xmmE,xmmE
318
	psrlq	xmmH,xmmB
319
	psrlq	xmmE,xmmB
320
	punpcklbw xmmE,xmmH
321
	; ----------------
322
	mov	ecx,edi
323
	and	ecx, byte SIZEOF_XMMWORD-1
324
	jz	short .adj0
325
	add	eax,ecx
326
	cmp	eax, byte SIZEOF_XMMWORD
327
	ja	short .adj0
328
	and	edi, byte (-SIZEOF_XMMWORD)	; align to 16-byte boundary
329
	shl	ecx, 3			; pslldq xmmA,ecx & pslldq xmmE,ecx
330
	movdqa	xmmG,xmmA
331
	movdqa	xmmC,xmmE
332
	pslldq	xmmA, SIZEOF_XMMWORD/2
333
	pslldq	xmmE, SIZEOF_XMMWORD/2
334
	movd	xmmD,ecx
335
	sub	ecx, byte (SIZEOF_XMMWORD/2)*BYTE_BIT
336
	jb	short .adj1
337
	movd	xmmF,ecx
338
	psllq	xmmA,xmmF
339
	psllq	xmmE,xmmF
340
	jmp	short .adj0
341
.adj1:	neg	ecx
342
	movd	xmmF,ecx
343
	psrlq	xmmA,xmmF
344
	psrlq	xmmE,xmmF
345
	psllq	xmmG,xmmD
346
	psllq	xmmC,xmmD
347
	por	xmmA,xmmG
348
	por	xmmE,xmmC
349
.adj0:	; ----------------
350
	maskmovdqu xmmA,xmmE			; movntdqu XMMWORD [edi], xmmA
351
352
%else ; RGB_PIXELSIZE == 4 ; -----------
353
354
%ifdef RGBX_FILLER_0XFF
355
	pcmpeqb   xmm6,xmm6		; xmm6=XE=X(02468ACE********)
356
	pcmpeqb   xmm7,xmm7		; xmm7=XO=X(13579BDF********)
357
%else
358
	pxor      xmm6,xmm6		; xmm6=XE=X(02468ACE********)
359
	pxor      xmm7,xmm7		; xmm7=XO=X(13579BDF********)
360
%endif
361
	; xmmA=(00 02 04 06 08 0A 0C 0E **), xmmB=(01 03 05 07 09 0B 0D 0F **)
362
	; xmmC=(10 12 14 16 18 1A 1C 1E **), xmmD=(11 13 15 17 19 1B 1D 1F **)
363
	; xmmE=(20 22 24 26 28 2A 2C 2E **), xmmF=(21 23 25 27 29 2B 2D 2F **)
364
	; xmmG=(30 32 34 36 38 3A 3C 3E **), xmmH=(31 33 35 37 39 3B 3D 3F **)
365
366
	punpcklbw xmmA,xmmC	; xmmA=(00 10 02 12 04 14 06 16 08 18 0A 1A 0C 1C 0E 1E)
367
	punpcklbw xmmE,xmmG	; xmmE=(20 30 22 32 24 34 26 36 28 38 2A 3A 2C 3C 2E 3E)
368
	punpcklbw xmmB,xmmD	; xmmB=(01 11 03 13 05 15 07 17 09 19 0B 1B 0D 1D 0F 1F)
369
	punpcklbw xmmF,xmmH	; xmmF=(21 31 23 33 25 35 27 37 29 39 2B 3B 2D 3D 2F 3F)
370
371
	movdqa    xmmC,xmmA
372
	punpcklwd xmmA,xmmE	; xmmA=(00 10 20 30 02 12 22 32 04 14 24 34 06 16 26 36)
373
	punpckhwd xmmC,xmmE	; xmmC=(08 18 28 38 0A 1A 2A 3A 0C 1C 2C 3C 0E 1E 2E 3E)
374
	movdqa    xmmG,xmmB
375
	punpcklwd xmmB,xmmF	; xmmB=(01 11 21 31 03 13 23 33 05 15 25 35 07 17 27 37)
376
	punpckhwd xmmG,xmmF	; xmmG=(09 19 29 39 0B 1B 2B 3B 0D 1D 2D 3D 0F 1F 2F 3F)
377
378
	movdqa    xmmD,xmmA
379
	punpckldq xmmA,xmmB	; xmmA=(00 10 20 30 01 11 21 31 02 12 22 32 03 13 23 33)
380
	punpckhdq xmmD,xmmB	; xmmD=(04 14 24 34 05 15 25 35 06 16 26 36 07 17 27 37)
381
	movdqa    xmmH,xmmC
382
	punpckldq xmmC,xmmG	; xmmC=(08 18 28 38 09 19 29 39 0A 1A 2A 3A 0B 1B 2B 3B)
383
	punpckhdq xmmH,xmmG	; xmmH=(0C 1C 2C 3C 0D 1D 2D 3D 0E 1E 2E 3E 0F 1F 2F 3F)
384
385
	cmp	ecx, byte SIZEOF_XMMWORD
386
	jb	short .column_st32
387
388
	test	edi, SIZEOF_XMMWORD-1
389
	jnz	short .out1
390
	; --(aligned)-------------------
391
	movntdq	XMMWORD [edi+0*SIZEOF_XMMWORD], xmmA
392
	movntdq	XMMWORD [edi+1*SIZEOF_XMMWORD], xmmD
393
	movntdq	XMMWORD [edi+2*SIZEOF_XMMWORD], xmmC
394
	movntdq	XMMWORD [edi+3*SIZEOF_XMMWORD], xmmH
395
	add	edi, byte RGB_PIXELSIZE*SIZEOF_XMMWORD	; outptr
396
	jmp	short .out0
397
.out1:	; --(unaligned)-----------------
398
	pcmpeqb    xmmE,xmmE			; xmmE=(all 1's)
399
	maskmovdqu xmmA,xmmE			; movntdqu XMMWORD [edi], xmmA
400
	add	edi, byte SIZEOF_XMMWORD	; outptr
401
	maskmovdqu xmmD,xmmE			; movntdqu XMMWORD [edi], xmmD
402
	add	edi, byte SIZEOF_XMMWORD	; outptr
403
	maskmovdqu xmmC,xmmE			; movntdqu XMMWORD [edi], xmmC
404
	add	edi, byte SIZEOF_XMMWORD	; outptr
405
	maskmovdqu xmmH,xmmE			; movntdqu XMMWORD [edi], xmmH
406
	add	edi, byte SIZEOF_XMMWORD	; outptr
407
.out0:
408
	sub	ecx, byte SIZEOF_XMMWORD
409
	jz	near .endcolumn
410
411
	add	esi, byte SIZEOF_XMMWORD	; inptr0
412
	dec	al			; Yctr
413
	jnz	near .Yloop_2nd
414
415
	add	ebx, byte SIZEOF_XMMWORD	; inptr1
416
	add	edx, byte SIZEOF_XMMWORD	; inptr2
417
	jmp	near .columnloop
418
	alignx	16,7
419
420
.column_st32:
421
	pcmpeqb	xmmE,xmmE			; xmmE=(all 1's)
422
	cmp	ecx, byte SIZEOF_XMMWORD/2
423
	jb	short .column_st16
424
	maskmovdqu xmmA,xmmE			; movntdqu XMMWORD [edi], xmmA
425
	add	edi, byte SIZEOF_XMMWORD	; outptr
426
	maskmovdqu xmmD,xmmE			; movntdqu XMMWORD [edi], xmmD
427
	add	edi, byte SIZEOF_XMMWORD	; outptr
428
	movdqa	xmmA,xmmC
429
	movdqa	xmmD,xmmH
430
	sub	ecx, byte SIZEOF_XMMWORD/2
431
.column_st16:
432
	cmp	ecx, byte SIZEOF_XMMWORD/4
433
	jb	short .column_st15
434
	maskmovdqu xmmA,xmmE			; movntdqu XMMWORD [edi], xmmA
435
	add	edi, byte SIZEOF_XMMWORD	; outptr
436
	movdqa	xmmA,xmmD
437
	sub	ecx, byte SIZEOF_XMMWORD/4
438
.column_st15:
439
	cmp	ecx, byte SIZEOF_XMMWORD/16
440
	jb	short .endcolumn
441
	mov	eax,ecx
442
	xor	ecx, byte 0x03
443
	inc	ecx
444
	shl	ecx, 4
445
	movd	xmmF,ecx
446
	psrlq	xmmE,xmmF
447
	punpcklbw xmmE,xmmE
448
	; ----------------
449
	mov	ecx,edi
450
	and	ecx, byte SIZEOF_XMMWORD-1
451
	jz	short .adj0
452
	lea	eax, [ecx+eax*4]	; RGB_PIXELSIZE
453
	cmp	eax, byte SIZEOF_XMMWORD
454
	ja	short .adj0
455
	and	edi, byte (-SIZEOF_XMMWORD)	; align to 16-byte boundary
456
	shl	ecx, 3			; pslldq xmmA,ecx & pslldq xmmE,ecx
457
	movdqa	xmmB,xmmA
458
	movdqa	xmmG,xmmE
459
	pslldq	xmmA, SIZEOF_XMMWORD/2
460
	pslldq	xmmE, SIZEOF_XMMWORD/2
461
	movd	xmmC,ecx
462
	sub	ecx, byte (SIZEOF_XMMWORD/2)*BYTE_BIT
463
	jb	short .adj1
464
	movd	xmmH,ecx
465
	psllq	xmmA,xmmH
466
	psllq	xmmE,xmmH
467
	jmp	short .adj0
468
.adj1:	neg	ecx
469
	movd	xmmH,ecx
470
	psrlq	xmmA,xmmH
471
	psrlq	xmmE,xmmH
472
	psllq	xmmB,xmmC
473
	psllq	xmmG,xmmC
474
	por	xmmA,xmmB
475
	por	xmmE,xmmG
476
.adj0:	; ----------------
477
	maskmovdqu xmmA,xmmE			; movntdqu XMMWORD [edi], xmmA
478
479
%endif ; RGB_PIXELSIZE ; ---------------
480
481
.endcolumn:
482
	sfence		; flush the write buffer
483
484
.return:
485
	pop	edi
486
	pop	esi
487
;	pop	edx		; need not be preserved
488
;	pop	ecx		; need not be preserved
489
	pop	ebx
490
	mov	esp,ebp		; esp <- aligned ebp
491
	pop	esp		; esp <- original ebp
492
	pop	ebp
493
	ret
494
495
; --------------------------------------------------------------------------
496
;
497
; Upsample and color convert for the case of 2:1 horizontal and 2:1 vertical.
498
;
499
; GLOBAL(void)
500
; jsimd_h2v2_merged_upsample_sse2 (JDIMENSION output_width,
501
;                                  JSAMPIMAGE input_buf,
502
;                                  JDIMENSION in_row_group_ctr,
503
;                                  JSAMPARRAY output_buf);
504
;
505
506
%define output_width(b)	(b)+8			; JDIMENSION output_width
507
%define input_buf(b)		(b)+12		; JSAMPIMAGE input_buf
508
%define in_row_group_ctr(b)	(b)+16		; JDIMENSION in_row_group_ctr
509
%define output_buf(b)		(b)+20		; JSAMPARRAY output_buf
510
511
	align	16
512
	global	EXTN(jsimd_h2v2_merged_upsample_sse2)
513
514
EXTN(jsimd_h2v2_merged_upsample_sse2):
515
	push	ebp
516
	mov	ebp,esp
517
	push	ebx
518
;	push	ecx		; need not be preserved
519
;	push	edx		; need not be preserved
520
	push	esi
521
	push	edi
522
523
	mov	eax, POINTER [output_width(ebp)]
524
525
	mov	edi, JSAMPIMAGE [input_buf(ebp)]
526
	mov	ecx, JDIMENSION [in_row_group_ctr(ebp)]
527
	mov	esi, JSAMPARRAY [edi+0*SIZEOF_JSAMPARRAY]
528
	mov	ebx, JSAMPARRAY [edi+1*SIZEOF_JSAMPARRAY]
529
	mov	edx, JSAMPARRAY [edi+2*SIZEOF_JSAMPARRAY]
530
	mov	edi, JSAMPARRAY [output_buf(ebp)]
531
	lea	esi, [esi+ecx*SIZEOF_JSAMPROW]
532
533
	push	edx			; inptr2
534
	push	ebx			; inptr1
535
	push	esi			; inptr00
536
	mov	ebx,esp
537
538
	push	edi			; output_buf (outptr0)
539
	push	ecx			; in_row_group_ctr
540
	push	ebx			; input_buf
541
	push	eax			; output_width
542
543
	call	near EXTN(jsimd_h2v1_merged_upsample_sse2)
544
545
	add	esi, byte SIZEOF_JSAMPROW	; inptr01
546
	add	edi, byte SIZEOF_JSAMPROW	; outptr1
547
	mov	POINTER [ebx+0*SIZEOF_POINTER], esi
548
	mov	POINTER [ebx-1*SIZEOF_POINTER], edi
549
550
	call	near EXTN(jsimd_h2v1_merged_upsample_sse2)
551
552
	add	esp, byte 7*SIZEOF_DWORD
553
554
	pop	edi
555
	pop	esi
556
;	pop	edx		; need not be preserved
557
;	pop	ecx		; need not be preserved
558
	pop	ebx
559
	pop	ebp
560
	ret
561
562
; For some reason, the OS X linker does not honor the request to align the
563
; segment unless we do this.
564
	align	16
(-)a/jpeg/simd/jdsammmx.asm (+737 lines)
Line     Link Here 
Line 0    Link Here 
1
;
2
; jdsammmx.asm - upsampling (MMX)
3
;
4
; Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
5
;
6
; Based on
7
; x86 SIMD extension for IJG JPEG library
8
; Copyright (C) 1999-2006, MIYASAKA Masaru.
9
; For conditions of distribution and use, see copyright notice in jsimdext.inc
10
;
11
; This file should be assembled with NASM (Netwide Assembler),
12
; can *not* be assembled with Microsoft's MASM or any compatible
13
; assembler (including Borland's Turbo Assembler).
14
; NASM is available from http://nasm.sourceforge.net/ or
15
; http://sourceforge.net/project/showfiles.php?group_id=6208
16
;
17
; [TAB8]
18
19
%include "jsimdext.inc"
20
21
; --------------------------------------------------------------------------
22
	SECTION	SEG_CONST
23
24
	alignz	16
25
	global	EXTN(jconst_fancy_upsample_mmx)
26
27
EXTN(jconst_fancy_upsample_mmx):
28
29
PW_ONE		times 4 dw  1
30
PW_TWO		times 4 dw  2
31
PW_THREE	times 4 dw  3
32
PW_SEVEN	times 4 dw  7
33
PW_EIGHT	times 4 dw  8
34
35
	alignz	16
36
37
; --------------------------------------------------------------------------
38
	SECTION	SEG_TEXT
39
	BITS	32
40
;
41
; Fancy processing for the common case of 2:1 horizontal and 1:1 vertical.
42
;
43
; The upsampling algorithm is linear interpolation between pixel centers,
44
; also known as a "triangle filter".  This is a good compromise between
45
; speed and visual quality.  The centers of the output pixels are 1/4 and 3/4
46
; of the way between input pixel centers.
47
;
48
; GLOBAL(void)
49
; jsimd_h2v1_fancy_upsample_mmx (int max_v_samp_factor,
50
;                                JDIMENSION downsampled_width,
51
;                                JSAMPARRAY input_data,
52
;                                JSAMPARRAY * output_data_ptr);
53
;
54
55
%define max_v_samp(b)		(b)+8			; int max_v_samp_factor
56
%define downsamp_width(b)	(b)+12	; JDIMENSION downsampled_width
57
%define input_data(b)		(b)+16		; JSAMPARRAY input_data
58
%define output_data_ptr(b)	(b)+20		; JSAMPARRAY * output_data_ptr
59
60
	align	16
61
	global	EXTN(jsimd_h2v1_fancy_upsample_mmx)
62
63
EXTN(jsimd_h2v1_fancy_upsample_mmx):
64
	push	ebp
65
	mov	ebp,esp
66
	pushpic	ebx
67
;	push	ecx		; need not be preserved
68
;	push	edx		; need not be preserved
69
	push	esi
70
	push	edi
71
72
	get_GOT	ebx		; get GOT address
73
74
	mov	eax, JDIMENSION [downsamp_width(ebp)]  ; colctr
75
	test	eax,eax
76
	jz	near .return
77
78
	mov	ecx, INT [max_v_samp(ebp)]	; rowctr
79
	test	ecx,ecx
80
	jz	near .return
81
82
	mov	esi, JSAMPARRAY [input_data(ebp)]	; input_data
83
	mov	edi, POINTER [output_data_ptr(ebp)]
84
	mov	edi, JSAMPARRAY [edi]			; output_data
85
	alignx	16,7
86
.rowloop:
87
	push	eax			; colctr
88
	push	edi
89
	push	esi
90
91
	mov	esi, JSAMPROW [esi]	; inptr
92
	mov	edi, JSAMPROW [edi]	; outptr
93
94
	test	eax, SIZEOF_MMWORD-1
95
	jz	short .skip
96
	mov	dl, JSAMPLE [esi+(eax-1)*SIZEOF_JSAMPLE]
97
	mov	JSAMPLE [esi+eax*SIZEOF_JSAMPLE], dl	; insert a dummy sample
98
.skip:
99
	pxor	mm0,mm0			; mm0=(all 0's)
100
	pcmpeqb	mm7,mm7
101
	psrlq	mm7,(SIZEOF_MMWORD-1)*BYTE_BIT
102
	pand	mm7, MMWORD [esi+0*SIZEOF_MMWORD]
103
104
	add	eax, byte SIZEOF_MMWORD-1
105
	and	eax, byte -SIZEOF_MMWORD
106
	cmp	eax, byte SIZEOF_MMWORD
107
	ja	short .columnloop
108
	alignx	16,7
109
110
.columnloop_last:
111
	pcmpeqb	mm6,mm6
112
	psllq	mm6,(SIZEOF_MMWORD-1)*BYTE_BIT
113
	pand	mm6, MMWORD [esi+0*SIZEOF_MMWORD]
114
	jmp	short .upsample
115
	alignx	16,7
116
117
.columnloop:
118
	movq	mm6, MMWORD [esi+1*SIZEOF_MMWORD]
119
	psllq	mm6,(SIZEOF_MMWORD-1)*BYTE_BIT
120
121
.upsample:
122
	movq	mm1, MMWORD [esi+0*SIZEOF_MMWORD]
123
	movq	mm2,mm1
124
	movq	mm3,mm1			; mm1=( 0 1 2 3 4 5 6 7)
125
	psllq	mm2,BYTE_BIT		; mm2=( - 0 1 2 3 4 5 6)
126
	psrlq	mm3,BYTE_BIT		; mm3=( 1 2 3 4 5 6 7 -)
127
128
	por	mm2,mm7			; mm2=(-1 0 1 2 3 4 5 6)
129
	por	mm3,mm6			; mm3=( 1 2 3 4 5 6 7 8)
130
131
	movq	mm7,mm1
132
	psrlq	mm7,(SIZEOF_MMWORD-1)*BYTE_BIT	; mm7=( 7 - - - - - - -)
133
134
	movq      mm4,mm1
135
	punpcklbw mm1,mm0		; mm1=( 0 1 2 3)
136
	punpckhbw mm4,mm0		; mm4=( 4 5 6 7)
137
	movq      mm5,mm2
138
	punpcklbw mm2,mm0		; mm2=(-1 0 1 2)
139
	punpckhbw mm5,mm0		; mm5=( 3 4 5 6)
140
	movq      mm6,mm3
141
	punpcklbw mm3,mm0		; mm3=( 1 2 3 4)
142
	punpckhbw mm6,mm0		; mm6=( 5 6 7 8)
143
144
	pmullw	mm1,[GOTOFF(ebx,PW_THREE)]
145
	pmullw	mm4,[GOTOFF(ebx,PW_THREE)]
146
	paddw	mm2,[GOTOFF(ebx,PW_ONE)]
147
	paddw	mm5,[GOTOFF(ebx,PW_ONE)]
148
	paddw	mm3,[GOTOFF(ebx,PW_TWO)]
149
	paddw	mm6,[GOTOFF(ebx,PW_TWO)]
150
151
	paddw	mm2,mm1
152
	paddw	mm5,mm4
153
	psrlw	mm2,2			; mm2=OutLE=( 0  2  4  6)
154
	psrlw	mm5,2			; mm5=OutHE=( 8 10 12 14)
155
	paddw	mm3,mm1
156
	paddw	mm6,mm4
157
	psrlw	mm3,2			; mm3=OutLO=( 1  3  5  7)
158
	psrlw	mm6,2			; mm6=OutHO=( 9 11 13 15)
159
160
	psllw	mm3,BYTE_BIT
161
	psllw	mm6,BYTE_BIT
162
	por	mm2,mm3			; mm2=OutL=( 0  1  2  3  4  5  6  7)
163
	por	mm5,mm6			; mm5=OutH=( 8  9 10 11 12 13 14 15)
164
165
	movq	MMWORD [edi+0*SIZEOF_MMWORD], mm2
166
	movq	MMWORD [edi+1*SIZEOF_MMWORD], mm5
167
168
	sub	eax, byte SIZEOF_MMWORD
169
	add	esi, byte 1*SIZEOF_MMWORD	; inptr
170
	add	edi, byte 2*SIZEOF_MMWORD	; outptr
171
	cmp	eax, byte SIZEOF_MMWORD
172
	ja	near .columnloop
173
	test	eax,eax
174
	jnz	near .columnloop_last
175
176
	pop	esi
177
	pop	edi
178
	pop	eax
179
180
	add	esi, byte SIZEOF_JSAMPROW	; input_data
181
	add	edi, byte SIZEOF_JSAMPROW	; output_data
182
	dec	ecx				; rowctr
183
	jg	near .rowloop
184
185
	emms		; empty MMX state
186
187
.return:
188
	pop	edi
189
	pop	esi
190
;	pop	edx		; need not be preserved
191
;	pop	ecx		; need not be preserved
192
	poppic	ebx
193
	pop	ebp
194
	ret
195
196
; --------------------------------------------------------------------------
197
;
198
; Fancy processing for the common case of 2:1 horizontal and 2:1 vertical.
199
; Again a triangle filter; see comments for h2v1 case, above.
200
;
201
; GLOBAL(void)
202
; jsimd_h2v2_fancy_upsample_mmx (int max_v_samp_factor,
203
;                                JDIMENSION downsampled_width,
204
;                                JSAMPARRAY input_data,
205
;                                JSAMPARRAY * output_data_ptr);
206
;
207
208
%define max_v_samp(b)		(b)+8			; int max_v_samp_factor
209
%define downsamp_width(b)	(b)+12	; JDIMENSION downsampled_width
210
%define input_data(b)		(b)+16		; JSAMPARRAY input_data
211
%define output_data_ptr(b)	(b)+20		; JSAMPARRAY * output_data_ptr
212
213
%define original_ebp	ebp+0
214
%define wk(i)		ebp-(WK_NUM-(i))*SIZEOF_MMWORD	; mmword wk[WK_NUM]
215
%define WK_NUM		4
216
%define gotptr		wk(0)-SIZEOF_POINTER	; void * gotptr
217
218
	align	16
219
	global	EXTN(jsimd_h2v2_fancy_upsample_mmx)
220
221
EXTN(jsimd_h2v2_fancy_upsample_mmx):
222
	push	ebp
223
	mov	eax,esp				; eax = original ebp
224
	sub	esp, byte 4
225
	and	esp, byte (-SIZEOF_MMWORD)	; align to 64 bits
226
	mov	[esp],eax
227
	mov	ebp,esp				; ebp = aligned ebp
228
	lea	esp, [wk(0)]
229
	pushpic	eax		; make a room for GOT address
230
	push	ebx
231
;	push	ecx		; need not be preserved
232
;	push	edx		; need not be preserved
233
	push	esi
234
	push	edi
235
236
	get_GOT	ebx			; get GOT address
237
	movpic	POINTER [gotptr], ebx	; save GOT address
238
239
	mov	edx,eax				; edx = original ebp
240
	mov	eax, JDIMENSION [downsamp_width(edx)]  ; colctr
241
	test	eax,eax
242
	jz	near .return
243
244
	mov	ecx, INT [max_v_samp(edx)]	; rowctr
245
	test	ecx,ecx
246
	jz	near .return
247
248
	mov	esi, JSAMPARRAY [input_data(edx)]	; input_data
249
	mov	edi, POINTER [output_data_ptr(edx)]
250
	mov	edi, JSAMPARRAY [edi]			; output_data
251
	alignx	16,7
252
.rowloop:
253
	push	eax					; colctr
254
	push	ecx
255
	push	edi
256
	push	esi
257
258
	mov	ecx, JSAMPROW [esi-1*SIZEOF_JSAMPROW]	; inptr1(above)
259
	mov	ebx, JSAMPROW [esi+0*SIZEOF_JSAMPROW]	; inptr0
260
	mov	esi, JSAMPROW [esi+1*SIZEOF_JSAMPROW]	; inptr1(below)
261
	mov	edx, JSAMPROW [edi+0*SIZEOF_JSAMPROW]	; outptr0
262
	mov	edi, JSAMPROW [edi+1*SIZEOF_JSAMPROW]	; outptr1
263
264
	test	eax, SIZEOF_MMWORD-1
265
	jz	short .skip
266
	push	edx
267
	mov	dl, JSAMPLE [ecx+(eax-1)*SIZEOF_JSAMPLE]
268
	mov	JSAMPLE [ecx+eax*SIZEOF_JSAMPLE], dl
269
	mov	dl, JSAMPLE [ebx+(eax-1)*SIZEOF_JSAMPLE]
270
	mov	JSAMPLE [ebx+eax*SIZEOF_JSAMPLE], dl
271
	mov	dl, JSAMPLE [esi+(eax-1)*SIZEOF_JSAMPLE]
272
	mov	JSAMPLE [esi+eax*SIZEOF_JSAMPLE], dl	; insert a dummy sample
273
	pop	edx
274
.skip:
275
	; -- process the first column block
276
277
	movq	mm0, MMWORD [ebx+0*SIZEOF_MMWORD]	; mm0=row[ 0][0]
278
	movq	mm1, MMWORD [ecx+0*SIZEOF_MMWORD]	; mm1=row[-1][0]
279
	movq	mm2, MMWORD [esi+0*SIZEOF_MMWORD]	; mm2=row[+1][0]
280
281
	pushpic	ebx
282
	movpic	ebx, POINTER [gotptr]	; load GOT address
283
284
	pxor      mm3,mm3		; mm3=(all 0's)
285
	movq      mm4,mm0
286
	punpcklbw mm0,mm3		; mm0=row[ 0][0]( 0 1 2 3)
287
	punpckhbw mm4,mm3		; mm4=row[ 0][0]( 4 5 6 7)
288
	movq      mm5,mm1
289
	punpcklbw mm1,mm3		; mm1=row[-1][0]( 0 1 2 3)
290
	punpckhbw mm5,mm3		; mm5=row[-1][0]( 4 5 6 7)
291
	movq      mm6,mm2
292
	punpcklbw mm2,mm3		; mm2=row[+1][0]( 0 1 2 3)
293
	punpckhbw mm6,mm3		; mm6=row[+1][0]( 4 5 6 7)
294
295
	pmullw	mm0,[GOTOFF(ebx,PW_THREE)]
296
	pmullw	mm4,[GOTOFF(ebx,PW_THREE)]
297
298
	pcmpeqb	mm7,mm7
299
	psrlq	mm7,(SIZEOF_MMWORD-2)*BYTE_BIT
300
301
	paddw	mm1,mm0			; mm1=Int0L=( 0 1 2 3)
302
	paddw	mm5,mm4			; mm5=Int0H=( 4 5 6 7)
303
	paddw	mm2,mm0			; mm2=Int1L=( 0 1 2 3)
304
	paddw	mm6,mm4			; mm6=Int1H=( 4 5 6 7)
305
306
	movq	MMWORD [edx+0*SIZEOF_MMWORD], mm1	; temporarily save
307
	movq	MMWORD [edx+1*SIZEOF_MMWORD], mm5	; the intermediate data
308
	movq	MMWORD [edi+0*SIZEOF_MMWORD], mm2
309
	movq	MMWORD [edi+1*SIZEOF_MMWORD], mm6
310
311
	pand	mm1,mm7			; mm1=( 0 - - -)
312
	pand	mm2,mm7			; mm2=( 0 - - -)
313
314
	movq	MMWORD [wk(0)], mm1
315
	movq	MMWORD [wk(1)], mm2
316
317
	poppic	ebx
318
319
	add	eax, byte SIZEOF_MMWORD-1
320
	and	eax, byte -SIZEOF_MMWORD
321
	cmp	eax, byte SIZEOF_MMWORD
322
	ja	short .columnloop
323
	alignx	16,7
324
325
.columnloop_last:
326
	; -- process the last column block
327
328
	pushpic	ebx
329
	movpic	ebx, POINTER [gotptr]	; load GOT address
330
331
	pcmpeqb	mm1,mm1
332
	psllq	mm1,(SIZEOF_MMWORD-2)*BYTE_BIT
333
	movq	mm2,mm1
334
335
	pand	mm1, MMWORD [edx+1*SIZEOF_MMWORD]	; mm1=( - - - 7)
336
	pand	mm2, MMWORD [edi+1*SIZEOF_MMWORD]	; mm2=( - - - 7)
337
338
	movq	MMWORD [wk(2)], mm1
339
	movq	MMWORD [wk(3)], mm2
340
341
	jmp	short .upsample
342
	alignx	16,7
343
344
.columnloop:
345
	; -- process the next column block
346
347
	movq	mm0, MMWORD [ebx+1*SIZEOF_MMWORD]	; mm0=row[ 0][1]
348
	movq	mm1, MMWORD [ecx+1*SIZEOF_MMWORD]	; mm1=row[-1][1]
349
	movq	mm2, MMWORD [esi+1*SIZEOF_MMWORD]	; mm2=row[+1][1]
350
351
	pushpic	ebx
352
	movpic	ebx, POINTER [gotptr]	; load GOT address
353
354
	pxor      mm3,mm3		; mm3=(all 0's)
355
	movq      mm4,mm0
356
	punpcklbw mm0,mm3		; mm0=row[ 0][1]( 0 1 2 3)
357
	punpckhbw mm4,mm3		; mm4=row[ 0][1]( 4 5 6 7)
358
	movq      mm5,mm1
359
	punpcklbw mm1,mm3		; mm1=row[-1][1]( 0 1 2 3)
360
	punpckhbw mm5,mm3		; mm5=row[-1][1]( 4 5 6 7)
361
	movq      mm6,mm2
362
	punpcklbw mm2,mm3		; mm2=row[+1][1]( 0 1 2 3)
363
	punpckhbw mm6,mm3		; mm6=row[+1][1]( 4 5 6 7)
364
365
	pmullw	mm0,[GOTOFF(ebx,PW_THREE)]
366
	pmullw	mm4,[GOTOFF(ebx,PW_THREE)]
367
368
	paddw	mm1,mm0			; mm1=Int0L=( 0 1 2 3)
369
	paddw	mm5,mm4			; mm5=Int0H=( 4 5 6 7)
370
	paddw	mm2,mm0			; mm2=Int1L=( 0 1 2 3)
371
	paddw	mm6,mm4			; mm6=Int1H=( 4 5 6 7)
372
373
	movq	MMWORD [edx+2*SIZEOF_MMWORD], mm1	; temporarily save
374
	movq	MMWORD [edx+3*SIZEOF_MMWORD], mm5	; the intermediate data
375
	movq	MMWORD [edi+2*SIZEOF_MMWORD], mm2
376
	movq	MMWORD [edi+3*SIZEOF_MMWORD], mm6
377
378
	psllq	mm1,(SIZEOF_MMWORD-2)*BYTE_BIT	; mm1=( - - - 0)
379
	psllq	mm2,(SIZEOF_MMWORD-2)*BYTE_BIT	; mm2=( - - - 0)
380
381
	movq	MMWORD [wk(2)], mm1
382
	movq	MMWORD [wk(3)], mm2
383
384
.upsample:
385
	; -- process the upper row
386
387
	movq	mm7, MMWORD [edx+0*SIZEOF_MMWORD]	; mm7=Int0L=( 0 1 2 3)
388
	movq	mm3, MMWORD [edx+1*SIZEOF_MMWORD]	; mm3=Int0H=( 4 5 6 7)
389
390
	movq	mm0,mm7
391
	movq	mm4,mm3
392
	psrlq	mm0,2*BYTE_BIT			; mm0=( 1 2 3 -)
393
	psllq	mm4,(SIZEOF_MMWORD-2)*BYTE_BIT	; mm4=( - - - 4)
394
	movq	mm5,mm7
395
	movq	mm6,mm3
396
	psrlq	mm5,(SIZEOF_MMWORD-2)*BYTE_BIT	; mm5=( 3 - - -)
397
	psllq	mm6,2*BYTE_BIT			; mm6=( - 4 5 6)
398
399
	por	mm0,mm4				; mm0=( 1 2 3 4)
400
	por	mm5,mm6				; mm5=( 3 4 5 6)
401
402
	movq	mm1,mm7
403
	movq	mm2,mm3
404
	psllq	mm1,2*BYTE_BIT			; mm1=( - 0 1 2)
405
	psrlq	mm2,2*BYTE_BIT			; mm2=( 5 6 7 -)
406
	movq	mm4,mm3
407
	psrlq	mm4,(SIZEOF_MMWORD-2)*BYTE_BIT	; mm4=( 7 - - -)
408
409
	por	mm1, MMWORD [wk(0)]		; mm1=(-1 0 1 2)
410
	por	mm2, MMWORD [wk(2)]		; mm2=( 5 6 7 8)
411
412
	movq	MMWORD [wk(0)], mm4
413
414
	pmullw	mm7,[GOTOFF(ebx,PW_THREE)]
415
	pmullw	mm3,[GOTOFF(ebx,PW_THREE)]
416
	paddw	mm1,[GOTOFF(ebx,PW_EIGHT)]
417
	paddw	mm5,[GOTOFF(ebx,PW_EIGHT)]
418
	paddw	mm0,[GOTOFF(ebx,PW_SEVEN)]
419
	paddw	mm2,[GOTOFF(ebx,PW_SEVEN)]
420
421
	paddw	mm1,mm7
422
	paddw	mm5,mm3
423
	psrlw	mm1,4			; mm1=Out0LE=( 0  2  4  6)
424
	psrlw	mm5,4			; mm5=Out0HE=( 8 10 12 14)
425
	paddw	mm0,mm7
426
	paddw	mm2,mm3
427
	psrlw	mm0,4			; mm0=Out0LO=( 1  3  5  7)
428
	psrlw	mm2,4			; mm2=Out0HO=( 9 11 13 15)
429
430
	psllw	mm0,BYTE_BIT
431
	psllw	mm2,BYTE_BIT
432
	por	mm1,mm0			; mm1=Out0L=( 0  1  2  3  4  5  6  7)
433
	por	mm5,mm2			; mm5=Out0H=( 8  9 10 11 12 13 14 15)
434
435
	movq	MMWORD [edx+0*SIZEOF_MMWORD], mm1
436
	movq	MMWORD [edx+1*SIZEOF_MMWORD], mm5
437
438
	; -- process the lower row
439
440
	movq	mm6, MMWORD [edi+0*SIZEOF_MMWORD]	; mm6=Int1L=( 0 1 2 3)
441
	movq	mm4, MMWORD [edi+1*SIZEOF_MMWORD]	; mm4=Int1H=( 4 5 6 7)
442
443
	movq	mm7,mm6
444
	movq	mm3,mm4
445
	psrlq	mm7,2*BYTE_BIT			; mm7=( 1 2 3 -)
446
	psllq	mm3,(SIZEOF_MMWORD-2)*BYTE_BIT	; mm3=( - - - 4)
447
	movq	mm0,mm6
448
	movq	mm2,mm4
449
	psrlq	mm0,(SIZEOF_MMWORD-2)*BYTE_BIT	; mm0=( 3 - - -)
450
	psllq	mm2,2*BYTE_BIT			; mm2=( - 4 5 6)
451
452
	por	mm7,mm3				; mm7=( 1 2 3 4)
453
	por	mm0,mm2				; mm0=( 3 4 5 6)
454
455
	movq	mm1,mm6
456
	movq	mm5,mm4
457
	psllq	mm1,2*BYTE_BIT			; mm1=( - 0 1 2)
458
	psrlq	mm5,2*BYTE_BIT			; mm5=( 5 6 7 -)
459
	movq	mm3,mm4
460
	psrlq	mm3,(SIZEOF_MMWORD-2)*BYTE_BIT	; mm3=( 7 - - -)
461
462
	por	mm1, MMWORD [wk(1)]		; mm1=(-1 0 1 2)
463
	por	mm5, MMWORD [wk(3)]		; mm5=( 5 6 7 8)
464
465
	movq	MMWORD [wk(1)], mm3
466
467
	pmullw	mm6,[GOTOFF(ebx,PW_THREE)]
468
	pmullw	mm4,[GOTOFF(ebx,PW_THREE)]
469
	paddw	mm1,[GOTOFF(ebx,PW_EIGHT)]
470
	paddw	mm0,[GOTOFF(ebx,PW_EIGHT)]
471
	paddw	mm7,[GOTOFF(ebx,PW_SEVEN)]
472
	paddw	mm5,[GOTOFF(ebx,PW_SEVEN)]
473
474
	paddw	mm1,mm6
475
	paddw	mm0,mm4
476
	psrlw	mm1,4			; mm1=Out1LE=( 0  2  4  6)
477
	psrlw	mm0,4			; mm0=Out1HE=( 8 10 12 14)
478
	paddw	mm7,mm6
479
	paddw	mm5,mm4
480
	psrlw	mm7,4			; mm7=Out1LO=( 1  3  5  7)
481
	psrlw	mm5,4			; mm5=Out1HO=( 9 11 13 15)
482
483
	psllw	mm7,BYTE_BIT
484
	psllw	mm5,BYTE_BIT
485
	por	mm1,mm7			; mm1=Out1L=( 0  1  2  3  4  5  6  7)
486
	por	mm0,mm5			; mm0=Out1H=( 8  9 10 11 12 13 14 15)
487
488
	movq	MMWORD [edi+0*SIZEOF_MMWORD], mm1
489
	movq	MMWORD [edi+1*SIZEOF_MMWORD], mm0
490
491
	poppic	ebx
492
493
	sub	eax, byte SIZEOF_MMWORD
494
	add	ecx, byte 1*SIZEOF_MMWORD	; inptr1(above)
495
	add	ebx, byte 1*SIZEOF_MMWORD	; inptr0
496
	add	esi, byte 1*SIZEOF_MMWORD	; inptr1(below)
497
	add	edx, byte 2*SIZEOF_MMWORD	; outptr0
498
	add	edi, byte 2*SIZEOF_MMWORD	; outptr1
499
	cmp	eax, byte SIZEOF_MMWORD
500
	ja	near .columnloop
501
	test	eax,eax
502
	jnz	near .columnloop_last
503
504
	pop	esi
505
	pop	edi
506
	pop	ecx
507
	pop	eax
508
509
	add	esi, byte 1*SIZEOF_JSAMPROW	; input_data
510
	add	edi, byte 2*SIZEOF_JSAMPROW	; output_data
511
	sub	ecx, byte 2			; rowctr
512
	jg	near .rowloop
513
514
	emms		; empty MMX state
515
516
.return:
517
	pop	edi
518
	pop	esi
519
;	pop	edx		; need not be preserved
520
;	pop	ecx		; need not be preserved
521
	pop	ebx
522
	mov	esp,ebp		; esp <- aligned ebp
523
	pop	esp		; esp <- original ebp
524
	pop	ebp
525
	ret
526
527
; --------------------------------------------------------------------------
528
;
529
; Fast processing for the common case of 2:1 horizontal and 1:1 vertical.
530
; It's still a box filter.
531
;
532
; GLOBAL(void)
533
; jsimd_h2v1_upsample_mmx (int max_v_samp_factor,
534
;                          JDIMENSION output_width,
535
;                          JSAMPARRAY input_data,
536
;                          JSAMPARRAY * output_data_ptr);
537
;
538
539
%define max_v_samp(b)		(b)+8			; int max_v_samp_factor
540
%define output_width(b)	(b)+12		; JDIMENSION output_width
541
%define input_data(b)		(b)+16		; JSAMPARRAY input_data
542
%define output_data_ptr(b)	(b)+20		; JSAMPARRAY * output_data_ptr
543
544
	align	16
545
	global	EXTN(jsimd_h2v1_upsample_mmx)
546
547
EXTN(jsimd_h2v1_upsample_mmx):
548
	push	ebp
549
	mov	ebp,esp
550
;	push	ebx		; unused
551
;	push	ecx		; need not be preserved
552
;	push	edx		; need not be preserved
553
	push	esi
554
	push	edi
555
556
	mov	edx, JDIMENSION [output_width(ebp)]
557
	add	edx, byte (2*SIZEOF_MMWORD)-1
558
	and	edx, byte -(2*SIZEOF_MMWORD)
559
	jz	short .return
560
561
	mov	ecx, INT [max_v_samp(ebp)]	; rowctr
562
	test	ecx,ecx
563
	jz	short .return
564
565
	mov	esi, JSAMPARRAY [input_data(ebp)]	; input_data
566
	mov	edi, POINTER [output_data_ptr(ebp)]
567
	mov	edi, JSAMPARRAY [edi]			; output_data
568
	alignx	16,7
569
.rowloop:
570
	push	edi
571
	push	esi
572
573
	mov	esi, JSAMPROW [esi]		; inptr
574
	mov	edi, JSAMPROW [edi]		; outptr
575
	mov	eax,edx				; colctr
576
	alignx	16,7
577
.columnloop:
578
579
	movq	mm0, MMWORD [esi+0*SIZEOF_MMWORD]
580
581
	movq      mm1,mm0
582
	punpcklbw mm0,mm0
583
	punpckhbw mm1,mm1
584
585
	movq	MMWORD [edi+0*SIZEOF_MMWORD], mm0
586
	movq	MMWORD [edi+1*SIZEOF_MMWORD], mm1
587
588
	sub	eax, byte 2*SIZEOF_MMWORD
589
	jz	short .nextrow
590
591
	movq	mm2, MMWORD [esi+1*SIZEOF_MMWORD]
592
593
	movq      mm3,mm2
594
	punpcklbw mm2,mm2
595
	punpckhbw mm3,mm3
596
597
	movq	MMWORD [edi+2*SIZEOF_MMWORD], mm2
598
	movq	MMWORD [edi+3*SIZEOF_MMWORD], mm3
599
600
	sub	eax, byte 2*SIZEOF_MMWORD
601
	jz	short .nextrow
602
603
	add	esi, byte 2*SIZEOF_MMWORD	; inptr
604
	add	edi, byte 4*SIZEOF_MMWORD	; outptr
605
	jmp	short .columnloop
606
	alignx	16,7
607
608
.nextrow:
609
	pop	esi
610
	pop	edi
611
612
	add	esi, byte SIZEOF_JSAMPROW	; input_data
613
	add	edi, byte SIZEOF_JSAMPROW	; output_data
614
	dec	ecx				; rowctr
615
	jg	short .rowloop
616
617
	emms		; empty MMX state
618
619
.return:
620
	pop	edi
621
	pop	esi
622
;	pop	edx		; need not be preserved
623
;	pop	ecx		; need not be preserved
624
;	pop	ebx		; unused
625
	pop	ebp
626
	ret
627
628
; --------------------------------------------------------------------------
629
;
630
; Fast processing for the common case of 2:1 horizontal and 2:1 vertical.
631
; It's still a box filter.
632
;
633
; GLOBAL(void)
634
; jsimd_h2v2_upsample_mmx (int max_v_samp_factor,
635
;                          JDIMENSION output_width,
636
;                          JSAMPARRAY input_data,
637
;                          JSAMPARRAY * output_data_ptr);
638
;
639
640
%define max_v_samp(b)		(b)+8			; int max_v_samp_factor
641
%define output_width(b)	(b)+12		; JDIMENSION output_width
642
%define input_data(b)		(b)+16		; JSAMPARRAY input_data
643
%define output_data_ptr(b)	(b)+20		; JSAMPARRAY * output_data_ptr
644
645
	align	16
646
	global	EXTN(jsimd_h2v2_upsample_mmx)
647
648
EXTN(jsimd_h2v2_upsample_mmx):
649
	push	ebp
650
	mov	ebp,esp
651
	push	ebx
652
;	push	ecx		; need not be preserved
653
;	push	edx		; need not be preserved
654
	push	esi
655
	push	edi
656
657
	mov	edx, JDIMENSION [output_width(ebp)]
658
	add	edx, byte (2*SIZEOF_MMWORD)-1
659
	and	edx, byte -(2*SIZEOF_MMWORD)
660
	jz	near .return
661
662
	mov	ecx, INT [max_v_samp(ebp)]	; rowctr
663
	test	ecx,ecx
664
	jz	short .return
665
666
	mov	esi, JSAMPARRAY [input_data(ebp)]	; input_data
667
	mov	edi, POINTER [output_data_ptr(ebp)]
668
	mov	edi, JSAMPARRAY [edi]			; output_data
669
	alignx	16,7
670
.rowloop:
671
	push	edi
672
	push	esi
673
674
	mov	esi, JSAMPROW [esi]			; inptr
675
	mov	ebx, JSAMPROW [edi+0*SIZEOF_JSAMPROW]	; outptr0
676
	mov	edi, JSAMPROW [edi+1*SIZEOF_JSAMPROW]	; outptr1
677
	mov	eax,edx					; colctr
678
	alignx	16,7
679
.columnloop:
680
681
	movq	mm0, MMWORD [esi+0*SIZEOF_MMWORD]
682
683
	movq      mm1,mm0
684
	punpcklbw mm0,mm0
685
	punpckhbw mm1,mm1
686
687
	movq	MMWORD [ebx+0*SIZEOF_MMWORD], mm0
688
	movq	MMWORD [ebx+1*SIZEOF_MMWORD], mm1
689
	movq	MMWORD [edi+0*SIZEOF_MMWORD], mm0
690
	movq	MMWORD [edi+1*SIZEOF_MMWORD], mm1
691
692
	sub	eax, byte 2*SIZEOF_MMWORD
693
	jz	short .nextrow
694
695
	movq	mm2, MMWORD [esi+1*SIZEOF_MMWORD]
696
697
	movq      mm3,mm2
698
	punpcklbw mm2,mm2
699
	punpckhbw mm3,mm3
700
701
	movq	MMWORD [ebx+2*SIZEOF_MMWORD], mm2
702
	movq	MMWORD [ebx+3*SIZEOF_MMWORD], mm3
703
	movq	MMWORD [edi+2*SIZEOF_MMWORD], mm2
704
	movq	MMWORD [edi+3*SIZEOF_MMWORD], mm3
705
706
	sub	eax, byte 2*SIZEOF_MMWORD
707
	jz	short .nextrow
708
709
	add	esi, byte 2*SIZEOF_MMWORD	; inptr
710
	add	ebx, byte 4*SIZEOF_MMWORD	; outptr0
711
	add	edi, byte 4*SIZEOF_MMWORD	; outptr1
712
	jmp	short .columnloop
713
	alignx	16,7
714
715
.nextrow:
716
	pop	esi
717
	pop	edi
718
719
	add	esi, byte 1*SIZEOF_JSAMPROW	; input_data
720
	add	edi, byte 2*SIZEOF_JSAMPROW	; output_data
721
	sub	ecx, byte 2			; rowctr
722
	jg	short .rowloop
723
724
	emms		; empty MMX state
725
726
.return:
727
	pop	edi
728
	pop	esi
729
;	pop	edx		; need not be preserved
730
;	pop	ecx		; need not be preserved
731
	pop	ebx
732
	pop	ebp
733
	ret
734
735
; For some reason, the OS X linker does not honor the request to align the
736
; segment unless we do this.
737
	align	16
(-)a/jpeg/simd/jdsamss2-64.asm (+671 lines)
Line     Link Here 
Line 0    Link Here 
1
;
2
; jdsamss2-64.asm - upsampling (64-bit SSE2)
3
;
4
; Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
5
; Copyright 2009 D. R. Commander
6
;
7
; Based on
8
; x86 SIMD extension for IJG JPEG library
9
; Copyright (C) 1999-2006, MIYASAKA Masaru.
10
; For conditions of distribution and use, see copyright notice in jsimdext.inc
11
;
12
; This file should be assembled with NASM (Netwide Assembler),
13
; can *not* be assembled with Microsoft's MASM or any compatible
14
; assembler (including Borland's Turbo Assembler).
15
; NASM is available from http://nasm.sourceforge.net/ or
16
; http://sourceforge.net/project/showfiles.php?group_id=6208
17
;
18
; [TAB8]
19
20
%include "jsimdext.inc"
21
22
; --------------------------------------------------------------------------
23
	SECTION	SEG_CONST
24
25
	alignz	16
26
	global	EXTN(jconst_fancy_upsample_sse2)
27
28
EXTN(jconst_fancy_upsample_sse2):
29
30
PW_ONE		times 8 dw  1
31
PW_TWO		times 8 dw  2
32
PW_THREE	times 8 dw  3
33
PW_SEVEN	times 8 dw  7
34
PW_EIGHT	times 8 dw  8
35
36
	alignz	16
37
38
; --------------------------------------------------------------------------
39
	SECTION	SEG_TEXT
40
	BITS	64
41
;
42
; Fancy processing for the common case of 2:1 horizontal and 1:1 vertical.
43
;
44
; The upsampling algorithm is linear interpolation between pixel centers,
45
; also known as a "triangle filter".  This is a good compromise between
46
; speed and visual quality.  The centers of the output pixels are 1/4 and 3/4
47
; of the way between input pixel centers.
48
;
49
; GLOBAL(void)
50
; jsimd_h2v1_fancy_upsample_sse2 (int max_v_samp_factor,
51
;                                 JDIMENSION downsampled_width,
52
;                                 JSAMPARRAY input_data,
53
;                                 JSAMPARRAY * output_data_ptr);
54
;
55
56
; r10 = int max_v_samp_factor
57
; r11 = JDIMENSION downsampled_width
58
; r12 = JSAMPARRAY input_data
59
; r13 = JSAMPARRAY * output_data_ptr
60
61
	align	16
62
	global	EXTN(jsimd_h2v1_fancy_upsample_sse2)
63
64
EXTN(jsimd_h2v1_fancy_upsample_sse2):
65
	push	rbp
66
	mov	rax,rsp
67
	mov	rbp,rsp
68
	collect_args
69
70
	mov	rax, r11  ; colctr
71
	test	rax,rax
72
	jz	near .return
73
74
	mov	rcx, r10	; rowctr
75
	test	rcx,rcx
76
	jz	near .return
77
78
	mov	rsi, r12	; input_data
79
	mov	rdi, r13
80
	mov	rdi, JSAMPARRAY [rdi]			; output_data
81
.rowloop:
82
	push	rax			; colctr
83
	push	rdi
84
	push	rsi
85
86
	mov	rsi, JSAMPROW [rsi]	; inptr
87
	mov	rdi, JSAMPROW [rdi]	; outptr
88
89
	test	rax, SIZEOF_XMMWORD-1
90
	jz	short .skip
91
	mov	dl, JSAMPLE [rsi+(rax-1)*SIZEOF_JSAMPLE]
92
	mov	JSAMPLE [rsi+rax*SIZEOF_JSAMPLE], dl	; insert a dummy sample
93
.skip:
94
	pxor	xmm0,xmm0		; xmm0=(all 0's)
95
	pcmpeqb	xmm7,xmm7
96
	psrldq	xmm7,(SIZEOF_XMMWORD-1)
97
	pand	xmm7, XMMWORD [rsi+0*SIZEOF_XMMWORD]
98
99
	add	rax, byte SIZEOF_XMMWORD-1
100
	and	rax, byte -SIZEOF_XMMWORD
101
	cmp	rax, byte SIZEOF_XMMWORD
102
	ja	short .columnloop
103
104
.columnloop_last:
105
	pcmpeqb	xmm6,xmm6
106
	pslldq	xmm6,(SIZEOF_XMMWORD-1)
107
	pand	xmm6, XMMWORD [rsi+0*SIZEOF_XMMWORD]
108
	jmp	short .upsample
109
110
.columnloop:
111
	movdqa	xmm6, XMMWORD [rsi+1*SIZEOF_XMMWORD]
112
	pslldq	xmm6,(SIZEOF_XMMWORD-1)
113
114
.upsample:
115
	movdqa	xmm1, XMMWORD [rsi+0*SIZEOF_XMMWORD]
116
	movdqa	xmm2,xmm1
117
	movdqa	xmm3,xmm1		; xmm1=( 0  1  2 ... 13 14 15)
118
	pslldq	xmm2,1			; xmm2=(--  0  1 ... 12 13 14)
119
	psrldq	xmm3,1			; xmm3=( 1  2  3 ... 14 15 --)
120
121
	por	xmm2,xmm7		; xmm2=(-1  0  1 ... 12 13 14)
122
	por	xmm3,xmm6		; xmm3=( 1  2  3 ... 14 15 16)
123
124
	movdqa	xmm7,xmm1
125
	psrldq	xmm7,(SIZEOF_XMMWORD-1)	; xmm7=(15 -- -- ... -- -- --)
126
127
	movdqa    xmm4,xmm1
128
	punpcklbw xmm1,xmm0		; xmm1=( 0  1  2  3  4  5  6  7)
129
	punpckhbw xmm4,xmm0		; xmm4=( 8  9 10 11 12 13 14 15)
130
	movdqa    xmm5,xmm2
131
	punpcklbw xmm2,xmm0		; xmm2=(-1  0  1  2  3  4  5  6)
132
	punpckhbw xmm5,xmm0		; xmm5=( 7  8  9 10 11 12 13 14)
133
	movdqa    xmm6,xmm3
134
	punpcklbw xmm3,xmm0		; xmm3=( 1  2  3  4  5  6  7  8)
135
	punpckhbw xmm6,xmm0		; xmm6=( 9 10 11 12 13 14 15 16)
136
137
	pmullw	xmm1,[rel PW_THREE]
138
	pmullw	xmm4,[rel PW_THREE]
139
	paddw	xmm2,[rel PW_ONE]
140
	paddw	xmm5,[rel PW_ONE]
141
	paddw	xmm3,[rel PW_TWO]
142
	paddw	xmm6,[rel PW_TWO]
143
144
	paddw	xmm2,xmm1
145
	paddw	xmm5,xmm4
146
	psrlw	xmm2,2			; xmm2=OutLE=( 0  2  4  6  8 10 12 14)
147
	psrlw	xmm5,2			; xmm5=OutHE=(16 18 20 22 24 26 28 30)
148
	paddw	xmm3,xmm1
149
	paddw	xmm6,xmm4
150
	psrlw	xmm3,2			; xmm3=OutLO=( 1  3  5  7  9 11 13 15)
151
	psrlw	xmm6,2			; xmm6=OutHO=(17 19 21 23 25 27 29 31)
152
153
	psllw	xmm3,BYTE_BIT
154
	psllw	xmm6,BYTE_BIT
155
	por	xmm2,xmm3		; xmm2=OutL=( 0  1  2 ... 13 14 15)
156
	por	xmm5,xmm6		; xmm5=OutH=(16 17 18 ... 29 30 31)
157
158
	movdqa	XMMWORD [rdi+0*SIZEOF_XMMWORD], xmm2
159
	movdqa	XMMWORD [rdi+1*SIZEOF_XMMWORD], xmm5
160
161
	sub	rax, byte SIZEOF_XMMWORD
162
	add	rsi, byte 1*SIZEOF_XMMWORD	; inptr
163
	add	rdi, byte 2*SIZEOF_XMMWORD	; outptr
164
	cmp	rax, byte SIZEOF_XMMWORD
165
	ja	near .columnloop
166
	test	eax,eax
167
	jnz	near .columnloop_last
168
169
	pop	rsi
170
	pop	rdi
171
	pop	rax
172
173
	add	rsi, byte SIZEOF_JSAMPROW	; input_data
174
	add	rdi, byte SIZEOF_JSAMPROW	; output_data
175
	dec	rcx				; rowctr
176
	jg	near .rowloop
177
178
.return:
179
	uncollect_args
180
	pop	rbp
181
	ret
182
183
; --------------------------------------------------------------------------
184
;
185
; Fancy processing for the common case of 2:1 horizontal and 2:1 vertical.
186
; Again a triangle filter; see comments for h2v1 case, above.
187
;
188
; GLOBAL(void)
189
; jsimd_h2v2_fancy_upsample_sse2 (int max_v_samp_factor,
190
;                                 JDIMENSION downsampled_width,
191
;                                 JSAMPARRAY input_data,
192
;                                 JSAMPARRAY * output_data_ptr);
193
;
194
195
; r10 = int max_v_samp_factor
196
; r11 = JDIMENSION downsampled_width
197
; r12 = JSAMPARRAY input_data
198
; r13 = JSAMPARRAY * output_data_ptr
199
200
%define wk(i)		rbp-(WK_NUM-(i))*SIZEOF_XMMWORD	; xmmword wk[WK_NUM]
201
%define WK_NUM		4
202
203
	align	16
204
	global	EXTN(jsimd_h2v2_fancy_upsample_sse2)
205
206
EXTN(jsimd_h2v2_fancy_upsample_sse2):
207
	push	rbp
208
	mov	rax,rsp				; rax = original rbp
209
	sub	rsp, byte 4
210
	and	rsp, byte (-SIZEOF_XMMWORD)	; align to 128 bits
211
	mov	[rsp],rax
212
	mov	rbp,rsp				; rbp = aligned rbp
213
	lea	rsp, [wk(0)]
214
	collect_args
215
	push	rbx
216
217
	mov	rax, r11  ; colctr
218
	test	rax,rax
219
	jz	near .return
220
221
	mov	rcx, r10	; rowctr
222
	test	rcx,rcx
223
	jz	near .return
224
225
	mov	rsi, r12	; input_data
226
	mov	rdi, r13
227
	mov	rdi, JSAMPARRAY [rdi]			; output_data
228
.rowloop:
229
	push	rax					; colctr
230
	push	rcx
231
	push	rdi
232
	push	rsi
233
234
	mov	rcx, JSAMPROW [rsi-1*SIZEOF_JSAMPROW]	; inptr1(above)
235
	mov	rbx, JSAMPROW [rsi+0*SIZEOF_JSAMPROW]	; inptr0
236
	mov	rsi, JSAMPROW [rsi+1*SIZEOF_JSAMPROW]	; inptr1(below)
237
	mov	rdx, JSAMPROW [rdi+0*SIZEOF_JSAMPROW]	; outptr0
238
	mov	rdi, JSAMPROW [rdi+1*SIZEOF_JSAMPROW]	; outptr1
239
240
	test	rax, SIZEOF_XMMWORD-1
241
	jz	short .skip
242
	push	rdx
243
	mov	dl, JSAMPLE [rcx+(rax-1)*SIZEOF_JSAMPLE]
244
	mov	JSAMPLE [rcx+rax*SIZEOF_JSAMPLE], dl
245
	mov	dl, JSAMPLE [rbx+(rax-1)*SIZEOF_JSAMPLE]
246
	mov	JSAMPLE [rbx+rax*SIZEOF_JSAMPLE], dl
247
	mov	dl, JSAMPLE [rsi+(rax-1)*SIZEOF_JSAMPLE]
248
	mov	JSAMPLE [rsi+rax*SIZEOF_JSAMPLE], dl	; insert a dummy sample
249
	pop	rdx
250
.skip:
251
	; -- process the first column block
252
253
	movdqa	xmm0, XMMWORD [rbx+0*SIZEOF_XMMWORD]	; xmm0=row[ 0][0]
254
	movdqa	xmm1, XMMWORD [rcx+0*SIZEOF_XMMWORD]	; xmm1=row[-1][0]
255
	movdqa	xmm2, XMMWORD [rsi+0*SIZEOF_XMMWORD]	; xmm2=row[+1][0]
256
257
	pxor      xmm3,xmm3		; xmm3=(all 0's)
258
	movdqa    xmm4,xmm0
259
	punpcklbw xmm0,xmm3		; xmm0=row[ 0]( 0  1  2  3  4  5  6  7)
260
	punpckhbw xmm4,xmm3		; xmm4=row[ 0]( 8  9 10 11 12 13 14 15)
261
	movdqa    xmm5,xmm1
262
	punpcklbw xmm1,xmm3		; xmm1=row[-1]( 0  1  2  3  4  5  6  7)
263
	punpckhbw xmm5,xmm3		; xmm5=row[-1]( 8  9 10 11 12 13 14 15)
264
	movdqa    xmm6,xmm2
265
	punpcklbw xmm2,xmm3		; xmm2=row[+1]( 0  1  2  3  4  5  6  7)
266
	punpckhbw xmm6,xmm3		; xmm6=row[+1]( 8  9 10 11 12 13 14 15)
267
268
	pmullw	xmm0,[rel PW_THREE]
269
	pmullw	xmm4,[rel PW_THREE]
270
271
	pcmpeqb	xmm7,xmm7
272
	psrldq	xmm7,(SIZEOF_XMMWORD-2)
273
274
	paddw	xmm1,xmm0		; xmm1=Int0L=( 0  1  2  3  4  5  6  7)
275
	paddw	xmm5,xmm4		; xmm5=Int0H=( 8  9 10 11 12 13 14 15)
276
	paddw	xmm2,xmm0		; xmm2=Int1L=( 0  1  2  3  4  5  6  7)
277
	paddw	xmm6,xmm4		; xmm6=Int1H=( 8  9 10 11 12 13 14 15)
278
279
	movdqa	XMMWORD [rdx+0*SIZEOF_XMMWORD], xmm1	; temporarily save
280
	movdqa	XMMWORD [rdx+1*SIZEOF_XMMWORD], xmm5	; the intermediate data
281
	movdqa	XMMWORD [rdi+0*SIZEOF_XMMWORD], xmm2
282
	movdqa	XMMWORD [rdi+1*SIZEOF_XMMWORD], xmm6
283
284
	pand	xmm1,xmm7		; xmm1=( 0 -- -- -- -- -- -- --)
285
	pand	xmm2,xmm7		; xmm2=( 0 -- -- -- -- -- -- --)
286
287
	movdqa	XMMWORD [wk(0)], xmm1
288
	movdqa	XMMWORD [wk(1)], xmm2
289
290
	add	rax, byte SIZEOF_XMMWORD-1
291
	and	rax, byte -SIZEOF_XMMWORD
292
	cmp	rax, byte SIZEOF_XMMWORD
293
	ja	short .columnloop
294
295
.columnloop_last:
296
	; -- process the last column block
297
298
	pcmpeqb	xmm1,xmm1
299
	pslldq	xmm1,(SIZEOF_XMMWORD-2)
300
	movdqa	xmm2,xmm1
301
302
	pand	xmm1, XMMWORD [rdx+1*SIZEOF_XMMWORD]
303
	pand	xmm2, XMMWORD [rdi+1*SIZEOF_XMMWORD]
304
305
	movdqa	XMMWORD [wk(2)], xmm1	; xmm1=(-- -- -- -- -- -- -- 15)
306
	movdqa	XMMWORD [wk(3)], xmm2	; xmm2=(-- -- -- -- -- -- -- 15)
307
308
	jmp	near .upsample
309
310
.columnloop:
311
	; -- process the next column block
312
313
	movdqa	xmm0, XMMWORD [rbx+1*SIZEOF_XMMWORD]	; xmm0=row[ 0][1]
314
	movdqa	xmm1, XMMWORD [rcx+1*SIZEOF_XMMWORD]	; xmm1=row[-1][1]
315
	movdqa	xmm2, XMMWORD [rsi+1*SIZEOF_XMMWORD]	; xmm2=row[+1][1]
316
317
	pxor      xmm3,xmm3		; xmm3=(all 0's)
318
	movdqa    xmm4,xmm0
319
	punpcklbw xmm0,xmm3		; xmm0=row[ 0]( 0  1  2  3  4  5  6  7)
320
	punpckhbw xmm4,xmm3		; xmm4=row[ 0]( 8  9 10 11 12 13 14 15)
321
	movdqa    xmm5,xmm1
322
	punpcklbw xmm1,xmm3		; xmm1=row[-1]( 0  1  2  3  4  5  6  7)
323
	punpckhbw xmm5,xmm3		; xmm5=row[-1]( 8  9 10 11 12 13 14 15)
324
	movdqa    xmm6,xmm2
325
	punpcklbw xmm2,xmm3		; xmm2=row[+1]( 0  1  2  3  4  5  6  7)
326
	punpckhbw xmm6,xmm3		; xmm6=row[+1]( 8  9 10 11 12 13 14 15)
327
328
	pmullw	xmm0,[rel PW_THREE]
329
	pmullw	xmm4,[rel PW_THREE]
330
331
	paddw	xmm1,xmm0		; xmm1=Int0L=( 0  1  2  3  4  5  6  7)
332
	paddw	xmm5,xmm4		; xmm5=Int0H=( 8  9 10 11 12 13 14 15)
333
	paddw	xmm2,xmm0		; xmm2=Int1L=( 0  1  2  3  4  5  6  7)
334
	paddw	xmm6,xmm4		; xmm6=Int1H=( 8  9 10 11 12 13 14 15)
335
336
	movdqa	XMMWORD [rdx+2*SIZEOF_XMMWORD], xmm1	; temporarily save
337
	movdqa	XMMWORD [rdx+3*SIZEOF_XMMWORD], xmm5	; the intermediate data
338
	movdqa	XMMWORD [rdi+2*SIZEOF_XMMWORD], xmm2
339
	movdqa	XMMWORD [rdi+3*SIZEOF_XMMWORD], xmm6
340
341
	pslldq	xmm1,(SIZEOF_XMMWORD-2)	; xmm1=(-- -- -- -- -- -- --  0)
342
	pslldq	xmm2,(SIZEOF_XMMWORD-2)	; xmm2=(-- -- -- -- -- -- --  0)
343
344
	movdqa	XMMWORD [wk(2)], xmm1
345
	movdqa	XMMWORD [wk(3)], xmm2
346
347
.upsample:
348
	; -- process the upper row
349
350
	movdqa	xmm7, XMMWORD [rdx+0*SIZEOF_XMMWORD]
351
	movdqa	xmm3, XMMWORD [rdx+1*SIZEOF_XMMWORD]
352
353
	movdqa	xmm0,xmm7		; xmm7=Int0L=( 0  1  2  3  4  5  6  7)
354
	movdqa	xmm4,xmm3		; xmm3=Int0H=( 8  9 10 11 12 13 14 15)
355
	psrldq	xmm0,2			; xmm0=( 1  2  3  4  5  6  7 --)
356
	pslldq	xmm4,(SIZEOF_XMMWORD-2)	; xmm4=(-- -- -- -- -- -- --  8)
357
	movdqa	xmm5,xmm7
358
	movdqa	xmm6,xmm3
359
	psrldq	xmm5,(SIZEOF_XMMWORD-2)	; xmm5=( 7 -- -- -- -- -- -- --)
360
	pslldq	xmm6,2			; xmm6=(--  8  9 10 11 12 13 14)
361
362
	por	xmm0,xmm4		; xmm0=( 1  2  3  4  5  6  7  8)
363
	por	xmm5,xmm6		; xmm5=( 7  8  9 10 11 12 13 14)
364
365
	movdqa	xmm1,xmm7
366
	movdqa	xmm2,xmm3
367
	pslldq	xmm1,2			; xmm1=(--  0  1  2  3  4  5  6)
368
	psrldq	xmm2,2			; xmm2=( 9 10 11 12 13 14 15 --)
369
	movdqa	xmm4,xmm3
370
	psrldq	xmm4,(SIZEOF_XMMWORD-2)	; xmm4=(15 -- -- -- -- -- -- --)
371
372
	por	xmm1, XMMWORD [wk(0)]	; xmm1=(-1  0  1  2  3  4  5  6)
373
	por	xmm2, XMMWORD [wk(2)]	; xmm2=( 9 10 11 12 13 14 15 16)
374
375
	movdqa	XMMWORD [wk(0)], xmm4
376
377
	pmullw	xmm7,[rel PW_THREE]
378
	pmullw	xmm3,[rel PW_THREE]
379
	paddw	xmm1,[rel PW_EIGHT]
380
	paddw	xmm5,[rel PW_EIGHT]
381
	paddw	xmm0,[rel PW_SEVEN]
382
	paddw	xmm2,[rel PW_SEVEN]
383
384
	paddw	xmm1,xmm7
385
	paddw	xmm5,xmm3
386
	psrlw	xmm1,4			; xmm1=Out0LE=( 0  2  4  6  8 10 12 14)
387
	psrlw	xmm5,4			; xmm5=Out0HE=(16 18 20 22 24 26 28 30)
388
	paddw	xmm0,xmm7
389
	paddw	xmm2,xmm3
390
	psrlw	xmm0,4			; xmm0=Out0LO=( 1  3  5  7  9 11 13 15)
391
	psrlw	xmm2,4			; xmm2=Out0HO=(17 19 21 23 25 27 29 31)
392
393
	psllw	xmm0,BYTE_BIT
394
	psllw	xmm2,BYTE_BIT
395
	por	xmm1,xmm0		; xmm1=Out0L=( 0  1  2 ... 13 14 15)
396
	por	xmm5,xmm2		; xmm5=Out0H=(16 17 18 ... 29 30 31)
397
398
	movdqa	XMMWORD [rdx+0*SIZEOF_XMMWORD], xmm1
399
	movdqa	XMMWORD [rdx+1*SIZEOF_XMMWORD], xmm5
400
401
	; -- process the lower row
402
403
	movdqa	xmm6, XMMWORD [rdi+0*SIZEOF_XMMWORD]
404
	movdqa	xmm4, XMMWORD [rdi+1*SIZEOF_XMMWORD]
405
406
	movdqa	xmm7,xmm6		; xmm6=Int1L=( 0  1  2  3  4  5  6  7)
407
	movdqa	xmm3,xmm4		; xmm4=Int1H=( 8  9 10 11 12 13 14 15)
408
	psrldq	xmm7,2			; xmm7=( 1  2  3  4  5  6  7 --)
409
	pslldq	xmm3,(SIZEOF_XMMWORD-2)	; xmm3=(-- -- -- -- -- -- --  8)
410
	movdqa	xmm0,xmm6
411
	movdqa	xmm2,xmm4
412
	psrldq	xmm0,(SIZEOF_XMMWORD-2)	; xmm0=( 7 -- -- -- -- -- -- --)
413
	pslldq	xmm2,2			; xmm2=(--  8  9 10 11 12 13 14)
414
415
	por	xmm7,xmm3		; xmm7=( 1  2  3  4  5  6  7  8)
416
	por	xmm0,xmm2		; xmm0=( 7  8  9 10 11 12 13 14)
417
418
	movdqa	xmm1,xmm6
419
	movdqa	xmm5,xmm4
420
	pslldq	xmm1,2			; xmm1=(--  0  1  2  3  4  5  6)
421
	psrldq	xmm5,2			; xmm5=( 9 10 11 12 13 14 15 --)
422
	movdqa	xmm3,xmm4
423
	psrldq	xmm3,(SIZEOF_XMMWORD-2)	; xmm3=(15 -- -- -- -- -- -- --)
424
425
	por	xmm1, XMMWORD [wk(1)]	; xmm1=(-1  0  1  2  3  4  5  6)
426
	por	xmm5, XMMWORD [wk(3)]	; xmm5=( 9 10 11 12 13 14 15 16)
427
428
	movdqa	XMMWORD [wk(1)], xmm3
429
430
	pmullw	xmm6,[rel PW_THREE]
431
	pmullw	xmm4,[rel PW_THREE]
432
	paddw	xmm1,[rel PW_EIGHT]
433
	paddw	xmm0,[rel PW_EIGHT]
434
	paddw	xmm7,[rel PW_SEVEN]
435
	paddw	xmm5,[rel PW_SEVEN]
436
437
	paddw	xmm1,xmm6
438
	paddw	xmm0,xmm4
439
	psrlw	xmm1,4			; xmm1=Out1LE=( 0  2  4  6  8 10 12 14)
440
	psrlw	xmm0,4			; xmm0=Out1HE=(16 18 20 22 24 26 28 30)
441
	paddw	xmm7,xmm6
442
	paddw	xmm5,xmm4
443
	psrlw	xmm7,4			; xmm7=Out1LO=( 1  3  5  7  9 11 13 15)
444
	psrlw	xmm5,4			; xmm5=Out1HO=(17 19 21 23 25 27 29 31)
445
446
	psllw	xmm7,BYTE_BIT
447
	psllw	xmm5,BYTE_BIT
448
	por	xmm1,xmm7		; xmm1=Out1L=( 0  1  2 ... 13 14 15)
449
	por	xmm0,xmm5		; xmm0=Out1H=(16 17 18 ... 29 30 31)
450
451
	movdqa	XMMWORD [rdi+0*SIZEOF_XMMWORD], xmm1
452
	movdqa	XMMWORD [rdi+1*SIZEOF_XMMWORD], xmm0
453
454
	sub	rax, byte SIZEOF_XMMWORD
455
	add	rcx, byte 1*SIZEOF_XMMWORD	; inptr1(above)
456
	add	rbx, byte 1*SIZEOF_XMMWORD	; inptr0
457
	add	rsi, byte 1*SIZEOF_XMMWORD	; inptr1(below)
458
	add	rdx, byte 2*SIZEOF_XMMWORD	; outptr0
459
	add	rdi, byte 2*SIZEOF_XMMWORD	; outptr1
460
	cmp	rax, byte SIZEOF_XMMWORD
461
	ja	near .columnloop
462
	test	rax,rax
463
	jnz	near .columnloop_last
464
465
	pop	rsi
466
	pop	rdi
467
	pop	rcx
468
	pop	rax
469
470
	add	rsi, byte 1*SIZEOF_JSAMPROW	; input_data
471
	add	rdi, byte 2*SIZEOF_JSAMPROW	; output_data
472
	sub	rcx, byte 2			; rowctr
473
	jg	near .rowloop
474
475
.return:
476
	pop	rbx
477
	uncollect_args
478
	mov	rsp,rbp		; rsp <- aligned rbp
479
	pop	rsp		; rsp <- original rbp
480
	pop	rbp
481
	ret
482
483
; --------------------------------------------------------------------------
484
;
485
; Fast processing for the common case of 2:1 horizontal and 1:1 vertical.
486
; It's still a box filter.
487
;
488
; GLOBAL(void)
489
; jsimd_h2v1_upsample_sse2 (int max_v_samp_factor,
490
;                           JDIMENSION output_width,
491
;                           JSAMPARRAY input_data,
492
;                           JSAMPARRAY * output_data_ptr);
493
;
494
495
; r10 = int max_v_samp_factor
496
; r11 = JDIMENSION output_width
497
; r12 = JSAMPARRAY input_data
498
; r13 = JSAMPARRAY * output_data_ptr
499
500
	align	16
501
	global	EXTN(jsimd_h2v1_upsample_sse2)
502
503
EXTN(jsimd_h2v1_upsample_sse2):
504
	push	rbp
505
	mov	rax,rsp
506
	mov	rbp,rsp
507
	collect_args
508
509
	mov	rdx, r11
510
	add	rdx, byte (2*SIZEOF_XMMWORD)-1
511
	and	rdx, byte -(2*SIZEOF_XMMWORD)
512
	jz	near .return
513
514
	mov	rcx, r10	; rowctr
515
	test	rcx,rcx
516
	jz	short .return
517
518
	mov	rsi, r12 ; input_data
519
	mov	rdi, r13
520
	mov	rdi, JSAMPARRAY [rdi]			; output_data
521
.rowloop:
522
	push	rdi
523
	push	rsi
524
525
	mov	rsi, JSAMPROW [rsi]		; inptr
526
	mov	rdi, JSAMPROW [rdi]		; outptr
527
	mov	rax,rdx				; colctr
528
.columnloop:
529
530
	movdqa	xmm0, XMMWORD [rsi+0*SIZEOF_XMMWORD]
531
532
	movdqa    xmm1,xmm0
533
	punpcklbw xmm0,xmm0
534
	punpckhbw xmm1,xmm1
535
536
	movdqa	XMMWORD [rdi+0*SIZEOF_XMMWORD], xmm0
537
	movdqa	XMMWORD [rdi+1*SIZEOF_XMMWORD], xmm1
538
539
	sub	rax, byte 2*SIZEOF_XMMWORD
540
	jz	short .nextrow
541
542
	movdqa	xmm2, XMMWORD [rsi+1*SIZEOF_XMMWORD]
543
544
	movdqa    xmm3,xmm2
545
	punpcklbw xmm2,xmm2
546
	punpckhbw xmm3,xmm3
547
548
	movdqa	XMMWORD [rdi+2*SIZEOF_XMMWORD], xmm2
549
	movdqa	XMMWORD [rdi+3*SIZEOF_XMMWORD], xmm3
550
551
	sub	rax, byte 2*SIZEOF_XMMWORD
552
	jz	short .nextrow
553
554
	add	rsi, byte 2*SIZEOF_XMMWORD	; inptr
555
	add	rdi, byte 4*SIZEOF_XMMWORD	; outptr
556
	jmp	short .columnloop
557
558
.nextrow:
559
	pop	rsi
560
	pop	rdi
561
562
	add	rsi, byte SIZEOF_JSAMPROW	; input_data
563
	add	rdi, byte SIZEOF_JSAMPROW	; output_data
564
	dec	rcx				; rowctr
565
	jg	short .rowloop
566
567
.return:
568
	uncollect_args
569
	pop	rbp
570
	ret
571
572
; --------------------------------------------------------------------------
573
;
574
; Fast processing for the common case of 2:1 horizontal and 2:1 vertical.
575
; It's still a box filter.
576
;
577
; GLOBAL(void)
578
; jsimd_h2v2_upsample_sse2 (nt max_v_samp_factor,
579
;                           JDIMENSION output_width,
580
;                           JSAMPARRAY input_data,
581
;                           JSAMPARRAY * output_data_ptr);
582
;
583
584
; r10 = int max_v_samp_factor
585
; r11 = JDIMENSION output_width
586
; r12 = JSAMPARRAY input_data
587
; r13 = JSAMPARRAY * output_data_ptr
588
589
	align	16
590
	global	EXTN(jsimd_h2v2_upsample_sse2)
591
592
EXTN(jsimd_h2v2_upsample_sse2):
593
	push	rbp
594
	mov	rax,rsp
595
	mov	rbp,rsp
596
	collect_args
597
	push	rbx
598
599
	mov	rdx, r11
600
	add	rdx, byte (2*SIZEOF_XMMWORD)-1
601
	and	rdx, byte -(2*SIZEOF_XMMWORD)
602
	jz	near .return
603
604
	mov	rcx, r10	; rowctr
605
	test	rcx,rcx
606
	jz	near .return
607
608
	mov	rsi, r12	; input_data
609
	mov	rdi, r13
610
	mov	rdi, JSAMPARRAY [rdi]			; output_data
611
.rowloop:
612
	push	rdi
613
	push	rsi
614
615
	mov	rsi, JSAMPROW [rsi]			; inptr
616
	mov	rbx, JSAMPROW [rdi+0*SIZEOF_JSAMPROW]	; outptr0
617
	mov	rdi, JSAMPROW [rdi+1*SIZEOF_JSAMPROW]	; outptr1
618
	mov	rax,rdx					; colctr
619
.columnloop:
620
621
	movdqa	xmm0, XMMWORD [rsi+0*SIZEOF_XMMWORD]
622
623
	movdqa    xmm1,xmm0
624
	punpcklbw xmm0,xmm0
625
	punpckhbw xmm1,xmm1
626
627
	movdqa	XMMWORD [rbx+0*SIZEOF_XMMWORD], xmm0
628
	movdqa	XMMWORD [rbx+1*SIZEOF_XMMWORD], xmm1
629
	movdqa	XMMWORD [rdi+0*SIZEOF_XMMWORD], xmm0
630
	movdqa	XMMWORD [rdi+1*SIZEOF_XMMWORD], xmm1
631
632
	sub	rax, byte 2*SIZEOF_XMMWORD
633
	jz	short .nextrow
634
635
	movdqa	xmm2, XMMWORD [rsi+1*SIZEOF_XMMWORD]
636
637
	movdqa    xmm3,xmm2
638
	punpcklbw xmm2,xmm2
639
	punpckhbw xmm3,xmm3
640
641
	movdqa	XMMWORD [rbx+2*SIZEOF_XMMWORD], xmm2
642
	movdqa	XMMWORD [rbx+3*SIZEOF_XMMWORD], xmm3
643
	movdqa	XMMWORD [rdi+2*SIZEOF_XMMWORD], xmm2
644
	movdqa	XMMWORD [rdi+3*SIZEOF_XMMWORD], xmm3
645
646
	sub	rax, byte 2*SIZEOF_XMMWORD
647
	jz	short .nextrow
648
649
	add	rsi, byte 2*SIZEOF_XMMWORD	; inptr
650
	add	rbx, byte 4*SIZEOF_XMMWORD	; outptr0
651
	add	rdi, byte 4*SIZEOF_XMMWORD	; outptr1
652
	jmp	short .columnloop
653
654
.nextrow:
655
	pop	rsi
656
	pop	rdi
657
658
	add	rsi, byte 1*SIZEOF_JSAMPROW	; input_data
659
	add	rdi, byte 2*SIZEOF_JSAMPROW	; output_data
660
	sub	rcx, byte 2			; rowctr
661
	jg	near .rowloop
662
663
.return:
664
	pop	rbx
665
	uncollect_args
666
	pop	rbp
667
	ret
668
669
; For some reason, the OS X linker does not honor the request to align the
670
; segment unless we do this.
671
	align	16
(-)a/jpeg/simd/jdsamss2.asm (+729 lines)
Line     Link Here 
Line 0    Link Here 
1
;
2
; jdsamss2.asm - upsampling (SSE2)
3
;
4
; Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
5
;
6
; Based on
7
; x86 SIMD extension for IJG JPEG library
8
; Copyright (C) 1999-2006, MIYASAKA Masaru.
9
; For conditions of distribution and use, see copyright notice in jsimdext.inc
10
;
11
; This file should be assembled with NASM (Netwide Assembler),
12
; can *not* be assembled with Microsoft's MASM or any compatible
13
; assembler (including Borland's Turbo Assembler).
14
; NASM is available from http://nasm.sourceforge.net/ or
15
; http://sourceforge.net/project/showfiles.php?group_id=6208
16
;
17
; [TAB8]
18
19
%include "jsimdext.inc"
20
21
; --------------------------------------------------------------------------
22
	SECTION	SEG_CONST
23
24
	alignz	16
25
	global	EXTN(jconst_fancy_upsample_sse2)
26
27
EXTN(jconst_fancy_upsample_sse2):
28
29
PW_ONE		times 8 dw  1
30
PW_TWO		times 8 dw  2
31
PW_THREE	times 8 dw  3
32
PW_SEVEN	times 8 dw  7
33
PW_EIGHT	times 8 dw  8
34
35
	alignz	16
36
37
; --------------------------------------------------------------------------
38
	SECTION	SEG_TEXT
39
	BITS	32
40
;
41
; Fancy processing for the common case of 2:1 horizontal and 1:1 vertical.
42
;
43
; The upsampling algorithm is linear interpolation between pixel centers,
44
; also known as a "triangle filter".  This is a good compromise between
45
; speed and visual quality.  The centers of the output pixels are 1/4 and 3/4
46
; of the way between input pixel centers.
47
;
48
; GLOBAL(void)
49
; jsimd_h2v1_fancy_upsample_sse2 (int max_v_samp_factor,
50
;                                 JDIMENSION downsampled_width,
51
;                                 JSAMPARRAY input_data,
52
;                                 JSAMPARRAY * output_data_ptr);
53
;
54
55
%define max_v_samp(b)		(b)+8			; int max_v_samp_factor
56
%define downsamp_width(b)	(b)+12	; JDIMENSION downsampled_width
57
%define input_data(b)		(b)+16		; JSAMPARRAY input_data
58
%define output_data_ptr(b)	(b)+20		; JSAMPARRAY * output_data_ptr
59
60
	align	16
61
	global	EXTN(jsimd_h2v1_fancy_upsample_sse2)
62
63
EXTN(jsimd_h2v1_fancy_upsample_sse2):
64
	push	ebp
65
	mov	ebp,esp
66
	pushpic	ebx
67
;	push	ecx		; need not be preserved
68
;	push	edx		; need not be preserved
69
	push	esi
70
	push	edi
71
72
	get_GOT	ebx		; get GOT address
73
74
	mov	eax, JDIMENSION [downsamp_width(ebp)]  ; colctr
75
	test	eax,eax
76
	jz	near .return
77
78
	mov	ecx, INT [max_v_samp(ebp)]	; rowctr
79
	test	ecx,ecx
80
	jz	near .return
81
82
	mov	esi, JSAMPARRAY [input_data(ebp)]	; input_data
83
	mov	edi, POINTER [output_data_ptr(ebp)]
84
	mov	edi, JSAMPARRAY [edi]			; output_data
85
	alignx	16,7
86
.rowloop:
87
	push	eax			; colctr
88
	push	edi
89
	push	esi
90
91
	mov	esi, JSAMPROW [esi]	; inptr
92
	mov	edi, JSAMPROW [edi]	; outptr
93
94
	test	eax, SIZEOF_XMMWORD-1
95
	jz	short .skip
96
	mov	dl, JSAMPLE [esi+(eax-1)*SIZEOF_JSAMPLE]
97
	mov	JSAMPLE [esi+eax*SIZEOF_JSAMPLE], dl	; insert a dummy sample
98
.skip:
99
	pxor	xmm0,xmm0		; xmm0=(all 0's)
100
	pcmpeqb	xmm7,xmm7
101
	psrldq	xmm7,(SIZEOF_XMMWORD-1)
102
	pand	xmm7, XMMWORD [esi+0*SIZEOF_XMMWORD]
103
104
	add	eax, byte SIZEOF_XMMWORD-1
105
	and	eax, byte -SIZEOF_XMMWORD
106
	cmp	eax, byte SIZEOF_XMMWORD
107
	ja	short .columnloop
108
	alignx	16,7
109
110
.columnloop_last:
111
	pcmpeqb	xmm6,xmm6
112
	pslldq	xmm6,(SIZEOF_XMMWORD-1)
113
	pand	xmm6, XMMWORD [esi+0*SIZEOF_XMMWORD]
114
	jmp	short .upsample
115
	alignx	16,7
116
117
.columnloop:
118
	movdqa	xmm6, XMMWORD [esi+1*SIZEOF_XMMWORD]
119
	pslldq	xmm6,(SIZEOF_XMMWORD-1)
120
121
.upsample:
122
	movdqa	xmm1, XMMWORD [esi+0*SIZEOF_XMMWORD]
123
	movdqa	xmm2,xmm1
124
	movdqa	xmm3,xmm1		; xmm1=( 0  1  2 ... 13 14 15)
125
	pslldq	xmm2,1			; xmm2=(--  0  1 ... 12 13 14)
126
	psrldq	xmm3,1			; xmm3=( 1  2  3 ... 14 15 --)
127
128
	por	xmm2,xmm7		; xmm2=(-1  0  1 ... 12 13 14)
129
	por	xmm3,xmm6		; xmm3=( 1  2  3 ... 14 15 16)
130
131
	movdqa	xmm7,xmm1
132
	psrldq	xmm7,(SIZEOF_XMMWORD-1)	; xmm7=(15 -- -- ... -- -- --)
133
134
	movdqa    xmm4,xmm1
135
	punpcklbw xmm1,xmm0		; xmm1=( 0  1  2  3  4  5  6  7)
136
	punpckhbw xmm4,xmm0		; xmm4=( 8  9 10 11 12 13 14 15)
137
	movdqa    xmm5,xmm2
138
	punpcklbw xmm2,xmm0		; xmm2=(-1  0  1  2  3  4  5  6)
139
	punpckhbw xmm5,xmm0		; xmm5=( 7  8  9 10 11 12 13 14)
140
	movdqa    xmm6,xmm3
141
	punpcklbw xmm3,xmm0		; xmm3=( 1  2  3  4  5  6  7  8)
142
	punpckhbw xmm6,xmm0		; xmm6=( 9 10 11 12 13 14 15 16)
143
144
	pmullw	xmm1,[GOTOFF(ebx,PW_THREE)]
145
	pmullw	xmm4,[GOTOFF(ebx,PW_THREE)]
146
	paddw	xmm2,[GOTOFF(ebx,PW_ONE)]
147
	paddw	xmm5,[GOTOFF(ebx,PW_ONE)]
148
	paddw	xmm3,[GOTOFF(ebx,PW_TWO)]
149
	paddw	xmm6,[GOTOFF(ebx,PW_TWO)]
150
151
	paddw	xmm2,xmm1
152
	paddw	xmm5,xmm4
153
	psrlw	xmm2,2			; xmm2=OutLE=( 0  2  4  6  8 10 12 14)
154
	psrlw	xmm5,2			; xmm5=OutHE=(16 18 20 22 24 26 28 30)
155
	paddw	xmm3,xmm1
156
	paddw	xmm6,xmm4
157
	psrlw	xmm3,2			; xmm3=OutLO=( 1  3  5  7  9 11 13 15)
158
	psrlw	xmm6,2			; xmm6=OutHO=(17 19 21 23 25 27 29 31)
159
160
	psllw	xmm3,BYTE_BIT
161
	psllw	xmm6,BYTE_BIT
162
	por	xmm2,xmm3		; xmm2=OutL=( 0  1  2 ... 13 14 15)
163
	por	xmm5,xmm6		; xmm5=OutH=(16 17 18 ... 29 30 31)
164
165
	movdqa	XMMWORD [edi+0*SIZEOF_XMMWORD], xmm2
166
	movdqa	XMMWORD [edi+1*SIZEOF_XMMWORD], xmm5
167
168
	sub	eax, byte SIZEOF_XMMWORD
169
	add	esi, byte 1*SIZEOF_XMMWORD	; inptr
170
	add	edi, byte 2*SIZEOF_XMMWORD	; outptr
171
	cmp	eax, byte SIZEOF_XMMWORD
172
	ja	near .columnloop
173
	test	eax,eax
174
	jnz	near .columnloop_last
175
176
	pop	esi
177
	pop	edi
178
	pop	eax
179
180
	add	esi, byte SIZEOF_JSAMPROW	; input_data
181
	add	edi, byte SIZEOF_JSAMPROW	; output_data
182
	dec	ecx				; rowctr
183
	jg	near .rowloop
184
185
.return:
186
	pop	edi
187
	pop	esi
188
;	pop	edx		; need not be preserved
189
;	pop	ecx		; need not be preserved
190
	poppic	ebx
191
	pop	ebp
192
	ret
193
194
; --------------------------------------------------------------------------
195
;
196
; Fancy processing for the common case of 2:1 horizontal and 2:1 vertical.
197
; Again a triangle filter; see comments for h2v1 case, above.
198
;
199
; GLOBAL(void)
200
; jsimd_h2v2_fancy_upsample_sse2 (int max_v_samp_factor,
201
;                                 JDIMENSION downsampled_width,
202
;                                 JSAMPARRAY input_data,
203
;                                 JSAMPARRAY * output_data_ptr);
204
;
205
206
%define max_v_samp(b)		(b)+8			; int max_v_samp_factor
207
%define downsamp_width(b)	(b)+12	; JDIMENSION downsampled_width
208
%define input_data(b)		(b)+16		; JSAMPARRAY input_data
209
%define output_data_ptr(b)	(b)+20		; JSAMPARRAY * output_data_ptr
210
211
%define original_ebp	ebp+0
212
%define wk(i)		ebp-(WK_NUM-(i))*SIZEOF_XMMWORD	; xmmword wk[WK_NUM]
213
%define WK_NUM		4
214
%define gotptr		wk(0)-SIZEOF_POINTER	; void * gotptr
215
216
	align	16
217
	global	EXTN(jsimd_h2v2_fancy_upsample_sse2)
218
219
EXTN(jsimd_h2v2_fancy_upsample_sse2):
220
	push	ebp
221
	mov	eax,esp				; eax = original ebp
222
	sub	esp, byte 4
223
	and	esp, byte (-SIZEOF_XMMWORD)	; align to 128 bits
224
	mov	[esp],eax
225
	mov	ebp,esp				; ebp = aligned ebp
226
	lea	esp, [wk(0)]
227
	pushpic	eax		; make a room for GOT address
228
	push	ebx
229
;	push	ecx		; need not be preserved
230
;	push	edx		; need not be preserved
231
	push	esi
232
	push	edi
233
234
	get_GOT	ebx			; get GOT address
235
	movpic	POINTER [gotptr], ebx	; save GOT address
236
237
	mov	edx,eax				; edx = original ebp
238
	mov	eax, JDIMENSION [downsamp_width(edx)]  ; colctr
239
	test	eax,eax
240
	jz	near .return
241
242
	mov	ecx, INT [max_v_samp(edx)]	; rowctr
243
	test	ecx,ecx
244
	jz	near .return
245
246
	mov	esi, JSAMPARRAY [input_data(edx)]	; input_data
247
	mov	edi, POINTER [output_data_ptr(edx)]
248
	mov	edi, JSAMPARRAY [edi]			; output_data
249
	alignx	16,7
250
.rowloop:
251
	push	eax					; colctr
252
	push	ecx
253
	push	edi
254
	push	esi
255
256
	mov	ecx, JSAMPROW [esi-1*SIZEOF_JSAMPROW]	; inptr1(above)
257
	mov	ebx, JSAMPROW [esi+0*SIZEOF_JSAMPROW]	; inptr0
258
	mov	esi, JSAMPROW [esi+1*SIZEOF_JSAMPROW]	; inptr1(below)
259
	mov	edx, JSAMPROW [edi+0*SIZEOF_JSAMPROW]	; outptr0
260
	mov	edi, JSAMPROW [edi+1*SIZEOF_JSAMPROW]	; outptr1
261
262
	test	eax, SIZEOF_XMMWORD-1
263
	jz	short .skip
264
	push	edx
265
	mov	dl, JSAMPLE [ecx+(eax-1)*SIZEOF_JSAMPLE]
266
	mov	JSAMPLE [ecx+eax*SIZEOF_JSAMPLE], dl
267
	mov	dl, JSAMPLE [ebx+(eax-1)*SIZEOF_JSAMPLE]
268
	mov	JSAMPLE [ebx+eax*SIZEOF_JSAMPLE], dl
269
	mov	dl, JSAMPLE [esi+(eax-1)*SIZEOF_JSAMPLE]
270
	mov	JSAMPLE [esi+eax*SIZEOF_JSAMPLE], dl	; insert a dummy sample
271
	pop	edx
272
.skip:
273
	; -- process the first column block
274
275
	movdqa	xmm0, XMMWORD [ebx+0*SIZEOF_XMMWORD]	; xmm0=row[ 0][0]
276
	movdqa	xmm1, XMMWORD [ecx+0*SIZEOF_XMMWORD]	; xmm1=row[-1][0]
277
	movdqa	xmm2, XMMWORD [esi+0*SIZEOF_XMMWORD]	; xmm2=row[+1][0]
278
279
	pushpic	ebx
280
	movpic	ebx, POINTER [gotptr]	; load GOT address
281
282
	pxor      xmm3,xmm3		; xmm3=(all 0's)
283
	movdqa    xmm4,xmm0
284
	punpcklbw xmm0,xmm3		; xmm0=row[ 0]( 0  1  2  3  4  5  6  7)
285
	punpckhbw xmm4,xmm3		; xmm4=row[ 0]( 8  9 10 11 12 13 14 15)
286
	movdqa    xmm5,xmm1
287
	punpcklbw xmm1,xmm3		; xmm1=row[-1]( 0  1  2  3  4  5  6  7)
288
	punpckhbw xmm5,xmm3		; xmm5=row[-1]( 8  9 10 11 12 13 14 15)
289
	movdqa    xmm6,xmm2
290
	punpcklbw xmm2,xmm3		; xmm2=row[+1]( 0  1  2  3  4  5  6  7)
291
	punpckhbw xmm6,xmm3		; xmm6=row[+1]( 8  9 10 11 12 13 14 15)
292
293
	pmullw	xmm0,[GOTOFF(ebx,PW_THREE)]
294
	pmullw	xmm4,[GOTOFF(ebx,PW_THREE)]
295
296
	pcmpeqb	xmm7,xmm7
297
	psrldq	xmm7,(SIZEOF_XMMWORD-2)
298
299
	paddw	xmm1,xmm0		; xmm1=Int0L=( 0  1  2  3  4  5  6  7)
300
	paddw	xmm5,xmm4		; xmm5=Int0H=( 8  9 10 11 12 13 14 15)
301
	paddw	xmm2,xmm0		; xmm2=Int1L=( 0  1  2  3  4  5  6  7)
302
	paddw	xmm6,xmm4		; xmm6=Int1H=( 8  9 10 11 12 13 14 15)
303
304
	movdqa	XMMWORD [edx+0*SIZEOF_XMMWORD], xmm1	; temporarily save
305
	movdqa	XMMWORD [edx+1*SIZEOF_XMMWORD], xmm5	; the intermediate data
306
	movdqa	XMMWORD [edi+0*SIZEOF_XMMWORD], xmm2
307
	movdqa	XMMWORD [edi+1*SIZEOF_XMMWORD], xmm6
308
309
	pand	xmm1,xmm7		; xmm1=( 0 -- -- -- -- -- -- --)
310
	pand	xmm2,xmm7		; xmm2=( 0 -- -- -- -- -- -- --)
311
312
	movdqa	XMMWORD [wk(0)], xmm1
313
	movdqa	XMMWORD [wk(1)], xmm2
314
315
	poppic	ebx
316
317
	add	eax, byte SIZEOF_XMMWORD-1
318
	and	eax, byte -SIZEOF_XMMWORD
319
	cmp	eax, byte SIZEOF_XMMWORD
320
	ja	short .columnloop
321
	alignx	16,7
322
323
.columnloop_last:
324
	; -- process the last column block
325
326
	pushpic	ebx
327
	movpic	ebx, POINTER [gotptr]	; load GOT address
328
329
	pcmpeqb	xmm1,xmm1
330
	pslldq	xmm1,(SIZEOF_XMMWORD-2)
331
	movdqa	xmm2,xmm1
332
333
	pand	xmm1, XMMWORD [edx+1*SIZEOF_XMMWORD]
334
	pand	xmm2, XMMWORD [edi+1*SIZEOF_XMMWORD]
335
336
	movdqa	XMMWORD [wk(2)], xmm1	; xmm1=(-- -- -- -- -- -- -- 15)
337
	movdqa	XMMWORD [wk(3)], xmm2	; xmm2=(-- -- -- -- -- -- -- 15)
338
339
	jmp	near .upsample
340
	alignx	16,7
341
342
.columnloop:
343
	; -- process the next column block
344
345
	movdqa	xmm0, XMMWORD [ebx+1*SIZEOF_XMMWORD]	; xmm0=row[ 0][1]
346
	movdqa	xmm1, XMMWORD [ecx+1*SIZEOF_XMMWORD]	; xmm1=row[-1][1]
347
	movdqa	xmm2, XMMWORD [esi+1*SIZEOF_XMMWORD]	; xmm2=row[+1][1]
348
349
	pushpic	ebx
350
	movpic	ebx, POINTER [gotptr]	; load GOT address
351
352
	pxor      xmm3,xmm3		; xmm3=(all 0's)
353
	movdqa    xmm4,xmm0
354
	punpcklbw xmm0,xmm3		; xmm0=row[ 0]( 0  1  2  3  4  5  6  7)
355
	punpckhbw xmm4,xmm3		; xmm4=row[ 0]( 8  9 10 11 12 13 14 15)
356
	movdqa    xmm5,xmm1
357
	punpcklbw xmm1,xmm3		; xmm1=row[-1]( 0  1  2  3  4  5  6  7)
358
	punpckhbw xmm5,xmm3		; xmm5=row[-1]( 8  9 10 11 12 13 14 15)
359
	movdqa    xmm6,xmm2
360
	punpcklbw xmm2,xmm3		; xmm2=row[+1]( 0  1  2  3  4  5  6  7)
361
	punpckhbw xmm6,xmm3		; xmm6=row[+1]( 8  9 10 11 12 13 14 15)
362
363
	pmullw	xmm0,[GOTOFF(ebx,PW_THREE)]
364
	pmullw	xmm4,[GOTOFF(ebx,PW_THREE)]
365
366
	paddw	xmm1,xmm0		; xmm1=Int0L=( 0  1  2  3  4  5  6  7)
367
	paddw	xmm5,xmm4		; xmm5=Int0H=( 8  9 10 11 12 13 14 15)
368
	paddw	xmm2,xmm0		; xmm2=Int1L=( 0  1  2  3  4  5  6  7)
369
	paddw	xmm6,xmm4		; xmm6=Int1H=( 8  9 10 11 12 13 14 15)
370
371
	movdqa	XMMWORD [edx+2*SIZEOF_XMMWORD], xmm1	; temporarily save
372
	movdqa	XMMWORD [edx+3*SIZEOF_XMMWORD], xmm5	; the intermediate data
373
	movdqa	XMMWORD [edi+2*SIZEOF_XMMWORD], xmm2
374
	movdqa	XMMWORD [edi+3*SIZEOF_XMMWORD], xmm6
375
376
	pslldq	xmm1,(SIZEOF_XMMWORD-2)	; xmm1=(-- -- -- -- -- -- --  0)
377
	pslldq	xmm2,(SIZEOF_XMMWORD-2)	; xmm2=(-- -- -- -- -- -- --  0)
378
379
	movdqa	XMMWORD [wk(2)], xmm1
380
	movdqa	XMMWORD [wk(3)], xmm2
381
382
.upsample:
383
	; -- process the upper row
384
385
	movdqa	xmm7, XMMWORD [edx+0*SIZEOF_XMMWORD]
386
	movdqa	xmm3, XMMWORD [edx+1*SIZEOF_XMMWORD]
387
388
	movdqa	xmm0,xmm7		; xmm7=Int0L=( 0  1  2  3  4  5  6  7)
389
	movdqa	xmm4,xmm3		; xmm3=Int0H=( 8  9 10 11 12 13 14 15)
390
	psrldq	xmm0,2			; xmm0=( 1  2  3  4  5  6  7 --)
391
	pslldq	xmm4,(SIZEOF_XMMWORD-2)	; xmm4=(-- -- -- -- -- -- --  8)
392
	movdqa	xmm5,xmm7
393
	movdqa	xmm6,xmm3
394
	psrldq	xmm5,(SIZEOF_XMMWORD-2)	; xmm5=( 7 -- -- -- -- -- -- --)
395
	pslldq	xmm6,2			; xmm6=(--  8  9 10 11 12 13 14)
396
397
	por	xmm0,xmm4		; xmm0=( 1  2  3  4  5  6  7  8)
398
	por	xmm5,xmm6		; xmm5=( 7  8  9 10 11 12 13 14)
399
400
	movdqa	xmm1,xmm7
401
	movdqa	xmm2,xmm3
402
	pslldq	xmm1,2			; xmm1=(--  0  1  2  3  4  5  6)
403
	psrldq	xmm2,2			; xmm2=( 9 10 11 12 13 14 15 --)
404
	movdqa	xmm4,xmm3
405
	psrldq	xmm4,(SIZEOF_XMMWORD-2)	; xmm4=(15 -- -- -- -- -- -- --)
406
407
	por	xmm1, XMMWORD [wk(0)]	; xmm1=(-1  0  1  2  3  4  5  6)
408
	por	xmm2, XMMWORD [wk(2)]	; xmm2=( 9 10 11 12 13 14 15 16)
409
410
	movdqa	XMMWORD [wk(0)], xmm4
411
412
	pmullw	xmm7,[GOTOFF(ebx,PW_THREE)]
413
	pmullw	xmm3,[GOTOFF(ebx,PW_THREE)]
414
	paddw	xmm1,[GOTOFF(ebx,PW_EIGHT)]
415
	paddw	xmm5,[GOTOFF(ebx,PW_EIGHT)]
416
	paddw	xmm0,[GOTOFF(ebx,PW_SEVEN)]
417
	paddw	xmm2,[GOTOFF(ebx,PW_SEVEN)]
418
419
	paddw	xmm1,xmm7
420
	paddw	xmm5,xmm3
421
	psrlw	xmm1,4			; xmm1=Out0LE=( 0  2  4  6  8 10 12 14)
422
	psrlw	xmm5,4			; xmm5=Out0HE=(16 18 20 22 24 26 28 30)
423
	paddw	xmm0,xmm7
424
	paddw	xmm2,xmm3
425
	psrlw	xmm0,4			; xmm0=Out0LO=( 1  3  5  7  9 11 13 15)
426
	psrlw	xmm2,4			; xmm2=Out0HO=(17 19 21 23 25 27 29 31)
427
428
	psllw	xmm0,BYTE_BIT
429
	psllw	xmm2,BYTE_BIT
430
	por	xmm1,xmm0		; xmm1=Out0L=( 0  1  2 ... 13 14 15)
431
	por	xmm5,xmm2		; xmm5=Out0H=(16 17 18 ... 29 30 31)
432
433
	movdqa	XMMWORD [edx+0*SIZEOF_XMMWORD], xmm1
434
	movdqa	XMMWORD [edx+1*SIZEOF_XMMWORD], xmm5
435
436
	; -- process the lower row
437
438
	movdqa	xmm6, XMMWORD [edi+0*SIZEOF_XMMWORD]
439
	movdqa	xmm4, XMMWORD [edi+1*SIZEOF_XMMWORD]
440
441
	movdqa	xmm7,xmm6		; xmm6=Int1L=( 0  1  2  3  4  5  6  7)
442
	movdqa	xmm3,xmm4		; xmm4=Int1H=( 8  9 10 11 12 13 14 15)
443
	psrldq	xmm7,2			; xmm7=( 1  2  3  4  5  6  7 --)
444
	pslldq	xmm3,(SIZEOF_XMMWORD-2)	; xmm3=(-- -- -- -- -- -- --  8)
445
	movdqa	xmm0,xmm6
446
	movdqa	xmm2,xmm4
447
	psrldq	xmm0,(SIZEOF_XMMWORD-2)	; xmm0=( 7 -- -- -- -- -- -- --)
448
	pslldq	xmm2,2			; xmm2=(--  8  9 10 11 12 13 14)
449
450
	por	xmm7,xmm3		; xmm7=( 1  2  3  4  5  6  7  8)
451
	por	xmm0,xmm2		; xmm0=( 7  8  9 10 11 12 13 14)
452
453
	movdqa	xmm1,xmm6
454
	movdqa	xmm5,xmm4
455
	pslldq	xmm1,2			; xmm1=(--  0  1  2  3  4  5  6)
456
	psrldq	xmm5,2			; xmm5=( 9 10 11 12 13 14 15 --)
457
	movdqa	xmm3,xmm4
458
	psrldq	xmm3,(SIZEOF_XMMWORD-2)	; xmm3=(15 -- -- -- -- -- -- --)
459
460
	por	xmm1, XMMWORD [wk(1)]	; xmm1=(-1  0  1  2  3  4  5  6)
461
	por	xmm5, XMMWORD [wk(3)]	; xmm5=( 9 10 11 12 13 14 15 16)
462
463
	movdqa	XMMWORD [wk(1)], xmm3
464
465
	pmullw	xmm6,[GOTOFF(ebx,PW_THREE)]
466
	pmullw	xmm4,[GOTOFF(ebx,PW_THREE)]
467
	paddw	xmm1,[GOTOFF(ebx,PW_EIGHT)]
468
	paddw	xmm0,[GOTOFF(ebx,PW_EIGHT)]
469
	paddw	xmm7,[GOTOFF(ebx,PW_SEVEN)]
470
	paddw	xmm5,[GOTOFF(ebx,PW_SEVEN)]
471
472
	paddw	xmm1,xmm6
473
	paddw	xmm0,xmm4
474
	psrlw	xmm1,4			; xmm1=Out1LE=( 0  2  4  6  8 10 12 14)
475
	psrlw	xmm0,4			; xmm0=Out1HE=(16 18 20 22 24 26 28 30)
476
	paddw	xmm7,xmm6
477
	paddw	xmm5,xmm4
478
	psrlw	xmm7,4			; xmm7=Out1LO=( 1  3  5  7  9 11 13 15)
479
	psrlw	xmm5,4			; xmm5=Out1HO=(17 19 21 23 25 27 29 31)
480
481
	psllw	xmm7,BYTE_BIT
482
	psllw	xmm5,BYTE_BIT
483
	por	xmm1,xmm7		; xmm1=Out1L=( 0  1  2 ... 13 14 15)
484
	por	xmm0,xmm5		; xmm0=Out1H=(16 17 18 ... 29 30 31)
485
486
	movdqa	XMMWORD [edi+0*SIZEOF_XMMWORD], xmm1
487
	movdqa	XMMWORD [edi+1*SIZEOF_XMMWORD], xmm0
488
489
	poppic	ebx
490
491
	sub	eax, byte SIZEOF_XMMWORD
492
	add	ecx, byte 1*SIZEOF_XMMWORD	; inptr1(above)
493
	add	ebx, byte 1*SIZEOF_XMMWORD	; inptr0
494
	add	esi, byte 1*SIZEOF_XMMWORD	; inptr1(below)
495
	add	edx, byte 2*SIZEOF_XMMWORD	; outptr0
496
	add	edi, byte 2*SIZEOF_XMMWORD	; outptr1
497
	cmp	eax, byte SIZEOF_XMMWORD
498
	ja	near .columnloop
499
	test	eax,eax
500
	jnz	near .columnloop_last
501
502
	pop	esi
503
	pop	edi
504
	pop	ecx
505
	pop	eax
506
507
	add	esi, byte 1*SIZEOF_JSAMPROW	; input_data
508
	add	edi, byte 2*SIZEOF_JSAMPROW	; output_data
509
	sub	ecx, byte 2			; rowctr
510
	jg	near .rowloop
511
512
.return:
513
	pop	edi
514
	pop	esi
515
;	pop	edx		; need not be preserved
516
;	pop	ecx		; need not be preserved
517
	pop	ebx
518
	mov	esp,ebp		; esp <- aligned ebp
519
	pop	esp		; esp <- original ebp
520
	pop	ebp
521
	ret
522
523
; --------------------------------------------------------------------------
524
;
525
; Fast processing for the common case of 2:1 horizontal and 1:1 vertical.
526
; It's still a box filter.
527
;
528
; GLOBAL(void)
529
; jsimd_h2v1_upsample_sse2 (int max_v_samp_factor,
530
;                           JDIMENSION output_width,
531
;                           JSAMPARRAY input_data,
532
;                           JSAMPARRAY * output_data_ptr);
533
;
534
535
%define max_v_samp(b)		(b)+8			; int max_v_samp_factor
536
%define output_width(b)	(b)+12		; JDIMENSION output_width
537
%define input_data(b)		(b)+16		; JSAMPARRAY input_data
538
%define output_data_ptr(b)	(b)+20		; JSAMPARRAY * output_data_ptr
539
540
	align	16
541
	global	EXTN(jsimd_h2v1_upsample_sse2)
542
543
EXTN(jsimd_h2v1_upsample_sse2):
544
	push	ebp
545
	mov	ebp,esp
546
;	push	ebx		; unused
547
;	push	ecx		; need not be preserved
548
;	push	edx		; need not be preserved
549
	push	esi
550
	push	edi
551
552
	mov	edx, JDIMENSION [output_width(ebp)]
553
	add	edx, byte (2*SIZEOF_XMMWORD)-1
554
	and	edx, byte -(2*SIZEOF_XMMWORD)
555
	jz	short .return
556
557
	mov	ecx, INT [max_v_samp(ebp)]	; rowctr
558
	test	ecx,ecx
559
	jz	short .return
560
561
	mov	esi, JSAMPARRAY [input_data(ebp)]	; input_data
562
	mov	edi, POINTER [output_data_ptr(ebp)]
563
	mov	edi, JSAMPARRAY [edi]			; output_data
564
	alignx	16,7
565
.rowloop:
566
	push	edi
567
	push	esi
568
569
	mov	esi, JSAMPROW [esi]		; inptr
570
	mov	edi, JSAMPROW [edi]		; outptr
571
	mov	eax,edx				; colctr
572
	alignx	16,7
573
.columnloop:
574
575
	movdqa	xmm0, XMMWORD [esi+0*SIZEOF_XMMWORD]
576
577
	movdqa    xmm1,xmm0
578
	punpcklbw xmm0,xmm0
579
	punpckhbw xmm1,xmm1
580
581
	movdqa	XMMWORD [edi+0*SIZEOF_XMMWORD], xmm0
582
	movdqa	XMMWORD [edi+1*SIZEOF_XMMWORD], xmm1
583
584
	sub	eax, byte 2*SIZEOF_XMMWORD
585
	jz	short .nextrow
586
587
	movdqa	xmm2, XMMWORD [esi+1*SIZEOF_XMMWORD]
588
589
	movdqa    xmm3,xmm2
590
	punpcklbw xmm2,xmm2
591
	punpckhbw xmm3,xmm3
592
593
	movdqa	XMMWORD [edi+2*SIZEOF_XMMWORD], xmm2
594
	movdqa	XMMWORD [edi+3*SIZEOF_XMMWORD], xmm3
595
596
	sub	eax, byte 2*SIZEOF_XMMWORD
597
	jz	short .nextrow
598
599
	add	esi, byte 2*SIZEOF_XMMWORD	; inptr
600
	add	edi, byte 4*SIZEOF_XMMWORD	; outptr
601
	jmp	short .columnloop
602
	alignx	16,7
603
604
.nextrow:
605
	pop	esi
606
	pop	edi
607
608
	add	esi, byte SIZEOF_JSAMPROW	; input_data
609
	add	edi, byte SIZEOF_JSAMPROW	; output_data
610
	dec	ecx				; rowctr
611
	jg	short .rowloop
612
613
.return:
614
	pop	edi
615
	pop	esi
616
;	pop	edx		; need not be preserved
617
;	pop	ecx		; need not be preserved
618
;	pop	ebx		; unused
619
	pop	ebp
620
	ret
621
622
; --------------------------------------------------------------------------
623
;
624
; Fast processing for the common case of 2:1 horizontal and 2:1 vertical.
625
; It's still a box filter.
626
;
627
; GLOBAL(void)
628
; jsimd_h2v2_upsample_sse2 (nt max_v_samp_factor,
629
;                           JDIMENSION output_width,
630
;                           JSAMPARRAY input_data,
631
;                           JSAMPARRAY * output_data_ptr);
632
;
633
634
%define max_v_samp(b)		(b)+8			; int max_v_samp_factor
635
%define output_width(b)	(b)+12		; JDIMENSION output_width
636
%define input_data(b)		(b)+16		; JSAMPARRAY input_data
637
%define output_data_ptr(b)	(b)+20		; JSAMPARRAY * output_data_ptr
638
639
	align	16
640
	global	EXTN(jsimd_h2v2_upsample_sse2)
641
642
EXTN(jsimd_h2v2_upsample_sse2):
643
	push	ebp
644
	mov	ebp,esp
645
	push	ebx
646
;	push	ecx		; need not be preserved
647
;	push	edx		; need not be preserved
648
	push	esi
649
	push	edi
650
651
	mov	edx, JDIMENSION [output_width(ebp)]
652
	add	edx, byte (2*SIZEOF_XMMWORD)-1
653
	and	edx, byte -(2*SIZEOF_XMMWORD)
654
	jz	near .return
655
656
	mov	ecx, INT [max_v_samp(ebp)]	; rowctr
657
	test	ecx,ecx
658
	jz	near .return
659
660
	mov	esi, JSAMPARRAY [input_data(ebp)]	; input_data
661
	mov	edi, POINTER [output_data_ptr(ebp)]
662
	mov	edi, JSAMPARRAY [edi]			; output_data
663
	alignx	16,7
664
.rowloop:
665
	push	edi
666
	push	esi
667
668
	mov	esi, JSAMPROW [esi]			; inptr
669
	mov	ebx, JSAMPROW [edi+0*SIZEOF_JSAMPROW]	; outptr0
670
	mov	edi, JSAMPROW [edi+1*SIZEOF_JSAMPROW]	; outptr1
671
	mov	eax,edx					; colctr
672
	alignx	16,7
673
.columnloop:
674
675
	movdqa	xmm0, XMMWORD [esi+0*SIZEOF_XMMWORD]
676
677
	movdqa    xmm1,xmm0
678
	punpcklbw xmm0,xmm0
679
	punpckhbw xmm1,xmm1
680
681
	movdqa	XMMWORD [ebx+0*SIZEOF_XMMWORD], xmm0
682
	movdqa	XMMWORD [ebx+1*SIZEOF_XMMWORD], xmm1
683
	movdqa	XMMWORD [edi+0*SIZEOF_XMMWORD], xmm0
684
	movdqa	XMMWORD [edi+1*SIZEOF_XMMWORD], xmm1
685
686
	sub	eax, byte 2*SIZEOF_XMMWORD
687
	jz	short .nextrow
688
689
	movdqa	xmm2, XMMWORD [esi+1*SIZEOF_XMMWORD]
690
691
	movdqa    xmm3,xmm2
692
	punpcklbw xmm2,xmm2
693
	punpckhbw xmm3,xmm3
694
695
	movdqa	XMMWORD [ebx+2*SIZEOF_XMMWORD], xmm2
696
	movdqa	XMMWORD [ebx+3*SIZEOF_XMMWORD], xmm3
697
	movdqa	XMMWORD [edi+2*SIZEOF_XMMWORD], xmm2
698
	movdqa	XMMWORD [edi+3*SIZEOF_XMMWORD], xmm3
699
700
	sub	eax, byte 2*SIZEOF_XMMWORD
701
	jz	short .nextrow
702
703
	add	esi, byte 2*SIZEOF_XMMWORD	; inptr
704
	add	ebx, byte 4*SIZEOF_XMMWORD	; outptr0
705
	add	edi, byte 4*SIZEOF_XMMWORD	; outptr1
706
	jmp	short .columnloop
707
	alignx	16,7
708
709
.nextrow:
710
	pop	esi
711
	pop	edi
712
713
	add	esi, byte 1*SIZEOF_JSAMPROW	; input_data
714
	add	edi, byte 2*SIZEOF_JSAMPROW	; output_data
715
	sub	ecx, byte 2			; rowctr
716
	jg	short .rowloop
717
718
.return:
719
	pop	edi
720
	pop	esi
721
;	pop	edx		; need not be preserved
722
;	pop	ecx		; need not be preserved
723
	pop	ebx
724
	pop	ebp
725
	ret
726
727
; For some reason, the OS X linker does not honor the request to align the
728
; segment unless we do this.
729
	align	16
(-)a/jpeg/simd/jf3dnflt.asm (+320 lines)
Line     Link Here 
Line 0    Link Here 
1
;
2
; jf3dnflt.asm - floating-point FDCT (3DNow!)
3
;
4
; Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
5
;
6
; Based on
7
; x86 SIMD extension for IJG JPEG library
8
; Copyright (C) 1999-2006, MIYASAKA Masaru.
9
; For conditions of distribution and use, see copyright notice in jsimdext.inc
10
;
11
; This file should be assembled with NASM (Netwide Assembler),
12
; can *not* be assembled with Microsoft's MASM or any compatible
13
; assembler (including Borland's Turbo Assembler).
14
; NASM is available from http://nasm.sourceforge.net/ or
15
; http://sourceforge.net/project/showfiles.php?group_id=6208
16
;
17
; This file contains a floating-point implementation of the forward DCT
18
; (Discrete Cosine Transform). The following code is based directly on
19
; the IJG's original jfdctflt.c; see the jfdctflt.c for more details.
20
;
21
; [TAB8]
22
23
%include "jsimdext.inc"
24
%include "jdct.inc"
25
26
; --------------------------------------------------------------------------
27
	SECTION	SEG_CONST
28
29
	alignz	16
30
	global	EXTN(jconst_fdct_float_3dnow)
31
32
EXTN(jconst_fdct_float_3dnow):
33
34
PD_0_382	times 2 dd  0.382683432365089771728460
35
PD_0_707	times 2 dd  0.707106781186547524400844
36
PD_0_541	times 2 dd  0.541196100146196984399723
37
PD_1_306	times 2 dd  1.306562964876376527856643
38
39
	alignz	16
40
41
; --------------------------------------------------------------------------
42
	SECTION	SEG_TEXT
43
	BITS	32
44
;
45
; Perform the forward DCT on one block of samples.
46
;
47
; GLOBAL(void)
48
; jsimd_fdct_float_3dnow (FAST_FLOAT * data)
49
;
50
51
%define data(b)		(b)+8		; FAST_FLOAT * data
52
53
%define original_ebp	ebp+0
54
%define wk(i)		ebp-(WK_NUM-(i))*SIZEOF_MMWORD	; mmword wk[WK_NUM]
55
%define WK_NUM		2
56
57
	align	16
58
	global	EXTN(jsimd_fdct_float_3dnow)
59
60
EXTN(jsimd_fdct_float_3dnow):
61
	push	ebp
62
	mov	eax,esp				; eax = original ebp
63
	sub	esp, byte 4
64
	and	esp, byte (-SIZEOF_MMWORD)	; align to 64 bits
65
	mov	[esp],eax
66
	mov	ebp,esp				; ebp = aligned ebp
67
	lea	esp, [wk(0)]
68
	pushpic	ebx
69
;	push	ecx		; need not be preserved
70
;	push	edx		; need not be preserved
71
;	push	esi		; unused
72
;	push	edi		; unused
73
74
	get_GOT	ebx		; get GOT address
75
76
	; ---- Pass 1: process rows.
77
78
	mov	edx, POINTER [data(eax)]	; (FAST_FLOAT *)
79
	mov	ecx, DCTSIZE/2
80
	alignx	16,7
81
.rowloop:
82
83
	movq	mm0, MMWORD [MMBLOCK(0,0,edx,SIZEOF_FAST_FLOAT)]
84
	movq	mm1, MMWORD [MMBLOCK(1,0,edx,SIZEOF_FAST_FLOAT)]
85
	movq	mm2, MMWORD [MMBLOCK(0,3,edx,SIZEOF_FAST_FLOAT)]
86
	movq	mm3, MMWORD [MMBLOCK(1,3,edx,SIZEOF_FAST_FLOAT)]
87
88
	; mm0=(00 01), mm1=(10 11), mm2=(06 07), mm3=(16 17)
89
90
	movq      mm4,mm0		; transpose coefficients
91
	punpckldq mm0,mm1		; mm0=(00 10)=data0
92
	punpckhdq mm4,mm1		; mm4=(01 11)=data1
93
	movq      mm5,mm2		; transpose coefficients
94
	punpckldq mm2,mm3		; mm2=(06 16)=data6
95
	punpckhdq mm5,mm3		; mm5=(07 17)=data7
96
97
	movq	mm6,mm4
98
	movq	mm7,mm0
99
	pfsub	mm4,mm2			; mm4=data1-data6=tmp6
100
	pfsub	mm0,mm5			; mm0=data0-data7=tmp7
101
	pfadd	mm6,mm2			; mm6=data1+data6=tmp1
102
	pfadd	mm7,mm5			; mm7=data0+data7=tmp0
103
104
	movq	mm1, MMWORD [MMBLOCK(0,1,edx,SIZEOF_FAST_FLOAT)]
105
	movq	mm3, MMWORD [MMBLOCK(1,1,edx,SIZEOF_FAST_FLOAT)]
106
	movq	mm2, MMWORD [MMBLOCK(0,2,edx,SIZEOF_FAST_FLOAT)]
107
	movq	mm5, MMWORD [MMBLOCK(1,2,edx,SIZEOF_FAST_FLOAT)]
108
109
	; mm1=(02 03), mm3=(12 13), mm2=(04 05), mm5=(14 15)
110
111
	movq	MMWORD [wk(0)], mm4	; wk(0)=tmp6
112
	movq	MMWORD [wk(1)], mm0	; wk(1)=tmp7
113
114
	movq      mm4,mm1		; transpose coefficients
115
	punpckldq mm1,mm3		; mm1=(02 12)=data2
116
	punpckhdq mm4,mm3		; mm4=(03 13)=data3
117
	movq      mm0,mm2		; transpose coefficients
118
	punpckldq mm2,mm5		; mm2=(04 14)=data4
119
	punpckhdq mm0,mm5		; mm0=(05 15)=data5
120
121
	movq	mm3,mm4
122
	movq	mm5,mm1
123
	pfadd	mm4,mm2			; mm4=data3+data4=tmp3
124
	pfadd	mm1,mm0			; mm1=data2+data5=tmp2
125
	pfsub	mm3,mm2			; mm3=data3-data4=tmp4
126
	pfsub	mm5,mm0			; mm5=data2-data5=tmp5
127
128
	; -- Even part
129
130
	movq	mm2,mm7
131
	movq	mm0,mm6
132
	pfsub	mm7,mm4			; mm7=tmp13
133
	pfsub	mm6,mm1			; mm6=tmp12
134
	pfadd	mm2,mm4			; mm2=tmp10
135
	pfadd	mm0,mm1			; mm0=tmp11
136
137
	pfadd	mm6,mm7
138
	pfmul	mm6,[GOTOFF(ebx,PD_0_707)] ; mm6=z1
139
140
	movq	mm4,mm2
141
	movq	mm1,mm7
142
	pfsub	mm2,mm0			; mm2=data4
143
	pfsub	mm7,mm6			; mm7=data6
144
	pfadd	mm4,mm0			; mm4=data0
145
	pfadd	mm1,mm6			; mm1=data2
146
147
	movq	MMWORD [MMBLOCK(0,2,edx,SIZEOF_FAST_FLOAT)], mm2
148
	movq	MMWORD [MMBLOCK(0,3,edx,SIZEOF_FAST_FLOAT)], mm7
149
	movq	MMWORD [MMBLOCK(0,0,edx,SIZEOF_FAST_FLOAT)], mm4
150
	movq	MMWORD [MMBLOCK(0,1,edx,SIZEOF_FAST_FLOAT)], mm1
151
152
	; -- Odd part
153
154
	movq	mm0, MMWORD [wk(0)]	; mm0=tmp6
155
	movq	mm6, MMWORD [wk(1)]	; mm6=tmp7
156
157
	pfadd	mm3,mm5			; mm3=tmp10
158
	pfadd	mm5,mm0			; mm5=tmp11
159
	pfadd	mm0,mm6			; mm0=tmp12, mm6=tmp7
160
161
	pfmul	mm5,[GOTOFF(ebx,PD_0_707)] ; mm5=z3
162
163
	movq	mm2,mm3			; mm2=tmp10
164
	pfsub	mm3,mm0
165
	pfmul	mm3,[GOTOFF(ebx,PD_0_382)] ; mm3=z5
166
	pfmul	mm2,[GOTOFF(ebx,PD_0_541)] ; mm2=MULTIPLY(tmp10,FIX_0_54119610)
167
	pfmul	mm0,[GOTOFF(ebx,PD_1_306)] ; mm0=MULTIPLY(tmp12,FIX_1_30656296)
168
	pfadd	mm2,mm3			; mm2=z2
169
	pfadd	mm0,mm3			; mm0=z4
170
171
	movq	mm7,mm6
172
	pfsub	mm6,mm5			; mm6=z13
173
	pfadd	mm7,mm5			; mm7=z11
174
175
	movq	mm4,mm6
176
	movq	mm1,mm7
177
	pfsub	mm6,mm2			; mm6=data3
178
	pfsub	mm7,mm0			; mm7=data7
179
	pfadd	mm4,mm2			; mm4=data5
180
	pfadd	mm1,mm0			; mm1=data1
181
182
	movq	MMWORD [MMBLOCK(1,1,edx,SIZEOF_FAST_FLOAT)], mm6
183
	movq	MMWORD [MMBLOCK(1,3,edx,SIZEOF_FAST_FLOAT)], mm7
184
	movq	MMWORD [MMBLOCK(1,2,edx,SIZEOF_FAST_FLOAT)], mm4
185
	movq	MMWORD [MMBLOCK(1,0,edx,SIZEOF_FAST_FLOAT)], mm1
186
187
	add	edx, byte 2*DCTSIZE*SIZEOF_FAST_FLOAT
188
	dec	ecx
189
	jnz	near .rowloop
190
191
	; ---- Pass 2: process columns.
192
193
	mov	edx, POINTER [data(eax)]	; (FAST_FLOAT *)
194
	mov	ecx, DCTSIZE/2
195
	alignx	16,7
196
.columnloop:
197
198
	movq	mm0, MMWORD [MMBLOCK(0,0,edx,SIZEOF_FAST_FLOAT)]
199
	movq	mm1, MMWORD [MMBLOCK(1,0,edx,SIZEOF_FAST_FLOAT)]
200
	movq	mm2, MMWORD [MMBLOCK(6,0,edx,SIZEOF_FAST_FLOAT)]
201
	movq	mm3, MMWORD [MMBLOCK(7,0,edx,SIZEOF_FAST_FLOAT)]
202
203
	; mm0=(00 10), mm1=(01 11), mm2=(60 70), mm3=(61 71)
204
205
	movq      mm4,mm0		; transpose coefficients
206
	punpckldq mm0,mm1		; mm0=(00 01)=data0
207
	punpckhdq mm4,mm1		; mm4=(10 11)=data1
208
	movq      mm5,mm2		; transpose coefficients
209
	punpckldq mm2,mm3		; mm2=(60 61)=data6
210
	punpckhdq mm5,mm3		; mm5=(70 71)=data7
211
212
	movq	mm6,mm4
213
	movq	mm7,mm0
214
	pfsub	mm4,mm2			; mm4=data1-data6=tmp6
215
	pfsub	mm0,mm5			; mm0=data0-data7=tmp7
216
	pfadd	mm6,mm2			; mm6=data1+data6=tmp1
217
	pfadd	mm7,mm5			; mm7=data0+data7=tmp0
218
219
	movq	mm1, MMWORD [MMBLOCK(2,0,edx,SIZEOF_FAST_FLOAT)]
220
	movq	mm3, MMWORD [MMBLOCK(3,0,edx,SIZEOF_FAST_FLOAT)]
221
	movq	mm2, MMWORD [MMBLOCK(4,0,edx,SIZEOF_FAST_FLOAT)]
222
	movq	mm5, MMWORD [MMBLOCK(5,0,edx,SIZEOF_FAST_FLOAT)]
223
224
	; mm1=(20 30), mm3=(21 31), mm2=(40 50), mm5=(41 51)
225
226
	movq	MMWORD [wk(0)], mm4	; wk(0)=tmp6
227
	movq	MMWORD [wk(1)], mm0	; wk(1)=tmp7
228
229
	movq      mm4,mm1		; transpose coefficients
230
	punpckldq mm1,mm3		; mm1=(20 21)=data2
231
	punpckhdq mm4,mm3		; mm4=(30 31)=data3
232
	movq      mm0,mm2		; transpose coefficients
233
	punpckldq mm2,mm5		; mm2=(40 41)=data4
234
	punpckhdq mm0,mm5		; mm0=(50 51)=data5
235
236
	movq	mm3,mm4
237
	movq	mm5,mm1
238
	pfadd	mm4,mm2			; mm4=data3+data4=tmp3
239
	pfadd	mm1,mm0			; mm1=data2+data5=tmp2
240
	pfsub	mm3,mm2			; mm3=data3-data4=tmp4
241
	pfsub	mm5,mm0			; mm5=data2-data5=tmp5
242
243
	; -- Even part
244
245
	movq	mm2,mm7
246
	movq	mm0,mm6
247
	pfsub	mm7,mm4			; mm7=tmp13
248
	pfsub	mm6,mm1			; mm6=tmp12
249
	pfadd	mm2,mm4			; mm2=tmp10
250
	pfadd	mm0,mm1			; mm0=tmp11
251
252
	pfadd	mm6,mm7
253
	pfmul	mm6,[GOTOFF(ebx,PD_0_707)] ; mm6=z1
254
255
	movq	mm4,mm2
256
	movq	mm1,mm7
257
	pfsub	mm2,mm0			; mm2=data4
258
	pfsub	mm7,mm6			; mm7=data6
259
	pfadd	mm4,mm0			; mm4=data0
260
	pfadd	mm1,mm6			; mm1=data2
261
262
	movq	MMWORD [MMBLOCK(4,0,edx,SIZEOF_FAST_FLOAT)], mm2
263
	movq	MMWORD [MMBLOCK(6,0,edx,SIZEOF_FAST_FLOAT)], mm7
264
	movq	MMWORD [MMBLOCK(0,0,edx,SIZEOF_FAST_FLOAT)], mm4
265
	movq	MMWORD [MMBLOCK(2,0,edx,SIZEOF_FAST_FLOAT)], mm1
266
267
	; -- Odd part
268
269
	movq	mm0, MMWORD [wk(0)]	; mm0=tmp6
270
	movq	mm6, MMWORD [wk(1)]	; mm6=tmp7
271
272
	pfadd	mm3,mm5			; mm3=tmp10
273
	pfadd	mm5,mm0			; mm5=tmp11
274
	pfadd	mm0,mm6			; mm0=tmp12, mm6=tmp7
275
276
	pfmul	mm5,[GOTOFF(ebx,PD_0_707)] ; mm5=z3
277
278
	movq	mm2,mm3			; mm2=tmp10
279
	pfsub	mm3,mm0
280
	pfmul	mm3,[GOTOFF(ebx,PD_0_382)] ; mm3=z5
281
	pfmul	mm2,[GOTOFF(ebx,PD_0_541)] ; mm2=MULTIPLY(tmp10,FIX_0_54119610)
282
	pfmul	mm0,[GOTOFF(ebx,PD_1_306)] ; mm0=MULTIPLY(tmp12,FIX_1_30656296)
283
	pfadd	mm2,mm3			; mm2=z2
284
	pfadd	mm0,mm3			; mm0=z4
285
286
	movq	mm7,mm6
287
	pfsub	mm6,mm5			; mm6=z13
288
	pfadd	mm7,mm5			; mm7=z11
289
290
	movq	mm4,mm6
291
	movq	mm1,mm7
292
	pfsub	mm6,mm2			; mm6=data3
293
	pfsub	mm7,mm0			; mm7=data7
294
	pfadd	mm4,mm2			; mm4=data5
295
	pfadd	mm1,mm0			; mm1=data1
296
297
	movq	MMWORD [MMBLOCK(3,0,edx,SIZEOF_FAST_FLOAT)], mm6
298
	movq	MMWORD [MMBLOCK(7,0,edx,SIZEOF_FAST_FLOAT)], mm7
299
	movq	MMWORD [MMBLOCK(5,0,edx,SIZEOF_FAST_FLOAT)], mm4
300
	movq	MMWORD [MMBLOCK(1,0,edx,SIZEOF_FAST_FLOAT)], mm1
301
302
	add	edx, byte 2*SIZEOF_FAST_FLOAT
303
	dec	ecx
304
	jnz	near .columnloop
305
306
	femms		; empty MMX/3DNow! state
307
308
;	pop	edi		; unused
309
;	pop	esi		; unused
310
;	pop	edx		; need not be preserved
311
;	pop	ecx		; need not be preserved
312
	poppic	ebx
313
	mov	esp,ebp		; esp <- aligned ebp
314
	pop	esp		; esp <- original ebp
315
	pop	ebp
316
	ret
317
318
; For some reason, the OS X linker does not honor the request to align the
319
; segment unless we do this.
320
	align	16
(-)a/jpeg/simd/jfmmxfst.asm (+397 lines)
Line     Link Here 
Line 0    Link Here 
1
;
2
; jfmmxfst.asm - fast integer FDCT (MMX)
3
;
4
; Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
5
;
6
; Based on
7
; x86 SIMD extension for IJG JPEG library
8
; Copyright (C) 1999-2006, MIYASAKA Masaru.
9
; For conditions of distribution and use, see copyright notice in jsimdext.inc
10
;
11
; This file should be assembled with NASM (Netwide Assembler),
12
; can *not* be assembled with Microsoft's MASM or any compatible
13
; assembler (including Borland's Turbo Assembler).
14
; NASM is available from http://nasm.sourceforge.net/ or
15
; http://sourceforge.net/project/showfiles.php?group_id=6208
16
;
17
; This file contains a fast, not so accurate integer implementation of
18
; the forward DCT (Discrete Cosine Transform). The following code is
19
; based directly on the IJG's original jfdctfst.c; see the jfdctfst.c
20
; for more details.
21
;
22
; [TAB8]
23
24
%include "jsimdext.inc"
25
%include "jdct.inc"
26
27
; --------------------------------------------------------------------------
28
29
%define CONST_BITS	8	; 14 is also OK.
30
31
%if CONST_BITS == 8
32
F_0_382	equ	 98		; FIX(0.382683433)
33
F_0_541	equ	139		; FIX(0.541196100)
34
F_0_707	equ	181		; FIX(0.707106781)
35
F_1_306	equ	334		; FIX(1.306562965)
36
%else
37
; NASM cannot do compile-time arithmetic on floating-point constants.
38
%define DESCALE(x,n)  (((x)+(1<<((n)-1)))>>(n))
39
F_0_382	equ	DESCALE( 410903207,30-CONST_BITS)	; FIX(0.382683433)
40
F_0_541	equ	DESCALE( 581104887,30-CONST_BITS)	; FIX(0.541196100)
41
F_0_707	equ	DESCALE( 759250124,30-CONST_BITS)	; FIX(0.707106781)
42
F_1_306	equ	DESCALE(1402911301,30-CONST_BITS)	; FIX(1.306562965)
43
%endif
44
45
; --------------------------------------------------------------------------
46
	SECTION	SEG_CONST
47
48
; PRE_MULTIPLY_SCALE_BITS <= 2 (to avoid overflow)
49
; CONST_BITS + CONST_SHIFT + PRE_MULTIPLY_SCALE_BITS == 16 (for pmulhw)
50
51
%define PRE_MULTIPLY_SCALE_BITS   2
52
%define CONST_SHIFT     (16 - PRE_MULTIPLY_SCALE_BITS - CONST_BITS)
53
54
	alignz	16
55
	global	EXTN(jconst_fdct_ifast_mmx)
56
57
EXTN(jconst_fdct_ifast_mmx):
58
59
PW_F0707	times 4 dw  F_0_707 << CONST_SHIFT
60
PW_F0382	times 4 dw  F_0_382 << CONST_SHIFT
61
PW_F0541	times 4 dw  F_0_541 << CONST_SHIFT
62
PW_F1306	times 4 dw  F_1_306 << CONST_SHIFT
63
64
	alignz	16
65
66
; --------------------------------------------------------------------------
67
	SECTION	SEG_TEXT
68
	BITS	32
69
;
70
; Perform the forward DCT on one block of samples.
71
;
72
; GLOBAL(void)
73
; jsimd_fdct_ifast_mmx (DCTELEM * data)
74
;
75
76
%define data(b)		(b)+8		; DCTELEM * data
77
78
%define original_ebp	ebp+0
79
%define wk(i)		ebp-(WK_NUM-(i))*SIZEOF_MMWORD	; mmword wk[WK_NUM]
80
%define WK_NUM		2
81
82
	align	16
83
	global	EXTN(jsimd_fdct_ifast_mmx)
84
85
EXTN(jsimd_fdct_ifast_mmx):
86
	push	ebp
87
	mov	eax,esp				; eax = original ebp
88
	sub	esp, byte 4
89
	and	esp, byte (-SIZEOF_MMWORD)	; align to 64 bits
90
	mov	[esp],eax
91
	mov	ebp,esp				; ebp = aligned ebp
92
	lea	esp, [wk(0)]
93
	pushpic	ebx
94
;	push	ecx		; need not be preserved
95
;	push	edx		; need not be preserved
96
;	push	esi		; unused
97
;	push	edi		; unused
98
99
	get_GOT	ebx		; get GOT address
100
101
	; ---- Pass 1: process rows.
102
103
	mov	edx, POINTER [data(eax)]	; (DCTELEM *)
104
	mov	ecx, DCTSIZE/4
105
	alignx	16,7
106
.rowloop:
107
108
	movq	mm0, MMWORD [MMBLOCK(2,0,edx,SIZEOF_DCTELEM)]
109
	movq	mm1, MMWORD [MMBLOCK(3,0,edx,SIZEOF_DCTELEM)]
110
	movq	mm2, MMWORD [MMBLOCK(2,1,edx,SIZEOF_DCTELEM)]
111
	movq	mm3, MMWORD [MMBLOCK(3,1,edx,SIZEOF_DCTELEM)]
112
113
	; mm0=(20 21 22 23), mm2=(24 25 26 27)
114
	; mm1=(30 31 32 33), mm3=(34 35 36 37)
115
116
	movq      mm4,mm0		; transpose coefficients(phase 1)
117
	punpcklwd mm0,mm1		; mm0=(20 30 21 31)
118
	punpckhwd mm4,mm1		; mm4=(22 32 23 33)
119
	movq      mm5,mm2		; transpose coefficients(phase 1)
120
	punpcklwd mm2,mm3		; mm2=(24 34 25 35)
121
	punpckhwd mm5,mm3		; mm5=(26 36 27 37)
122
123
	movq	mm6, MMWORD [MMBLOCK(0,0,edx,SIZEOF_DCTELEM)]
124
	movq	mm7, MMWORD [MMBLOCK(1,0,edx,SIZEOF_DCTELEM)]
125
	movq	mm1, MMWORD [MMBLOCK(0,1,edx,SIZEOF_DCTELEM)]
126
	movq	mm3, MMWORD [MMBLOCK(1,1,edx,SIZEOF_DCTELEM)]
127
128
	; mm6=(00 01 02 03), mm1=(04 05 06 07)
129
	; mm7=(10 11 12 13), mm3=(14 15 16 17)
130
131
	movq	MMWORD [wk(0)], mm4	; wk(0)=(22 32 23 33)
132
	movq	MMWORD [wk(1)], mm2	; wk(1)=(24 34 25 35)
133
134
	movq      mm4,mm6		; transpose coefficients(phase 1)
135
	punpcklwd mm6,mm7		; mm6=(00 10 01 11)
136
	punpckhwd mm4,mm7		; mm4=(02 12 03 13)
137
	movq      mm2,mm1		; transpose coefficients(phase 1)
138
	punpcklwd mm1,mm3		; mm1=(04 14 05 15)
139
	punpckhwd mm2,mm3		; mm2=(06 16 07 17)
140
141
	movq      mm7,mm6		; transpose coefficients(phase 2)
142
	punpckldq mm6,mm0		; mm6=(00 10 20 30)=data0
143
	punpckhdq mm7,mm0		; mm7=(01 11 21 31)=data1
144
	movq      mm3,mm2		; transpose coefficients(phase 2)
145
	punpckldq mm2,mm5		; mm2=(06 16 26 36)=data6
146
	punpckhdq mm3,mm5		; mm3=(07 17 27 37)=data7
147
148
	movq	mm0,mm7
149
	movq	mm5,mm6
150
	psubw	mm7,mm2			; mm7=data1-data6=tmp6
151
	psubw	mm6,mm3			; mm6=data0-data7=tmp7
152
	paddw	mm0,mm2			; mm0=data1+data6=tmp1
153
	paddw	mm5,mm3			; mm5=data0+data7=tmp0
154
155
	movq	mm2, MMWORD [wk(0)]	; mm2=(22 32 23 33)
156
	movq	mm3, MMWORD [wk(1)]	; mm3=(24 34 25 35)
157
	movq	MMWORD [wk(0)], mm7	; wk(0)=tmp6
158
	movq	MMWORD [wk(1)], mm6	; wk(1)=tmp7
159
160
	movq      mm7,mm4		; transpose coefficients(phase 2)
161
	punpckldq mm4,mm2		; mm4=(02 12 22 32)=data2
162
	punpckhdq mm7,mm2		; mm7=(03 13 23 33)=data3
163
	movq      mm6,mm1		; transpose coefficients(phase 2)
164
	punpckldq mm1,mm3		; mm1=(04 14 24 34)=data4
165
	punpckhdq mm6,mm3		; mm6=(05 15 25 35)=data5
166
167
	movq	mm2,mm7
168
	movq	mm3,mm4
169
	paddw	mm7,mm1			; mm7=data3+data4=tmp3
170
	paddw	mm4,mm6			; mm4=data2+data5=tmp2
171
	psubw	mm2,mm1			; mm2=data3-data4=tmp4
172
	psubw	mm3,mm6			; mm3=data2-data5=tmp5
173
174
	; -- Even part
175
176
	movq	mm1,mm5
177
	movq	mm6,mm0
178
	psubw	mm5,mm7			; mm5=tmp13
179
	psubw	mm0,mm4			; mm0=tmp12
180
	paddw	mm1,mm7			; mm1=tmp10
181
	paddw	mm6,mm4			; mm6=tmp11
182
183
	paddw	mm0,mm5
184
	psllw	mm0,PRE_MULTIPLY_SCALE_BITS
185
	pmulhw	mm0,[GOTOFF(ebx,PW_F0707)] ; mm0=z1
186
187
	movq	mm7,mm1
188
	movq	mm4,mm5
189
	psubw	mm1,mm6			; mm1=data4
190
	psubw	mm5,mm0			; mm5=data6
191
	paddw	mm7,mm6			; mm7=data0
192
	paddw	mm4,mm0			; mm4=data2
193
194
	movq	MMWORD [MMBLOCK(0,1,edx,SIZEOF_DCTELEM)], mm1
195
	movq	MMWORD [MMBLOCK(2,1,edx,SIZEOF_DCTELEM)], mm5
196
	movq	MMWORD [MMBLOCK(0,0,edx,SIZEOF_DCTELEM)], mm7
197
	movq	MMWORD [MMBLOCK(2,0,edx,SIZEOF_DCTELEM)], mm4
198
199
	; -- Odd part
200
201
	movq	mm6, MMWORD [wk(0)]	; mm6=tmp6
202
	movq	mm0, MMWORD [wk(1)]	; mm0=tmp7
203
204
	paddw	mm2,mm3			; mm2=tmp10
205
	paddw	mm3,mm6			; mm3=tmp11
206
	paddw	mm6,mm0			; mm6=tmp12, mm0=tmp7
207
208
	psllw	mm2,PRE_MULTIPLY_SCALE_BITS
209
	psllw	mm6,PRE_MULTIPLY_SCALE_BITS
210
211
	psllw	mm3,PRE_MULTIPLY_SCALE_BITS
212
	pmulhw	mm3,[GOTOFF(ebx,PW_F0707)] ; mm3=z3
213
214
	movq	mm1,mm2			; mm1=tmp10
215
	psubw	mm2,mm6
216
	pmulhw	mm2,[GOTOFF(ebx,PW_F0382)] ; mm2=z5
217
	pmulhw	mm1,[GOTOFF(ebx,PW_F0541)] ; mm1=MULTIPLY(tmp10,FIX_0_54119610)
218
	pmulhw	mm6,[GOTOFF(ebx,PW_F1306)] ; mm6=MULTIPLY(tmp12,FIX_1_30656296)
219
	paddw	mm1,mm2			; mm1=z2
220
	paddw	mm6,mm2			; mm6=z4
221
222
	movq	mm5,mm0
223
	psubw	mm0,mm3			; mm0=z13
224
	paddw	mm5,mm3			; mm5=z11
225
226
	movq	mm7,mm0
227
	movq	mm4,mm5
228
	psubw	mm0,mm1			; mm0=data3
229
	psubw	mm5,mm6			; mm5=data7
230
	paddw	mm7,mm1			; mm7=data5
231
	paddw	mm4,mm6			; mm4=data1
232
233
	movq	MMWORD [MMBLOCK(3,0,edx,SIZEOF_DCTELEM)], mm0
234
	movq	MMWORD [MMBLOCK(3,1,edx,SIZEOF_DCTELEM)], mm5
235
	movq	MMWORD [MMBLOCK(1,1,edx,SIZEOF_DCTELEM)], mm7
236
	movq	MMWORD [MMBLOCK(1,0,edx,SIZEOF_DCTELEM)], mm4
237
238
	add	edx, byte 4*DCTSIZE*SIZEOF_DCTELEM
239
	dec	ecx
240
	jnz	near .rowloop
241
242
	; ---- Pass 2: process columns.
243
244
	mov	edx, POINTER [data(eax)]	; (DCTELEM *)
245
	mov	ecx, DCTSIZE/4
246
	alignx	16,7
247
.columnloop:
248
249
	movq	mm0, MMWORD [MMBLOCK(2,0,edx,SIZEOF_DCTELEM)]
250
	movq	mm1, MMWORD [MMBLOCK(3,0,edx,SIZEOF_DCTELEM)]
251
	movq	mm2, MMWORD [MMBLOCK(6,0,edx,SIZEOF_DCTELEM)]
252
	movq	mm3, MMWORD [MMBLOCK(7,0,edx,SIZEOF_DCTELEM)]
253
254
	; mm0=(02 12 22 32), mm2=(42 52 62 72)
255
	; mm1=(03 13 23 33), mm3=(43 53 63 73)
256
257
	movq      mm4,mm0		; transpose coefficients(phase 1)
258
	punpcklwd mm0,mm1		; mm0=(02 03 12 13)
259
	punpckhwd mm4,mm1		; mm4=(22 23 32 33)
260
	movq      mm5,mm2		; transpose coefficients(phase 1)
261
	punpcklwd mm2,mm3		; mm2=(42 43 52 53)
262
	punpckhwd mm5,mm3		; mm5=(62 63 72 73)
263
264
	movq	mm6, MMWORD [MMBLOCK(0,0,edx,SIZEOF_DCTELEM)]
265
	movq	mm7, MMWORD [MMBLOCK(1,0,edx,SIZEOF_DCTELEM)]
266
	movq	mm1, MMWORD [MMBLOCK(4,0,edx,SIZEOF_DCTELEM)]
267
	movq	mm3, MMWORD [MMBLOCK(5,0,edx,SIZEOF_DCTELEM)]
268
269
	; mm6=(00 10 20 30), mm1=(40 50 60 70)
270
	; mm7=(01 11 21 31), mm3=(41 51 61 71)
271
272
	movq	MMWORD [wk(0)], mm4	; wk(0)=(22 23 32 33)
273
	movq	MMWORD [wk(1)], mm2	; wk(1)=(42 43 52 53)
274
275
	movq      mm4,mm6		; transpose coefficients(phase 1)
276
	punpcklwd mm6,mm7		; mm6=(00 01 10 11)
277
	punpckhwd mm4,mm7		; mm4=(20 21 30 31)
278
	movq      mm2,mm1		; transpose coefficients(phase 1)
279
	punpcklwd mm1,mm3		; mm1=(40 41 50 51)
280
	punpckhwd mm2,mm3		; mm2=(60 61 70 71)
281
282
	movq      mm7,mm6		; transpose coefficients(phase 2)
283
	punpckldq mm6,mm0		; mm6=(00 01 02 03)=data0
284
	punpckhdq mm7,mm0		; mm7=(10 11 12 13)=data1
285
	movq      mm3,mm2		; transpose coefficients(phase 2)
286
	punpckldq mm2,mm5		; mm2=(60 61 62 63)=data6
287
	punpckhdq mm3,mm5		; mm3=(70 71 72 73)=data7
288
289
	movq	mm0,mm7
290
	movq	mm5,mm6
291
	psubw	mm7,mm2			; mm7=data1-data6=tmp6
292
	psubw	mm6,mm3			; mm6=data0-data7=tmp7
293
	paddw	mm0,mm2			; mm0=data1+data6=tmp1
294
	paddw	mm5,mm3			; mm5=data0+data7=tmp0
295
296
	movq	mm2, MMWORD [wk(0)]	; mm2=(22 23 32 33)
297
	movq	mm3, MMWORD [wk(1)]	; mm3=(42 43 52 53)
298
	movq	MMWORD [wk(0)], mm7	; wk(0)=tmp6
299
	movq	MMWORD [wk(1)], mm6	; wk(1)=tmp7
300
301
	movq      mm7,mm4		; transpose coefficients(phase 2)
302
	punpckldq mm4,mm2		; mm4=(20 21 22 23)=data2
303
	punpckhdq mm7,mm2		; mm7=(30 31 32 33)=data3
304
	movq      mm6,mm1		; transpose coefficients(phase 2)
305
	punpckldq mm1,mm3		; mm1=(40 41 42 43)=data4
306
	punpckhdq mm6,mm3		; mm6=(50 51 52 53)=data5
307
308
	movq	mm2,mm7
309
	movq	mm3,mm4
310
	paddw	mm7,mm1			; mm7=data3+data4=tmp3
311
	paddw	mm4,mm6			; mm4=data2+data5=tmp2
312
	psubw	mm2,mm1			; mm2=data3-data4=tmp4
313
	psubw	mm3,mm6			; mm3=data2-data5=tmp5
314
315
	; -- Even part
316
317
	movq	mm1,mm5
318
	movq	mm6,mm0
319
	psubw	mm5,mm7			; mm5=tmp13
320
	psubw	mm0,mm4			; mm0=tmp12
321
	paddw	mm1,mm7			; mm1=tmp10
322
	paddw	mm6,mm4			; mm6=tmp11
323
324
	paddw	mm0,mm5
325
	psllw	mm0,PRE_MULTIPLY_SCALE_BITS
326
	pmulhw	mm0,[GOTOFF(ebx,PW_F0707)] ; mm0=z1
327
328
	movq	mm7,mm1
329
	movq	mm4,mm5
330
	psubw	mm1,mm6			; mm1=data4
331
	psubw	mm5,mm0			; mm5=data6
332
	paddw	mm7,mm6			; mm7=data0
333
	paddw	mm4,mm0			; mm4=data2
334
335
	movq	MMWORD [MMBLOCK(4,0,edx,SIZEOF_DCTELEM)], mm1
336
	movq	MMWORD [MMBLOCK(6,0,edx,SIZEOF_DCTELEM)], mm5
337
	movq	MMWORD [MMBLOCK(0,0,edx,SIZEOF_DCTELEM)], mm7
338
	movq	MMWORD [MMBLOCK(2,0,edx,SIZEOF_DCTELEM)], mm4
339
340
	; -- Odd part
341
342
	movq	mm6, MMWORD [wk(0)]	; mm6=tmp6
343
	movq	mm0, MMWORD [wk(1)]	; mm0=tmp7
344
345
	paddw	mm2,mm3			; mm2=tmp10
346
	paddw	mm3,mm6			; mm3=tmp11
347
	paddw	mm6,mm0			; mm6=tmp12, mm0=tmp7
348
349
	psllw	mm2,PRE_MULTIPLY_SCALE_BITS
350
	psllw	mm6,PRE_MULTIPLY_SCALE_BITS
351
352
	psllw	mm3,PRE_MULTIPLY_SCALE_BITS
353
	pmulhw	mm3,[GOTOFF(ebx,PW_F0707)] ; mm3=z3
354
355
	movq	mm1,mm2			; mm1=tmp10
356
	psubw	mm2,mm6
357
	pmulhw	mm2,[GOTOFF(ebx,PW_F0382)] ; mm2=z5
358
	pmulhw	mm1,[GOTOFF(ebx,PW_F0541)] ; mm1=MULTIPLY(tmp10,FIX_0_54119610)
359
	pmulhw	mm6,[GOTOFF(ebx,PW_F1306)] ; mm6=MULTIPLY(tmp12,FIX_1_30656296)
360
	paddw	mm1,mm2			; mm1=z2
361
	paddw	mm6,mm2			; mm6=z4
362
363
	movq	mm5,mm0
364
	psubw	mm0,mm3			; mm0=z13
365
	paddw	mm5,mm3			; mm5=z11
366
367
	movq	mm7,mm0
368
	movq	mm4,mm5
369
	psubw	mm0,mm1			; mm0=data3
370
	psubw	mm5,mm6			; mm5=data7
371
	paddw	mm7,mm1			; mm7=data5
372
	paddw	mm4,mm6			; mm4=data1
373
374
	movq	MMWORD [MMBLOCK(3,0,edx,SIZEOF_DCTELEM)], mm0
375
	movq	MMWORD [MMBLOCK(7,0,edx,SIZEOF_DCTELEM)], mm5
376
	movq	MMWORD [MMBLOCK(5,0,edx,SIZEOF_DCTELEM)], mm7
377
	movq	MMWORD [MMBLOCK(1,0,edx,SIZEOF_DCTELEM)], mm4
378
379
	add	edx, byte 4*SIZEOF_DCTELEM
380
	dec	ecx
381
	jnz	near .columnloop
382
383
	emms		; empty MMX state
384
385
;	pop	edi		; unused
386
;	pop	esi		; unused
387
;	pop	edx		; need not be preserved
388
;	pop	ecx		; need not be preserved
389
	poppic	ebx
390
	mov	esp,ebp		; esp <- aligned ebp
391
	pop	esp		; esp <- original ebp
392
	pop	ebp
393
	ret
394
395
; For some reason, the OS X linker does not honor the request to align the
396
; segment unless we do this.
397
	align	16
(-)a/jpeg/simd/jfmmxint.asm (+622 lines)
Line     Link Here 
Line 0    Link Here 
1
;
2
; jfmmxint.asm - accurate integer FDCT (MMX)
3
;
4
; Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
5
;
6
; Based on
7
; x86 SIMD extension for IJG JPEG library
8
; Copyright (C) 1999-2006, MIYASAKA Masaru.
9
; For conditions of distribution and use, see copyright notice in jsimdext.inc
10
;
11
; This file should be assembled with NASM (Netwide Assembler),
12
; can *not* be assembled with Microsoft's MASM or any compatible
13
; assembler (including Borland's Turbo Assembler).
14
; NASM is available from http://nasm.sourceforge.net/ or
15
; http://sourceforge.net/project/showfiles.php?group_id=6208
16
;
17
; This file contains a slow-but-accurate integer implementation of the
18
; forward DCT (Discrete Cosine Transform). The following code is based
19
; directly on the IJG's original jfdctint.c; see the jfdctint.c for
20
; more details.
21
;
22
; [TAB8]
23
24
%include "jsimdext.inc"
25
%include "jdct.inc"
26
27
; --------------------------------------------------------------------------
28
29
%define CONST_BITS	13
30
%define PASS1_BITS	2
31
32
%define DESCALE_P1	(CONST_BITS-PASS1_BITS)
33
%define DESCALE_P2	(CONST_BITS+PASS1_BITS)
34
35
%if CONST_BITS == 13
36
F_0_298	equ	 2446		; FIX(0.298631336)
37
F_0_390	equ	 3196		; FIX(0.390180644)
38
F_0_541	equ	 4433		; FIX(0.541196100)
39
F_0_765	equ	 6270		; FIX(0.765366865)
40
F_0_899	equ	 7373		; FIX(0.899976223)
41
F_1_175	equ	 9633		; FIX(1.175875602)
42
F_1_501	equ	12299		; FIX(1.501321110)
43
F_1_847	equ	15137		; FIX(1.847759065)
44
F_1_961	equ	16069		; FIX(1.961570560)
45
F_2_053	equ	16819		; FIX(2.053119869)
46
F_2_562	equ	20995		; FIX(2.562915447)
47
F_3_072	equ	25172		; FIX(3.072711026)
48
%else
49
; NASM cannot do compile-time arithmetic on floating-point constants.
50
%define DESCALE(x,n)  (((x)+(1<<((n)-1)))>>(n))
51
F_0_298	equ	DESCALE( 320652955,30-CONST_BITS)	; FIX(0.298631336)
52
F_0_390	equ	DESCALE( 418953276,30-CONST_BITS)	; FIX(0.390180644)
53
F_0_541	equ	DESCALE( 581104887,30-CONST_BITS)	; FIX(0.541196100)
54
F_0_765	equ	DESCALE( 821806413,30-CONST_BITS)	; FIX(0.765366865)
55
F_0_899	equ	DESCALE( 966342111,30-CONST_BITS)	; FIX(0.899976223)
56
F_1_175	equ	DESCALE(1262586813,30-CONST_BITS)	; FIX(1.175875602)
57
F_1_501	equ	DESCALE(1612031267,30-CONST_BITS)	; FIX(1.501321110)
58
F_1_847	equ	DESCALE(1984016188,30-CONST_BITS)	; FIX(1.847759065)
59
F_1_961	equ	DESCALE(2106220350,30-CONST_BITS)	; FIX(1.961570560)
60
F_2_053	equ	DESCALE(2204520673,30-CONST_BITS)	; FIX(2.053119869)
61
F_2_562	equ	DESCALE(2751909506,30-CONST_BITS)	; FIX(2.562915447)
62
F_3_072	equ	DESCALE(3299298341,30-CONST_BITS)	; FIX(3.072711026)
63
%endif
64
65
; --------------------------------------------------------------------------
66
	SECTION	SEG_CONST
67
68
	alignz	16
69
	global	EXTN(jconst_fdct_islow_mmx)
70
71
EXTN(jconst_fdct_islow_mmx):
72
73
PW_F130_F054	times 2 dw  (F_0_541+F_0_765), F_0_541
74
PW_F054_MF130	times 2 dw  F_0_541, (F_0_541-F_1_847)
75
PW_MF078_F117	times 2 dw  (F_1_175-F_1_961), F_1_175
76
PW_F117_F078	times 2 dw  F_1_175, (F_1_175-F_0_390)
77
PW_MF060_MF089	times 2 dw  (F_0_298-F_0_899),-F_0_899
78
PW_MF089_F060	times 2 dw -F_0_899, (F_1_501-F_0_899)
79
PW_MF050_MF256	times 2 dw  (F_2_053-F_2_562),-F_2_562
80
PW_MF256_F050	times 2 dw -F_2_562, (F_3_072-F_2_562)
81
PD_DESCALE_P1	times 2 dd  1 << (DESCALE_P1-1)
82
PD_DESCALE_P2	times 2 dd  1 << (DESCALE_P2-1)
83
PW_DESCALE_P2X	times 4 dw  1 << (PASS1_BITS-1)
84
85
	alignz	16
86
87
; --------------------------------------------------------------------------
88
	SECTION	SEG_TEXT
89
	BITS	32
90
;
91
; Perform the forward DCT on one block of samples.
92
;
93
; GLOBAL(void)
94
; jsimd_fdct_islow_mmx (DCTELEM * data)
95
;
96
97
%define data(b)		(b)+8		; DCTELEM * data
98
99
%define original_ebp	ebp+0
100
%define wk(i)		ebp-(WK_NUM-(i))*SIZEOF_MMWORD	; mmword wk[WK_NUM]
101
%define WK_NUM		2
102
103
	align	16
104
	global	EXTN(jsimd_fdct_islow_mmx)
105
106
EXTN(jsimd_fdct_islow_mmx):
107
	push	ebp
108
	mov	eax,esp				; eax = original ebp
109
	sub	esp, byte 4
110
	and	esp, byte (-SIZEOF_MMWORD)	; align to 64 bits
111
	mov	[esp],eax
112
	mov	ebp,esp				; ebp = aligned ebp
113
	lea	esp, [wk(0)]
114
	pushpic	ebx
115
;	push	ecx		; need not be preserved
116
;	push	edx		; need not be preserved
117
;	push	esi		; unused
118
;	push	edi		; unused
119
120
	get_GOT	ebx		; get GOT address
121
122
	; ---- Pass 1: process rows.
123
124
	mov	edx, POINTER [data(eax)]	; (DCTELEM *)
125
	mov	ecx, DCTSIZE/4
126
	alignx	16,7
127
.rowloop:
128
129
	movq	mm0, MMWORD [MMBLOCK(2,0,edx,SIZEOF_DCTELEM)]
130
	movq	mm1, MMWORD [MMBLOCK(3,0,edx,SIZEOF_DCTELEM)]
131
	movq	mm2, MMWORD [MMBLOCK(2,1,edx,SIZEOF_DCTELEM)]
132
	movq	mm3, MMWORD [MMBLOCK(3,1,edx,SIZEOF_DCTELEM)]
133
134
	; mm0=(20 21 22 23), mm2=(24 25 26 27)
135
	; mm1=(30 31 32 33), mm3=(34 35 36 37)
136
137
	movq      mm4,mm0		; transpose coefficients(phase 1)
138
	punpcklwd mm0,mm1		; mm0=(20 30 21 31)
139
	punpckhwd mm4,mm1		; mm4=(22 32 23 33)
140
	movq      mm5,mm2		; transpose coefficients(phase 1)
141
	punpcklwd mm2,mm3		; mm2=(24 34 25 35)
142
	punpckhwd mm5,mm3		; mm5=(26 36 27 37)
143
144
	movq	mm6, MMWORD [MMBLOCK(0,0,edx,SIZEOF_DCTELEM)]
145
	movq	mm7, MMWORD [MMBLOCK(1,0,edx,SIZEOF_DCTELEM)]
146
	movq	mm1, MMWORD [MMBLOCK(0,1,edx,SIZEOF_DCTELEM)]
147
	movq	mm3, MMWORD [MMBLOCK(1,1,edx,SIZEOF_DCTELEM)]
148
149
	; mm6=(00 01 02 03), mm1=(04 05 06 07)
150
	; mm7=(10 11 12 13), mm3=(14 15 16 17)
151
152
	movq	MMWORD [wk(0)], mm4	; wk(0)=(22 32 23 33)
153
	movq	MMWORD [wk(1)], mm2	; wk(1)=(24 34 25 35)
154
155
	movq      mm4,mm6		; transpose coefficients(phase 1)
156
	punpcklwd mm6,mm7		; mm6=(00 10 01 11)
157
	punpckhwd mm4,mm7		; mm4=(02 12 03 13)
158
	movq      mm2,mm1		; transpose coefficients(phase 1)
159
	punpcklwd mm1,mm3		; mm1=(04 14 05 15)
160
	punpckhwd mm2,mm3		; mm2=(06 16 07 17)
161
162
	movq      mm7,mm6		; transpose coefficients(phase 2)
163
	punpckldq mm6,mm0		; mm6=(00 10 20 30)=data0
164
	punpckhdq mm7,mm0		; mm7=(01 11 21 31)=data1
165
	movq      mm3,mm2		; transpose coefficients(phase 2)
166
	punpckldq mm2,mm5		; mm2=(06 16 26 36)=data6
167
	punpckhdq mm3,mm5		; mm3=(07 17 27 37)=data7
168
169
	movq	mm0,mm7
170
	movq	mm5,mm6
171
	psubw	mm7,mm2			; mm7=data1-data6=tmp6
172
	psubw	mm6,mm3			; mm6=data0-data7=tmp7
173
	paddw	mm0,mm2			; mm0=data1+data6=tmp1
174
	paddw	mm5,mm3			; mm5=data0+data7=tmp0
175
176
	movq	mm2, MMWORD [wk(0)]	; mm2=(22 32 23 33)
177
	movq	mm3, MMWORD [wk(1)]	; mm3=(24 34 25 35)
178
	movq	MMWORD [wk(0)], mm7	; wk(0)=tmp6
179
	movq	MMWORD [wk(1)], mm6	; wk(1)=tmp7
180
181
	movq      mm7,mm4		; transpose coefficients(phase 2)
182
	punpckldq mm4,mm2		; mm4=(02 12 22 32)=data2
183
	punpckhdq mm7,mm2		; mm7=(03 13 23 33)=data3
184
	movq      mm6,mm1		; transpose coefficients(phase 2)
185
	punpckldq mm1,mm3		; mm1=(04 14 24 34)=data4
186
	punpckhdq mm6,mm3		; mm6=(05 15 25 35)=data5
187
188
	movq	mm2,mm7
189
	movq	mm3,mm4
190
	paddw	mm7,mm1			; mm7=data3+data4=tmp3
191
	paddw	mm4,mm6			; mm4=data2+data5=tmp2
192
	psubw	mm2,mm1			; mm2=data3-data4=tmp4
193
	psubw	mm3,mm6			; mm3=data2-data5=tmp5
194
195
	; -- Even part
196
197
	movq	mm1,mm5
198
	movq	mm6,mm0
199
	paddw	mm5,mm7			; mm5=tmp10
200
	paddw	mm0,mm4			; mm0=tmp11
201
	psubw	mm1,mm7			; mm1=tmp13
202
	psubw	mm6,mm4			; mm6=tmp12
203
204
	movq	mm7,mm5
205
	paddw	mm5,mm0			; mm5=tmp10+tmp11
206
	psubw	mm7,mm0			; mm7=tmp10-tmp11
207
208
	psllw	mm5,PASS1_BITS		; mm5=data0
209
	psllw	mm7,PASS1_BITS		; mm7=data4
210
211
	movq	MMWORD [MMBLOCK(0,0,edx,SIZEOF_DCTELEM)], mm5
212
	movq	MMWORD [MMBLOCK(0,1,edx,SIZEOF_DCTELEM)], mm7
213
214
	; (Original)
215
	; z1 = (tmp12 + tmp13) * 0.541196100;
216
	; data2 = z1 + tmp13 * 0.765366865;
217
	; data6 = z1 + tmp12 * -1.847759065;
218
	;
219
	; (This implementation)
220
	; data2 = tmp13 * (0.541196100 + 0.765366865) + tmp12 * 0.541196100;
221
	; data6 = tmp13 * 0.541196100 + tmp12 * (0.541196100 - 1.847759065);
222
223
	movq      mm4,mm1		; mm1=tmp13
224
	movq      mm0,mm1
225
	punpcklwd mm4,mm6		; mm6=tmp12
226
	punpckhwd mm0,mm6
227
	movq      mm1,mm4
228
	movq      mm6,mm0
229
	pmaddwd   mm4,[GOTOFF(ebx,PW_F130_F054)]	; mm4=data2L
230
	pmaddwd   mm0,[GOTOFF(ebx,PW_F130_F054)]	; mm0=data2H
231
	pmaddwd   mm1,[GOTOFF(ebx,PW_F054_MF130)]	; mm1=data6L
232
	pmaddwd   mm6,[GOTOFF(ebx,PW_F054_MF130)]	; mm6=data6H
233
234
	paddd	mm4,[GOTOFF(ebx,PD_DESCALE_P1)]
235
	paddd	mm0,[GOTOFF(ebx,PD_DESCALE_P1)]
236
	psrad	mm4,DESCALE_P1
237
	psrad	mm0,DESCALE_P1
238
	paddd	mm1,[GOTOFF(ebx,PD_DESCALE_P1)]
239
	paddd	mm6,[GOTOFF(ebx,PD_DESCALE_P1)]
240
	psrad	mm1,DESCALE_P1
241
	psrad	mm6,DESCALE_P1
242
243
	packssdw  mm4,mm0		; mm4=data2
244
	packssdw  mm1,mm6		; mm1=data6
245
246
	movq	MMWORD [MMBLOCK(2,0,edx,SIZEOF_DCTELEM)], mm4
247
	movq	MMWORD [MMBLOCK(2,1,edx,SIZEOF_DCTELEM)], mm1
248
249
	; -- Odd part
250
251
	movq	mm5, MMWORD [wk(0)]	; mm5=tmp6
252
	movq	mm7, MMWORD [wk(1)]	; mm7=tmp7
253
254
	movq	mm0,mm2			; mm2=tmp4
255
	movq	mm6,mm3			; mm3=tmp5
256
	paddw	mm0,mm5			; mm0=z3
257
	paddw	mm6,mm7			; mm6=z4
258
259
	; (Original)
260
	; z5 = (z3 + z4) * 1.175875602;
261
	; z3 = z3 * -1.961570560;  z4 = z4 * -0.390180644;
262
	; z3 += z5;  z4 += z5;
263
	;
264
	; (This implementation)
265
	; z3 = z3 * (1.175875602 - 1.961570560) + z4 * 1.175875602;
266
	; z4 = z3 * 1.175875602 + z4 * (1.175875602 - 0.390180644);
267
268
	movq      mm4,mm0
269
	movq      mm1,mm0
270
	punpcklwd mm4,mm6
271
	punpckhwd mm1,mm6
272
	movq      mm0,mm4
273
	movq      mm6,mm1
274
	pmaddwd   mm4,[GOTOFF(ebx,PW_MF078_F117)]	; mm4=z3L
275
	pmaddwd   mm1,[GOTOFF(ebx,PW_MF078_F117)]	; mm1=z3H
276
	pmaddwd   mm0,[GOTOFF(ebx,PW_F117_F078)]	; mm0=z4L
277
	pmaddwd   mm6,[GOTOFF(ebx,PW_F117_F078)]	; mm6=z4H
278
279
	movq	MMWORD [wk(0)], mm4	; wk(0)=z3L
280
	movq	MMWORD [wk(1)], mm1	; wk(1)=z3H
281
282
	; (Original)
283
	; z1 = tmp4 + tmp7;  z2 = tmp5 + tmp6;
284
	; tmp4 = tmp4 * 0.298631336;  tmp5 = tmp5 * 2.053119869;
285
	; tmp6 = tmp6 * 3.072711026;  tmp7 = tmp7 * 1.501321110;
286
	; z1 = z1 * -0.899976223;  z2 = z2 * -2.562915447;
287
	; data7 = tmp4 + z1 + z3;  data5 = tmp5 + z2 + z4;
288
	; data3 = tmp6 + z2 + z3;  data1 = tmp7 + z1 + z4;
289
	;
290
	; (This implementation)
291
	; tmp4 = tmp4 * (0.298631336 - 0.899976223) + tmp7 * -0.899976223;
292
	; tmp5 = tmp5 * (2.053119869 - 2.562915447) + tmp6 * -2.562915447;
293
	; tmp6 = tmp5 * -2.562915447 + tmp6 * (3.072711026 - 2.562915447);
294
	; tmp7 = tmp4 * -0.899976223 + tmp7 * (1.501321110 - 0.899976223);
295
	; data7 = tmp4 + z3;  data5 = tmp5 + z4;
296
	; data3 = tmp6 + z3;  data1 = tmp7 + z4;
297
298
	movq      mm4,mm2
299
	movq      mm1,mm2
300
	punpcklwd mm4,mm7
301
	punpckhwd mm1,mm7
302
	movq      mm2,mm4
303
	movq      mm7,mm1
304
	pmaddwd   mm4,[GOTOFF(ebx,PW_MF060_MF089)]	; mm4=tmp4L
305
	pmaddwd   mm1,[GOTOFF(ebx,PW_MF060_MF089)]	; mm1=tmp4H
306
	pmaddwd   mm2,[GOTOFF(ebx,PW_MF089_F060)]	; mm2=tmp7L
307
	pmaddwd   mm7,[GOTOFF(ebx,PW_MF089_F060)]	; mm7=tmp7H
308
309
	paddd	mm4, MMWORD [wk(0)]	; mm4=data7L
310
	paddd	mm1, MMWORD [wk(1)]	; mm1=data7H
311
	paddd	mm2,mm0			; mm2=data1L
312
	paddd	mm7,mm6			; mm7=data1H
313
314
	paddd	mm4,[GOTOFF(ebx,PD_DESCALE_P1)]
315
	paddd	mm1,[GOTOFF(ebx,PD_DESCALE_P1)]
316
	psrad	mm4,DESCALE_P1
317
	psrad	mm1,DESCALE_P1
318
	paddd	mm2,[GOTOFF(ebx,PD_DESCALE_P1)]
319
	paddd	mm7,[GOTOFF(ebx,PD_DESCALE_P1)]
320
	psrad	mm2,DESCALE_P1
321
	psrad	mm7,DESCALE_P1
322
323
	packssdw  mm4,mm1		; mm4=data7
324
	packssdw  mm2,mm7		; mm2=data1
325
326
	movq	MMWORD [MMBLOCK(3,1,edx,SIZEOF_DCTELEM)], mm4
327
	movq	MMWORD [MMBLOCK(1,0,edx,SIZEOF_DCTELEM)], mm2
328
329
	movq      mm1,mm3
330
	movq      mm7,mm3
331
	punpcklwd mm1,mm5
332
	punpckhwd mm7,mm5
333
	movq      mm3,mm1
334
	movq      mm5,mm7
335
	pmaddwd   mm1,[GOTOFF(ebx,PW_MF050_MF256)]	; mm1=tmp5L
336
	pmaddwd   mm7,[GOTOFF(ebx,PW_MF050_MF256)]	; mm7=tmp5H
337
	pmaddwd   mm3,[GOTOFF(ebx,PW_MF256_F050)]	; mm3=tmp6L
338
	pmaddwd   mm5,[GOTOFF(ebx,PW_MF256_F050)]	; mm5=tmp6H
339
340
	paddd	mm1,mm0			; mm1=data5L
341
	paddd	mm7,mm6			; mm7=data5H
342
	paddd	mm3, MMWORD [wk(0)]	; mm3=data3L
343
	paddd	mm5, MMWORD [wk(1)]	; mm5=data3H
344
345
	paddd	mm1,[GOTOFF(ebx,PD_DESCALE_P1)]
346
	paddd	mm7,[GOTOFF(ebx,PD_DESCALE_P1)]
347
	psrad	mm1,DESCALE_P1
348
	psrad	mm7,DESCALE_P1
349
	paddd	mm3,[GOTOFF(ebx,PD_DESCALE_P1)]
350
	paddd	mm5,[GOTOFF(ebx,PD_DESCALE_P1)]
351
	psrad	mm3,DESCALE_P1
352
	psrad	mm5,DESCALE_P1
353
354
	packssdw  mm1,mm7		; mm1=data5
355
	packssdw  mm3,mm5		; mm3=data3
356
357
	movq	MMWORD [MMBLOCK(1,1,edx,SIZEOF_DCTELEM)], mm1
358
	movq	MMWORD [MMBLOCK(3,0,edx,SIZEOF_DCTELEM)], mm3
359
360
	add	edx, byte 4*DCTSIZE*SIZEOF_DCTELEM
361
	dec	ecx
362
	jnz	near .rowloop
363
364
	; ---- Pass 2: process columns.
365
366
	mov	edx, POINTER [data(eax)]	; (DCTELEM *)
367
	mov	ecx, DCTSIZE/4
368
	alignx	16,7
369
.columnloop:
370
371
	movq	mm0, MMWORD [MMBLOCK(2,0,edx,SIZEOF_DCTELEM)]
372
	movq	mm1, MMWORD [MMBLOCK(3,0,edx,SIZEOF_DCTELEM)]
373
	movq	mm2, MMWORD [MMBLOCK(6,0,edx,SIZEOF_DCTELEM)]
374
	movq	mm3, MMWORD [MMBLOCK(7,0,edx,SIZEOF_DCTELEM)]
375
376
	; mm0=(02 12 22 32), mm2=(42 52 62 72)
377
	; mm1=(03 13 23 33), mm3=(43 53 63 73)
378
379
	movq      mm4,mm0		; transpose coefficients(phase 1)
380
	punpcklwd mm0,mm1		; mm0=(02 03 12 13)
381
	punpckhwd mm4,mm1		; mm4=(22 23 32 33)
382
	movq      mm5,mm2		; transpose coefficients(phase 1)
383
	punpcklwd mm2,mm3		; mm2=(42 43 52 53)
384
	punpckhwd mm5,mm3		; mm5=(62 63 72 73)
385
386
	movq	mm6, MMWORD [MMBLOCK(0,0,edx,SIZEOF_DCTELEM)]
387
	movq	mm7, MMWORD [MMBLOCK(1,0,edx,SIZEOF_DCTELEM)]
388
	movq	mm1, MMWORD [MMBLOCK(4,0,edx,SIZEOF_DCTELEM)]
389
	movq	mm3, MMWORD [MMBLOCK(5,0,edx,SIZEOF_DCTELEM)]
390
391
	; mm6=(00 10 20 30), mm1=(40 50 60 70)
392
	; mm7=(01 11 21 31), mm3=(41 51 61 71)
393
394
	movq	MMWORD [wk(0)], mm4	; wk(0)=(22 23 32 33)
395
	movq	MMWORD [wk(1)], mm2	; wk(1)=(42 43 52 53)
396
397
	movq      mm4,mm6		; transpose coefficients(phase 1)
398
	punpcklwd mm6,mm7		; mm6=(00 01 10 11)
399
	punpckhwd mm4,mm7		; mm4=(20 21 30 31)
400
	movq      mm2,mm1		; transpose coefficients(phase 1)
401
	punpcklwd mm1,mm3		; mm1=(40 41 50 51)
402
	punpckhwd mm2,mm3		; mm2=(60 61 70 71)
403
404
	movq      mm7,mm6		; transpose coefficients(phase 2)
405
	punpckldq mm6,mm0		; mm6=(00 01 02 03)=data0
406
	punpckhdq mm7,mm0		; mm7=(10 11 12 13)=data1
407
	movq      mm3,mm2		; transpose coefficients(phase 2)
408
	punpckldq mm2,mm5		; mm2=(60 61 62 63)=data6
409
	punpckhdq mm3,mm5		; mm3=(70 71 72 73)=data7
410
411
	movq	mm0,mm7
412
	movq	mm5,mm6
413
	psubw	mm7,mm2			; mm7=data1-data6=tmp6
414
	psubw	mm6,mm3			; mm6=data0-data7=tmp7
415
	paddw	mm0,mm2			; mm0=data1+data6=tmp1
416
	paddw	mm5,mm3			; mm5=data0+data7=tmp0
417
418
	movq	mm2, MMWORD [wk(0)]	; mm2=(22 23 32 33)
419
	movq	mm3, MMWORD [wk(1)]	; mm3=(42 43 52 53)
420
	movq	MMWORD [wk(0)], mm7	; wk(0)=tmp6
421
	movq	MMWORD [wk(1)], mm6	; wk(1)=tmp7
422
423
	movq      mm7,mm4		; transpose coefficients(phase 2)
424
	punpckldq mm4,mm2		; mm4=(20 21 22 23)=data2
425
	punpckhdq mm7,mm2		; mm7=(30 31 32 33)=data3
426
	movq      mm6,mm1		; transpose coefficients(phase 2)
427
	punpckldq mm1,mm3		; mm1=(40 41 42 43)=data4
428
	punpckhdq mm6,mm3		; mm6=(50 51 52 53)=data5
429
430
	movq	mm2,mm7
431
	movq	mm3,mm4
432
	paddw	mm7,mm1			; mm7=data3+data4=tmp3
433
	paddw	mm4,mm6			; mm4=data2+data5=tmp2
434
	psubw	mm2,mm1			; mm2=data3-data4=tmp4
435
	psubw	mm3,mm6			; mm3=data2-data5=tmp5
436
437
	; -- Even part
438
439
	movq	mm1,mm5
440
	movq	mm6,mm0
441
	paddw	mm5,mm7			; mm5=tmp10
442
	paddw	mm0,mm4			; mm0=tmp11
443
	psubw	mm1,mm7			; mm1=tmp13
444
	psubw	mm6,mm4			; mm6=tmp12
445
446
	movq	mm7,mm5
447
	paddw	mm5,mm0			; mm5=tmp10+tmp11
448
	psubw	mm7,mm0			; mm7=tmp10-tmp11
449
450
	paddw	mm5,[GOTOFF(ebx,PW_DESCALE_P2X)]
451
	paddw	mm7,[GOTOFF(ebx,PW_DESCALE_P2X)]
452
	psraw	mm5,PASS1_BITS		; mm5=data0
453
	psraw	mm7,PASS1_BITS		; mm7=data4
454
455
	movq	MMWORD [MMBLOCK(0,0,edx,SIZEOF_DCTELEM)], mm5
456
	movq	MMWORD [MMBLOCK(4,0,edx,SIZEOF_DCTELEM)], mm7
457
458
	; (Original)
459
	; z1 = (tmp12 + tmp13) * 0.541196100;
460
	; data2 = z1 + tmp13 * 0.765366865;
461
	; data6 = z1 + tmp12 * -1.847759065;
462
	;
463
	; (This implementation)
464
	; data2 = tmp13 * (0.541196100 + 0.765366865) + tmp12 * 0.541196100;
465
	; data6 = tmp13 * 0.541196100 + tmp12 * (0.541196100 - 1.847759065);
466
467
	movq      mm4,mm1		; mm1=tmp13
468
	movq      mm0,mm1
469
	punpcklwd mm4,mm6		; mm6=tmp12
470
	punpckhwd mm0,mm6
471
	movq      mm1,mm4
472
	movq      mm6,mm0
473
	pmaddwd   mm4,[GOTOFF(ebx,PW_F130_F054)]	; mm4=data2L
474
	pmaddwd   mm0,[GOTOFF(ebx,PW_F130_F054)]	; mm0=data2H
475
	pmaddwd   mm1,[GOTOFF(ebx,PW_F054_MF130)]	; mm1=data6L
476
	pmaddwd   mm6,[GOTOFF(ebx,PW_F054_MF130)]	; mm6=data6H
477
478
	paddd	mm4,[GOTOFF(ebx,PD_DESCALE_P2)]
479
	paddd	mm0,[GOTOFF(ebx,PD_DESCALE_P2)]
480
	psrad	mm4,DESCALE_P2
481
	psrad	mm0,DESCALE_P2
482
	paddd	mm1,[GOTOFF(ebx,PD_DESCALE_P2)]
483
	paddd	mm6,[GOTOFF(ebx,PD_DESCALE_P2)]
484
	psrad	mm1,DESCALE_P2
485
	psrad	mm6,DESCALE_P2
486
487
	packssdw  mm4,mm0		; mm4=data2
488
	packssdw  mm1,mm6		; mm1=data6
489
490
	movq	MMWORD [MMBLOCK(2,0,edx,SIZEOF_DCTELEM)], mm4
491
	movq	MMWORD [MMBLOCK(6,0,edx,SIZEOF_DCTELEM)], mm1
492
493
	; -- Odd part
494
495
	movq	mm5, MMWORD [wk(0)]	; mm5=tmp6
496
	movq	mm7, MMWORD [wk(1)]	; mm7=tmp7
497
498
	movq	mm0,mm2			; mm2=tmp4
499
	movq	mm6,mm3			; mm3=tmp5
500
	paddw	mm0,mm5			; mm0=z3
501
	paddw	mm6,mm7			; mm6=z4
502
503
	; (Original)
504
	; z5 = (z3 + z4) * 1.175875602;
505
	; z3 = z3 * -1.961570560;  z4 = z4 * -0.390180644;
506
	; z3 += z5;  z4 += z5;
507
	;
508
	; (This implementation)
509
	; z3 = z3 * (1.175875602 - 1.961570560) + z4 * 1.175875602;
510
	; z4 = z3 * 1.175875602 + z4 * (1.175875602 - 0.390180644);
511
512
	movq      mm4,mm0
513
	movq      mm1,mm0
514
	punpcklwd mm4,mm6
515
	punpckhwd mm1,mm6
516
	movq      mm0,mm4
517
	movq      mm6,mm1
518
	pmaddwd   mm4,[GOTOFF(ebx,PW_MF078_F117)]	; mm4=z3L
519
	pmaddwd   mm1,[GOTOFF(ebx,PW_MF078_F117)]	; mm1=z3H
520
	pmaddwd   mm0,[GOTOFF(ebx,PW_F117_F078)]	; mm0=z4L
521
	pmaddwd   mm6,[GOTOFF(ebx,PW_F117_F078)]	; mm6=z4H
522
523
	movq	MMWORD [wk(0)], mm4	; wk(0)=z3L
524
	movq	MMWORD [wk(1)], mm1	; wk(1)=z3H
525
526
	; (Original)
527
	; z1 = tmp4 + tmp7;  z2 = tmp5 + tmp6;
528
	; tmp4 = tmp4 * 0.298631336;  tmp5 = tmp5 * 2.053119869;
529
	; tmp6 = tmp6 * 3.072711026;  tmp7 = tmp7 * 1.501321110;
530
	; z1 = z1 * -0.899976223;  z2 = z2 * -2.562915447;
531
	; data7 = tmp4 + z1 + z3;  data5 = tmp5 + z2 + z4;
532
	; data3 = tmp6 + z2 + z3;  data1 = tmp7 + z1 + z4;
533
	;
534
	; (This implementation)
535
	; tmp4 = tmp4 * (0.298631336 - 0.899976223) + tmp7 * -0.899976223;
536
	; tmp5 = tmp5 * (2.053119869 - 2.562915447) + tmp6 * -2.562915447;
537
	; tmp6 = tmp5 * -2.562915447 + tmp6 * (3.072711026 - 2.562915447);
538
	; tmp7 = tmp4 * -0.899976223 + tmp7 * (1.501321110 - 0.899976223);
539
	; data7 = tmp4 + z3;  data5 = tmp5 + z4;
540
	; data3 = tmp6 + z3;  data1 = tmp7 + z4;
541
542
	movq      mm4,mm2
543
	movq      mm1,mm2
544
	punpcklwd mm4,mm7
545
	punpckhwd mm1,mm7
546
	movq      mm2,mm4
547
	movq      mm7,mm1
548
	pmaddwd   mm4,[GOTOFF(ebx,PW_MF060_MF089)]	; mm4=tmp4L
549
	pmaddwd   mm1,[GOTOFF(ebx,PW_MF060_MF089)]	; mm1=tmp4H
550
	pmaddwd   mm2,[GOTOFF(ebx,PW_MF089_F060)]	; mm2=tmp7L
551
	pmaddwd   mm7,[GOTOFF(ebx,PW_MF089_F060)]	; mm7=tmp7H
552
553
	paddd	mm4, MMWORD [wk(0)]	; mm4=data7L
554
	paddd	mm1, MMWORD [wk(1)]	; mm1=data7H
555
	paddd	mm2,mm0			; mm2=data1L
556
	paddd	mm7,mm6			; mm7=data1H
557
558
	paddd	mm4,[GOTOFF(ebx,PD_DESCALE_P2)]
559
	paddd	mm1,[GOTOFF(ebx,PD_DESCALE_P2)]
560
	psrad	mm4,DESCALE_P2
561
	psrad	mm1,DESCALE_P2
562
	paddd	mm2,[GOTOFF(ebx,PD_DESCALE_P2)]
563
	paddd	mm7,[GOTOFF(ebx,PD_DESCALE_P2)]
564
	psrad	mm2,DESCALE_P2
565
	psrad	mm7,DESCALE_P2
566
567
	packssdw  mm4,mm1		; mm4=data7
568
	packssdw  mm2,mm7		; mm2=data1
569
570
	movq	MMWORD [MMBLOCK(7,0,edx,SIZEOF_DCTELEM)], mm4
571
	movq	MMWORD [MMBLOCK(1,0,edx,SIZEOF_DCTELEM)], mm2
572
573
	movq      mm1,mm3
574
	movq      mm7,mm3
575
	punpcklwd mm1,mm5
576
	punpckhwd mm7,mm5
577
	movq      mm3,mm1
578
	movq      mm5,mm7
579
	pmaddwd   mm1,[GOTOFF(ebx,PW_MF050_MF256)]	; mm1=tmp5L
580
	pmaddwd   mm7,[GOTOFF(ebx,PW_MF050_MF256)]	; mm7=tmp5H
581
	pmaddwd   mm3,[GOTOFF(ebx,PW_MF256_F050)]	; mm3=tmp6L
582
	pmaddwd   mm5,[GOTOFF(ebx,PW_MF256_F050)]	; mm5=tmp6H
583
584
	paddd	mm1,mm0			; mm1=data5L
585
	paddd	mm7,mm6			; mm7=data5H
586
	paddd	mm3, MMWORD [wk(0)]	; mm3=data3L
587
	paddd	mm5, MMWORD [wk(1)]	; mm5=data3H
588
589
	paddd	mm1,[GOTOFF(ebx,PD_DESCALE_P2)]
590
	paddd	mm7,[GOTOFF(ebx,PD_DESCALE_P2)]
591
	psrad	mm1,DESCALE_P2
592
	psrad	mm7,DESCALE_P2
593
	paddd	mm3,[GOTOFF(ebx,PD_DESCALE_P2)]
594
	paddd	mm5,[GOTOFF(ebx,PD_DESCALE_P2)]
595
	psrad	mm3,DESCALE_P2
596
	psrad	mm5,DESCALE_P2
597
598
	packssdw  mm1,mm7		; mm1=data5
599
	packssdw  mm3,mm5		; mm3=data3
600
601
	movq	MMWORD [MMBLOCK(5,0,edx,SIZEOF_DCTELEM)], mm1
602
	movq	MMWORD [MMBLOCK(3,0,edx,SIZEOF_DCTELEM)], mm3
603
604
	add	edx, byte 4*SIZEOF_DCTELEM
605
	dec	ecx
606
	jnz	near .columnloop
607
608
	emms		; empty MMX state
609
610
;	pop	edi		; unused
611
;	pop	esi		; unused
612
;	pop	edx		; need not be preserved
613
;	pop	ecx		; need not be preserved
614
	poppic	ebx
615
	mov	esp,ebp		; esp <- aligned ebp
616
	pop	esp		; esp <- original ebp
617
	pop	ebp
618
	ret
619
620
; For some reason, the OS X linker does not honor the request to align the
621
; segment unless we do this.
622
	align	16
(-)a/jpeg/simd/jfss2fst-64.asm (+392 lines)
Line     Link Here 
Line 0    Link Here 
1
;
2
; jfss2fst-64.asm - fast integer FDCT (64-bit SSE2)
3
;
4
; Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
5
; Copyright 2009 D. R. Commander
6
;
7
; Based on
8
; x86 SIMD extension for IJG JPEG library
9
; Copyright (C) 1999-2006, MIYASAKA Masaru.
10
; For conditions of distribution and use, see copyright notice in jsimdext.inc
11
;
12
; This file should be assembled with NASM (Netwide Assembler),
13
; can *not* be assembled with Microsoft's MASM or any compatible
14
; assembler (including Borland's Turbo Assembler).
15
; NASM is available from http://nasm.sourceforge.net/ or
16
; http://sourceforge.net/project/showfiles.php?group_id=6208
17
;
18
; This file contains a fast, not so accurate integer implementation of
19
; the forward DCT (Discrete Cosine Transform). The following code is
20
; based directly on the IJG's original jfdctfst.c; see the jfdctfst.c
21
; for more details.
22
;
23
; [TAB8]
24
25
%include "jsimdext.inc"
26
%include "jdct.inc"
27
28
; --------------------------------------------------------------------------
29
30
%define CONST_BITS	8	; 14 is also OK.
31
32
%if CONST_BITS == 8
33
F_0_382	equ	 98		; FIX(0.382683433)
34
F_0_541	equ	139		; FIX(0.541196100)
35
F_0_707	equ	181		; FIX(0.707106781)
36
F_1_306	equ	334		; FIX(1.306562965)
37
%else
38
; NASM cannot do compile-time arithmetic on floating-point constants.
39
%define DESCALE(x,n)  (((x)+(1<<((n)-1)))>>(n))
40
F_0_382	equ	DESCALE( 410903207,30-CONST_BITS)	; FIX(0.382683433)
41
F_0_541	equ	DESCALE( 581104887,30-CONST_BITS)	; FIX(0.541196100)
42
F_0_707	equ	DESCALE( 759250124,30-CONST_BITS)	; FIX(0.707106781)
43
F_1_306	equ	DESCALE(1402911301,30-CONST_BITS)	; FIX(1.306562965)
44
%endif
45
46
; --------------------------------------------------------------------------
47
	SECTION	SEG_CONST
48
49
; PRE_MULTIPLY_SCALE_BITS <= 2 (to avoid overflow)
50
; CONST_BITS + CONST_SHIFT + PRE_MULTIPLY_SCALE_BITS == 16 (for pmulhw)
51
52
%define PRE_MULTIPLY_SCALE_BITS   2
53
%define CONST_SHIFT     (16 - PRE_MULTIPLY_SCALE_BITS - CONST_BITS)
54
55
	alignz	16
56
	global	EXTN(jconst_fdct_ifast_sse2)
57
58
EXTN(jconst_fdct_ifast_sse2):
59
60
PW_F0707	times 8 dw  F_0_707 << CONST_SHIFT
61
PW_F0382	times 8 dw  F_0_382 << CONST_SHIFT
62
PW_F0541	times 8 dw  F_0_541 << CONST_SHIFT
63
PW_F1306	times 8 dw  F_1_306 << CONST_SHIFT
64
65
	alignz	16
66
67
; --------------------------------------------------------------------------
68
	SECTION	SEG_TEXT
69
	BITS	64
70
;
71
; Perform the forward DCT on one block of samples.
72
;
73
; GLOBAL(void)
74
; jsimd_fdct_ifast_sse2 (DCTELEM * data)
75
;
76
77
; r10 = DCTELEM * data
78
79
%define wk(i)		rbp-(WK_NUM-(i))*SIZEOF_XMMWORD	; xmmword wk[WK_NUM]
80
%define WK_NUM		2
81
82
	align	16
83
	global	EXTN(jsimd_fdct_ifast_sse2)
84
85
EXTN(jsimd_fdct_ifast_sse2):
86
	push	rbp
87
	mov	rax,rsp				; rax = original rbp
88
	sub	rsp, byte 4
89
	and	rsp, byte (-SIZEOF_XMMWORD)	; align to 128 bits
90
	mov	[rsp],rax
91
	mov	rbp,rsp				; rbp = aligned rbp
92
	lea	rsp, [wk(0)]
93
	collect_args
94
95
	; ---- Pass 1: process rows.
96
97
	mov	rdx, r10	; (DCTELEM *)
98
99
	movdqa	xmm0, XMMWORD [XMMBLOCK(0,0,rdx,SIZEOF_DCTELEM)]
100
	movdqa	xmm1, XMMWORD [XMMBLOCK(1,0,rdx,SIZEOF_DCTELEM)]
101
	movdqa	xmm2, XMMWORD [XMMBLOCK(2,0,rdx,SIZEOF_DCTELEM)]
102
	movdqa	xmm3, XMMWORD [XMMBLOCK(3,0,rdx,SIZEOF_DCTELEM)]
103
104
	; xmm0=(00 01 02 03 04 05 06 07), xmm2=(20 21 22 23 24 25 26 27)
105
	; xmm1=(10 11 12 13 14 15 16 17), xmm3=(30 31 32 33 34 35 36 37)
106
107
	movdqa    xmm4,xmm0		; transpose coefficients(phase 1)
108
	punpcklwd xmm0,xmm1		; xmm0=(00 10 01 11 02 12 03 13)
109
	punpckhwd xmm4,xmm1		; xmm4=(04 14 05 15 06 16 07 17)
110
	movdqa    xmm5,xmm2		; transpose coefficients(phase 1)
111
	punpcklwd xmm2,xmm3		; xmm2=(20 30 21 31 22 32 23 33)
112
	punpckhwd xmm5,xmm3		; xmm5=(24 34 25 35 26 36 27 37)
113
114
	movdqa	xmm6, XMMWORD [XMMBLOCK(4,0,rdx,SIZEOF_DCTELEM)]
115
	movdqa	xmm7, XMMWORD [XMMBLOCK(5,0,rdx,SIZEOF_DCTELEM)]
116
	movdqa	xmm1, XMMWORD [XMMBLOCK(6,0,rdx,SIZEOF_DCTELEM)]
117
	movdqa	xmm3, XMMWORD [XMMBLOCK(7,0,rdx,SIZEOF_DCTELEM)]
118
119
	; xmm6=( 4 12 20 28 36 44 52 60), xmm1=( 6 14 22 30 38 46 54 62)
120
	; xmm7=( 5 13 21 29 37 45 53 61), xmm3=( 7 15 23 31 39 47 55 63)
121
122
	movdqa	XMMWORD [wk(0)], xmm2	; wk(0)=(20 30 21 31 22 32 23 33)
123
	movdqa	XMMWORD [wk(1)], xmm5	; wk(1)=(24 34 25 35 26 36 27 37)
124
125
	movdqa    xmm2,xmm6		; transpose coefficients(phase 1)
126
	punpcklwd xmm6,xmm7		; xmm6=(40 50 41 51 42 52 43 53)
127
	punpckhwd xmm2,xmm7		; xmm2=(44 54 45 55 46 56 47 57)
128
	movdqa    xmm5,xmm1		; transpose coefficients(phase 1)
129
	punpcklwd xmm1,xmm3		; xmm1=(60 70 61 71 62 72 63 73)
130
	punpckhwd xmm5,xmm3		; xmm5=(64 74 65 75 66 76 67 77)
131
132
	movdqa    xmm7,xmm6		; transpose coefficients(phase 2)
133
	punpckldq xmm6,xmm1		; xmm6=(40 50 60 70 41 51 61 71)
134
	punpckhdq xmm7,xmm1		; xmm7=(42 52 62 72 43 53 63 73)
135
	movdqa    xmm3,xmm2		; transpose coefficients(phase 2)
136
	punpckldq xmm2,xmm5		; xmm2=(44 54 64 74 45 55 65 75)
137
	punpckhdq xmm3,xmm5		; xmm3=(46 56 66 76 47 57 67 77)
138
139
	movdqa	xmm1, XMMWORD [wk(0)]	; xmm1=(20 30 21 31 22 32 23 33)
140
	movdqa	xmm5, XMMWORD [wk(1)]	; xmm5=(24 34 25 35 26 36 27 37)
141
	movdqa	XMMWORD [wk(0)], xmm7	; wk(0)=(42 52 62 72 43 53 63 73)
142
	movdqa	XMMWORD [wk(1)], xmm2	; wk(1)=(44 54 64 74 45 55 65 75)
143
144
	movdqa    xmm7,xmm0		; transpose coefficients(phase 2)
145
	punpckldq xmm0,xmm1		; xmm0=(00 10 20 30 01 11 21 31)
146
	punpckhdq xmm7,xmm1		; xmm7=(02 12 22 32 03 13 23 33)
147
	movdqa    xmm2,xmm4		; transpose coefficients(phase 2)
148
	punpckldq xmm4,xmm5		; xmm4=(04 14 24 34 05 15 25 35)
149
	punpckhdq xmm2,xmm5		; xmm2=(06 16 26 36 07 17 27 37)
150
151
	movdqa     xmm1,xmm0		; transpose coefficients(phase 3)
152
	punpcklqdq xmm0,xmm6		; xmm0=(00 10 20 30 40 50 60 70)=data0
153
	punpckhqdq xmm1,xmm6		; xmm1=(01 11 21 31 41 51 61 71)=data1
154
	movdqa     xmm5,xmm2		; transpose coefficients(phase 3)
155
	punpcklqdq xmm2,xmm3		; xmm2=(06 16 26 36 46 56 66 76)=data6
156
	punpckhqdq xmm5,xmm3		; xmm5=(07 17 27 37 47 57 67 77)=data7
157
158
	movdqa	xmm6,xmm1
159
	movdqa	xmm3,xmm0
160
	psubw	xmm1,xmm2		; xmm1=data1-data6=tmp6
161
	psubw	xmm0,xmm5		; xmm0=data0-data7=tmp7
162
	paddw	xmm6,xmm2		; xmm6=data1+data6=tmp1
163
	paddw	xmm3,xmm5		; xmm3=data0+data7=tmp0
164
165
	movdqa	xmm2, XMMWORD [wk(0)]	; xmm2=(42 52 62 72 43 53 63 73)
166
	movdqa	xmm5, XMMWORD [wk(1)]	; xmm5=(44 54 64 74 45 55 65 75)
167
	movdqa	XMMWORD [wk(0)], xmm1	; wk(0)=tmp6
168
	movdqa	XMMWORD [wk(1)], xmm0	; wk(1)=tmp7
169
170
	movdqa     xmm1,xmm7		; transpose coefficients(phase 3)
171
	punpcklqdq xmm7,xmm2		; xmm7=(02 12 22 32 42 52 62 72)=data2
172
	punpckhqdq xmm1,xmm2		; xmm1=(03 13 23 33 43 53 63 73)=data3
173
	movdqa     xmm0,xmm4		; transpose coefficients(phase 3)
174
	punpcklqdq xmm4,xmm5		; xmm4=(04 14 24 34 44 54 64 74)=data4
175
	punpckhqdq xmm0,xmm5		; xmm0=(05 15 25 35 45 55 65 75)=data5
176
177
	movdqa	xmm2,xmm1
178
	movdqa	xmm5,xmm7
179
	paddw	xmm1,xmm4		; xmm1=data3+data4=tmp3
180
	paddw	xmm7,xmm0		; xmm7=data2+data5=tmp2
181
	psubw	xmm2,xmm4		; xmm2=data3-data4=tmp4
182
	psubw	xmm5,xmm0		; xmm5=data2-data5=tmp5
183
184
	; -- Even part
185
186
	movdqa	xmm4,xmm3
187
	movdqa	xmm0,xmm6
188
	psubw	xmm3,xmm1		; xmm3=tmp13
189
	psubw	xmm6,xmm7		; xmm6=tmp12
190
	paddw	xmm4,xmm1		; xmm4=tmp10
191
	paddw	xmm0,xmm7		; xmm0=tmp11
192
193
	paddw	xmm6,xmm3
194
	psllw	xmm6,PRE_MULTIPLY_SCALE_BITS
195
	pmulhw	xmm6,[rel PW_F0707] ; xmm6=z1
196
197
	movdqa	xmm1,xmm4
198
	movdqa	xmm7,xmm3
199
	psubw	xmm4,xmm0		; xmm4=data4
200
	psubw	xmm3,xmm6		; xmm3=data6
201
	paddw	xmm1,xmm0		; xmm1=data0
202
	paddw	xmm7,xmm6		; xmm7=data2
203
204
	movdqa	xmm0, XMMWORD [wk(0)]	; xmm0=tmp6
205
	movdqa	xmm6, XMMWORD [wk(1)]	; xmm6=tmp7
206
	movdqa	XMMWORD [wk(0)], xmm4	; wk(0)=data4
207
	movdqa	XMMWORD [wk(1)], xmm3	; wk(1)=data6
208
209
	; -- Odd part
210
211
	paddw	xmm2,xmm5		; xmm2=tmp10
212
	paddw	xmm5,xmm0		; xmm5=tmp11
213
	paddw	xmm0,xmm6		; xmm0=tmp12, xmm6=tmp7
214
215
	psllw	xmm2,PRE_MULTIPLY_SCALE_BITS
216
	psllw	xmm0,PRE_MULTIPLY_SCALE_BITS
217
218
	psllw	xmm5,PRE_MULTIPLY_SCALE_BITS
219
	pmulhw	xmm5,[rel PW_F0707] ; xmm5=z3
220
221
	movdqa	xmm4,xmm2		; xmm4=tmp10
222
	psubw	xmm2,xmm0
223
	pmulhw	xmm2,[rel PW_F0382] ; xmm2=z5
224
	pmulhw	xmm4,[rel PW_F0541] ; xmm4=MULTIPLY(tmp10,FIX_0_541196)
225
	pmulhw	xmm0,[rel PW_F1306] ; xmm0=MULTIPLY(tmp12,FIX_1_306562)
226
	paddw	xmm4,xmm2		; xmm4=z2
227
	paddw	xmm0,xmm2		; xmm0=z4
228
229
	movdqa	xmm3,xmm6
230
	psubw	xmm6,xmm5		; xmm6=z13
231
	paddw	xmm3,xmm5		; xmm3=z11
232
233
	movdqa	xmm2,xmm6
234
	movdqa	xmm5,xmm3
235
	psubw	xmm6,xmm4		; xmm6=data3
236
	psubw	xmm3,xmm0		; xmm3=data7
237
	paddw	xmm2,xmm4		; xmm2=data5
238
	paddw	xmm5,xmm0		; xmm5=data1
239
240
	; ---- Pass 2: process columns.
241
242
	; xmm1=(00 10 20 30 40 50 60 70), xmm7=(02 12 22 32 42 52 62 72)
243
	; xmm5=(01 11 21 31 41 51 61 71), xmm6=(03 13 23 33 43 53 63 73)
244
245
	movdqa    xmm4,xmm1		; transpose coefficients(phase 1)
246
	punpcklwd xmm1,xmm5		; xmm1=(00 01 10 11 20 21 30 31)
247
	punpckhwd xmm4,xmm5		; xmm4=(40 41 50 51 60 61 70 71)
248
	movdqa    xmm0,xmm7		; transpose coefficients(phase 1)
249
	punpcklwd xmm7,xmm6		; xmm7=(02 03 12 13 22 23 32 33)
250
	punpckhwd xmm0,xmm6		; xmm0=(42 43 52 53 62 63 72 73)
251
252
	movdqa	xmm5, XMMWORD [wk(0)]	; xmm5=col4
253
	movdqa	xmm6, XMMWORD [wk(1)]	; xmm6=col6
254
255
	; xmm5=(04 14 24 34 44 54 64 74), xmm6=(06 16 26 36 46 56 66 76)
256
	; xmm2=(05 15 25 35 45 55 65 75), xmm3=(07 17 27 37 47 57 67 77)
257
258
	movdqa	XMMWORD [wk(0)], xmm7	; wk(0)=(02 03 12 13 22 23 32 33)
259
	movdqa	XMMWORD [wk(1)], xmm0	; wk(1)=(42 43 52 53 62 63 72 73)
260
261
	movdqa    xmm7,xmm5		; transpose coefficients(phase 1)
262
	punpcklwd xmm5,xmm2		; xmm5=(04 05 14 15 24 25 34 35)
263
	punpckhwd xmm7,xmm2		; xmm7=(44 45 54 55 64 65 74 75)
264
	movdqa    xmm0,xmm6		; transpose coefficients(phase 1)
265
	punpcklwd xmm6,xmm3		; xmm6=(06 07 16 17 26 27 36 37)
266
	punpckhwd xmm0,xmm3		; xmm0=(46 47 56 57 66 67 76 77)
267
268
	movdqa    xmm2,xmm5		; transpose coefficients(phase 2)
269
	punpckldq xmm5,xmm6		; xmm5=(04 05 06 07 14 15 16 17)
270
	punpckhdq xmm2,xmm6		; xmm2=(24 25 26 27 34 35 36 37)
271
	movdqa    xmm3,xmm7		; transpose coefficients(phase 2)
272
	punpckldq xmm7,xmm0		; xmm7=(44 45 46 47 54 55 56 57)
273
	punpckhdq xmm3,xmm0		; xmm3=(64 65 66 67 74 75 76 77)
274
275
	movdqa	xmm6, XMMWORD [wk(0)]	; xmm6=(02 03 12 13 22 23 32 33)
276
	movdqa	xmm0, XMMWORD [wk(1)]	; xmm0=(42 43 52 53 62 63 72 73)
277
	movdqa	XMMWORD [wk(0)], xmm2	; wk(0)=(24 25 26 27 34 35 36 37)
278
	movdqa	XMMWORD [wk(1)], xmm7	; wk(1)=(44 45 46 47 54 55 56 57)
279
280
	movdqa    xmm2,xmm1		; transpose coefficients(phase 2)
281
	punpckldq xmm1,xmm6		; xmm1=(00 01 02 03 10 11 12 13)
282
	punpckhdq xmm2,xmm6		; xmm2=(20 21 22 23 30 31 32 33)
283
	movdqa    xmm7,xmm4		; transpose coefficients(phase 2)
284
	punpckldq xmm4,xmm0		; xmm4=(40 41 42 43 50 51 52 53)
285
	punpckhdq xmm7,xmm0		; xmm7=(60 61 62 63 70 71 72 73)
286
287
	movdqa     xmm6,xmm1		; transpose coefficients(phase 3)
288
	punpcklqdq xmm1,xmm5		; xmm1=(00 01 02 03 04 05 06 07)=data0
289
	punpckhqdq xmm6,xmm5		; xmm6=(10 11 12 13 14 15 16 17)=data1
290
	movdqa     xmm0,xmm7		; transpose coefficients(phase 3)
291
	punpcklqdq xmm7,xmm3		; xmm7=(60 61 62 63 64 65 66 67)=data6
292
	punpckhqdq xmm0,xmm3		; xmm0=(70 71 72 73 74 75 76 77)=data7
293
294
	movdqa	xmm5,xmm6
295
	movdqa	xmm3,xmm1
296
	psubw	xmm6,xmm7		; xmm6=data1-data6=tmp6
297
	psubw	xmm1,xmm0		; xmm1=data0-data7=tmp7
298
	paddw	xmm5,xmm7		; xmm5=data1+data6=tmp1
299
	paddw	xmm3,xmm0		; xmm3=data0+data7=tmp0
300
301
	movdqa	xmm7, XMMWORD [wk(0)]	; xmm7=(24 25 26 27 34 35 36 37)
302
	movdqa	xmm0, XMMWORD [wk(1)]	; xmm0=(44 45 46 47 54 55 56 57)
303
	movdqa	XMMWORD [wk(0)], xmm6	; wk(0)=tmp6
304
	movdqa	XMMWORD [wk(1)], xmm1	; wk(1)=tmp7
305
306
	movdqa     xmm6,xmm2		; transpose coefficients(phase 3)
307
	punpcklqdq xmm2,xmm7		; xmm2=(20 21 22 23 24 25 26 27)=data2
308
	punpckhqdq xmm6,xmm7		; xmm6=(30 31 32 33 34 35 36 37)=data3
309
	movdqa     xmm1,xmm4		; transpose coefficients(phase 3)
310
	punpcklqdq xmm4,xmm0		; xmm4=(40 41 42 43 44 45 46 47)=data4
311
	punpckhqdq xmm1,xmm0		; xmm1=(50 51 52 53 54 55 56 57)=data5
312
313
	movdqa	xmm7,xmm6
314
	movdqa	xmm0,xmm2
315
	paddw	xmm6,xmm4		; xmm6=data3+data4=tmp3
316
	paddw	xmm2,xmm1		; xmm2=data2+data5=tmp2
317
	psubw	xmm7,xmm4		; xmm7=data3-data4=tmp4
318
	psubw	xmm0,xmm1		; xmm0=data2-data5=tmp5
319
320
	; -- Even part
321
322
	movdqa	xmm4,xmm3
323
	movdqa	xmm1,xmm5
324
	psubw	xmm3,xmm6		; xmm3=tmp13
325
	psubw	xmm5,xmm2		; xmm5=tmp12
326
	paddw	xmm4,xmm6		; xmm4=tmp10
327
	paddw	xmm1,xmm2		; xmm1=tmp11
328
329
	paddw	xmm5,xmm3
330
	psllw	xmm5,PRE_MULTIPLY_SCALE_BITS
331
	pmulhw	xmm5,[rel PW_F0707] ; xmm5=z1
332
333
	movdqa	xmm6,xmm4
334
	movdqa	xmm2,xmm3
335
	psubw	xmm4,xmm1		; xmm4=data4
336
	psubw	xmm3,xmm5		; xmm3=data6
337
	paddw	xmm6,xmm1		; xmm6=data0
338
	paddw	xmm2,xmm5		; xmm2=data2
339
340
	movdqa	XMMWORD [XMMBLOCK(4,0,rdx,SIZEOF_DCTELEM)], xmm4
341
	movdqa	XMMWORD [XMMBLOCK(6,0,rdx,SIZEOF_DCTELEM)], xmm3
342
	movdqa	XMMWORD [XMMBLOCK(0,0,rdx,SIZEOF_DCTELEM)], xmm6
343
	movdqa	XMMWORD [XMMBLOCK(2,0,rdx,SIZEOF_DCTELEM)], xmm2
344
345
	; -- Odd part
346
347
	movdqa	xmm1, XMMWORD [wk(0)]	; xmm1=tmp6
348
	movdqa	xmm5, XMMWORD [wk(1)]	; xmm5=tmp7
349
350
	paddw	xmm7,xmm0		; xmm7=tmp10
351
	paddw	xmm0,xmm1		; xmm0=tmp11
352
	paddw	xmm1,xmm5		; xmm1=tmp12, xmm5=tmp7
353
354
	psllw	xmm7,PRE_MULTIPLY_SCALE_BITS
355
	psllw	xmm1,PRE_MULTIPLY_SCALE_BITS
356
357
	psllw	xmm0,PRE_MULTIPLY_SCALE_BITS
358
	pmulhw	xmm0,[rel PW_F0707] ; xmm0=z3
359
360
	movdqa	xmm4,xmm7		; xmm4=tmp10
361
	psubw	xmm7,xmm1
362
	pmulhw	xmm7,[rel PW_F0382] ; xmm7=z5
363
	pmulhw	xmm4,[rel PW_F0541] ; xmm4=MULTIPLY(tmp10,FIX_0_541196)
364
	pmulhw	xmm1,[rel PW_F1306] ; xmm1=MULTIPLY(tmp12,FIX_1_306562)
365
	paddw	xmm4,xmm7		; xmm4=z2
366
	paddw	xmm1,xmm7		; xmm1=z4
367
368
	movdqa	xmm3,xmm5
369
	psubw	xmm5,xmm0		; xmm5=z13
370
	paddw	xmm3,xmm0		; xmm3=z11
371
372
	movdqa	xmm6,xmm5
373
	movdqa	xmm2,xmm3
374
	psubw	xmm5,xmm4		; xmm5=data3
375
	psubw	xmm3,xmm1		; xmm3=data7
376
	paddw	xmm6,xmm4		; xmm6=data5
377
	paddw	xmm2,xmm1		; xmm2=data1
378
379
	movdqa	XMMWORD [XMMBLOCK(3,0,rdx,SIZEOF_DCTELEM)], xmm5
380
	movdqa	XMMWORD [XMMBLOCK(7,0,rdx,SIZEOF_DCTELEM)], xmm3
381
	movdqa	XMMWORD [XMMBLOCK(5,0,rdx,SIZEOF_DCTELEM)], xmm6
382
	movdqa	XMMWORD [XMMBLOCK(1,0,rdx,SIZEOF_DCTELEM)], xmm2
383
384
	uncollect_args
385
	mov	rsp,rbp		; rsp <- aligned rbp
386
	pop	rsp		; rsp <- original rbp
387
	pop	rbp
388
	ret
389
390
; For some reason, the OS X linker does not honor the request to align the
391
; segment unless we do this.
392
	align	16
(-)a/jpeg/simd/jfss2fst.asm (+404 lines)
Line     Link Here 
Line 0    Link Here 
1
;
2
; jfss2fst.asm - fast integer FDCT (SSE2)
3
;
4
; Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
5
;
6
; Based on
7
; x86 SIMD extension for IJG JPEG library
8
; Copyright (C) 1999-2006, MIYASAKA Masaru.
9
; For conditions of distribution and use, see copyright notice in jsimdext.inc
10
;
11
; This file should be assembled with NASM (Netwide Assembler),
12
; can *not* be assembled with Microsoft's MASM or any compatible
13
; assembler (including Borland's Turbo Assembler).
14
; NASM is available from http://nasm.sourceforge.net/ or
15
; http://sourceforge.net/project/showfiles.php?group_id=6208
16
;
17
; This file contains a fast, not so accurate integer implementation of
18
; the forward DCT (Discrete Cosine Transform). The following code is
19
; based directly on the IJG's original jfdctfst.c; see the jfdctfst.c
20
; for more details.
21
;
22
; [TAB8]
23
24
%include "jsimdext.inc"
25
%include "jdct.inc"
26
27
; --------------------------------------------------------------------------
28
29
%define CONST_BITS	8	; 14 is also OK.
30
31
%if CONST_BITS == 8
32
F_0_382	equ	 98		; FIX(0.382683433)
33
F_0_541	equ	139		; FIX(0.541196100)
34
F_0_707	equ	181		; FIX(0.707106781)
35
F_1_306	equ	334		; FIX(1.306562965)
36
%else
37
; NASM cannot do compile-time arithmetic on floating-point constants.
38
%define DESCALE(x,n)  (((x)+(1<<((n)-1)))>>(n))
39
F_0_382	equ	DESCALE( 410903207,30-CONST_BITS)	; FIX(0.382683433)
40
F_0_541	equ	DESCALE( 581104887,30-CONST_BITS)	; FIX(0.541196100)
41
F_0_707	equ	DESCALE( 759250124,30-CONST_BITS)	; FIX(0.707106781)
42
F_1_306	equ	DESCALE(1402911301,30-CONST_BITS)	; FIX(1.306562965)
43
%endif
44
45
; --------------------------------------------------------------------------
46
	SECTION	SEG_CONST
47
48
; PRE_MULTIPLY_SCALE_BITS <= 2 (to avoid overflow)
49
; CONST_BITS + CONST_SHIFT + PRE_MULTIPLY_SCALE_BITS == 16 (for pmulhw)
50
51
%define PRE_MULTIPLY_SCALE_BITS   2
52
%define CONST_SHIFT     (16 - PRE_MULTIPLY_SCALE_BITS - CONST_BITS)
53
54
	alignz	16
55
	global	EXTN(jconst_fdct_ifast_sse2)
56
57
EXTN(jconst_fdct_ifast_sse2):
58
59
PW_F0707	times 8 dw  F_0_707 << CONST_SHIFT
60
PW_F0382	times 8 dw  F_0_382 << CONST_SHIFT
61
PW_F0541	times 8 dw  F_0_541 << CONST_SHIFT
62
PW_F1306	times 8 dw  F_1_306 << CONST_SHIFT
63
64
	alignz	16
65
66
; --------------------------------------------------------------------------
67
	SECTION	SEG_TEXT
68
	BITS	32
69
;
70
; Perform the forward DCT on one block of samples.
71
;
72
; GLOBAL(void)
73
; jsimd_fdct_ifast_sse2 (DCTELEM * data)
74
;
75
76
%define data(b)		(b)+8		; DCTELEM * data
77
78
%define original_ebp	ebp+0
79
%define wk(i)		ebp-(WK_NUM-(i))*SIZEOF_XMMWORD	; xmmword wk[WK_NUM]
80
%define WK_NUM		2
81
82
	align	16
83
	global	EXTN(jsimd_fdct_ifast_sse2)
84
85
EXTN(jsimd_fdct_ifast_sse2):
86
	push	ebp
87
	mov	eax,esp				; eax = original ebp
88
	sub	esp, byte 4
89
	and	esp, byte (-SIZEOF_XMMWORD)	; align to 128 bits
90
	mov	[esp],eax
91
	mov	ebp,esp				; ebp = aligned ebp
92
	lea	esp, [wk(0)]
93
	pushpic	ebx
94
;	push	ecx		; unused
95
;	push	edx		; need not be preserved
96
;	push	esi		; unused
97
;	push	edi		; unused
98
99
	get_GOT	ebx		; get GOT address
100
101
	; ---- Pass 1: process rows.
102
103
	mov	edx, POINTER [data(eax)]	; (DCTELEM *)
104
105
	movdqa	xmm0, XMMWORD [XMMBLOCK(0,0,edx,SIZEOF_DCTELEM)]
106
	movdqa	xmm1, XMMWORD [XMMBLOCK(1,0,edx,SIZEOF_DCTELEM)]
107
	movdqa	xmm2, XMMWORD [XMMBLOCK(2,0,edx,SIZEOF_DCTELEM)]
108
	movdqa	xmm3, XMMWORD [XMMBLOCK(3,0,edx,SIZEOF_DCTELEM)]
109
110
	; xmm0=(00 01 02 03 04 05 06 07), xmm2=(20 21 22 23 24 25 26 27)
111
	; xmm1=(10 11 12 13 14 15 16 17), xmm3=(30 31 32 33 34 35 36 37)
112
113
	movdqa    xmm4,xmm0		; transpose coefficients(phase 1)
114
	punpcklwd xmm0,xmm1		; xmm0=(00 10 01 11 02 12 03 13)
115
	punpckhwd xmm4,xmm1		; xmm4=(04 14 05 15 06 16 07 17)
116
	movdqa    xmm5,xmm2		; transpose coefficients(phase 1)
117
	punpcklwd xmm2,xmm3		; xmm2=(20 30 21 31 22 32 23 33)
118
	punpckhwd xmm5,xmm3		; xmm5=(24 34 25 35 26 36 27 37)
119
120
	movdqa	xmm6, XMMWORD [XMMBLOCK(4,0,edx,SIZEOF_DCTELEM)]
121
	movdqa	xmm7, XMMWORD [XMMBLOCK(5,0,edx,SIZEOF_DCTELEM)]
122
	movdqa	xmm1, XMMWORD [XMMBLOCK(6,0,edx,SIZEOF_DCTELEM)]
123
	movdqa	xmm3, XMMWORD [XMMBLOCK(7,0,edx,SIZEOF_DCTELEM)]
124
125
	; xmm6=( 4 12 20 28 36 44 52 60), xmm1=( 6 14 22 30 38 46 54 62)
126
	; xmm7=( 5 13 21 29 37 45 53 61), xmm3=( 7 15 23 31 39 47 55 63)
127
128
	movdqa	XMMWORD [wk(0)], xmm2	; wk(0)=(20 30 21 31 22 32 23 33)
129
	movdqa	XMMWORD [wk(1)], xmm5	; wk(1)=(24 34 25 35 26 36 27 37)
130
131
	movdqa    xmm2,xmm6		; transpose coefficients(phase 1)
132
	punpcklwd xmm6,xmm7		; xmm6=(40 50 41 51 42 52 43 53)
133
	punpckhwd xmm2,xmm7		; xmm2=(44 54 45 55 46 56 47 57)
134
	movdqa    xmm5,xmm1		; transpose coefficients(phase 1)
135
	punpcklwd xmm1,xmm3		; xmm1=(60 70 61 71 62 72 63 73)
136
	punpckhwd xmm5,xmm3		; xmm5=(64 74 65 75 66 76 67 77)
137
138
	movdqa    xmm7,xmm6		; transpose coefficients(phase 2)
139
	punpckldq xmm6,xmm1		; xmm6=(40 50 60 70 41 51 61 71)
140
	punpckhdq xmm7,xmm1		; xmm7=(42 52 62 72 43 53 63 73)
141
	movdqa    xmm3,xmm2		; transpose coefficients(phase 2)
142
	punpckldq xmm2,xmm5		; xmm2=(44 54 64 74 45 55 65 75)
143
	punpckhdq xmm3,xmm5		; xmm3=(46 56 66 76 47 57 67 77)
144
145
	movdqa	xmm1, XMMWORD [wk(0)]	; xmm1=(20 30 21 31 22 32 23 33)
146
	movdqa	xmm5, XMMWORD [wk(1)]	; xmm5=(24 34 25 35 26 36 27 37)
147
	movdqa	XMMWORD [wk(0)], xmm7	; wk(0)=(42 52 62 72 43 53 63 73)
148
	movdqa	XMMWORD [wk(1)], xmm2	; wk(1)=(44 54 64 74 45 55 65 75)
149
150
	movdqa    xmm7,xmm0		; transpose coefficients(phase 2)
151
	punpckldq xmm0,xmm1		; xmm0=(00 10 20 30 01 11 21 31)
152
	punpckhdq xmm7,xmm1		; xmm7=(02 12 22 32 03 13 23 33)
153
	movdqa    xmm2,xmm4		; transpose coefficients(phase 2)
154
	punpckldq xmm4,xmm5		; xmm4=(04 14 24 34 05 15 25 35)
155
	punpckhdq xmm2,xmm5		; xmm2=(06 16 26 36 07 17 27 37)
156
157
	movdqa     xmm1,xmm0		; transpose coefficients(phase 3)
158
	punpcklqdq xmm0,xmm6		; xmm0=(00 10 20 30 40 50 60 70)=data0
159
	punpckhqdq xmm1,xmm6		; xmm1=(01 11 21 31 41 51 61 71)=data1
160
	movdqa     xmm5,xmm2		; transpose coefficients(phase 3)
161
	punpcklqdq xmm2,xmm3		; xmm2=(06 16 26 36 46 56 66 76)=data6
162
	punpckhqdq xmm5,xmm3		; xmm5=(07 17 27 37 47 57 67 77)=data7
163
164
	movdqa	xmm6,xmm1
165
	movdqa	xmm3,xmm0
166
	psubw	xmm1,xmm2		; xmm1=data1-data6=tmp6
167
	psubw	xmm0,xmm5		; xmm0=data0-data7=tmp7
168
	paddw	xmm6,xmm2		; xmm6=data1+data6=tmp1
169
	paddw	xmm3,xmm5		; xmm3=data0+data7=tmp0
170
171
	movdqa	xmm2, XMMWORD [wk(0)]	; xmm2=(42 52 62 72 43 53 63 73)
172
	movdqa	xmm5, XMMWORD [wk(1)]	; xmm5=(44 54 64 74 45 55 65 75)
173
	movdqa	XMMWORD [wk(0)], xmm1	; wk(0)=tmp6
174
	movdqa	XMMWORD [wk(1)], xmm0	; wk(1)=tmp7
175
176
	movdqa     xmm1,xmm7		; transpose coefficients(phase 3)
177
	punpcklqdq xmm7,xmm2		; xmm7=(02 12 22 32 42 52 62 72)=data2
178
	punpckhqdq xmm1,xmm2		; xmm1=(03 13 23 33 43 53 63 73)=data3
179
	movdqa     xmm0,xmm4		; transpose coefficients(phase 3)
180
	punpcklqdq xmm4,xmm5		; xmm4=(04 14 24 34 44 54 64 74)=data4
181
	punpckhqdq xmm0,xmm5		; xmm0=(05 15 25 35 45 55 65 75)=data5
182
183
	movdqa	xmm2,xmm1
184
	movdqa	xmm5,xmm7
185
	paddw	xmm1,xmm4		; xmm1=data3+data4=tmp3
186
	paddw	xmm7,xmm0		; xmm7=data2+data5=tmp2
187
	psubw	xmm2,xmm4		; xmm2=data3-data4=tmp4
188
	psubw	xmm5,xmm0		; xmm5=data2-data5=tmp5
189
190
	; -- Even part
191
192
	movdqa	xmm4,xmm3
193
	movdqa	xmm0,xmm6
194
	psubw	xmm3,xmm1		; xmm3=tmp13
195
	psubw	xmm6,xmm7		; xmm6=tmp12
196
	paddw	xmm4,xmm1		; xmm4=tmp10
197
	paddw	xmm0,xmm7		; xmm0=tmp11
198
199
	paddw	xmm6,xmm3
200
	psllw	xmm6,PRE_MULTIPLY_SCALE_BITS
201
	pmulhw	xmm6,[GOTOFF(ebx,PW_F0707)] ; xmm6=z1
202
203
	movdqa	xmm1,xmm4
204
	movdqa	xmm7,xmm3
205
	psubw	xmm4,xmm0		; xmm4=data4
206
	psubw	xmm3,xmm6		; xmm3=data6
207
	paddw	xmm1,xmm0		; xmm1=data0
208
	paddw	xmm7,xmm6		; xmm7=data2
209
210
	movdqa	xmm0, XMMWORD [wk(0)]	; xmm0=tmp6
211
	movdqa	xmm6, XMMWORD [wk(1)]	; xmm6=tmp7
212
	movdqa	XMMWORD [wk(0)], xmm4	; wk(0)=data4
213
	movdqa	XMMWORD [wk(1)], xmm3	; wk(1)=data6
214
215
	; -- Odd part
216
217
	paddw	xmm2,xmm5		; xmm2=tmp10
218
	paddw	xmm5,xmm0		; xmm5=tmp11
219
	paddw	xmm0,xmm6		; xmm0=tmp12, xmm6=tmp7
220
221
	psllw	xmm2,PRE_MULTIPLY_SCALE_BITS
222
	psllw	xmm0,PRE_MULTIPLY_SCALE_BITS
223
224
	psllw	xmm5,PRE_MULTIPLY_SCALE_BITS
225
	pmulhw	xmm5,[GOTOFF(ebx,PW_F0707)] ; xmm5=z3
226
227
	movdqa	xmm4,xmm2		; xmm4=tmp10
228
	psubw	xmm2,xmm0
229
	pmulhw	xmm2,[GOTOFF(ebx,PW_F0382)] ; xmm2=z5
230
	pmulhw	xmm4,[GOTOFF(ebx,PW_F0541)] ; xmm4=MULTIPLY(tmp10,FIX_0_541196)
231
	pmulhw	xmm0,[GOTOFF(ebx,PW_F1306)] ; xmm0=MULTIPLY(tmp12,FIX_1_306562)
232
	paddw	xmm4,xmm2		; xmm4=z2
233
	paddw	xmm0,xmm2		; xmm0=z4
234
235
	movdqa	xmm3,xmm6
236
	psubw	xmm6,xmm5		; xmm6=z13
237
	paddw	xmm3,xmm5		; xmm3=z11
238
239
	movdqa	xmm2,xmm6
240
	movdqa	xmm5,xmm3
241
	psubw	xmm6,xmm4		; xmm6=data3
242
	psubw	xmm3,xmm0		; xmm3=data7
243
	paddw	xmm2,xmm4		; xmm2=data5
244
	paddw	xmm5,xmm0		; xmm5=data1
245
246
	; ---- Pass 2: process columns.
247
248
;	mov	edx, POINTER [data(eax)]	; (DCTELEM *)
249
250
	; xmm1=(00 10 20 30 40 50 60 70), xmm7=(02 12 22 32 42 52 62 72)
251
	; xmm5=(01 11 21 31 41 51 61 71), xmm6=(03 13 23 33 43 53 63 73)
252
253
	movdqa    xmm4,xmm1		; transpose coefficients(phase 1)
254
	punpcklwd xmm1,xmm5		; xmm1=(00 01 10 11 20 21 30 31)
255
	punpckhwd xmm4,xmm5		; xmm4=(40 41 50 51 60 61 70 71)
256
	movdqa    xmm0,xmm7		; transpose coefficients(phase 1)
257
	punpcklwd xmm7,xmm6		; xmm7=(02 03 12 13 22 23 32 33)
258
	punpckhwd xmm0,xmm6		; xmm0=(42 43 52 53 62 63 72 73)
259
260
	movdqa	xmm5, XMMWORD [wk(0)]	; xmm5=col4
261
	movdqa	xmm6, XMMWORD [wk(1)]	; xmm6=col6
262
263
	; xmm5=(04 14 24 34 44 54 64 74), xmm6=(06 16 26 36 46 56 66 76)
264
	; xmm2=(05 15 25 35 45 55 65 75), xmm3=(07 17 27 37 47 57 67 77)
265
266
	movdqa	XMMWORD [wk(0)], xmm7	; wk(0)=(02 03 12 13 22 23 32 33)
267
	movdqa	XMMWORD [wk(1)], xmm0	; wk(1)=(42 43 52 53 62 63 72 73)
268
269
	movdqa    xmm7,xmm5		; transpose coefficients(phase 1)
270
	punpcklwd xmm5,xmm2		; xmm5=(04 05 14 15 24 25 34 35)
271
	punpckhwd xmm7,xmm2		; xmm7=(44 45 54 55 64 65 74 75)
272
	movdqa    xmm0,xmm6		; transpose coefficients(phase 1)
273
	punpcklwd xmm6,xmm3		; xmm6=(06 07 16 17 26 27 36 37)
274
	punpckhwd xmm0,xmm3		; xmm0=(46 47 56 57 66 67 76 77)
275
276
	movdqa    xmm2,xmm5		; transpose coefficients(phase 2)
277
	punpckldq xmm5,xmm6		; xmm5=(04 05 06 07 14 15 16 17)
278
	punpckhdq xmm2,xmm6		; xmm2=(24 25 26 27 34 35 36 37)
279
	movdqa    xmm3,xmm7		; transpose coefficients(phase 2)
280
	punpckldq xmm7,xmm0		; xmm7=(44 45 46 47 54 55 56 57)
281
	punpckhdq xmm3,xmm0		; xmm3=(64 65 66 67 74 75 76 77)
282
283
	movdqa	xmm6, XMMWORD [wk(0)]	; xmm6=(02 03 12 13 22 23 32 33)
284
	movdqa	xmm0, XMMWORD [wk(1)]	; xmm0=(42 43 52 53 62 63 72 73)
285
	movdqa	XMMWORD [wk(0)], xmm2	; wk(0)=(24 25 26 27 34 35 36 37)
286
	movdqa	XMMWORD [wk(1)], xmm7	; wk(1)=(44 45 46 47 54 55 56 57)
287
288
	movdqa    xmm2,xmm1		; transpose coefficients(phase 2)
289
	punpckldq xmm1,xmm6		; xmm1=(00 01 02 03 10 11 12 13)
290
	punpckhdq xmm2,xmm6		; xmm2=(20 21 22 23 30 31 32 33)
291
	movdqa    xmm7,xmm4		; transpose coefficients(phase 2)
292
	punpckldq xmm4,xmm0		; xmm4=(40 41 42 43 50 51 52 53)
293
	punpckhdq xmm7,xmm0		; xmm7=(60 61 62 63 70 71 72 73)
294
295
	movdqa     xmm6,xmm1		; transpose coefficients(phase 3)
296
	punpcklqdq xmm1,xmm5		; xmm1=(00 01 02 03 04 05 06 07)=data0
297
	punpckhqdq xmm6,xmm5		; xmm6=(10 11 12 13 14 15 16 17)=data1
298
	movdqa     xmm0,xmm7		; transpose coefficients(phase 3)
299
	punpcklqdq xmm7,xmm3		; xmm7=(60 61 62 63 64 65 66 67)=data6
300
	punpckhqdq xmm0,xmm3		; xmm0=(70 71 72 73 74 75 76 77)=data7
301
302
	movdqa	xmm5,xmm6
303
	movdqa	xmm3,xmm1
304
	psubw	xmm6,xmm7		; xmm6=data1-data6=tmp6
305
	psubw	xmm1,xmm0		; xmm1=data0-data7=tmp7
306
	paddw	xmm5,xmm7		; xmm5=data1+data6=tmp1
307
	paddw	xmm3,xmm0		; xmm3=data0+data7=tmp0
308
309
	movdqa	xmm7, XMMWORD [wk(0)]	; xmm7=(24 25 26 27 34 35 36 37)
310
	movdqa	xmm0, XMMWORD [wk(1)]	; xmm0=(44 45 46 47 54 55 56 57)
311
	movdqa	XMMWORD [wk(0)], xmm6	; wk(0)=tmp6
312
	movdqa	XMMWORD [wk(1)], xmm1	; wk(1)=tmp7
313
314
	movdqa     xmm6,xmm2		; transpose coefficients(phase 3)
315
	punpcklqdq xmm2,xmm7		; xmm2=(20 21 22 23 24 25 26 27)=data2
316
	punpckhqdq xmm6,xmm7		; xmm6=(30 31 32 33 34 35 36 37)=data3
317
	movdqa     xmm1,xmm4		; transpose coefficients(phase 3)
318
	punpcklqdq xmm4,xmm0		; xmm4=(40 41 42 43 44 45 46 47)=data4
319
	punpckhqdq xmm1,xmm0		; xmm1=(50 51 52 53 54 55 56 57)=data5
320
321
	movdqa	xmm7,xmm6
322
	movdqa	xmm0,xmm2
323
	paddw	xmm6,xmm4		; xmm6=data3+data4=tmp3
324
	paddw	xmm2,xmm1		; xmm2=data2+data5=tmp2
325
	psubw	xmm7,xmm4		; xmm7=data3-data4=tmp4
326
	psubw	xmm0,xmm1		; xmm0=data2-data5=tmp5
327
328
	; -- Even part
329
330
	movdqa	xmm4,xmm3
331
	movdqa	xmm1,xmm5
332
	psubw	xmm3,xmm6		; xmm3=tmp13
333
	psubw	xmm5,xmm2		; xmm5=tmp12
334
	paddw	xmm4,xmm6		; xmm4=tmp10
335
	paddw	xmm1,xmm2		; xmm1=tmp11
336
337
	paddw	xmm5,xmm3
338
	psllw	xmm5,PRE_MULTIPLY_SCALE_BITS
339
	pmulhw	xmm5,[GOTOFF(ebx,PW_F0707)] ; xmm5=z1
340
341
	movdqa	xmm6,xmm4
342
	movdqa	xmm2,xmm3
343
	psubw	xmm4,xmm1		; xmm4=data4
344
	psubw	xmm3,xmm5		; xmm3=data6
345
	paddw	xmm6,xmm1		; xmm6=data0
346
	paddw	xmm2,xmm5		; xmm2=data2
347
348
	movdqa	XMMWORD [XMMBLOCK(4,0,edx,SIZEOF_DCTELEM)], xmm4
349
	movdqa	XMMWORD [XMMBLOCK(6,0,edx,SIZEOF_DCTELEM)], xmm3
350
	movdqa	XMMWORD [XMMBLOCK(0,0,edx,SIZEOF_DCTELEM)], xmm6
351
	movdqa	XMMWORD [XMMBLOCK(2,0,edx,SIZEOF_DCTELEM)], xmm2
352
353
	; -- Odd part
354
355
	movdqa	xmm1, XMMWORD [wk(0)]	; xmm1=tmp6
356
	movdqa	xmm5, XMMWORD [wk(1)]	; xmm5=tmp7
357
358
	paddw	xmm7,xmm0		; xmm7=tmp10
359
	paddw	xmm0,xmm1		; xmm0=tmp11
360
	paddw	xmm1,xmm5		; xmm1=tmp12, xmm5=tmp7
361
362
	psllw	xmm7,PRE_MULTIPLY_SCALE_BITS
363
	psllw	xmm1,PRE_MULTIPLY_SCALE_BITS
364
365
	psllw	xmm0,PRE_MULTIPLY_SCALE_BITS
366
	pmulhw	xmm0,[GOTOFF(ebx,PW_F0707)] ; xmm0=z3
367
368
	movdqa	xmm4,xmm7		; xmm4=tmp10
369
	psubw	xmm7,xmm1
370
	pmulhw	xmm7,[GOTOFF(ebx,PW_F0382)] ; xmm7=z5
371
	pmulhw	xmm4,[GOTOFF(ebx,PW_F0541)] ; xmm4=MULTIPLY(tmp10,FIX_0_541196)
372
	pmulhw	xmm1,[GOTOFF(ebx,PW_F1306)] ; xmm1=MULTIPLY(tmp12,FIX_1_306562)
373
	paddw	xmm4,xmm7		; xmm4=z2
374
	paddw	xmm1,xmm7		; xmm1=z4
375
376
	movdqa	xmm3,xmm5
377
	psubw	xmm5,xmm0		; xmm5=z13
378
	paddw	xmm3,xmm0		; xmm3=z11
379
380
	movdqa	xmm6,xmm5
381
	movdqa	xmm2,xmm3
382
	psubw	xmm5,xmm4		; xmm5=data3
383
	psubw	xmm3,xmm1		; xmm3=data7
384
	paddw	xmm6,xmm4		; xmm6=data5
385
	paddw	xmm2,xmm1		; xmm2=data1
386
387
	movdqa	XMMWORD [XMMBLOCK(3,0,edx,SIZEOF_DCTELEM)], xmm5
388
	movdqa	XMMWORD [XMMBLOCK(7,0,edx,SIZEOF_DCTELEM)], xmm3
389
	movdqa	XMMWORD [XMMBLOCK(5,0,edx,SIZEOF_DCTELEM)], xmm6
390
	movdqa	XMMWORD [XMMBLOCK(1,0,edx,SIZEOF_DCTELEM)], xmm2
391
392
;	pop	edi		; unused
393
;	pop	esi		; unused
394
;	pop	edx		; need not be preserved
395
;	pop	ecx		; unused
396
	poppic	ebx
397
	mov	esp,ebp		; esp <- aligned ebp
398
	pop	esp		; esp <- original ebp
399
	pop	ebp
400
	ret
401
402
; For some reason, the OS X linker does not honor the request to align the
403
; segment unless we do this.
404
	align	16
(-)a/jpeg/simd/jfss2int-64.asm (+622 lines)
Line     Link Here 
Line 0    Link Here 
1
;
2
; jfss2int-64.asm - accurate integer FDCT (64-bit SSE2)
3
;
4
; Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
5
; Copyright 2009 D. R. Commander
6
;
7
; Based on
8
; x86 SIMD extension for IJG JPEG library
9
; Copyright (C) 1999-2006, MIYASAKA Masaru.
10
; For conditions of distribution and use, see copyright notice in jsimdext.inc
11
;
12
; This file should be assembled with NASM (Netwide Assembler),
13
; can *not* be assembled with Microsoft's MASM or any compatible
14
; assembler (including Borland's Turbo Assembler).
15
; NASM is available from http://nasm.sourceforge.net/ or
16
; http://sourceforge.net/project/showfiles.php?group_id=6208
17
;
18
; This file contains a slow-but-accurate integer implementation of the
19
; forward DCT (Discrete Cosine Transform). The following code is based
20
; directly on the IJG's original jfdctint.c; see the jfdctint.c for
21
; more details.
22
;
23
; [TAB8]
24
25
%include "jsimdext.inc"
26
%include "jdct.inc"
27
28
; --------------------------------------------------------------------------
29
30
%define CONST_BITS	13
31
%define PASS1_BITS	2
32
33
%define DESCALE_P1	(CONST_BITS-PASS1_BITS)
34
%define DESCALE_P2	(CONST_BITS+PASS1_BITS)
35
36
%if CONST_BITS == 13
37
F_0_298	equ	 2446		; FIX(0.298631336)
38
F_0_390	equ	 3196		; FIX(0.390180644)
39
F_0_541	equ	 4433		; FIX(0.541196100)
40
F_0_765	equ	 6270		; FIX(0.765366865)
41
F_0_899	equ	 7373		; FIX(0.899976223)
42
F_1_175	equ	 9633		; FIX(1.175875602)
43
F_1_501	equ	12299		; FIX(1.501321110)
44
F_1_847	equ	15137		; FIX(1.847759065)
45
F_1_961	equ	16069		; FIX(1.961570560)
46
F_2_053	equ	16819		; FIX(2.053119869)
47
F_2_562	equ	20995		; FIX(2.562915447)
48
F_3_072	equ	25172		; FIX(3.072711026)
49
%else
50
; NASM cannot do compile-time arithmetic on floating-point constants.
51
%define DESCALE(x,n)  (((x)+(1<<((n)-1)))>>(n))
52
F_0_298	equ	DESCALE( 320652955,30-CONST_BITS)	; FIX(0.298631336)
53
F_0_390	equ	DESCALE( 418953276,30-CONST_BITS)	; FIX(0.390180644)
54
F_0_541	equ	DESCALE( 581104887,30-CONST_BITS)	; FIX(0.541196100)
55
F_0_765	equ	DESCALE( 821806413,30-CONST_BITS)	; FIX(0.765366865)
56
F_0_899	equ	DESCALE( 966342111,30-CONST_BITS)	; FIX(0.899976223)
57
F_1_175	equ	DESCALE(1262586813,30-CONST_BITS)	; FIX(1.175875602)
58
F_1_501	equ	DESCALE(1612031267,30-CONST_BITS)	; FIX(1.501321110)
59
F_1_847	equ	DESCALE(1984016188,30-CONST_BITS)	; FIX(1.847759065)
60
F_1_961	equ	DESCALE(2106220350,30-CONST_BITS)	; FIX(1.961570560)
61
F_2_053	equ	DESCALE(2204520673,30-CONST_BITS)	; FIX(2.053119869)
62
F_2_562	equ	DESCALE(2751909506,30-CONST_BITS)	; FIX(2.562915447)
63
F_3_072	equ	DESCALE(3299298341,30-CONST_BITS)	; FIX(3.072711026)
64
%endif
65
66
; --------------------------------------------------------------------------
67
	SECTION	SEG_CONST
68
69
	alignz	16
70
	global	EXTN(jconst_fdct_islow_sse2)
71
72
EXTN(jconst_fdct_islow_sse2):
73
74
PW_F130_F054	times 4 dw  (F_0_541+F_0_765), F_0_541
75
PW_F054_MF130	times 4 dw  F_0_541, (F_0_541-F_1_847)
76
PW_MF078_F117	times 4 dw  (F_1_175-F_1_961), F_1_175
77
PW_F117_F078	times 4 dw  F_1_175, (F_1_175-F_0_390)
78
PW_MF060_MF089	times 4 dw  (F_0_298-F_0_899),-F_0_899
79
PW_MF089_F060	times 4 dw -F_0_899, (F_1_501-F_0_899)
80
PW_MF050_MF256	times 4 dw  (F_2_053-F_2_562),-F_2_562
81
PW_MF256_F050	times 4 dw -F_2_562, (F_3_072-F_2_562)
82
PD_DESCALE_P1	times 4 dd  1 << (DESCALE_P1-1)
83
PD_DESCALE_P2	times 4 dd  1 << (DESCALE_P2-1)
84
PW_DESCALE_P2X	times 8 dw  1 << (PASS1_BITS-1)
85
86
	alignz	16
87
88
; --------------------------------------------------------------------------
89
	SECTION	SEG_TEXT
90
	BITS	64
91
;
92
; Perform the forward DCT on one block of samples.
93
;
94
; GLOBAL(void)
95
; jsimd_fdct_islow_sse2 (DCTELEM * data)
96
;
97
98
; r10 = DCTELEM * data
99
100
%define wk(i)		rbp-(WK_NUM-(i))*SIZEOF_XMMWORD	; xmmword wk[WK_NUM]
101
%define WK_NUM		6
102
103
	align	16
104
	global	EXTN(jsimd_fdct_islow_sse2)
105
106
EXTN(jsimd_fdct_islow_sse2):
107
	push	rbp
108
	mov	rax,rsp				; rax = original rbp
109
	sub	rsp, byte 4
110
	and	rsp, byte (-SIZEOF_XMMWORD)	; align to 128 bits
111
	mov	[rsp],rax
112
	mov	rbp,rsp				; rbp = aligned rbp
113
	lea	rsp, [wk(0)]
114
	collect_args
115
116
	; ---- Pass 1: process rows.
117
118
	mov	rdx, r10	; (DCTELEM *)
119
120
	movdqa	xmm0, XMMWORD [XMMBLOCK(0,0,rdx,SIZEOF_DCTELEM)]
121
	movdqa	xmm1, XMMWORD [XMMBLOCK(1,0,rdx,SIZEOF_DCTELEM)]
122
	movdqa	xmm2, XMMWORD [XMMBLOCK(2,0,rdx,SIZEOF_DCTELEM)]
123
	movdqa	xmm3, XMMWORD [XMMBLOCK(3,0,rdx,SIZEOF_DCTELEM)]
124
125
	; xmm0=(00 01 02 03 04 05 06 07), xmm2=(20 21 22 23 24 25 26 27)
126
	; xmm1=(10 11 12 13 14 15 16 17), xmm3=(30 31 32 33 34 35 36 37)
127
128
	movdqa    xmm4,xmm0		; transpose coefficients(phase 1)
129
	punpcklwd xmm0,xmm1		; xmm0=(00 10 01 11 02 12 03 13)
130
	punpckhwd xmm4,xmm1		; xmm4=(04 14 05 15 06 16 07 17)
131
	movdqa    xmm5,xmm2		; transpose coefficients(phase 1)
132
	punpcklwd xmm2,xmm3		; xmm2=(20 30 21 31 22 32 23 33)
133
	punpckhwd xmm5,xmm3		; xmm5=(24 34 25 35 26 36 27 37)
134
135
	movdqa	xmm6, XMMWORD [XMMBLOCK(4,0,rdx,SIZEOF_DCTELEM)]
136
	movdqa	xmm7, XMMWORD [XMMBLOCK(5,0,rdx,SIZEOF_DCTELEM)]
137
	movdqa	xmm1, XMMWORD [XMMBLOCK(6,0,rdx,SIZEOF_DCTELEM)]
138
	movdqa	xmm3, XMMWORD [XMMBLOCK(7,0,rdx,SIZEOF_DCTELEM)]
139
140
	; xmm6=( 4 12 20 28 36 44 52 60), xmm1=( 6 14 22 30 38 46 54 62)
141
	; xmm7=( 5 13 21 29 37 45 53 61), xmm3=( 7 15 23 31 39 47 55 63)
142
143
	movdqa	XMMWORD [wk(0)], xmm2	; wk(0)=(20 30 21 31 22 32 23 33)
144
	movdqa	XMMWORD [wk(1)], xmm5	; wk(1)=(24 34 25 35 26 36 27 37)
145
146
	movdqa    xmm2,xmm6		; transpose coefficients(phase 1)
147
	punpcklwd xmm6,xmm7		; xmm6=(40 50 41 51 42 52 43 53)
148
	punpckhwd xmm2,xmm7		; xmm2=(44 54 45 55 46 56 47 57)
149
	movdqa    xmm5,xmm1		; transpose coefficients(phase 1)
150
	punpcklwd xmm1,xmm3		; xmm1=(60 70 61 71 62 72 63 73)
151
	punpckhwd xmm5,xmm3		; xmm5=(64 74 65 75 66 76 67 77)
152
153
	movdqa    xmm7,xmm6		; transpose coefficients(phase 2)
154
	punpckldq xmm6,xmm1		; xmm6=(40 50 60 70 41 51 61 71)
155
	punpckhdq xmm7,xmm1		; xmm7=(42 52 62 72 43 53 63 73)
156
	movdqa    xmm3,xmm2		; transpose coefficients(phase 2)
157
	punpckldq xmm2,xmm5		; xmm2=(44 54 64 74 45 55 65 75)
158
	punpckhdq xmm3,xmm5		; xmm3=(46 56 66 76 47 57 67 77)
159
160
	movdqa	xmm1, XMMWORD [wk(0)]	; xmm1=(20 30 21 31 22 32 23 33)
161
	movdqa	xmm5, XMMWORD [wk(1)]	; xmm5=(24 34 25 35 26 36 27 37)
162
	movdqa	XMMWORD [wk(2)], xmm7	; wk(2)=(42 52 62 72 43 53 63 73)
163
	movdqa	XMMWORD [wk(3)], xmm2	; wk(3)=(44 54 64 74 45 55 65 75)
164
165
	movdqa    xmm7,xmm0		; transpose coefficients(phase 2)
166
	punpckldq xmm0,xmm1		; xmm0=(00 10 20 30 01 11 21 31)
167
	punpckhdq xmm7,xmm1		; xmm7=(02 12 22 32 03 13 23 33)
168
	movdqa    xmm2,xmm4		; transpose coefficients(phase 2)
169
	punpckldq xmm4,xmm5		; xmm4=(04 14 24 34 05 15 25 35)
170
	punpckhdq xmm2,xmm5		; xmm2=(06 16 26 36 07 17 27 37)
171
172
	movdqa     xmm1,xmm0		; transpose coefficients(phase 3)
173
	punpcklqdq xmm0,xmm6		; xmm0=(00 10 20 30 40 50 60 70)=data0
174
	punpckhqdq xmm1,xmm6		; xmm1=(01 11 21 31 41 51 61 71)=data1
175
	movdqa     xmm5,xmm2		; transpose coefficients(phase 3)
176
	punpcklqdq xmm2,xmm3		; xmm2=(06 16 26 36 46 56 66 76)=data6
177
	punpckhqdq xmm5,xmm3		; xmm5=(07 17 27 37 47 57 67 77)=data7
178
179
	movdqa	xmm6,xmm1
180
	movdqa	xmm3,xmm0
181
	psubw	xmm1,xmm2		; xmm1=data1-data6=tmp6
182
	psubw	xmm0,xmm5		; xmm0=data0-data7=tmp7
183
	paddw	xmm6,xmm2		; xmm6=data1+data6=tmp1
184
	paddw	xmm3,xmm5		; xmm3=data0+data7=tmp0
185
186
	movdqa	xmm2, XMMWORD [wk(2)]	; xmm2=(42 52 62 72 43 53 63 73)
187
	movdqa	xmm5, XMMWORD [wk(3)]	; xmm5=(44 54 64 74 45 55 65 75)
188
	movdqa	XMMWORD [wk(0)], xmm1	; wk(0)=tmp6
189
	movdqa	XMMWORD [wk(1)], xmm0	; wk(1)=tmp7
190
191
	movdqa     xmm1,xmm7		; transpose coefficients(phase 3)
192
	punpcklqdq xmm7,xmm2		; xmm7=(02 12 22 32 42 52 62 72)=data2
193
	punpckhqdq xmm1,xmm2		; xmm1=(03 13 23 33 43 53 63 73)=data3
194
	movdqa     xmm0,xmm4		; transpose coefficients(phase 3)
195
	punpcklqdq xmm4,xmm5		; xmm4=(04 14 24 34 44 54 64 74)=data4
196
	punpckhqdq xmm0,xmm5		; xmm0=(05 15 25 35 45 55 65 75)=data5
197
198
	movdqa	xmm2,xmm1
199
	movdqa	xmm5,xmm7
200
	paddw	xmm1,xmm4		; xmm1=data3+data4=tmp3
201
	paddw	xmm7,xmm0		; xmm7=data2+data5=tmp2
202
	psubw	xmm2,xmm4		; xmm2=data3-data4=tmp4
203
	psubw	xmm5,xmm0		; xmm5=data2-data5=tmp5
204
205
	; -- Even part
206
207
	movdqa	xmm4,xmm3
208
	movdqa	xmm0,xmm6
209
	paddw	xmm3,xmm1		; xmm3=tmp10
210
	paddw	xmm6,xmm7		; xmm6=tmp11
211
	psubw	xmm4,xmm1		; xmm4=tmp13
212
	psubw	xmm0,xmm7		; xmm0=tmp12
213
214
	movdqa	xmm1,xmm3
215
	paddw	xmm3,xmm6		; xmm3=tmp10+tmp11
216
	psubw	xmm1,xmm6		; xmm1=tmp10-tmp11
217
218
	psllw	xmm3,PASS1_BITS		; xmm3=data0
219
	psllw	xmm1,PASS1_BITS		; xmm1=data4
220
221
	movdqa	XMMWORD [wk(2)], xmm3	; wk(2)=data0
222
	movdqa	XMMWORD [wk(3)], xmm1	; wk(3)=data4
223
224
	; (Original)
225
	; z1 = (tmp12 + tmp13) * 0.541196100;
226
	; data2 = z1 + tmp13 * 0.765366865;
227
	; data6 = z1 + tmp12 * -1.847759065;
228
	;
229
	; (This implementation)
230
	; data2 = tmp13 * (0.541196100 + 0.765366865) + tmp12 * 0.541196100;
231
	; data6 = tmp13 * 0.541196100 + tmp12 * (0.541196100 - 1.847759065);
232
233
	movdqa    xmm7,xmm4		; xmm4=tmp13
234
	movdqa    xmm6,xmm4
235
	punpcklwd xmm7,xmm0		; xmm0=tmp12
236
	punpckhwd xmm6,xmm0
237
	movdqa    xmm4,xmm7
238
	movdqa    xmm0,xmm6
239
	pmaddwd   xmm7,[rel PW_F130_F054]	; xmm7=data2L
240
	pmaddwd   xmm6,[rel PW_F130_F054]	; xmm6=data2H
241
	pmaddwd   xmm4,[rel PW_F054_MF130]	; xmm4=data6L
242
	pmaddwd   xmm0,[rel PW_F054_MF130]	; xmm0=data6H
243
244
	paddd	xmm7,[rel PD_DESCALE_P1]
245
	paddd	xmm6,[rel PD_DESCALE_P1]
246
	psrad	xmm7,DESCALE_P1
247
	psrad	xmm6,DESCALE_P1
248
	paddd	xmm4,[rel PD_DESCALE_P1]
249
	paddd	xmm0,[rel PD_DESCALE_P1]
250
	psrad	xmm4,DESCALE_P1
251
	psrad	xmm0,DESCALE_P1
252
253
	packssdw  xmm7,xmm6		; xmm7=data2
254
	packssdw  xmm4,xmm0		; xmm4=data6
255
256
	movdqa	XMMWORD [wk(4)], xmm7	; wk(4)=data2
257
	movdqa	XMMWORD [wk(5)], xmm4	; wk(5)=data6
258
259
	; -- Odd part
260
261
	movdqa	xmm3, XMMWORD [wk(0)]	; xmm3=tmp6
262
	movdqa	xmm1, XMMWORD [wk(1)]	; xmm1=tmp7
263
264
	movdqa	xmm6,xmm2		; xmm2=tmp4
265
	movdqa	xmm0,xmm5		; xmm5=tmp5
266
	paddw	xmm6,xmm3		; xmm6=z3
267
	paddw	xmm0,xmm1		; xmm0=z4
268
269
	; (Original)
270
	; z5 = (z3 + z4) * 1.175875602;
271
	; z3 = z3 * -1.961570560;  z4 = z4 * -0.390180644;
272
	; z3 += z5;  z4 += z5;
273
	;
274
	; (This implementation)
275
	; z3 = z3 * (1.175875602 - 1.961570560) + z4 * 1.175875602;
276
	; z4 = z3 * 1.175875602 + z4 * (1.175875602 - 0.390180644);
277
278
	movdqa    xmm7,xmm6
279
	movdqa    xmm4,xmm6
280
	punpcklwd xmm7,xmm0
281
	punpckhwd xmm4,xmm0
282
	movdqa    xmm6,xmm7
283
	movdqa    xmm0,xmm4
284
	pmaddwd   xmm7,[rel PW_MF078_F117]	; xmm7=z3L
285
	pmaddwd   xmm4,[rel PW_MF078_F117]	; xmm4=z3H
286
	pmaddwd   xmm6,[rel PW_F117_F078]	; xmm6=z4L
287
	pmaddwd   xmm0,[rel PW_F117_F078]	; xmm0=z4H
288
289
	movdqa	XMMWORD [wk(0)], xmm7	; wk(0)=z3L
290
	movdqa	XMMWORD [wk(1)], xmm4	; wk(1)=z3H
291
292
	; (Original)
293
	; z1 = tmp4 + tmp7;  z2 = tmp5 + tmp6;
294
	; tmp4 = tmp4 * 0.298631336;  tmp5 = tmp5 * 2.053119869;
295
	; tmp6 = tmp6 * 3.072711026;  tmp7 = tmp7 * 1.501321110;
296
	; z1 = z1 * -0.899976223;  z2 = z2 * -2.562915447;
297
	; data7 = tmp4 + z1 + z3;  data5 = tmp5 + z2 + z4;
298
	; data3 = tmp6 + z2 + z3;  data1 = tmp7 + z1 + z4;
299
	;
300
	; (This implementation)
301
	; tmp4 = tmp4 * (0.298631336 - 0.899976223) + tmp7 * -0.899976223;
302
	; tmp5 = tmp5 * (2.053119869 - 2.562915447) + tmp6 * -2.562915447;
303
	; tmp6 = tmp5 * -2.562915447 + tmp6 * (3.072711026 - 2.562915447);
304
	; tmp7 = tmp4 * -0.899976223 + tmp7 * (1.501321110 - 0.899976223);
305
	; data7 = tmp4 + z3;  data5 = tmp5 + z4;
306
	; data3 = tmp6 + z3;  data1 = tmp7 + z4;
307
308
	movdqa    xmm7,xmm2
309
	movdqa    xmm4,xmm2
310
	punpcklwd xmm7,xmm1
311
	punpckhwd xmm4,xmm1
312
	movdqa    xmm2,xmm7
313
	movdqa    xmm1,xmm4
314
	pmaddwd   xmm7,[rel PW_MF060_MF089]	; xmm7=tmp4L
315
	pmaddwd   xmm4,[rel PW_MF060_MF089]	; xmm4=tmp4H
316
	pmaddwd   xmm2,[rel PW_MF089_F060]	; xmm2=tmp7L
317
	pmaddwd   xmm1,[rel PW_MF089_F060]	; xmm1=tmp7H
318
319
	paddd	xmm7, XMMWORD [wk(0)]	; xmm7=data7L
320
	paddd	xmm4, XMMWORD [wk(1)]	; xmm4=data7H
321
	paddd	xmm2,xmm6		; xmm2=data1L
322
	paddd	xmm1,xmm0		; xmm1=data1H
323
324
	paddd	xmm7,[rel PD_DESCALE_P1]
325
	paddd	xmm4,[rel PD_DESCALE_P1]
326
	psrad	xmm7,DESCALE_P1
327
	psrad	xmm4,DESCALE_P1
328
	paddd	xmm2,[rel PD_DESCALE_P1]
329
	paddd	xmm1,[rel PD_DESCALE_P1]
330
	psrad	xmm2,DESCALE_P1
331
	psrad	xmm1,DESCALE_P1
332
333
	packssdw  xmm7,xmm4		; xmm7=data7
334
	packssdw  xmm2,xmm1		; xmm2=data1
335
336
	movdqa    xmm4,xmm5
337
	movdqa    xmm1,xmm5
338
	punpcklwd xmm4,xmm3
339
	punpckhwd xmm1,xmm3
340
	movdqa    xmm5,xmm4
341
	movdqa    xmm3,xmm1
342
	pmaddwd   xmm4,[rel PW_MF050_MF256]	; xmm4=tmp5L
343
	pmaddwd   xmm1,[rel PW_MF050_MF256]	; xmm1=tmp5H
344
	pmaddwd   xmm5,[rel PW_MF256_F050]	; xmm5=tmp6L
345
	pmaddwd   xmm3,[rel PW_MF256_F050]	; xmm3=tmp6H
346
347
	paddd	xmm4,xmm6		; xmm4=data5L
348
	paddd	xmm1,xmm0		; xmm1=data5H
349
	paddd	xmm5, XMMWORD [wk(0)]	; xmm5=data3L
350
	paddd	xmm3, XMMWORD [wk(1)]	; xmm3=data3H
351
352
	paddd	xmm4,[rel PD_DESCALE_P1]
353
	paddd	xmm1,[rel PD_DESCALE_P1]
354
	psrad	xmm4,DESCALE_P1
355
	psrad	xmm1,DESCALE_P1
356
	paddd	xmm5,[rel PD_DESCALE_P1]
357
	paddd	xmm3,[rel PD_DESCALE_P1]
358
	psrad	xmm5,DESCALE_P1
359
	psrad	xmm3,DESCALE_P1
360
361
	packssdw  xmm4,xmm1		; xmm4=data5
362
	packssdw  xmm5,xmm3		; xmm5=data3
363
364
	; ---- Pass 2: process columns.
365
366
	movdqa	xmm6, XMMWORD [wk(2)]	; xmm6=col0
367
	movdqa	xmm0, XMMWORD [wk(4)]	; xmm0=col2
368
369
	; xmm6=(00 10 20 30 40 50 60 70), xmm0=(02 12 22 32 42 52 62 72)
370
	; xmm2=(01 11 21 31 41 51 61 71), xmm5=(03 13 23 33 43 53 63 73)
371
372
	movdqa    xmm1,xmm6		; transpose coefficients(phase 1)
373
	punpcklwd xmm6,xmm2		; xmm6=(00 01 10 11 20 21 30 31)
374
	punpckhwd xmm1,xmm2		; xmm1=(40 41 50 51 60 61 70 71)
375
	movdqa    xmm3,xmm0		; transpose coefficients(phase 1)
376
	punpcklwd xmm0,xmm5		; xmm0=(02 03 12 13 22 23 32 33)
377
	punpckhwd xmm3,xmm5		; xmm3=(42 43 52 53 62 63 72 73)
378
379
	movdqa	xmm2, XMMWORD [wk(3)]	; xmm2=col4
380
	movdqa	xmm5, XMMWORD [wk(5)]	; xmm5=col6
381
382
	; xmm2=(04 14 24 34 44 54 64 74), xmm5=(06 16 26 36 46 56 66 76)
383
	; xmm4=(05 15 25 35 45 55 65 75), xmm7=(07 17 27 37 47 57 67 77)
384
385
	movdqa	XMMWORD [wk(0)], xmm0	; wk(0)=(02 03 12 13 22 23 32 33)
386
	movdqa	XMMWORD [wk(1)], xmm3	; wk(1)=(42 43 52 53 62 63 72 73)
387
388
	movdqa    xmm0,xmm2		; transpose coefficients(phase 1)
389
	punpcklwd xmm2,xmm4		; xmm2=(04 05 14 15 24 25 34 35)
390
	punpckhwd xmm0,xmm4		; xmm0=(44 45 54 55 64 65 74 75)
391
	movdqa    xmm3,xmm5		; transpose coefficients(phase 1)
392
	punpcklwd xmm5,xmm7		; xmm5=(06 07 16 17 26 27 36 37)
393
	punpckhwd xmm3,xmm7		; xmm3=(46 47 56 57 66 67 76 77)
394
395
	movdqa    xmm4,xmm2		; transpose coefficients(phase 2)
396
	punpckldq xmm2,xmm5		; xmm2=(04 05 06 07 14 15 16 17)
397
	punpckhdq xmm4,xmm5		; xmm4=(24 25 26 27 34 35 36 37)
398
	movdqa    xmm7,xmm0		; transpose coefficients(phase 2)
399
	punpckldq xmm0,xmm3		; xmm0=(44 45 46 47 54 55 56 57)
400
	punpckhdq xmm7,xmm3		; xmm7=(64 65 66 67 74 75 76 77)
401
402
	movdqa	xmm5, XMMWORD [wk(0)]	; xmm5=(02 03 12 13 22 23 32 33)
403
	movdqa	xmm3, XMMWORD [wk(1)]	; xmm3=(42 43 52 53 62 63 72 73)
404
	movdqa	XMMWORD [wk(2)], xmm4	; wk(2)=(24 25 26 27 34 35 36 37)
405
	movdqa	XMMWORD [wk(3)], xmm0	; wk(3)=(44 45 46 47 54 55 56 57)
406
407
	movdqa    xmm4,xmm6		; transpose coefficients(phase 2)
408
	punpckldq xmm6,xmm5		; xmm6=(00 01 02 03 10 11 12 13)
409
	punpckhdq xmm4,xmm5		; xmm4=(20 21 22 23 30 31 32 33)
410
	movdqa    xmm0,xmm1		; transpose coefficients(phase 2)
411
	punpckldq xmm1,xmm3		; xmm1=(40 41 42 43 50 51 52 53)
412
	punpckhdq xmm0,xmm3		; xmm0=(60 61 62 63 70 71 72 73)
413
414
	movdqa     xmm5,xmm6		; transpose coefficients(phase 3)
415
	punpcklqdq xmm6,xmm2		; xmm6=(00 01 02 03 04 05 06 07)=data0
416
	punpckhqdq xmm5,xmm2		; xmm5=(10 11 12 13 14 15 16 17)=data1
417
	movdqa     xmm3,xmm0		; transpose coefficients(phase 3)
418
	punpcklqdq xmm0,xmm7		; xmm0=(60 61 62 63 64 65 66 67)=data6
419
	punpckhqdq xmm3,xmm7		; xmm3=(70 71 72 73 74 75 76 77)=data7
420
421
	movdqa	xmm2,xmm5
422
	movdqa	xmm7,xmm6
423
	psubw	xmm5,xmm0		; xmm5=data1-data6=tmp6
424
	psubw	xmm6,xmm3		; xmm6=data0-data7=tmp7
425
	paddw	xmm2,xmm0		; xmm2=data1+data6=tmp1
426
	paddw	xmm7,xmm3		; xmm7=data0+data7=tmp0
427
428
	movdqa	xmm0, XMMWORD [wk(2)]	; xmm0=(24 25 26 27 34 35 36 37)
429
	movdqa	xmm3, XMMWORD [wk(3)]	; xmm3=(44 45 46 47 54 55 56 57)
430
	movdqa	XMMWORD [wk(0)], xmm5	; wk(0)=tmp6
431
	movdqa	XMMWORD [wk(1)], xmm6	; wk(1)=tmp7
432
433
	movdqa     xmm5,xmm4		; transpose coefficients(phase 3)
434
	punpcklqdq xmm4,xmm0		; xmm4=(20 21 22 23 24 25 26 27)=data2
435
	punpckhqdq xmm5,xmm0		; xmm5=(30 31 32 33 34 35 36 37)=data3
436
	movdqa     xmm6,xmm1		; transpose coefficients(phase 3)
437
	punpcklqdq xmm1,xmm3		; xmm1=(40 41 42 43 44 45 46 47)=data4
438
	punpckhqdq xmm6,xmm3		; xmm6=(50 51 52 53 54 55 56 57)=data5
439
440
	movdqa	xmm0,xmm5
441
	movdqa	xmm3,xmm4
442
	paddw	xmm5,xmm1		; xmm5=data3+data4=tmp3
443
	paddw	xmm4,xmm6		; xmm4=data2+data5=tmp2
444
	psubw	xmm0,xmm1		; xmm0=data3-data4=tmp4
445
	psubw	xmm3,xmm6		; xmm3=data2-data5=tmp5
446
447
	; -- Even part
448
449
	movdqa	xmm1,xmm7
450
	movdqa	xmm6,xmm2
451
	paddw	xmm7,xmm5		; xmm7=tmp10
452
	paddw	xmm2,xmm4		; xmm2=tmp11
453
	psubw	xmm1,xmm5		; xmm1=tmp13
454
	psubw	xmm6,xmm4		; xmm6=tmp12
455
456
	movdqa	xmm5,xmm7
457
	paddw	xmm7,xmm2		; xmm7=tmp10+tmp11
458
	psubw	xmm5,xmm2		; xmm5=tmp10-tmp11
459
460
	paddw	xmm7,[rel PW_DESCALE_P2X]
461
	paddw	xmm5,[rel PW_DESCALE_P2X]
462
	psraw	xmm7,PASS1_BITS		; xmm7=data0
463
	psraw	xmm5,PASS1_BITS		; xmm5=data4
464
465
	movdqa	XMMWORD [XMMBLOCK(0,0,rdx,SIZEOF_DCTELEM)], xmm7
466
	movdqa	XMMWORD [XMMBLOCK(4,0,rdx,SIZEOF_DCTELEM)], xmm5
467
468
	; (Original)
469
	; z1 = (tmp12 + tmp13) * 0.541196100;
470
	; data2 = z1 + tmp13 * 0.765366865;
471
	; data6 = z1 + tmp12 * -1.847759065;
472
	;
473
	; (This implementation)
474
	; data2 = tmp13 * (0.541196100 + 0.765366865) + tmp12 * 0.541196100;
475
	; data6 = tmp13 * 0.541196100 + tmp12 * (0.541196100 - 1.847759065);
476
477
	movdqa    xmm4,xmm1		; xmm1=tmp13
478
	movdqa    xmm2,xmm1
479
	punpcklwd xmm4,xmm6		; xmm6=tmp12
480
	punpckhwd xmm2,xmm6
481
	movdqa    xmm1,xmm4
482
	movdqa    xmm6,xmm2
483
	pmaddwd   xmm4,[rel PW_F130_F054]	; xmm4=data2L
484
	pmaddwd   xmm2,[rel PW_F130_F054]	; xmm2=data2H
485
	pmaddwd   xmm1,[rel PW_F054_MF130]	; xmm1=data6L
486
	pmaddwd   xmm6,[rel PW_F054_MF130]	; xmm6=data6H
487
488
	paddd	xmm4,[rel PD_DESCALE_P2]
489
	paddd	xmm2,[rel PD_DESCALE_P2]
490
	psrad	xmm4,DESCALE_P2
491
	psrad	xmm2,DESCALE_P2
492
	paddd	xmm1,[rel PD_DESCALE_P2]
493
	paddd	xmm6,[rel PD_DESCALE_P2]
494
	psrad	xmm1,DESCALE_P2
495
	psrad	xmm6,DESCALE_P2
496
497
	packssdw  xmm4,xmm2		; xmm4=data2
498
	packssdw  xmm1,xmm6		; xmm1=data6
499
500
	movdqa	XMMWORD [XMMBLOCK(2,0,rdx,SIZEOF_DCTELEM)], xmm4
501
	movdqa	XMMWORD [XMMBLOCK(6,0,rdx,SIZEOF_DCTELEM)], xmm1
502
503
	; -- Odd part
504
505
	movdqa	xmm7, XMMWORD [wk(0)]	; xmm7=tmp6
506
	movdqa	xmm5, XMMWORD [wk(1)]	; xmm5=tmp7
507
508
	movdqa	xmm2,xmm0		; xmm0=tmp4
509
	movdqa	xmm6,xmm3		; xmm3=tmp5
510
	paddw	xmm2,xmm7		; xmm2=z3
511
	paddw	xmm6,xmm5		; xmm6=z4
512
513
	; (Original)
514
	; z5 = (z3 + z4) * 1.175875602;
515
	; z3 = z3 * -1.961570560;  z4 = z4 * -0.390180644;
516
	; z3 += z5;  z4 += z5;
517
	;
518
	; (This implementation)
519
	; z3 = z3 * (1.175875602 - 1.961570560) + z4 * 1.175875602;
520
	; z4 = z3 * 1.175875602 + z4 * (1.175875602 - 0.390180644);
521
522
	movdqa    xmm4,xmm2
523
	movdqa    xmm1,xmm2
524
	punpcklwd xmm4,xmm6
525
	punpckhwd xmm1,xmm6
526
	movdqa    xmm2,xmm4
527
	movdqa    xmm6,xmm1
528
	pmaddwd   xmm4,[rel PW_MF078_F117]	; xmm4=z3L
529
	pmaddwd   xmm1,[rel PW_MF078_F117]	; xmm1=z3H
530
	pmaddwd   xmm2,[rel PW_F117_F078]	; xmm2=z4L
531
	pmaddwd   xmm6,[rel PW_F117_F078]	; xmm6=z4H
532
533
	movdqa	XMMWORD [wk(0)], xmm4	; wk(0)=z3L
534
	movdqa	XMMWORD [wk(1)], xmm1	; wk(1)=z3H
535
536
	; (Original)
537
	; z1 = tmp4 + tmp7;  z2 = tmp5 + tmp6;
538
	; tmp4 = tmp4 * 0.298631336;  tmp5 = tmp5 * 2.053119869;
539
	; tmp6 = tmp6 * 3.072711026;  tmp7 = tmp7 * 1.501321110;
540
	; z1 = z1 * -0.899976223;  z2 = z2 * -2.562915447;
541
	; data7 = tmp4 + z1 + z3;  data5 = tmp5 + z2 + z4;
542
	; data3 = tmp6 + z2 + z3;  data1 = tmp7 + z1 + z4;
543
	;
544
	; (This implementation)
545
	; tmp4 = tmp4 * (0.298631336 - 0.899976223) + tmp7 * -0.899976223;
546
	; tmp5 = tmp5 * (2.053119869 - 2.562915447) + tmp6 * -2.562915447;
547
	; tmp6 = tmp5 * -2.562915447 + tmp6 * (3.072711026 - 2.562915447);
548
	; tmp7 = tmp4 * -0.899976223 + tmp7 * (1.501321110 - 0.899976223);
549
	; data7 = tmp4 + z3;  data5 = tmp5 + z4;
550
	; data3 = tmp6 + z3;  data1 = tmp7 + z4;
551
552
	movdqa    xmm4,xmm0
553
	movdqa    xmm1,xmm0
554
	punpcklwd xmm4,xmm5
555
	punpckhwd xmm1,xmm5
556
	movdqa    xmm0,xmm4
557
	movdqa    xmm5,xmm1
558
	pmaddwd   xmm4,[rel PW_MF060_MF089]	; xmm4=tmp4L
559
	pmaddwd   xmm1,[rel PW_MF060_MF089]	; xmm1=tmp4H
560
	pmaddwd   xmm0,[rel PW_MF089_F060]	; xmm0=tmp7L
561
	pmaddwd   xmm5,[rel PW_MF089_F060]	; xmm5=tmp7H
562
563
	paddd	xmm4, XMMWORD [wk(0)]	; xmm4=data7L
564
	paddd	xmm1, XMMWORD [wk(1)]	; xmm1=data7H
565
	paddd	xmm0,xmm2		; xmm0=data1L
566
	paddd	xmm5,xmm6		; xmm5=data1H
567
568
	paddd	xmm4,[rel PD_DESCALE_P2]
569
	paddd	xmm1,[rel PD_DESCALE_P2]
570
	psrad	xmm4,DESCALE_P2
571
	psrad	xmm1,DESCALE_P2
572
	paddd	xmm0,[rel PD_DESCALE_P2]
573
	paddd	xmm5,[rel PD_DESCALE_P2]
574
	psrad	xmm0,DESCALE_P2
575
	psrad	xmm5,DESCALE_P2
576
577
	packssdw  xmm4,xmm1		; xmm4=data7
578
	packssdw  xmm0,xmm5		; xmm0=data1
579
580
	movdqa	XMMWORD [XMMBLOCK(7,0,rdx,SIZEOF_DCTELEM)], xmm4
581
	movdqa	XMMWORD [XMMBLOCK(1,0,rdx,SIZEOF_DCTELEM)], xmm0
582
583
	movdqa    xmm1,xmm3
584
	movdqa    xmm5,xmm3
585
	punpcklwd xmm1,xmm7
586
	punpckhwd xmm5,xmm7
587
	movdqa    xmm3,xmm1
588
	movdqa    xmm7,xmm5
589
	pmaddwd   xmm1,[rel PW_MF050_MF256]	; xmm1=tmp5L
590
	pmaddwd   xmm5,[rel PW_MF050_MF256]	; xmm5=tmp5H
591
	pmaddwd   xmm3,[rel PW_MF256_F050]	; xmm3=tmp6L
592
	pmaddwd   xmm7,[rel PW_MF256_F050]	; xmm7=tmp6H
593
594
	paddd	xmm1,xmm2		; xmm1=data5L
595
	paddd	xmm5,xmm6		; xmm5=data5H
596
	paddd	xmm3, XMMWORD [wk(0)]	; xmm3=data3L
597
	paddd	xmm7, XMMWORD [wk(1)]	; xmm7=data3H
598
599
	paddd	xmm1,[rel PD_DESCALE_P2]
600
	paddd	xmm5,[rel PD_DESCALE_P2]
601
	psrad	xmm1,DESCALE_P2
602
	psrad	xmm5,DESCALE_P2
603
	paddd	xmm3,[rel PD_DESCALE_P2]
604
	paddd	xmm7,[rel PD_DESCALE_P2]
605
	psrad	xmm3,DESCALE_P2
606
	psrad	xmm7,DESCALE_P2
607
608
	packssdw  xmm1,xmm5		; xmm1=data5
609
	packssdw  xmm3,xmm7		; xmm3=data3
610
611
	movdqa	XMMWORD [XMMBLOCK(5,0,rdx,SIZEOF_DCTELEM)], xmm1
612
	movdqa	XMMWORD [XMMBLOCK(3,0,rdx,SIZEOF_DCTELEM)], xmm3
613
614
	uncollect_args
615
	mov	rsp,rbp		; rsp <- aligned rbp
616
	pop	rsp		; rsp <- original rbp
617
	pop	rbp
618
	ret
619
620
; For some reason, the OS X linker does not honor the request to align the
621
; segment unless we do this.
622
	align	16
(-)a/jpeg/simd/jfss2int.asm (+634 lines)
Line     Link Here 
Line 0    Link Here 
1
;
2
; jfss2int.asm - accurate integer FDCT (SSE2)
3
;
4
; Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
5
;
6
; Based on
7
; x86 SIMD extension for IJG JPEG library
8
; Copyright (C) 1999-2006, MIYASAKA Masaru.
9
; For conditions of distribution and use, see copyright notice in jsimdext.inc
10
;
11
; This file should be assembled with NASM (Netwide Assembler),
12
; can *not* be assembled with Microsoft's MASM or any compatible
13
; assembler (including Borland's Turbo Assembler).
14
; NASM is available from http://nasm.sourceforge.net/ or
15
; http://sourceforge.net/project/showfiles.php?group_id=6208
16
;
17
; This file contains a slow-but-accurate integer implementation of the
18
; forward DCT (Discrete Cosine Transform). The following code is based
19
; directly on the IJG's original jfdctint.c; see the jfdctint.c for
20
; more details.
21
;
22
; [TAB8]
23
24
%include "jsimdext.inc"
25
%include "jdct.inc"
26
27
; --------------------------------------------------------------------------
28
29
%define CONST_BITS	13
30
%define PASS1_BITS	2
31
32
%define DESCALE_P1	(CONST_BITS-PASS1_BITS)
33
%define DESCALE_P2	(CONST_BITS+PASS1_BITS)
34
35
%if CONST_BITS == 13
36
F_0_298	equ	 2446		; FIX(0.298631336)
37
F_0_390	equ	 3196		; FIX(0.390180644)
38
F_0_541	equ	 4433		; FIX(0.541196100)
39
F_0_765	equ	 6270		; FIX(0.765366865)
40
F_0_899	equ	 7373		; FIX(0.899976223)
41
F_1_175	equ	 9633		; FIX(1.175875602)
42
F_1_501	equ	12299		; FIX(1.501321110)
43
F_1_847	equ	15137		; FIX(1.847759065)
44
F_1_961	equ	16069		; FIX(1.961570560)
45
F_2_053	equ	16819		; FIX(2.053119869)
46
F_2_562	equ	20995		; FIX(2.562915447)
47
F_3_072	equ	25172		; FIX(3.072711026)
48
%else
49
; NASM cannot do compile-time arithmetic on floating-point constants.
50
%define DESCALE(x,n)  (((x)+(1<<((n)-1)))>>(n))
51
F_0_298	equ	DESCALE( 320652955,30-CONST_BITS)	; FIX(0.298631336)
52
F_0_390	equ	DESCALE( 418953276,30-CONST_BITS)	; FIX(0.390180644)
53
F_0_541	equ	DESCALE( 581104887,30-CONST_BITS)	; FIX(0.541196100)
54
F_0_765	equ	DESCALE( 821806413,30-CONST_BITS)	; FIX(0.765366865)
55
F_0_899	equ	DESCALE( 966342111,30-CONST_BITS)	; FIX(0.899976223)
56
F_1_175	equ	DESCALE(1262586813,30-CONST_BITS)	; FIX(1.175875602)
57
F_1_501	equ	DESCALE(1612031267,30-CONST_BITS)	; FIX(1.501321110)
58
F_1_847	equ	DESCALE(1984016188,30-CONST_BITS)	; FIX(1.847759065)
59
F_1_961	equ	DESCALE(2106220350,30-CONST_BITS)	; FIX(1.961570560)
60
F_2_053	equ	DESCALE(2204520673,30-CONST_BITS)	; FIX(2.053119869)
61
F_2_562	equ	DESCALE(2751909506,30-CONST_BITS)	; FIX(2.562915447)
62
F_3_072	equ	DESCALE(3299298341,30-CONST_BITS)	; FIX(3.072711026)
63
%endif
64
65
; --------------------------------------------------------------------------
66
	SECTION	SEG_CONST
67
68
	alignz	16
69
	global	EXTN(jconst_fdct_islow_sse2)
70
71
EXTN(jconst_fdct_islow_sse2):
72
73
PW_F130_F054	times 4 dw  (F_0_541+F_0_765), F_0_541
74
PW_F054_MF130	times 4 dw  F_0_541, (F_0_541-F_1_847)
75
PW_MF078_F117	times 4 dw  (F_1_175-F_1_961), F_1_175
76
PW_F117_F078	times 4 dw  F_1_175, (F_1_175-F_0_390)
77
PW_MF060_MF089	times 4 dw  (F_0_298-F_0_899),-F_0_899
78
PW_MF089_F060	times 4 dw -F_0_899, (F_1_501-F_0_899)
79
PW_MF050_MF256	times 4 dw  (F_2_053-F_2_562),-F_2_562
80
PW_MF256_F050	times 4 dw -F_2_562, (F_3_072-F_2_562)
81
PD_DESCALE_P1	times 4 dd  1 << (DESCALE_P1-1)
82
PD_DESCALE_P2	times 4 dd  1 << (DESCALE_P2-1)
83
PW_DESCALE_P2X	times 8 dw  1 << (PASS1_BITS-1)
84
85
	alignz	16
86
87
; --------------------------------------------------------------------------
88
	SECTION	SEG_TEXT
89
	BITS	32
90
;
91
; Perform the forward DCT on one block of samples.
92
;
93
; GLOBAL(void)
94
; jsimd_fdct_islow_sse2 (DCTELEM * data)
95
;
96
97
%define data(b)		(b)+8		; DCTELEM * data
98
99
%define original_ebp	ebp+0
100
%define wk(i)		ebp-(WK_NUM-(i))*SIZEOF_XMMWORD	; xmmword wk[WK_NUM]
101
%define WK_NUM		6
102
103
	align	16
104
	global	EXTN(jsimd_fdct_islow_sse2)
105
106
EXTN(jsimd_fdct_islow_sse2):
107
	push	ebp
108
	mov	eax,esp				; eax = original ebp
109
	sub	esp, byte 4
110
	and	esp, byte (-SIZEOF_XMMWORD)	; align to 128 bits
111
	mov	[esp],eax
112
	mov	ebp,esp				; ebp = aligned ebp
113
	lea	esp, [wk(0)]
114
	pushpic	ebx
115
;	push	ecx		; unused
116
;	push	edx		; need not be preserved
117
;	push	esi		; unused
118
;	push	edi		; unused
119
120
	get_GOT	ebx		; get GOT address
121
122
	; ---- Pass 1: process rows.
123
124
	mov	edx, POINTER [data(eax)]	; (DCTELEM *)
125
126
	movdqa	xmm0, XMMWORD [XMMBLOCK(0,0,edx,SIZEOF_DCTELEM)]
127
	movdqa	xmm1, XMMWORD [XMMBLOCK(1,0,edx,SIZEOF_DCTELEM)]
128
	movdqa	xmm2, XMMWORD [XMMBLOCK(2,0,edx,SIZEOF_DCTELEM)]
129
	movdqa	xmm3, XMMWORD [XMMBLOCK(3,0,edx,SIZEOF_DCTELEM)]
130
131
	; xmm0=(00 01 02 03 04 05 06 07), xmm2=(20 21 22 23 24 25 26 27)
132
	; xmm1=(10 11 12 13 14 15 16 17), xmm3=(30 31 32 33 34 35 36 37)
133
134
	movdqa    xmm4,xmm0		; transpose coefficients(phase 1)
135
	punpcklwd xmm0,xmm1		; xmm0=(00 10 01 11 02 12 03 13)
136
	punpckhwd xmm4,xmm1		; xmm4=(04 14 05 15 06 16 07 17)
137
	movdqa    xmm5,xmm2		; transpose coefficients(phase 1)
138
	punpcklwd xmm2,xmm3		; xmm2=(20 30 21 31 22 32 23 33)
139
	punpckhwd xmm5,xmm3		; xmm5=(24 34 25 35 26 36 27 37)
140
141
	movdqa	xmm6, XMMWORD [XMMBLOCK(4,0,edx,SIZEOF_DCTELEM)]
142
	movdqa	xmm7, XMMWORD [XMMBLOCK(5,0,edx,SIZEOF_DCTELEM)]
143
	movdqa	xmm1, XMMWORD [XMMBLOCK(6,0,edx,SIZEOF_DCTELEM)]
144
	movdqa	xmm3, XMMWORD [XMMBLOCK(7,0,edx,SIZEOF_DCTELEM)]
145
146
	; xmm6=( 4 12 20 28 36 44 52 60), xmm1=( 6 14 22 30 38 46 54 62)
147
	; xmm7=( 5 13 21 29 37 45 53 61), xmm3=( 7 15 23 31 39 47 55 63)
148
149
	movdqa	XMMWORD [wk(0)], xmm2	; wk(0)=(20 30 21 31 22 32 23 33)
150
	movdqa	XMMWORD [wk(1)], xmm5	; wk(1)=(24 34 25 35 26 36 27 37)
151
152
	movdqa    xmm2,xmm6		; transpose coefficients(phase 1)
153
	punpcklwd xmm6,xmm7		; xmm6=(40 50 41 51 42 52 43 53)
154
	punpckhwd xmm2,xmm7		; xmm2=(44 54 45 55 46 56 47 57)
155
	movdqa    xmm5,xmm1		; transpose coefficients(phase 1)
156
	punpcklwd xmm1,xmm3		; xmm1=(60 70 61 71 62 72 63 73)
157
	punpckhwd xmm5,xmm3		; xmm5=(64 74 65 75 66 76 67 77)
158
159
	movdqa    xmm7,xmm6		; transpose coefficients(phase 2)
160
	punpckldq xmm6,xmm1		; xmm6=(40 50 60 70 41 51 61 71)
161
	punpckhdq xmm7,xmm1		; xmm7=(42 52 62 72 43 53 63 73)
162
	movdqa    xmm3,xmm2		; transpose coefficients(phase 2)
163
	punpckldq xmm2,xmm5		; xmm2=(44 54 64 74 45 55 65 75)
164
	punpckhdq xmm3,xmm5		; xmm3=(46 56 66 76 47 57 67 77)
165
166
	movdqa	xmm1, XMMWORD [wk(0)]	; xmm1=(20 30 21 31 22 32 23 33)
167
	movdqa	xmm5, XMMWORD [wk(1)]	; xmm5=(24 34 25 35 26 36 27 37)
168
	movdqa	XMMWORD [wk(2)], xmm7	; wk(2)=(42 52 62 72 43 53 63 73)
169
	movdqa	XMMWORD [wk(3)], xmm2	; wk(3)=(44 54 64 74 45 55 65 75)
170
171
	movdqa    xmm7,xmm0		; transpose coefficients(phase 2)
172
	punpckldq xmm0,xmm1		; xmm0=(00 10 20 30 01 11 21 31)
173
	punpckhdq xmm7,xmm1		; xmm7=(02 12 22 32 03 13 23 33)
174
	movdqa    xmm2,xmm4		; transpose coefficients(phase 2)
175
	punpckldq xmm4,xmm5		; xmm4=(04 14 24 34 05 15 25 35)
176
	punpckhdq xmm2,xmm5		; xmm2=(06 16 26 36 07 17 27 37)
177
178
	movdqa     xmm1,xmm0		; transpose coefficients(phase 3)
179
	punpcklqdq xmm0,xmm6		; xmm0=(00 10 20 30 40 50 60 70)=data0
180
	punpckhqdq xmm1,xmm6		; xmm1=(01 11 21 31 41 51 61 71)=data1
181
	movdqa     xmm5,xmm2		; transpose coefficients(phase 3)
182
	punpcklqdq xmm2,xmm3		; xmm2=(06 16 26 36 46 56 66 76)=data6
183
	punpckhqdq xmm5,xmm3		; xmm5=(07 17 27 37 47 57 67 77)=data7
184
185
	movdqa	xmm6,xmm1
186
	movdqa	xmm3,xmm0
187
	psubw	xmm1,xmm2		; xmm1=data1-data6=tmp6
188
	psubw	xmm0,xmm5		; xmm0=data0-data7=tmp7
189
	paddw	xmm6,xmm2		; xmm6=data1+data6=tmp1
190
	paddw	xmm3,xmm5		; xmm3=data0+data7=tmp0
191
192
	movdqa	xmm2, XMMWORD [wk(2)]	; xmm2=(42 52 62 72 43 53 63 73)
193
	movdqa	xmm5, XMMWORD [wk(3)]	; xmm5=(44 54 64 74 45 55 65 75)
194
	movdqa	XMMWORD [wk(0)], xmm1	; wk(0)=tmp6
195
	movdqa	XMMWORD [wk(1)], xmm0	; wk(1)=tmp7
196
197
	movdqa     xmm1,xmm7		; transpose coefficients(phase 3)
198
	punpcklqdq xmm7,xmm2		; xmm7=(02 12 22 32 42 52 62 72)=data2
199
	punpckhqdq xmm1,xmm2		; xmm1=(03 13 23 33 43 53 63 73)=data3
200
	movdqa     xmm0,xmm4		; transpose coefficients(phase 3)
201
	punpcklqdq xmm4,xmm5		; xmm4=(04 14 24 34 44 54 64 74)=data4
202
	punpckhqdq xmm0,xmm5		; xmm0=(05 15 25 35 45 55 65 75)=data5
203
204
	movdqa	xmm2,xmm1
205
	movdqa	xmm5,xmm7
206
	paddw	xmm1,xmm4		; xmm1=data3+data4=tmp3
207
	paddw	xmm7,xmm0		; xmm7=data2+data5=tmp2
208
	psubw	xmm2,xmm4		; xmm2=data3-data4=tmp4
209
	psubw	xmm5,xmm0		; xmm5=data2-data5=tmp5
210
211
	; -- Even part
212
213
	movdqa	xmm4,xmm3
214
	movdqa	xmm0,xmm6
215
	paddw	xmm3,xmm1		; xmm3=tmp10
216
	paddw	xmm6,xmm7		; xmm6=tmp11
217
	psubw	xmm4,xmm1		; xmm4=tmp13
218
	psubw	xmm0,xmm7		; xmm0=tmp12
219
220
	movdqa	xmm1,xmm3
221
	paddw	xmm3,xmm6		; xmm3=tmp10+tmp11
222
	psubw	xmm1,xmm6		; xmm1=tmp10-tmp11
223
224
	psllw	xmm3,PASS1_BITS		; xmm3=data0
225
	psllw	xmm1,PASS1_BITS		; xmm1=data4
226
227
	movdqa	XMMWORD [wk(2)], xmm3	; wk(2)=data0
228
	movdqa	XMMWORD [wk(3)], xmm1	; wk(3)=data4
229
230
	; (Original)
231
	; z1 = (tmp12 + tmp13) * 0.541196100;
232
	; data2 = z1 + tmp13 * 0.765366865;
233
	; data6 = z1 + tmp12 * -1.847759065;
234
	;
235
	; (This implementation)
236
	; data2 = tmp13 * (0.541196100 + 0.765366865) + tmp12 * 0.541196100;
237
	; data6 = tmp13 * 0.541196100 + tmp12 * (0.541196100 - 1.847759065);
238
239
	movdqa    xmm7,xmm4		; xmm4=tmp13
240
	movdqa    xmm6,xmm4
241
	punpcklwd xmm7,xmm0		; xmm0=tmp12
242
	punpckhwd xmm6,xmm0
243
	movdqa    xmm4,xmm7
244
	movdqa    xmm0,xmm6
245
	pmaddwd   xmm7,[GOTOFF(ebx,PW_F130_F054)]	; xmm7=data2L
246
	pmaddwd   xmm6,[GOTOFF(ebx,PW_F130_F054)]	; xmm6=data2H
247
	pmaddwd   xmm4,[GOTOFF(ebx,PW_F054_MF130)]	; xmm4=data6L
248
	pmaddwd   xmm0,[GOTOFF(ebx,PW_F054_MF130)]	; xmm0=data6H
249
250
	paddd	xmm7,[GOTOFF(ebx,PD_DESCALE_P1)]
251
	paddd	xmm6,[GOTOFF(ebx,PD_DESCALE_P1)]
252
	psrad	xmm7,DESCALE_P1
253
	psrad	xmm6,DESCALE_P1
254
	paddd	xmm4,[GOTOFF(ebx,PD_DESCALE_P1)]
255
	paddd	xmm0,[GOTOFF(ebx,PD_DESCALE_P1)]
256
	psrad	xmm4,DESCALE_P1
257
	psrad	xmm0,DESCALE_P1
258
259
	packssdw  xmm7,xmm6		; xmm7=data2
260
	packssdw  xmm4,xmm0		; xmm4=data6
261
262
	movdqa	XMMWORD [wk(4)], xmm7	; wk(4)=data2
263
	movdqa	XMMWORD [wk(5)], xmm4	; wk(5)=data6
264
265
	; -- Odd part
266
267
	movdqa	xmm3, XMMWORD [wk(0)]	; xmm3=tmp6
268
	movdqa	xmm1, XMMWORD [wk(1)]	; xmm1=tmp7
269
270
	movdqa	xmm6,xmm2		; xmm2=tmp4
271
	movdqa	xmm0,xmm5		; xmm5=tmp5
272
	paddw	xmm6,xmm3		; xmm6=z3
273
	paddw	xmm0,xmm1		; xmm0=z4
274
275
	; (Original)
276
	; z5 = (z3 + z4) * 1.175875602;
277
	; z3 = z3 * -1.961570560;  z4 = z4 * -0.390180644;
278
	; z3 += z5;  z4 += z5;
279
	;
280
	; (This implementation)
281
	; z3 = z3 * (1.175875602 - 1.961570560) + z4 * 1.175875602;
282
	; z4 = z3 * 1.175875602 + z4 * (1.175875602 - 0.390180644);
283
284
	movdqa    xmm7,xmm6
285
	movdqa    xmm4,xmm6
286
	punpcklwd xmm7,xmm0
287
	punpckhwd xmm4,xmm0
288
	movdqa    xmm6,xmm7
289
	movdqa    xmm0,xmm4
290
	pmaddwd   xmm7,[GOTOFF(ebx,PW_MF078_F117)]	; xmm7=z3L
291
	pmaddwd   xmm4,[GOTOFF(ebx,PW_MF078_F117)]	; xmm4=z3H
292
	pmaddwd   xmm6,[GOTOFF(ebx,PW_F117_F078)]	; xmm6=z4L
293
	pmaddwd   xmm0,[GOTOFF(ebx,PW_F117_F078)]	; xmm0=z4H
294
295
	movdqa	XMMWORD [wk(0)], xmm7	; wk(0)=z3L
296
	movdqa	XMMWORD [wk(1)], xmm4	; wk(1)=z3H
297
298
	; (Original)
299
	; z1 = tmp4 + tmp7;  z2 = tmp5 + tmp6;
300
	; tmp4 = tmp4 * 0.298631336;  tmp5 = tmp5 * 2.053119869;
301
	; tmp6 = tmp6 * 3.072711026;  tmp7 = tmp7 * 1.501321110;
302
	; z1 = z1 * -0.899976223;  z2 = z2 * -2.562915447;
303
	; data7 = tmp4 + z1 + z3;  data5 = tmp5 + z2 + z4;
304
	; data3 = tmp6 + z2 + z3;  data1 = tmp7 + z1 + z4;
305
	;
306
	; (This implementation)
307
	; tmp4 = tmp4 * (0.298631336 - 0.899976223) + tmp7 * -0.899976223;
308
	; tmp5 = tmp5 * (2.053119869 - 2.562915447) + tmp6 * -2.562915447;
309
	; tmp6 = tmp5 * -2.562915447 + tmp6 * (3.072711026 - 2.562915447);
310
	; tmp7 = tmp4 * -0.899976223 + tmp7 * (1.501321110 - 0.899976223);
311
	; data7 = tmp4 + z3;  data5 = tmp5 + z4;
312
	; data3 = tmp6 + z3;  data1 = tmp7 + z4;
313
314
	movdqa    xmm7,xmm2
315
	movdqa    xmm4,xmm2
316
	punpcklwd xmm7,xmm1
317
	punpckhwd xmm4,xmm1
318
	movdqa    xmm2,xmm7
319
	movdqa    xmm1,xmm4
320
	pmaddwd   xmm7,[GOTOFF(ebx,PW_MF060_MF089)]	; xmm7=tmp4L
321
	pmaddwd   xmm4,[GOTOFF(ebx,PW_MF060_MF089)]	; xmm4=tmp4H
322
	pmaddwd   xmm2,[GOTOFF(ebx,PW_MF089_F060)]	; xmm2=tmp7L
323
	pmaddwd   xmm1,[GOTOFF(ebx,PW_MF089_F060)]	; xmm1=tmp7H
324
325
	paddd	xmm7, XMMWORD [wk(0)]	; xmm7=data7L
326
	paddd	xmm4, XMMWORD [wk(1)]	; xmm4=data7H
327
	paddd	xmm2,xmm6		; xmm2=data1L
328
	paddd	xmm1,xmm0		; xmm1=data1H
329
330
	paddd	xmm7,[GOTOFF(ebx,PD_DESCALE_P1)]
331
	paddd	xmm4,[GOTOFF(ebx,PD_DESCALE_P1)]
332
	psrad	xmm7,DESCALE_P1
333
	psrad	xmm4,DESCALE_P1
334
	paddd	xmm2,[GOTOFF(ebx,PD_DESCALE_P1)]
335
	paddd	xmm1,[GOTOFF(ebx,PD_DESCALE_P1)]
336
	psrad	xmm2,DESCALE_P1
337
	psrad	xmm1,DESCALE_P1
338
339
	packssdw  xmm7,xmm4		; xmm7=data7
340
	packssdw  xmm2,xmm1		; xmm2=data1
341
342
	movdqa    xmm4,xmm5
343
	movdqa    xmm1,xmm5
344
	punpcklwd xmm4,xmm3
345
	punpckhwd xmm1,xmm3
346
	movdqa    xmm5,xmm4
347
	movdqa    xmm3,xmm1
348
	pmaddwd   xmm4,[GOTOFF(ebx,PW_MF050_MF256)]	; xmm4=tmp5L
349
	pmaddwd   xmm1,[GOTOFF(ebx,PW_MF050_MF256)]	; xmm1=tmp5H
350
	pmaddwd   xmm5,[GOTOFF(ebx,PW_MF256_F050)]	; xmm5=tmp6L
351
	pmaddwd   xmm3,[GOTOFF(ebx,PW_MF256_F050)]	; xmm3=tmp6H
352
353
	paddd	xmm4,xmm6		; xmm4=data5L
354
	paddd	xmm1,xmm0		; xmm1=data5H
355
	paddd	xmm5, XMMWORD [wk(0)]	; xmm5=data3L
356
	paddd	xmm3, XMMWORD [wk(1)]	; xmm3=data3H
357
358
	paddd	xmm4,[GOTOFF(ebx,PD_DESCALE_P1)]
359
	paddd	xmm1,[GOTOFF(ebx,PD_DESCALE_P1)]
360
	psrad	xmm4,DESCALE_P1
361
	psrad	xmm1,DESCALE_P1
362
	paddd	xmm5,[GOTOFF(ebx,PD_DESCALE_P1)]
363
	paddd	xmm3,[GOTOFF(ebx,PD_DESCALE_P1)]
364
	psrad	xmm5,DESCALE_P1
365
	psrad	xmm3,DESCALE_P1
366
367
	packssdw  xmm4,xmm1		; xmm4=data5
368
	packssdw  xmm5,xmm3		; xmm5=data3
369
370
	; ---- Pass 2: process columns.
371
372
;	mov	edx, POINTER [data(eax)]	; (DCTELEM *)
373
374
	movdqa	xmm6, XMMWORD [wk(2)]	; xmm6=col0
375
	movdqa	xmm0, XMMWORD [wk(4)]	; xmm0=col2
376
377
	; xmm6=(00 10 20 30 40 50 60 70), xmm0=(02 12 22 32 42 52 62 72)
378
	; xmm2=(01 11 21 31 41 51 61 71), xmm5=(03 13 23 33 43 53 63 73)
379
380
	movdqa    xmm1,xmm6		; transpose coefficients(phase 1)
381
	punpcklwd xmm6,xmm2		; xmm6=(00 01 10 11 20 21 30 31)
382
	punpckhwd xmm1,xmm2		; xmm1=(40 41 50 51 60 61 70 71)
383
	movdqa    xmm3,xmm0		; transpose coefficients(phase 1)
384
	punpcklwd xmm0,xmm5		; xmm0=(02 03 12 13 22 23 32 33)
385
	punpckhwd xmm3,xmm5		; xmm3=(42 43 52 53 62 63 72 73)
386
387
	movdqa	xmm2, XMMWORD [wk(3)]	; xmm2=col4
388
	movdqa	xmm5, XMMWORD [wk(5)]	; xmm5=col6
389
390
	; xmm2=(04 14 24 34 44 54 64 74), xmm5=(06 16 26 36 46 56 66 76)
391
	; xmm4=(05 15 25 35 45 55 65 75), xmm7=(07 17 27 37 47 57 67 77)
392
393
	movdqa	XMMWORD [wk(0)], xmm0	; wk(0)=(02 03 12 13 22 23 32 33)
394
	movdqa	XMMWORD [wk(1)], xmm3	; wk(1)=(42 43 52 53 62 63 72 73)
395
396
	movdqa    xmm0,xmm2		; transpose coefficients(phase 1)
397
	punpcklwd xmm2,xmm4		; xmm2=(04 05 14 15 24 25 34 35)
398
	punpckhwd xmm0,xmm4		; xmm0=(44 45 54 55 64 65 74 75)
399
	movdqa    xmm3,xmm5		; transpose coefficients(phase 1)
400
	punpcklwd xmm5,xmm7		; xmm5=(06 07 16 17 26 27 36 37)
401
	punpckhwd xmm3,xmm7		; xmm3=(46 47 56 57 66 67 76 77)
402
403
	movdqa    xmm4,xmm2		; transpose coefficients(phase 2)
404
	punpckldq xmm2,xmm5		; xmm2=(04 05 06 07 14 15 16 17)
405
	punpckhdq xmm4,xmm5		; xmm4=(24 25 26 27 34 35 36 37)
406
	movdqa    xmm7,xmm0		; transpose coefficients(phase 2)
407
	punpckldq xmm0,xmm3		; xmm0=(44 45 46 47 54 55 56 57)
408
	punpckhdq xmm7,xmm3		; xmm7=(64 65 66 67 74 75 76 77)
409
410
	movdqa	xmm5, XMMWORD [wk(0)]	; xmm5=(02 03 12 13 22 23 32 33)
411
	movdqa	xmm3, XMMWORD [wk(1)]	; xmm3=(42 43 52 53 62 63 72 73)
412
	movdqa	XMMWORD [wk(2)], xmm4	; wk(2)=(24 25 26 27 34 35 36 37)
413
	movdqa	XMMWORD [wk(3)], xmm0	; wk(3)=(44 45 46 47 54 55 56 57)
414
415
	movdqa    xmm4,xmm6		; transpose coefficients(phase 2)
416
	punpckldq xmm6,xmm5		; xmm6=(00 01 02 03 10 11 12 13)
417
	punpckhdq xmm4,xmm5		; xmm4=(20 21 22 23 30 31 32 33)
418
	movdqa    xmm0,xmm1		; transpose coefficients(phase 2)
419
	punpckldq xmm1,xmm3		; xmm1=(40 41 42 43 50 51 52 53)
420
	punpckhdq xmm0,xmm3		; xmm0=(60 61 62 63 70 71 72 73)
421
422
	movdqa     xmm5,xmm6		; transpose coefficients(phase 3)
423
	punpcklqdq xmm6,xmm2		; xmm6=(00 01 02 03 04 05 06 07)=data0
424
	punpckhqdq xmm5,xmm2		; xmm5=(10 11 12 13 14 15 16 17)=data1
425
	movdqa     xmm3,xmm0		; transpose coefficients(phase 3)
426
	punpcklqdq xmm0,xmm7		; xmm0=(60 61 62 63 64 65 66 67)=data6
427
	punpckhqdq xmm3,xmm7		; xmm3=(70 71 72 73 74 75 76 77)=data7
428
429
	movdqa	xmm2,xmm5
430
	movdqa	xmm7,xmm6
431
	psubw	xmm5,xmm0		; xmm5=data1-data6=tmp6
432
	psubw	xmm6,xmm3		; xmm6=data0-data7=tmp7
433
	paddw	xmm2,xmm0		; xmm2=data1+data6=tmp1
434
	paddw	xmm7,xmm3		; xmm7=data0+data7=tmp0
435
436
	movdqa	xmm0, XMMWORD [wk(2)]	; xmm0=(24 25 26 27 34 35 36 37)
437
	movdqa	xmm3, XMMWORD [wk(3)]	; xmm3=(44 45 46 47 54 55 56 57)
438
	movdqa	XMMWORD [wk(0)], xmm5	; wk(0)=tmp6
439
	movdqa	XMMWORD [wk(1)], xmm6	; wk(1)=tmp7
440
441
	movdqa     xmm5,xmm4		; transpose coefficients(phase 3)
442
	punpcklqdq xmm4,xmm0		; xmm4=(20 21 22 23 24 25 26 27)=data2
443
	punpckhqdq xmm5,xmm0		; xmm5=(30 31 32 33 34 35 36 37)=data3
444
	movdqa     xmm6,xmm1		; transpose coefficients(phase 3)
445
	punpcklqdq xmm1,xmm3		; xmm1=(40 41 42 43 44 45 46 47)=data4
446
	punpckhqdq xmm6,xmm3		; xmm6=(50 51 52 53 54 55 56 57)=data5
447
448
	movdqa	xmm0,xmm5
449
	movdqa	xmm3,xmm4
450
	paddw	xmm5,xmm1		; xmm5=data3+data4=tmp3
451
	paddw	xmm4,xmm6		; xmm4=data2+data5=tmp2
452
	psubw	xmm0,xmm1		; xmm0=data3-data4=tmp4
453
	psubw	xmm3,xmm6		; xmm3=data2-data5=tmp5
454
455
	; -- Even part
456
457
	movdqa	xmm1,xmm7
458
	movdqa	xmm6,xmm2
459
	paddw	xmm7,xmm5		; xmm7=tmp10
460
	paddw	xmm2,xmm4		; xmm2=tmp11
461
	psubw	xmm1,xmm5		; xmm1=tmp13
462
	psubw	xmm6,xmm4		; xmm6=tmp12
463
464
	movdqa	xmm5,xmm7
465
	paddw	xmm7,xmm2		; xmm7=tmp10+tmp11
466
	psubw	xmm5,xmm2		; xmm5=tmp10-tmp11
467
468
	paddw	xmm7,[GOTOFF(ebx,PW_DESCALE_P2X)]
469
	paddw	xmm5,[GOTOFF(ebx,PW_DESCALE_P2X)]
470
	psraw	xmm7,PASS1_BITS		; xmm7=data0
471
	psraw	xmm5,PASS1_BITS		; xmm5=data4
472
473
	movdqa	XMMWORD [XMMBLOCK(0,0,edx,SIZEOF_DCTELEM)], xmm7
474
	movdqa	XMMWORD [XMMBLOCK(4,0,edx,SIZEOF_DCTELEM)], xmm5
475
476
	; (Original)
477
	; z1 = (tmp12 + tmp13) * 0.541196100;
478
	; data2 = z1 + tmp13 * 0.765366865;
479
	; data6 = z1 + tmp12 * -1.847759065;
480
	;
481
	; (This implementation)
482
	; data2 = tmp13 * (0.541196100 + 0.765366865) + tmp12 * 0.541196100;
483
	; data6 = tmp13 * 0.541196100 + tmp12 * (0.541196100 - 1.847759065);
484
485
	movdqa    xmm4,xmm1		; xmm1=tmp13
486
	movdqa    xmm2,xmm1
487
	punpcklwd xmm4,xmm6		; xmm6=tmp12
488
	punpckhwd xmm2,xmm6
489
	movdqa    xmm1,xmm4
490
	movdqa    xmm6,xmm2
491
	pmaddwd   xmm4,[GOTOFF(ebx,PW_F130_F054)]	; xmm4=data2L
492
	pmaddwd   xmm2,[GOTOFF(ebx,PW_F130_F054)]	; xmm2=data2H
493
	pmaddwd   xmm1,[GOTOFF(ebx,PW_F054_MF130)]	; xmm1=data6L
494
	pmaddwd   xmm6,[GOTOFF(ebx,PW_F054_MF130)]	; xmm6=data6H
495
496
	paddd	xmm4,[GOTOFF(ebx,PD_DESCALE_P2)]
497
	paddd	xmm2,[GOTOFF(ebx,PD_DESCALE_P2)]
498
	psrad	xmm4,DESCALE_P2
499
	psrad	xmm2,DESCALE_P2
500
	paddd	xmm1,[GOTOFF(ebx,PD_DESCALE_P2)]
501
	paddd	xmm6,[GOTOFF(ebx,PD_DESCALE_P2)]
502
	psrad	xmm1,DESCALE_P2
503
	psrad	xmm6,DESCALE_P2
504
505
	packssdw  xmm4,xmm2		; xmm4=data2
506
	packssdw  xmm1,xmm6		; xmm1=data6
507
508
	movdqa	XMMWORD [XMMBLOCK(2,0,edx,SIZEOF_DCTELEM)], xmm4
509
	movdqa	XMMWORD [XMMBLOCK(6,0,edx,SIZEOF_DCTELEM)], xmm1
510
511
	; -- Odd part
512
513
	movdqa	xmm7, XMMWORD [wk(0)]	; xmm7=tmp6
514
	movdqa	xmm5, XMMWORD [wk(1)]	; xmm5=tmp7
515
516
	movdqa	xmm2,xmm0		; xmm0=tmp4
517
	movdqa	xmm6,xmm3		; xmm3=tmp5
518
	paddw	xmm2,xmm7		; xmm2=z3
519
	paddw	xmm6,xmm5		; xmm6=z4
520
521
	; (Original)
522
	; z5 = (z3 + z4) * 1.175875602;
523
	; z3 = z3 * -1.961570560;  z4 = z4 * -0.390180644;
524
	; z3 += z5;  z4 += z5;
525
	;
526
	; (This implementation)
527
	; z3 = z3 * (1.175875602 - 1.961570560) + z4 * 1.175875602;
528
	; z4 = z3 * 1.175875602 + z4 * (1.175875602 - 0.390180644);
529
530
	movdqa    xmm4,xmm2
531
	movdqa    xmm1,xmm2
532
	punpcklwd xmm4,xmm6
533
	punpckhwd xmm1,xmm6
534
	movdqa    xmm2,xmm4
535
	movdqa    xmm6,xmm1
536
	pmaddwd   xmm4,[GOTOFF(ebx,PW_MF078_F117)]	; xmm4=z3L
537
	pmaddwd   xmm1,[GOTOFF(ebx,PW_MF078_F117)]	; xmm1=z3H
538
	pmaddwd   xmm2,[GOTOFF(ebx,PW_F117_F078)]	; xmm2=z4L
539
	pmaddwd   xmm6,[GOTOFF(ebx,PW_F117_F078)]	; xmm6=z4H
540
541
	movdqa	XMMWORD [wk(0)], xmm4	; wk(0)=z3L
542
	movdqa	XMMWORD [wk(1)], xmm1	; wk(1)=z3H
543
544
	; (Original)
545
	; z1 = tmp4 + tmp7;  z2 = tmp5 + tmp6;
546
	; tmp4 = tmp4 * 0.298631336;  tmp5 = tmp5 * 2.053119869;
547
	; tmp6 = tmp6 * 3.072711026;  tmp7 = tmp7 * 1.501321110;
548
	; z1 = z1 * -0.899976223;  z2 = z2 * -2.562915447;
549
	; data7 = tmp4 + z1 + z3;  data5 = tmp5 + z2 + z4;
550
	; data3 = tmp6 + z2 + z3;  data1 = tmp7 + z1 + z4;
551
	;
552
	; (This implementation)
553
	; tmp4 = tmp4 * (0.298631336 - 0.899976223) + tmp7 * -0.899976223;
554
	; tmp5 = tmp5 * (2.053119869 - 2.562915447) + tmp6 * -2.562915447;
555
	; tmp6 = tmp5 * -2.562915447 + tmp6 * (3.072711026 - 2.562915447);
556
	; tmp7 = tmp4 * -0.899976223 + tmp7 * (1.501321110 - 0.899976223);
557
	; data7 = tmp4 + z3;  data5 = tmp5 + z4;
558
	; data3 = tmp6 + z3;  data1 = tmp7 + z4;
559
560
	movdqa    xmm4,xmm0
561
	movdqa    xmm1,xmm0
562
	punpcklwd xmm4,xmm5
563
	punpckhwd xmm1,xmm5
564
	movdqa    xmm0,xmm4
565
	movdqa    xmm5,xmm1
566
	pmaddwd   xmm4,[GOTOFF(ebx,PW_MF060_MF089)]	; xmm4=tmp4L
567
	pmaddwd   xmm1,[GOTOFF(ebx,PW_MF060_MF089)]	; xmm1=tmp4H
568
	pmaddwd   xmm0,[GOTOFF(ebx,PW_MF089_F060)]	; xmm0=tmp7L
569
	pmaddwd   xmm5,[GOTOFF(ebx,PW_MF089_F060)]	; xmm5=tmp7H
570
571
	paddd	xmm4, XMMWORD [wk(0)]	; xmm4=data7L
572
	paddd	xmm1, XMMWORD [wk(1)]	; xmm1=data7H
573
	paddd	xmm0,xmm2		; xmm0=data1L
574
	paddd	xmm5,xmm6		; xmm5=data1H
575
576
	paddd	xmm4,[GOTOFF(ebx,PD_DESCALE_P2)]
577
	paddd	xmm1,[GOTOFF(ebx,PD_DESCALE_P2)]
578
	psrad	xmm4,DESCALE_P2
579
	psrad	xmm1,DESCALE_P2
580
	paddd	xmm0,[GOTOFF(ebx,PD_DESCALE_P2)]
581
	paddd	xmm5,[GOTOFF(ebx,PD_DESCALE_P2)]
582
	psrad	xmm0,DESCALE_P2
583
	psrad	xmm5,DESCALE_P2
584
585
	packssdw  xmm4,xmm1		; xmm4=data7
586
	packssdw  xmm0,xmm5		; xmm0=data1
587
588
	movdqa	XMMWORD [XMMBLOCK(7,0,edx,SIZEOF_DCTELEM)], xmm4
589
	movdqa	XMMWORD [XMMBLOCK(1,0,edx,SIZEOF_DCTELEM)], xmm0
590
591
	movdqa    xmm1,xmm3
592
	movdqa    xmm5,xmm3
593
	punpcklwd xmm1,xmm7
594
	punpckhwd xmm5,xmm7
595
	movdqa    xmm3,xmm1
596
	movdqa    xmm7,xmm5
597
	pmaddwd   xmm1,[GOTOFF(ebx,PW_MF050_MF256)]	; xmm1=tmp5L
598
	pmaddwd   xmm5,[GOTOFF(ebx,PW_MF050_MF256)]	; xmm5=tmp5H
599
	pmaddwd   xmm3,[GOTOFF(ebx,PW_MF256_F050)]	; xmm3=tmp6L
600
	pmaddwd   xmm7,[GOTOFF(ebx,PW_MF256_F050)]	; xmm7=tmp6H
601
602
	paddd	xmm1,xmm2		; xmm1=data5L
603
	paddd	xmm5,xmm6		; xmm5=data5H
604
	paddd	xmm3, XMMWORD [wk(0)]	; xmm3=data3L
605
	paddd	xmm7, XMMWORD [wk(1)]	; xmm7=data3H
606
607
	paddd	xmm1,[GOTOFF(ebx,PD_DESCALE_P2)]
608
	paddd	xmm5,[GOTOFF(ebx,PD_DESCALE_P2)]
609
	psrad	xmm1,DESCALE_P2
610
	psrad	xmm5,DESCALE_P2
611
	paddd	xmm3,[GOTOFF(ebx,PD_DESCALE_P2)]
612
	paddd	xmm7,[GOTOFF(ebx,PD_DESCALE_P2)]
613
	psrad	xmm3,DESCALE_P2
614
	psrad	xmm7,DESCALE_P2
615
616
	packssdw  xmm1,xmm5		; xmm1=data5
617
	packssdw  xmm3,xmm7		; xmm3=data3
618
619
	movdqa	XMMWORD [XMMBLOCK(5,0,edx,SIZEOF_DCTELEM)], xmm1
620
	movdqa	XMMWORD [XMMBLOCK(3,0,edx,SIZEOF_DCTELEM)], xmm3
621
622
;	pop	edi		; unused
623
;	pop	esi		; unused
624
;	pop	edx		; need not be preserved
625
;	pop	ecx		; unused
626
	poppic	ebx
627
	mov	esp,ebp		; esp <- aligned ebp
628
	pop	esp		; esp <- original ebp
629
	pop	ebp
630
	ret
631
632
; For some reason, the OS X linker does not honor the request to align the
633
; segment unless we do this.
634
	align	16
(-)a/jpeg/simd/jfsseflt-64.asm (+358 lines)
Line     Link Here 
Line 0    Link Here 
1
;
2
; jfsseflt-64.asm - floating-point FDCT (64-bit SSE)
3
;
4
; Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
5
; Copyright 2009 D. R. Commander
6
;
7
; Based on
8
; x86 SIMD extension for IJG JPEG library
9
; Copyright (C) 1999-2006, MIYASAKA Masaru.
10
; For conditions of distribution and use, see copyright notice in jsimdext.inc
11
;
12
; This file should be assembled with NASM (Netwide Assembler),
13
; can *not* be assembled with Microsoft's MASM or any compatible
14
; assembler (including Borland's Turbo Assembler).
15
; NASM is available from http://nasm.sourceforge.net/ or
16
; http://sourceforge.net/project/showfiles.php?group_id=6208
17
;
18
; This file contains a floating-point implementation of the forward DCT
19
; (Discrete Cosine Transform). The following code is based directly on
20
; the IJG's original jfdctflt.c; see the jfdctflt.c for more details.
21
;
22
; [TAB8]
23
24
%include "jsimdext.inc"
25
%include "jdct.inc"
26
27
; --------------------------------------------------------------------------
28
29
%macro	unpcklps2 2	; %1=(0 1 2 3) / %2=(4 5 6 7) => %1=(0 1 4 5)
30
	shufps	%1,%2,0x44
31
%endmacro
32
33
%macro	unpckhps2 2	; %1=(0 1 2 3) / %2=(4 5 6 7) => %1=(2 3 6 7)
34
	shufps	%1,%2,0xEE
35
%endmacro
36
37
; --------------------------------------------------------------------------
38
	SECTION	SEG_CONST
39
40
	alignz	16
41
	global	EXTN(jconst_fdct_float_sse)
42
43
EXTN(jconst_fdct_float_sse):
44
45
PD_0_382	times 4 dd  0.382683432365089771728460
46
PD_0_707	times 4 dd  0.707106781186547524400844
47
PD_0_541	times 4 dd  0.541196100146196984399723
48
PD_1_306	times 4 dd  1.306562964876376527856643
49
50
	alignz	16
51
52
; --------------------------------------------------------------------------
53
	SECTION	SEG_TEXT
54
	BITS	64
55
;
56
; Perform the forward DCT on one block of samples.
57
;
58
; GLOBAL(void)
59
; jsimd_fdct_float_sse (FAST_FLOAT * data)
60
;
61
62
; r10 = FAST_FLOAT * data
63
64
%define wk(i)		rbp-(WK_NUM-(i))*SIZEOF_XMMWORD	; xmmword wk[WK_NUM]
65
%define WK_NUM		2
66
67
	align	16
68
	global	EXTN(jsimd_fdct_float_sse)
69
70
EXTN(jsimd_fdct_float_sse):
71
	push	rbp
72
	mov	rax,rsp				; rax = original rbp
73
	sub	rsp, byte 4
74
	and	rsp, byte (-SIZEOF_XMMWORD)	; align to 128 bits
75
	mov	[rsp],rax
76
	mov	rbp,rsp				; rbp = aligned rbp
77
	lea	rsp, [wk(0)]
78
	collect_args
79
80
	; ---- Pass 1: process rows.
81
82
	mov	rdx, r10	; (FAST_FLOAT *)
83
	mov	rcx, DCTSIZE/4
84
.rowloop:
85
86
	movaps	xmm0, XMMWORD [XMMBLOCK(2,0,rdx,SIZEOF_FAST_FLOAT)]
87
	movaps	xmm1, XMMWORD [XMMBLOCK(3,0,rdx,SIZEOF_FAST_FLOAT)]
88
	movaps	xmm2, XMMWORD [XMMBLOCK(2,1,rdx,SIZEOF_FAST_FLOAT)]
89
	movaps	xmm3, XMMWORD [XMMBLOCK(3,1,rdx,SIZEOF_FAST_FLOAT)]
90
91
	; xmm0=(20 21 22 23), xmm2=(24 25 26 27)
92
	; xmm1=(30 31 32 33), xmm3=(34 35 36 37)
93
94
	movaps   xmm4,xmm0		; transpose coefficients(phase 1)
95
	unpcklps xmm0,xmm1		; xmm0=(20 30 21 31)
96
	unpckhps xmm4,xmm1		; xmm4=(22 32 23 33)
97
	movaps   xmm5,xmm2		; transpose coefficients(phase 1)
98
	unpcklps xmm2,xmm3		; xmm2=(24 34 25 35)
99
	unpckhps xmm5,xmm3		; xmm5=(26 36 27 37)
100
101
	movaps	xmm6, XMMWORD [XMMBLOCK(0,0,rdx,SIZEOF_FAST_FLOAT)]
102
	movaps	xmm7, XMMWORD [XMMBLOCK(1,0,rdx,SIZEOF_FAST_FLOAT)]
103
	movaps	xmm1, XMMWORD [XMMBLOCK(0,1,rdx,SIZEOF_FAST_FLOAT)]
104
	movaps	xmm3, XMMWORD [XMMBLOCK(1,1,rdx,SIZEOF_FAST_FLOAT)]
105
106
	; xmm6=(00 01 02 03), xmm1=(04 05 06 07)
107
	; xmm7=(10 11 12 13), xmm3=(14 15 16 17)
108
109
	movaps	XMMWORD [wk(0)], xmm4	; wk(0)=(22 32 23 33)
110
	movaps	XMMWORD [wk(1)], xmm2	; wk(1)=(24 34 25 35)
111
112
	movaps   xmm4,xmm6		; transpose coefficients(phase 1)
113
	unpcklps xmm6,xmm7		; xmm6=(00 10 01 11)
114
	unpckhps xmm4,xmm7		; xmm4=(02 12 03 13)
115
	movaps   xmm2,xmm1		; transpose coefficients(phase 1)
116
	unpcklps xmm1,xmm3		; xmm1=(04 14 05 15)
117
	unpckhps xmm2,xmm3		; xmm2=(06 16 07 17)
118
119
	movaps    xmm7,xmm6		; transpose coefficients(phase 2)
120
	unpcklps2 xmm6,xmm0		; xmm6=(00 10 20 30)=data0
121
	unpckhps2 xmm7,xmm0		; xmm7=(01 11 21 31)=data1
122
	movaps    xmm3,xmm2		; transpose coefficients(phase 2)
123
	unpcklps2 xmm2,xmm5		; xmm2=(06 16 26 36)=data6
124
	unpckhps2 xmm3,xmm5		; xmm3=(07 17 27 37)=data7
125
126
	movaps	xmm0,xmm7
127
	movaps	xmm5,xmm6
128
	subps	xmm7,xmm2		; xmm7=data1-data6=tmp6
129
	subps	xmm6,xmm3		; xmm6=data0-data7=tmp7
130
	addps	xmm0,xmm2		; xmm0=data1+data6=tmp1
131
	addps	xmm5,xmm3		; xmm5=data0+data7=tmp0
132
133
	movaps	xmm2, XMMWORD [wk(0)]	; xmm2=(22 32 23 33)
134
	movaps	xmm3, XMMWORD [wk(1)]	; xmm3=(24 34 25 35)
135
	movaps	XMMWORD [wk(0)], xmm7	; wk(0)=tmp6
136
	movaps	XMMWORD [wk(1)], xmm6	; wk(1)=tmp7
137
138
	movaps    xmm7,xmm4		; transpose coefficients(phase 2)
139
	unpcklps2 xmm4,xmm2		; xmm4=(02 12 22 32)=data2
140
	unpckhps2 xmm7,xmm2		; xmm7=(03 13 23 33)=data3
141
	movaps    xmm6,xmm1		; transpose coefficients(phase 2)
142
	unpcklps2 xmm1,xmm3		; xmm1=(04 14 24 34)=data4
143
	unpckhps2 xmm6,xmm3		; xmm6=(05 15 25 35)=data5
144
145
	movaps	xmm2,xmm7
146
	movaps	xmm3,xmm4
147
	addps	xmm7,xmm1		; xmm7=data3+data4=tmp3
148
	addps	xmm4,xmm6		; xmm4=data2+data5=tmp2
149
	subps	xmm2,xmm1		; xmm2=data3-data4=tmp4
150
	subps	xmm3,xmm6		; xmm3=data2-data5=tmp5
151
152
	; -- Even part
153
154
	movaps	xmm1,xmm5
155
	movaps	xmm6,xmm0
156
	subps	xmm5,xmm7		; xmm5=tmp13
157
	subps	xmm0,xmm4		; xmm0=tmp12
158
	addps	xmm1,xmm7		; xmm1=tmp10
159
	addps	xmm6,xmm4		; xmm6=tmp11
160
161
	addps	xmm0,xmm5
162
	mulps	xmm0,[rel PD_0_707] ; xmm0=z1
163
164
	movaps	xmm7,xmm1
165
	movaps	xmm4,xmm5
166
	subps	xmm1,xmm6		; xmm1=data4
167
	subps	xmm5,xmm0		; xmm5=data6
168
	addps	xmm7,xmm6		; xmm7=data0
169
	addps	xmm4,xmm0		; xmm4=data2
170
171
	movaps	XMMWORD [XMMBLOCK(0,1,rdx,SIZEOF_FAST_FLOAT)], xmm1
172
	movaps	XMMWORD [XMMBLOCK(2,1,rdx,SIZEOF_FAST_FLOAT)], xmm5
173
	movaps	XMMWORD [XMMBLOCK(0,0,rdx,SIZEOF_FAST_FLOAT)], xmm7
174
	movaps	XMMWORD [XMMBLOCK(2,0,rdx,SIZEOF_FAST_FLOAT)], xmm4
175
176
	; -- Odd part
177
178
	movaps	xmm6, XMMWORD [wk(0)]	; xmm6=tmp6
179
	movaps	xmm0, XMMWORD [wk(1)]	; xmm0=tmp7
180
181
	addps	xmm2,xmm3		; xmm2=tmp10
182
	addps	xmm3,xmm6		; xmm3=tmp11
183
	addps	xmm6,xmm0		; xmm6=tmp12, xmm0=tmp7
184
185
	mulps	xmm3,[rel PD_0_707] ; xmm3=z3
186
187
	movaps	xmm1,xmm2		; xmm1=tmp10
188
	subps	xmm2,xmm6
189
	mulps	xmm2,[rel PD_0_382] ; xmm2=z5
190
	mulps	xmm1,[rel PD_0_541] ; xmm1=MULTIPLY(tmp10,FIX_0_541196)
191
	mulps	xmm6,[rel PD_1_306] ; xmm6=MULTIPLY(tmp12,FIX_1_306562)
192
	addps	xmm1,xmm2		; xmm1=z2
193
	addps	xmm6,xmm2		; xmm6=z4
194
195
	movaps	xmm5,xmm0
196
	subps	xmm0,xmm3		; xmm0=z13
197
	addps	xmm5,xmm3		; xmm5=z11
198
199
	movaps	xmm7,xmm0
200
	movaps	xmm4,xmm5
201
	subps	xmm0,xmm1		; xmm0=data3
202
	subps	xmm5,xmm6		; xmm5=data7
203
	addps	xmm7,xmm1		; xmm7=data5
204
	addps	xmm4,xmm6		; xmm4=data1
205
206
	movaps	XMMWORD [XMMBLOCK(3,0,rdx,SIZEOF_FAST_FLOAT)], xmm0
207
	movaps	XMMWORD [XMMBLOCK(3,1,rdx,SIZEOF_FAST_FLOAT)], xmm5
208
	movaps	XMMWORD [XMMBLOCK(1,1,rdx,SIZEOF_FAST_FLOAT)], xmm7
209
	movaps	XMMWORD [XMMBLOCK(1,0,rdx,SIZEOF_FAST_FLOAT)], xmm4
210
211
	add	rdx, 4*DCTSIZE*SIZEOF_FAST_FLOAT
212
	dec	rcx
213
	jnz	near .rowloop
214
215
	; ---- Pass 2: process columns.
216
217
	mov	rdx, r10	; (FAST_FLOAT *)
218
	mov	rcx, DCTSIZE/4
219
.columnloop:
220
221
	movaps	xmm0, XMMWORD [XMMBLOCK(2,0,rdx,SIZEOF_FAST_FLOAT)]
222
	movaps	xmm1, XMMWORD [XMMBLOCK(3,0,rdx,SIZEOF_FAST_FLOAT)]
223
	movaps	xmm2, XMMWORD [XMMBLOCK(6,0,rdx,SIZEOF_FAST_FLOAT)]
224
	movaps	xmm3, XMMWORD [XMMBLOCK(7,0,rdx,SIZEOF_FAST_FLOAT)]
225
226
	; xmm0=(02 12 22 32), xmm2=(42 52 62 72)
227
	; xmm1=(03 13 23 33), xmm3=(43 53 63 73)
228
229
	movaps   xmm4,xmm0		; transpose coefficients(phase 1)
230
	unpcklps xmm0,xmm1		; xmm0=(02 03 12 13)
231
	unpckhps xmm4,xmm1		; xmm4=(22 23 32 33)
232
	movaps   xmm5,xmm2		; transpose coefficients(phase 1)
233
	unpcklps xmm2,xmm3		; xmm2=(42 43 52 53)
234
	unpckhps xmm5,xmm3		; xmm5=(62 63 72 73)
235
236
	movaps	xmm6, XMMWORD [XMMBLOCK(0,0,rdx,SIZEOF_FAST_FLOAT)]
237
	movaps	xmm7, XMMWORD [XMMBLOCK(1,0,rdx,SIZEOF_FAST_FLOAT)]
238
	movaps	xmm1, XMMWORD [XMMBLOCK(4,0,rdx,SIZEOF_FAST_FLOAT)]
239
	movaps	xmm3, XMMWORD [XMMBLOCK(5,0,rdx,SIZEOF_FAST_FLOAT)]
240
241
	; xmm6=(00 10 20 30), xmm1=(40 50 60 70)
242
	; xmm7=(01 11 21 31), xmm3=(41 51 61 71)
243
244
	movaps	XMMWORD [wk(0)], xmm4	; wk(0)=(22 23 32 33)
245
	movaps	XMMWORD [wk(1)], xmm2	; wk(1)=(42 43 52 53)
246
247
	movaps   xmm4,xmm6		; transpose coefficients(phase 1)
248
	unpcklps xmm6,xmm7		; xmm6=(00 01 10 11)
249
	unpckhps xmm4,xmm7		; xmm4=(20 21 30 31)
250
	movaps   xmm2,xmm1		; transpose coefficients(phase 1)
251
	unpcklps xmm1,xmm3		; xmm1=(40 41 50 51)
252
	unpckhps xmm2,xmm3		; xmm2=(60 61 70 71)
253
254
	movaps    xmm7,xmm6		; transpose coefficients(phase 2)
255
	unpcklps2 xmm6,xmm0		; xmm6=(00 01 02 03)=data0
256
	unpckhps2 xmm7,xmm0		; xmm7=(10 11 12 13)=data1
257
	movaps    xmm3,xmm2		; transpose coefficients(phase 2)
258
	unpcklps2 xmm2,xmm5		; xmm2=(60 61 62 63)=data6
259
	unpckhps2 xmm3,xmm5		; xmm3=(70 71 72 73)=data7
260
261
	movaps	xmm0,xmm7
262
	movaps	xmm5,xmm6
263
	subps	xmm7,xmm2		; xmm7=data1-data6=tmp6
264
	subps	xmm6,xmm3		; xmm6=data0-data7=tmp7
265
	addps	xmm0,xmm2		; xmm0=data1+data6=tmp1
266
	addps	xmm5,xmm3		; xmm5=data0+data7=tmp0
267
268
	movaps	xmm2, XMMWORD [wk(0)]	; xmm2=(22 23 32 33)
269
	movaps	xmm3, XMMWORD [wk(1)]	; xmm3=(42 43 52 53)
270
	movaps	XMMWORD [wk(0)], xmm7	; wk(0)=tmp6
271
	movaps	XMMWORD [wk(1)], xmm6	; wk(1)=tmp7
272
273
	movaps    xmm7,xmm4		; transpose coefficients(phase 2)
274
	unpcklps2 xmm4,xmm2		; xmm4=(20 21 22 23)=data2
275
	unpckhps2 xmm7,xmm2		; xmm7=(30 31 32 33)=data3
276
	movaps    xmm6,xmm1		; transpose coefficients(phase 2)
277
	unpcklps2 xmm1,xmm3		; xmm1=(40 41 42 43)=data4
278
	unpckhps2 xmm6,xmm3		; xmm6=(50 51 52 53)=data5
279
280
	movaps	xmm2,xmm7
281
	movaps	xmm3,xmm4
282
	addps	xmm7,xmm1		; xmm7=data3+data4=tmp3
283
	addps	xmm4,xmm6		; xmm4=data2+data5=tmp2
284
	subps	xmm2,xmm1		; xmm2=data3-data4=tmp4
285
	subps	xmm3,xmm6		; xmm3=data2-data5=tmp5
286
287
	; -- Even part
288
289
	movaps	xmm1,xmm5
290
	movaps	xmm6,xmm0
291
	subps	xmm5,xmm7		; xmm5=tmp13
292
	subps	xmm0,xmm4		; xmm0=tmp12
293
	addps	xmm1,xmm7		; xmm1=tmp10
294
	addps	xmm6,xmm4		; xmm6=tmp11
295
296
	addps	xmm0,xmm5
297
	mulps	xmm0,[rel PD_0_707] ; xmm0=z1
298
299
	movaps	xmm7,xmm1
300
	movaps	xmm4,xmm5
301
	subps	xmm1,xmm6		; xmm1=data4
302
	subps	xmm5,xmm0		; xmm5=data6
303
	addps	xmm7,xmm6		; xmm7=data0
304
	addps	xmm4,xmm0		; xmm4=data2
305
306
	movaps	XMMWORD [XMMBLOCK(4,0,rdx,SIZEOF_FAST_FLOAT)], xmm1
307
	movaps	XMMWORD [XMMBLOCK(6,0,rdx,SIZEOF_FAST_FLOAT)], xmm5
308
	movaps	XMMWORD [XMMBLOCK(0,0,rdx,SIZEOF_FAST_FLOAT)], xmm7
309
	movaps	XMMWORD [XMMBLOCK(2,0,rdx,SIZEOF_FAST_FLOAT)], xmm4
310
311
	; -- Odd part
312
313
	movaps	xmm6, XMMWORD [wk(0)]	; xmm6=tmp6
314
	movaps	xmm0, XMMWORD [wk(1)]	; xmm0=tmp7
315
316
	addps	xmm2,xmm3		; xmm2=tmp10
317
	addps	xmm3,xmm6		; xmm3=tmp11
318
	addps	xmm6,xmm0		; xmm6=tmp12, xmm0=tmp7
319
320
	mulps	xmm3,[rel PD_0_707] ; xmm3=z3
321
322
	movaps	xmm1,xmm2		; xmm1=tmp10
323
	subps	xmm2,xmm6
324
	mulps	xmm2,[rel PD_0_382] ; xmm2=z5
325
	mulps	xmm1,[rel PD_0_541] ; xmm1=MULTIPLY(tmp10,FIX_0_541196)
326
	mulps	xmm6,[rel PD_1_306] ; xmm6=MULTIPLY(tmp12,FIX_1_306562)
327
	addps	xmm1,xmm2		; xmm1=z2
328
	addps	xmm6,xmm2		; xmm6=z4
329
330
	movaps	xmm5,xmm0
331
	subps	xmm0,xmm3		; xmm0=z13
332
	addps	xmm5,xmm3		; xmm5=z11
333
334
	movaps	xmm7,xmm0
335
	movaps	xmm4,xmm5
336
	subps	xmm0,xmm1		; xmm0=data3
337
	subps	xmm5,xmm6		; xmm5=data7
338
	addps	xmm7,xmm1		; xmm7=data5
339
	addps	xmm4,xmm6		; xmm4=data1
340
341
	movaps	XMMWORD [XMMBLOCK(3,0,rdx,SIZEOF_FAST_FLOAT)], xmm0
342
	movaps	XMMWORD [XMMBLOCK(7,0,rdx,SIZEOF_FAST_FLOAT)], xmm5
343
	movaps	XMMWORD [XMMBLOCK(5,0,rdx,SIZEOF_FAST_FLOAT)], xmm7
344
	movaps	XMMWORD [XMMBLOCK(1,0,rdx,SIZEOF_FAST_FLOAT)], xmm4
345
346
	add	rdx, byte 4*SIZEOF_FAST_FLOAT
347
	dec	rcx
348
	jnz	near .columnloop
349
350
	uncollect_args
351
	mov	rsp,rbp		; rsp <- aligned rbp
352
	pop	rsp		; rsp <- original rbp
353
	pop	rbp
354
	ret
355
356
; For some reason, the OS X linker does not honor the request to align the
357
; segment unless we do this.
358
	align	16
(-)a/jpeg/simd/jfsseflt.asm (+370 lines)
Line     Link Here 
Line 0    Link Here 
1
;
2
; jfsseflt.asm - floating-point FDCT (SSE)
3
;
4
; Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
5
;
6
; Based on
7
; x86 SIMD extension for IJG JPEG library
8
; Copyright (C) 1999-2006, MIYASAKA Masaru.
9
; For conditions of distribution and use, see copyright notice in jsimdext.inc
10
;
11
; This file should be assembled with NASM (Netwide Assembler),
12
; can *not* be assembled with Microsoft's MASM or any compatible
13
; assembler (including Borland's Turbo Assembler).
14
; NASM is available from http://nasm.sourceforge.net/ or
15
; http://sourceforge.net/project/showfiles.php?group_id=6208
16
;
17
; This file contains a floating-point implementation of the forward DCT
18
; (Discrete Cosine Transform). The following code is based directly on
19
; the IJG's original jfdctflt.c; see the jfdctflt.c for more details.
20
;
21
; [TAB8]
22
23
%include "jsimdext.inc"
24
%include "jdct.inc"
25
26
; --------------------------------------------------------------------------
27
28
%macro	unpcklps2 2	; %1=(0 1 2 3) / %2=(4 5 6 7) => %1=(0 1 4 5)
29
	shufps	%1,%2,0x44
30
%endmacro
31
32
%macro	unpckhps2 2	; %1=(0 1 2 3) / %2=(4 5 6 7) => %1=(2 3 6 7)
33
	shufps	%1,%2,0xEE
34
%endmacro
35
36
; --------------------------------------------------------------------------
37
	SECTION	SEG_CONST
38
39
	alignz	16
40
	global	EXTN(jconst_fdct_float_sse)
41
42
EXTN(jconst_fdct_float_sse):
43
44
PD_0_382	times 4 dd  0.382683432365089771728460
45
PD_0_707	times 4 dd  0.707106781186547524400844
46
PD_0_541	times 4 dd  0.541196100146196984399723
47
PD_1_306	times 4 dd  1.306562964876376527856643
48
49
	alignz	16
50
51
; --------------------------------------------------------------------------
52
	SECTION	SEG_TEXT
53
	BITS	32
54
;
55
; Perform the forward DCT on one block of samples.
56
;
57
; GLOBAL(void)
58
; jsimd_fdct_float_sse (FAST_FLOAT * data)
59
;
60
61
%define data(b)		(b)+8		; FAST_FLOAT * data
62
63
%define original_ebp	ebp+0
64
%define wk(i)		ebp-(WK_NUM-(i))*SIZEOF_XMMWORD	; xmmword wk[WK_NUM]
65
%define WK_NUM		2
66
67
	align	16
68
	global	EXTN(jsimd_fdct_float_sse)
69
70
EXTN(jsimd_fdct_float_sse):
71
	push	ebp
72
	mov	eax,esp				; eax = original ebp
73
	sub	esp, byte 4
74
	and	esp, byte (-SIZEOF_XMMWORD)	; align to 128 bits
75
	mov	[esp],eax
76
	mov	ebp,esp				; ebp = aligned ebp
77
	lea	esp, [wk(0)]
78
	pushpic	ebx
79
;	push	ecx		; need not be preserved
80
;	push	edx		; need not be preserved
81
;	push	esi		; unused
82
;	push	edi		; unused
83
84
	get_GOT	ebx		; get GOT address
85
86
	; ---- Pass 1: process rows.
87
88
	mov	edx, POINTER [data(eax)]	; (FAST_FLOAT *)
89
	mov	ecx, DCTSIZE/4
90
	alignx	16,7
91
.rowloop:
92
93
	movaps	xmm0, XMMWORD [XMMBLOCK(2,0,edx,SIZEOF_FAST_FLOAT)]
94
	movaps	xmm1, XMMWORD [XMMBLOCK(3,0,edx,SIZEOF_FAST_FLOAT)]
95
	movaps	xmm2, XMMWORD [XMMBLOCK(2,1,edx,SIZEOF_FAST_FLOAT)]
96
	movaps	xmm3, XMMWORD [XMMBLOCK(3,1,edx,SIZEOF_FAST_FLOAT)]
97
98
	; xmm0=(20 21 22 23), xmm2=(24 25 26 27)
99
	; xmm1=(30 31 32 33), xmm3=(34 35 36 37)
100
101
	movaps   xmm4,xmm0		; transpose coefficients(phase 1)
102
	unpcklps xmm0,xmm1		; xmm0=(20 30 21 31)
103
	unpckhps xmm4,xmm1		; xmm4=(22 32 23 33)
104
	movaps   xmm5,xmm2		; transpose coefficients(phase 1)
105
	unpcklps xmm2,xmm3		; xmm2=(24 34 25 35)
106
	unpckhps xmm5,xmm3		; xmm5=(26 36 27 37)
107
108
	movaps	xmm6, XMMWORD [XMMBLOCK(0,0,edx,SIZEOF_FAST_FLOAT)]
109
	movaps	xmm7, XMMWORD [XMMBLOCK(1,0,edx,SIZEOF_FAST_FLOAT)]
110
	movaps	xmm1, XMMWORD [XMMBLOCK(0,1,edx,SIZEOF_FAST_FLOAT)]
111
	movaps	xmm3, XMMWORD [XMMBLOCK(1,1,edx,SIZEOF_FAST_FLOAT)]
112
113
	; xmm6=(00 01 02 03), xmm1=(04 05 06 07)
114
	; xmm7=(10 11 12 13), xmm3=(14 15 16 17)
115
116
	movaps	XMMWORD [wk(0)], xmm4	; wk(0)=(22 32 23 33)
117
	movaps	XMMWORD [wk(1)], xmm2	; wk(1)=(24 34 25 35)
118
119
	movaps   xmm4,xmm6		; transpose coefficients(phase 1)
120
	unpcklps xmm6,xmm7		; xmm6=(00 10 01 11)
121
	unpckhps xmm4,xmm7		; xmm4=(02 12 03 13)
122
	movaps   xmm2,xmm1		; transpose coefficients(phase 1)
123
	unpcklps xmm1,xmm3		; xmm1=(04 14 05 15)
124
	unpckhps xmm2,xmm3		; xmm2=(06 16 07 17)
125
126
	movaps    xmm7,xmm6		; transpose coefficients(phase 2)
127
	unpcklps2 xmm6,xmm0		; xmm6=(00 10 20 30)=data0
128
	unpckhps2 xmm7,xmm0		; xmm7=(01 11 21 31)=data1
129
	movaps    xmm3,xmm2		; transpose coefficients(phase 2)
130
	unpcklps2 xmm2,xmm5		; xmm2=(06 16 26 36)=data6
131
	unpckhps2 xmm3,xmm5		; xmm3=(07 17 27 37)=data7
132
133
	movaps	xmm0,xmm7
134
	movaps	xmm5,xmm6
135
	subps	xmm7,xmm2		; xmm7=data1-data6=tmp6
136
	subps	xmm6,xmm3		; xmm6=data0-data7=tmp7
137
	addps	xmm0,xmm2		; xmm0=data1+data6=tmp1
138
	addps	xmm5,xmm3		; xmm5=data0+data7=tmp0
139
140
	movaps	xmm2, XMMWORD [wk(0)]	; xmm2=(22 32 23 33)
141
	movaps	xmm3, XMMWORD [wk(1)]	; xmm3=(24 34 25 35)
142
	movaps	XMMWORD [wk(0)], xmm7	; wk(0)=tmp6
143
	movaps	XMMWORD [wk(1)], xmm6	; wk(1)=tmp7
144
145
	movaps    xmm7,xmm4		; transpose coefficients(phase 2)
146
	unpcklps2 xmm4,xmm2		; xmm4=(02 12 22 32)=data2
147
	unpckhps2 xmm7,xmm2		; xmm7=(03 13 23 33)=data3
148
	movaps    xmm6,xmm1		; transpose coefficients(phase 2)
149
	unpcklps2 xmm1,xmm3		; xmm1=(04 14 24 34)=data4
150
	unpckhps2 xmm6,xmm3		; xmm6=(05 15 25 35)=data5
151
152
	movaps	xmm2,xmm7
153
	movaps	xmm3,xmm4
154
	addps	xmm7,xmm1		; xmm7=data3+data4=tmp3
155
	addps	xmm4,xmm6		; xmm4=data2+data5=tmp2
156
	subps	xmm2,xmm1		; xmm2=data3-data4=tmp4
157
	subps	xmm3,xmm6		; xmm3=data2-data5=tmp5
158
159
	; -- Even part
160
161
	movaps	xmm1,xmm5
162
	movaps	xmm6,xmm0
163
	subps	xmm5,xmm7		; xmm5=tmp13
164
	subps	xmm0,xmm4		; xmm0=tmp12
165
	addps	xmm1,xmm7		; xmm1=tmp10
166
	addps	xmm6,xmm4		; xmm6=tmp11
167
168
	addps	xmm0,xmm5
169
	mulps	xmm0,[GOTOFF(ebx,PD_0_707)] ; xmm0=z1
170
171
	movaps	xmm7,xmm1
172
	movaps	xmm4,xmm5
173
	subps	xmm1,xmm6		; xmm1=data4
174
	subps	xmm5,xmm0		; xmm5=data6
175
	addps	xmm7,xmm6		; xmm7=data0
176
	addps	xmm4,xmm0		; xmm4=data2
177
178
	movaps	XMMWORD [XMMBLOCK(0,1,edx,SIZEOF_FAST_FLOAT)], xmm1
179
	movaps	XMMWORD [XMMBLOCK(2,1,edx,SIZEOF_FAST_FLOAT)], xmm5
180
	movaps	XMMWORD [XMMBLOCK(0,0,edx,SIZEOF_FAST_FLOAT)], xmm7
181
	movaps	XMMWORD [XMMBLOCK(2,0,edx,SIZEOF_FAST_FLOAT)], xmm4
182
183
	; -- Odd part
184
185
	movaps	xmm6, XMMWORD [wk(0)]	; xmm6=tmp6
186
	movaps	xmm0, XMMWORD [wk(1)]	; xmm0=tmp7
187
188
	addps	xmm2,xmm3		; xmm2=tmp10
189
	addps	xmm3,xmm6		; xmm3=tmp11
190
	addps	xmm6,xmm0		; xmm6=tmp12, xmm0=tmp7
191
192
	mulps	xmm3,[GOTOFF(ebx,PD_0_707)] ; xmm3=z3
193
194
	movaps	xmm1,xmm2		; xmm1=tmp10
195
	subps	xmm2,xmm6
196
	mulps	xmm2,[GOTOFF(ebx,PD_0_382)] ; xmm2=z5
197
	mulps	xmm1,[GOTOFF(ebx,PD_0_541)] ; xmm1=MULTIPLY(tmp10,FIX_0_541196)
198
	mulps	xmm6,[GOTOFF(ebx,PD_1_306)] ; xmm6=MULTIPLY(tmp12,FIX_1_306562)
199
	addps	xmm1,xmm2		; xmm1=z2
200
	addps	xmm6,xmm2		; xmm6=z4
201
202
	movaps	xmm5,xmm0
203
	subps	xmm0,xmm3		; xmm0=z13
204
	addps	xmm5,xmm3		; xmm5=z11
205
206
	movaps	xmm7,xmm0
207
	movaps	xmm4,xmm5
208
	subps	xmm0,xmm1		; xmm0=data3
209
	subps	xmm5,xmm6		; xmm5=data7
210
	addps	xmm7,xmm1		; xmm7=data5
211
	addps	xmm4,xmm6		; xmm4=data1
212
213
	movaps	XMMWORD [XMMBLOCK(3,0,edx,SIZEOF_FAST_FLOAT)], xmm0
214
	movaps	XMMWORD [XMMBLOCK(3,1,edx,SIZEOF_FAST_FLOAT)], xmm5
215
	movaps	XMMWORD [XMMBLOCK(1,1,edx,SIZEOF_FAST_FLOAT)], xmm7
216
	movaps	XMMWORD [XMMBLOCK(1,0,edx,SIZEOF_FAST_FLOAT)], xmm4
217
218
	add	edx, 4*DCTSIZE*SIZEOF_FAST_FLOAT
219
	dec	ecx
220
	jnz	near .rowloop
221
222
	; ---- Pass 2: process columns.
223
224
	mov	edx, POINTER [data(eax)]	; (FAST_FLOAT *)
225
	mov	ecx, DCTSIZE/4
226
	alignx	16,7
227
.columnloop:
228
229
	movaps	xmm0, XMMWORD [XMMBLOCK(2,0,edx,SIZEOF_FAST_FLOAT)]
230
	movaps	xmm1, XMMWORD [XMMBLOCK(3,0,edx,SIZEOF_FAST_FLOAT)]
231
	movaps	xmm2, XMMWORD [XMMBLOCK(6,0,edx,SIZEOF_FAST_FLOAT)]
232
	movaps	xmm3, XMMWORD [XMMBLOCK(7,0,edx,SIZEOF_FAST_FLOAT)]
233
234
	; xmm0=(02 12 22 32), xmm2=(42 52 62 72)
235
	; xmm1=(03 13 23 33), xmm3=(43 53 63 73)
236
237
	movaps   xmm4,xmm0		; transpose coefficients(phase 1)
238
	unpcklps xmm0,xmm1		; xmm0=(02 03 12 13)
239
	unpckhps xmm4,xmm1		; xmm4=(22 23 32 33)
240
	movaps   xmm5,xmm2		; transpose coefficients(phase 1)
241
	unpcklps xmm2,xmm3		; xmm2=(42 43 52 53)
242
	unpckhps xmm5,xmm3		; xmm5=(62 63 72 73)
243
244
	movaps	xmm6, XMMWORD [XMMBLOCK(0,0,edx,SIZEOF_FAST_FLOAT)]
245
	movaps	xmm7, XMMWORD [XMMBLOCK(1,0,edx,SIZEOF_FAST_FLOAT)]
246
	movaps	xmm1, XMMWORD [XMMBLOCK(4,0,edx,SIZEOF_FAST_FLOAT)]
247
	movaps	xmm3, XMMWORD [XMMBLOCK(5,0,edx,SIZEOF_FAST_FLOAT)]
248
249
	; xmm6=(00 10 20 30), xmm1=(40 50 60 70)
250
	; xmm7=(01 11 21 31), xmm3=(41 51 61 71)
251
252
	movaps	XMMWORD [wk(0)], xmm4	; wk(0)=(22 23 32 33)
253
	movaps	XMMWORD [wk(1)], xmm2	; wk(1)=(42 43 52 53)
254
255
	movaps   xmm4,xmm6		; transpose coefficients(phase 1)
256
	unpcklps xmm6,xmm7		; xmm6=(00 01 10 11)
257
	unpckhps xmm4,xmm7		; xmm4=(20 21 30 31)
258
	movaps   xmm2,xmm1		; transpose coefficients(phase 1)
259
	unpcklps xmm1,xmm3		; xmm1=(40 41 50 51)
260
	unpckhps xmm2,xmm3		; xmm2=(60 61 70 71)
261
262
	movaps    xmm7,xmm6		; transpose coefficients(phase 2)
263
	unpcklps2 xmm6,xmm0		; xmm6=(00 01 02 03)=data0
264
	unpckhps2 xmm7,xmm0		; xmm7=(10 11 12 13)=data1
265
	movaps    xmm3,xmm2		; transpose coefficients(phase 2)
266
	unpcklps2 xmm2,xmm5		; xmm2=(60 61 62 63)=data6
267
	unpckhps2 xmm3,xmm5		; xmm3=(70 71 72 73)=data7
268
269
	movaps	xmm0,xmm7
270
	movaps	xmm5,xmm6
271
	subps	xmm7,xmm2		; xmm7=data1-data6=tmp6
272
	subps	xmm6,xmm3		; xmm6=data0-data7=tmp7
273
	addps	xmm0,xmm2		; xmm0=data1+data6=tmp1
274
	addps	xmm5,xmm3		; xmm5=data0+data7=tmp0
275
276
	movaps	xmm2, XMMWORD [wk(0)]	; xmm2=(22 23 32 33)
277
	movaps	xmm3, XMMWORD [wk(1)]	; xmm3=(42 43 52 53)
278
	movaps	XMMWORD [wk(0)], xmm7	; wk(0)=tmp6
279
	movaps	XMMWORD [wk(1)], xmm6	; wk(1)=tmp7
280
281
	movaps    xmm7,xmm4		; transpose coefficients(phase 2)
282
	unpcklps2 xmm4,xmm2		; xmm4=(20 21 22 23)=data2
283
	unpckhps2 xmm7,xmm2		; xmm7=(30 31 32 33)=data3
284
	movaps    xmm6,xmm1		; transpose coefficients(phase 2)
285
	unpcklps2 xmm1,xmm3		; xmm1=(40 41 42 43)=data4
286
	unpckhps2 xmm6,xmm3		; xmm6=(50 51 52 53)=data5
287
288
	movaps	xmm2,xmm7
289
	movaps	xmm3,xmm4
290
	addps	xmm7,xmm1		; xmm7=data3+data4=tmp3
291
	addps	xmm4,xmm6		; xmm4=data2+data5=tmp2
292
	subps	xmm2,xmm1		; xmm2=data3-data4=tmp4
293
	subps	xmm3,xmm6		; xmm3=data2-data5=tmp5
294
295
	; -- Even part
296
297
	movaps	xmm1,xmm5
298
	movaps	xmm6,xmm0
299
	subps	xmm5,xmm7		; xmm5=tmp13
300
	subps	xmm0,xmm4		; xmm0=tmp12
301
	addps	xmm1,xmm7		; xmm1=tmp10
302
	addps	xmm6,xmm4		; xmm6=tmp11
303
304
	addps	xmm0,xmm5
305
	mulps	xmm0,[GOTOFF(ebx,PD_0_707)] ; xmm0=z1
306
307
	movaps	xmm7,xmm1
308
	movaps	xmm4,xmm5
309
	subps	xmm1,xmm6		; xmm1=data4
310
	subps	xmm5,xmm0		; xmm5=data6
311
	addps	xmm7,xmm6		; xmm7=data0
312
	addps	xmm4,xmm0		; xmm4=data2
313
314
	movaps	XMMWORD [XMMBLOCK(4,0,edx,SIZEOF_FAST_FLOAT)], xmm1
315
	movaps	XMMWORD [XMMBLOCK(6,0,edx,SIZEOF_FAST_FLOAT)], xmm5
316
	movaps	XMMWORD [XMMBLOCK(0,0,edx,SIZEOF_FAST_FLOAT)], xmm7
317
	movaps	XMMWORD [XMMBLOCK(2,0,edx,SIZEOF_FAST_FLOAT)], xmm4
318
319
	; -- Odd part
320
321
	movaps	xmm6, XMMWORD [wk(0)]	; xmm6=tmp6
322
	movaps	xmm0, XMMWORD [wk(1)]	; xmm0=tmp7
323
324
	addps	xmm2,xmm3		; xmm2=tmp10
325
	addps	xmm3,xmm6		; xmm3=tmp11
326
	addps	xmm6,xmm0		; xmm6=tmp12, xmm0=tmp7
327
328
	mulps	xmm3,[GOTOFF(ebx,PD_0_707)] ; xmm3=z3
329
330
	movaps	xmm1,xmm2		; xmm1=tmp10
331
	subps	xmm2,xmm6
332
	mulps	xmm2,[GOTOFF(ebx,PD_0_382)] ; xmm2=z5
333
	mulps	xmm1,[GOTOFF(ebx,PD_0_541)] ; xmm1=MULTIPLY(tmp10,FIX_0_541196)
334
	mulps	xmm6,[GOTOFF(ebx,PD_1_306)] ; xmm6=MULTIPLY(tmp12,FIX_1_306562)
335
	addps	xmm1,xmm2		; xmm1=z2
336
	addps	xmm6,xmm2		; xmm6=z4
337
338
	movaps	xmm5,xmm0
339
	subps	xmm0,xmm3		; xmm0=z13
340
	addps	xmm5,xmm3		; xmm5=z11
341
342
	movaps	xmm7,xmm0
343
	movaps	xmm4,xmm5
344
	subps	xmm0,xmm1		; xmm0=data3
345
	subps	xmm5,xmm6		; xmm5=data7
346
	addps	xmm7,xmm1		; xmm7=data5
347
	addps	xmm4,xmm6		; xmm4=data1
348
349
	movaps	XMMWORD [XMMBLOCK(3,0,edx,SIZEOF_FAST_FLOAT)], xmm0
350
	movaps	XMMWORD [XMMBLOCK(7,0,edx,SIZEOF_FAST_FLOAT)], xmm5
351
	movaps	XMMWORD [XMMBLOCK(5,0,edx,SIZEOF_FAST_FLOAT)], xmm7
352
	movaps	XMMWORD [XMMBLOCK(1,0,edx,SIZEOF_FAST_FLOAT)], xmm4
353
354
	add	edx, byte 4*SIZEOF_FAST_FLOAT
355
	dec	ecx
356
	jnz	near .columnloop
357
358
;	pop	edi		; unused
359
;	pop	esi		; unused
360
;	pop	edx		; need not be preserved
361
;	pop	ecx		; need not be preserved
362
	poppic	ebx
363
	mov	esp,ebp		; esp <- aligned ebp
364
	pop	esp		; esp <- original ebp
365
	pop	ebp
366
	ret
367
368
; For some reason, the OS X linker does not honor the request to align the
369
; segment unless we do this.
370
	align	16
(-)a/jpeg/simd/ji3dnflt.asm (+452 lines)
Line     Link Here 
Line 0    Link Here 
1
;
2
; ji3dnflt.asm - floating-point IDCT (3DNow! & MMX)
3
;
4
; Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
5
;
6
; Based on
7
; x86 SIMD extension for IJG JPEG library
8
; Copyright (C) 1999-2006, MIYASAKA Masaru.
9
; For conditions of distribution and use, see copyright notice in jsimdext.inc
10
;
11
; This file should be assembled with NASM (Netwide Assembler),
12
; can *not* be assembled with Microsoft's MASM or any compatible
13
; assembler (including Borland's Turbo Assembler).
14
; NASM is available from http://nasm.sourceforge.net/ or
15
; http://sourceforge.net/project/showfiles.php?group_id=6208
16
;
17
; This file contains a floating-point implementation of the inverse DCT
18
; (Discrete Cosine Transform). The following code is based directly on
19
; the IJG's original jidctflt.c; see the jidctflt.c for more details.
20
;
21
; [TAB8]
22
23
%include "jsimdext.inc"
24
%include "jdct.inc"
25
26
; --------------------------------------------------------------------------
27
	SECTION	SEG_CONST
28
29
	alignz	16
30
	global	EXTN(jconst_idct_float_3dnow)
31
32
EXTN(jconst_idct_float_3dnow):
33
34
PD_1_414	times 2 dd  1.414213562373095048801689
35
PD_1_847	times 2 dd  1.847759065022573512256366
36
PD_1_082	times 2 dd  1.082392200292393968799446
37
PD_2_613	times 2 dd  2.613125929752753055713286
38
PD_RNDINT_MAGIC	times 2 dd  100663296.0	; (float)(0x00C00000 << 3)
39
PB_CENTERJSAMP	times 8 db  CENTERJSAMPLE
40
41
	alignz	16
42
43
; --------------------------------------------------------------------------
44
	SECTION	SEG_TEXT
45
	BITS	32
46
;
47
; Perform dequantization and inverse DCT on one block of coefficients.
48
;
49
; GLOBAL(void)
50
; jsimd_idct_float_3dnow (void * dct_table, JCOEFPTR coef_block,
51
;                         JSAMPARRAY output_buf, JDIMENSION output_col)
52
;
53
54
%define dct_table(b)	(b)+8			; void * dct_table
55
%define coef_block(b)	(b)+12		; JCOEFPTR coef_block
56
%define output_buf(b)	(b)+16		; JSAMPARRAY output_buf
57
%define output_col(b)	(b)+20		; JDIMENSION output_col
58
59
%define original_ebp	ebp+0
60
%define wk(i)		ebp-(WK_NUM-(i))*SIZEOF_MMWORD	; mmword wk[WK_NUM]
61
%define WK_NUM		2
62
%define workspace	wk(0)-DCTSIZE2*SIZEOF_FAST_FLOAT
63
					; FAST_FLOAT workspace[DCTSIZE2]
64
65
	align	16
66
	global	EXTN(jsimd_idct_float_3dnow)
67
68
EXTN(jsimd_idct_float_3dnow):
69
	push	ebp
70
	mov	eax,esp				; eax = original ebp
71
	sub	esp, byte 4
72
	and	esp, byte (-SIZEOF_MMWORD)	; align to 64 bits
73
	mov	[esp],eax
74
	mov	ebp,esp				; ebp = aligned ebp
75
	lea	esp, [workspace]
76
	push	ebx
77
;	push	ecx		; need not be preserved
78
;	push	edx		; need not be preserved
79
	push	esi
80
	push	edi
81
82
	get_GOT	ebx		; get GOT address
83
84
	; ---- Pass 1: process columns from input, store into work array.
85
86
;	mov	eax, [original_ebp]
87
	mov	edx, POINTER [dct_table(eax)]	; quantptr
88
	mov	esi, JCOEFPTR [coef_block(eax)]		; inptr
89
	lea	edi, [workspace]			; FAST_FLOAT * wsptr
90
	mov	ecx, DCTSIZE/2				; ctr
91
	alignx	16,7
92
.columnloop:
93
%ifndef NO_ZERO_COLUMN_TEST_FLOAT_3DNOW
94
	mov	eax, DWORD [DWBLOCK(1,0,esi,SIZEOF_JCOEF)]
95
	or	eax, DWORD [DWBLOCK(2,0,esi,SIZEOF_JCOEF)]
96
	jnz	short .columnDCT
97
98
	pushpic	ebx		; save GOT address
99
	mov	ebx, DWORD [DWBLOCK(3,0,esi,SIZEOF_JCOEF)]
100
	mov	eax, DWORD [DWBLOCK(4,0,esi,SIZEOF_JCOEF)]
101
	or	ebx, DWORD [DWBLOCK(5,0,esi,SIZEOF_JCOEF)]
102
	or	eax, DWORD [DWBLOCK(6,0,esi,SIZEOF_JCOEF)]
103
	or	ebx, DWORD [DWBLOCK(7,0,esi,SIZEOF_JCOEF)]
104
	or	eax,ebx
105
	poppic	ebx		; restore GOT address
106
	jnz	short .columnDCT
107
108
	; -- AC terms all zero
109
110
	movd      mm0, DWORD [DWBLOCK(0,0,esi,SIZEOF_JCOEF)]
111
112
	punpcklwd mm0,mm0
113
	psrad     mm0,(DWORD_BIT-WORD_BIT)
114
	pi2fd     mm0,mm0
115
116
	pfmul     mm0, MMWORD [MMBLOCK(0,0,edx,SIZEOF_FLOAT_MULT_TYPE)]
117
118
	movq      mm1,mm0
119
	punpckldq mm0,mm0
120
	punpckhdq mm1,mm1
121
122
	movq	MMWORD [MMBLOCK(0,0,edi,SIZEOF_FAST_FLOAT)], mm0
123
	movq	MMWORD [MMBLOCK(0,1,edi,SIZEOF_FAST_FLOAT)], mm0
124
	movq	MMWORD [MMBLOCK(0,2,edi,SIZEOF_FAST_FLOAT)], mm0
125
	movq	MMWORD [MMBLOCK(0,3,edi,SIZEOF_FAST_FLOAT)], mm0
126
	movq	MMWORD [MMBLOCK(1,0,edi,SIZEOF_FAST_FLOAT)], mm1
127
	movq	MMWORD [MMBLOCK(1,1,edi,SIZEOF_FAST_FLOAT)], mm1
128
	movq	MMWORD [MMBLOCK(1,2,edi,SIZEOF_FAST_FLOAT)], mm1
129
	movq	MMWORD [MMBLOCK(1,3,edi,SIZEOF_FAST_FLOAT)], mm1
130
	jmp	near .nextcolumn
131
	alignx	16,7
132
%endif
133
.columnDCT:
134
135
	; -- Even part
136
137
	movd      mm0, DWORD [DWBLOCK(0,0,esi,SIZEOF_JCOEF)]
138
	movd      mm1, DWORD [DWBLOCK(2,0,esi,SIZEOF_JCOEF)]
139
	movd      mm2, DWORD [DWBLOCK(4,0,esi,SIZEOF_JCOEF)]
140
	movd      mm3, DWORD [DWBLOCK(6,0,esi,SIZEOF_JCOEF)]
141
142
	punpcklwd mm0,mm0
143
	punpcklwd mm1,mm1
144
	psrad     mm0,(DWORD_BIT-WORD_BIT)
145
	psrad     mm1,(DWORD_BIT-WORD_BIT)
146
	pi2fd     mm0,mm0
147
	pi2fd     mm1,mm1
148
149
	pfmul     mm0, MMWORD [MMBLOCK(0,0,edx,SIZEOF_FLOAT_MULT_TYPE)]
150
	pfmul     mm1, MMWORD [MMBLOCK(2,0,edx,SIZEOF_FLOAT_MULT_TYPE)]
151
152
	punpcklwd mm2,mm2
153
	punpcklwd mm3,mm3
154
	psrad     mm2,(DWORD_BIT-WORD_BIT)
155
	psrad     mm3,(DWORD_BIT-WORD_BIT)
156
	pi2fd     mm2,mm2
157
	pi2fd     mm3,mm3
158
159
	pfmul     mm2, MMWORD [MMBLOCK(4,0,edx,SIZEOF_FLOAT_MULT_TYPE)]
160
	pfmul     mm3, MMWORD [MMBLOCK(6,0,edx,SIZEOF_FLOAT_MULT_TYPE)]
161
162
	movq	mm4,mm0
163
	movq	mm5,mm1
164
	pfsub	mm0,mm2			; mm0=tmp11
165
	pfsub	mm1,mm3
166
	pfadd	mm4,mm2			; mm4=tmp10
167
	pfadd	mm5,mm3			; mm5=tmp13
168
169
	pfmul	mm1,[GOTOFF(ebx,PD_1_414)]
170
	pfsub	mm1,mm5			; mm1=tmp12
171
172
	movq	mm6,mm4
173
	movq	mm7,mm0
174
	pfsub	mm4,mm5			; mm4=tmp3
175
	pfsub	mm0,mm1			; mm0=tmp2
176
	pfadd	mm6,mm5			; mm6=tmp0
177
	pfadd	mm7,mm1			; mm7=tmp1
178
179
	movq	MMWORD [wk(1)], mm4	; tmp3
180
	movq	MMWORD [wk(0)], mm0	; tmp2
181
182
	; -- Odd part
183
184
	movd      mm2, DWORD [DWBLOCK(1,0,esi,SIZEOF_JCOEF)]
185
	movd      mm3, DWORD [DWBLOCK(3,0,esi,SIZEOF_JCOEF)]
186
	movd      mm5, DWORD [DWBLOCK(5,0,esi,SIZEOF_JCOEF)]
187
	movd      mm1, DWORD [DWBLOCK(7,0,esi,SIZEOF_JCOEF)]
188
189
	punpcklwd mm2,mm2
190
	punpcklwd mm3,mm3
191
	psrad     mm2,(DWORD_BIT-WORD_BIT)
192
	psrad     mm3,(DWORD_BIT-WORD_BIT)
193
	pi2fd     mm2,mm2
194
	pi2fd     mm3,mm3
195
196
	pfmul     mm2, MMWORD [MMBLOCK(1,0,edx,SIZEOF_FLOAT_MULT_TYPE)]
197
	pfmul     mm3, MMWORD [MMBLOCK(3,0,edx,SIZEOF_FLOAT_MULT_TYPE)]
198
199
	punpcklwd mm5,mm5
200
	punpcklwd mm1,mm1
201
	psrad     mm5,(DWORD_BIT-WORD_BIT)
202
	psrad     mm1,(DWORD_BIT-WORD_BIT)
203
	pi2fd     mm5,mm5
204
	pi2fd     mm1,mm1
205
206
	pfmul     mm5, MMWORD [MMBLOCK(5,0,edx,SIZEOF_FLOAT_MULT_TYPE)]
207
	pfmul     mm1, MMWORD [MMBLOCK(7,0,edx,SIZEOF_FLOAT_MULT_TYPE)]
208
209
	movq	mm4,mm2
210
	movq	mm0,mm5
211
	pfadd	mm2,mm1			; mm2=z11
212
	pfadd	mm5,mm3			; mm5=z13
213
	pfsub	mm4,mm1			; mm4=z12
214
	pfsub	mm0,mm3			; mm0=z10
215
216
	movq	mm1,mm2
217
	pfsub	mm2,mm5
218
	pfadd	mm1,mm5			; mm1=tmp7
219
220
	pfmul	mm2,[GOTOFF(ebx,PD_1_414)]	; mm2=tmp11
221
222
	movq	mm3,mm0
223
	pfadd	mm0,mm4
224
	pfmul	mm0,[GOTOFF(ebx,PD_1_847)]	; mm0=z5
225
	pfmul	mm3,[GOTOFF(ebx,PD_2_613)]	; mm3=(z10 * 2.613125930)
226
	pfmul	mm4,[GOTOFF(ebx,PD_1_082)]	; mm4=(z12 * 1.082392200)
227
	pfsubr	mm3,mm0			; mm3=tmp12
228
	pfsub	mm4,mm0			; mm4=tmp10
229
230
	; -- Final output stage
231
232
	pfsub	mm3,mm1			; mm3=tmp6
233
	movq	mm5,mm6
234
	movq	mm0,mm7
235
	pfadd	mm6,mm1			; mm6=data0=(00 01)
236
	pfadd	mm7,mm3			; mm7=data1=(10 11)
237
	pfsub	mm5,mm1			; mm5=data7=(70 71)
238
	pfsub	mm0,mm3			; mm0=data6=(60 61)
239
	pfsub	mm2,mm3			; mm2=tmp5
240
241
	movq      mm1,mm6		; transpose coefficients
242
	punpckldq mm6,mm7		; mm6=(00 10)
243
	punpckhdq mm1,mm7		; mm1=(01 11)
244
	movq      mm3,mm0		; transpose coefficients
245
	punpckldq mm0,mm5		; mm0=(60 70)
246
	punpckhdq mm3,mm5		; mm3=(61 71)
247
248
	movq	MMWORD [MMBLOCK(0,0,edi,SIZEOF_FAST_FLOAT)], mm6
249
	movq	MMWORD [MMBLOCK(1,0,edi,SIZEOF_FAST_FLOAT)], mm1
250
	movq	MMWORD [MMBLOCK(0,3,edi,SIZEOF_FAST_FLOAT)], mm0
251
	movq	MMWORD [MMBLOCK(1,3,edi,SIZEOF_FAST_FLOAT)], mm3
252
253
	movq	mm7, MMWORD [wk(0)]	; mm7=tmp2
254
	movq	mm5, MMWORD [wk(1)]	; mm5=tmp3
255
256
	pfadd	mm4,mm2			; mm4=tmp4
257
	movq	mm6,mm7
258
	movq	mm1,mm5
259
	pfadd	mm7,mm2			; mm7=data2=(20 21)
260
	pfadd	mm5,mm4			; mm5=data4=(40 41)
261
	pfsub	mm6,mm2			; mm6=data5=(50 51)
262
	pfsub	mm1,mm4			; mm1=data3=(30 31)
263
264
	movq      mm0,mm7		; transpose coefficients
265
	punpckldq mm7,mm1		; mm7=(20 30)
266
	punpckhdq mm0,mm1		; mm0=(21 31)
267
	movq      mm3,mm5		; transpose coefficients
268
	punpckldq mm5,mm6		; mm5=(40 50)
269
	punpckhdq mm3,mm6		; mm3=(41 51)
270
271
	movq	MMWORD [MMBLOCK(0,1,edi,SIZEOF_FAST_FLOAT)], mm7
272
	movq	MMWORD [MMBLOCK(1,1,edi,SIZEOF_FAST_FLOAT)], mm0
273
	movq	MMWORD [MMBLOCK(0,2,edi,SIZEOF_FAST_FLOAT)], mm5
274
	movq	MMWORD [MMBLOCK(1,2,edi,SIZEOF_FAST_FLOAT)], mm3
275
276
.nextcolumn:
277
	add	esi, byte 2*SIZEOF_JCOEF		; coef_block
278
	add	edx, byte 2*SIZEOF_FLOAT_MULT_TYPE	; quantptr
279
	add	edi, byte 2*DCTSIZE*SIZEOF_FAST_FLOAT	; wsptr
280
	dec	ecx					; ctr
281
	jnz	near .columnloop
282
283
	; -- Prefetch the next coefficient block
284
285
	prefetch [esi + (DCTSIZE2-8)*SIZEOF_JCOEF + 0*32]
286
	prefetch [esi + (DCTSIZE2-8)*SIZEOF_JCOEF + 1*32]
287
	prefetch [esi + (DCTSIZE2-8)*SIZEOF_JCOEF + 2*32]
288
	prefetch [esi + (DCTSIZE2-8)*SIZEOF_JCOEF + 3*32]
289
290
	; ---- Pass 2: process rows from work array, store into output array.
291
292
	mov	eax, [original_ebp]
293
	lea	esi, [workspace]			; FAST_FLOAT * wsptr
294
	mov	edi, JSAMPARRAY [output_buf(eax)]	; (JSAMPROW *)
295
	mov	eax, JDIMENSION [output_col(eax)]
296
	mov	ecx, DCTSIZE/2				; ctr
297
	alignx	16,7
298
.rowloop:
299
300
	; -- Even part
301
302
	movq	mm0, MMWORD [MMBLOCK(0,0,esi,SIZEOF_FAST_FLOAT)]
303
	movq	mm1, MMWORD [MMBLOCK(2,0,esi,SIZEOF_FAST_FLOAT)]
304
	movq	mm2, MMWORD [MMBLOCK(4,0,esi,SIZEOF_FAST_FLOAT)]
305
	movq	mm3, MMWORD [MMBLOCK(6,0,esi,SIZEOF_FAST_FLOAT)]
306
307
	movq	mm4,mm0
308
	movq	mm5,mm1
309
	pfsub	mm0,mm2			; mm0=tmp11
310
	pfsub	mm1,mm3
311
	pfadd	mm4,mm2			; mm4=tmp10
312
	pfadd	mm5,mm3			; mm5=tmp13
313
314
	pfmul	mm1,[GOTOFF(ebx,PD_1_414)]
315
	pfsub	mm1,mm5			; mm1=tmp12
316
317
	movq	mm6,mm4
318
	movq	mm7,mm0
319
	pfsub	mm4,mm5			; mm4=tmp3
320
	pfsub	mm0,mm1			; mm0=tmp2
321
	pfadd	mm6,mm5			; mm6=tmp0
322
	pfadd	mm7,mm1			; mm7=tmp1
323
324
	movq	MMWORD [wk(1)], mm4	; tmp3
325
	movq	MMWORD [wk(0)], mm0	; tmp2
326
327
	; -- Odd part
328
329
	movq	mm2, MMWORD [MMBLOCK(1,0,esi,SIZEOF_FAST_FLOAT)]
330
	movq	mm3, MMWORD [MMBLOCK(3,0,esi,SIZEOF_FAST_FLOAT)]
331
	movq	mm5, MMWORD [MMBLOCK(5,0,esi,SIZEOF_FAST_FLOAT)]
332
	movq	mm1, MMWORD [MMBLOCK(7,0,esi,SIZEOF_FAST_FLOAT)]
333
334
	movq	mm4,mm2
335
	movq	mm0,mm5
336
	pfadd	mm2,mm1			; mm2=z11
337
	pfadd	mm5,mm3			; mm5=z13
338
	pfsub	mm4,mm1			; mm4=z12
339
	pfsub	mm0,mm3			; mm0=z10
340
341
	movq	mm1,mm2
342
	pfsub	mm2,mm5
343
	pfadd	mm1,mm5			; mm1=tmp7
344
345
	pfmul	mm2,[GOTOFF(ebx,PD_1_414)]	; mm2=tmp11
346
347
	movq	mm3,mm0
348
	pfadd	mm0,mm4
349
	pfmul	mm0,[GOTOFF(ebx,PD_1_847)]	; mm0=z5
350
	pfmul	mm3,[GOTOFF(ebx,PD_2_613)]	; mm3=(z10 * 2.613125930)
351
	pfmul	mm4,[GOTOFF(ebx,PD_1_082)]	; mm4=(z12 * 1.082392200)
352
	pfsubr	mm3,mm0			; mm3=tmp12
353
	pfsub	mm4,mm0			; mm4=tmp10
354
355
	; -- Final output stage
356
357
	pfsub	mm3,mm1			; mm3=tmp6
358
	movq	mm5,mm6
359
	movq	mm0,mm7
360
	pfadd	mm6,mm1			; mm6=data0=(00 10)
361
	pfadd	mm7,mm3			; mm7=data1=(01 11)
362
	pfsub	mm5,mm1			; mm5=data7=(07 17)
363
	pfsub	mm0,mm3			; mm0=data6=(06 16)
364
	pfsub	mm2,mm3			; mm2=tmp5
365
366
	movq	mm1,[GOTOFF(ebx,PD_RNDINT_MAGIC)]	; mm1=[PD_RNDINT_MAGIC]
367
	pcmpeqd	mm3,mm3
368
	psrld	mm3,WORD_BIT		; mm3={0xFFFF 0x0000 0xFFFF 0x0000}
369
370
	pfadd	mm6,mm1			; mm6=roundint(data0/8)=(00 ** 10 **)
371
	pfadd	mm7,mm1			; mm7=roundint(data1/8)=(01 ** 11 **)
372
	pfadd	mm0,mm1			; mm0=roundint(data6/8)=(06 ** 16 **)
373
	pfadd	mm5,mm1			; mm5=roundint(data7/8)=(07 ** 17 **)
374
375
	pand	mm6,mm3			; mm6=(00 -- 10 --)
376
	pslld	mm7,WORD_BIT		; mm7=(-- 01 -- 11)
377
	pand	mm0,mm3			; mm0=(06 -- 16 --)
378
	pslld	mm5,WORD_BIT		; mm5=(-- 07 -- 17)
379
	por	mm6,mm7			; mm6=(00 01 10 11)
380
	por	mm0,mm5			; mm0=(06 07 16 17)
381
382
	movq	mm1, MMWORD [wk(0)]	; mm1=tmp2
383
	movq	mm3, MMWORD [wk(1)]	; mm3=tmp3
384
385
	pfadd	mm4,mm2			; mm4=tmp4
386
	movq	mm7,mm1
387
	movq	mm5,mm3
388
	pfadd	mm1,mm2			; mm1=data2=(02 12)
389
	pfadd	mm3,mm4			; mm3=data4=(04 14)
390
	pfsub	mm7,mm2			; mm7=data5=(05 15)
391
	pfsub	mm5,mm4			; mm5=data3=(03 13)
392
393
	movq	mm2,[GOTOFF(ebx,PD_RNDINT_MAGIC)]	; mm2=[PD_RNDINT_MAGIC]
394
	pcmpeqd	mm4,mm4
395
	psrld	mm4,WORD_BIT		; mm4={0xFFFF 0x0000 0xFFFF 0x0000}
396
397
	pfadd	mm3,mm2			; mm3=roundint(data4/8)=(04 ** 14 **)
398
	pfadd	mm7,mm2			; mm7=roundint(data5/8)=(05 ** 15 **)
399
	pfadd	mm1,mm2			; mm1=roundint(data2/8)=(02 ** 12 **)
400
	pfadd	mm5,mm2			; mm5=roundint(data3/8)=(03 ** 13 **)
401
402
	pand	mm3,mm4			; mm3=(04 -- 14 --)
403
	pslld	mm7,WORD_BIT		; mm7=(-- 05 -- 15)
404
	pand	mm1,mm4			; mm1=(02 -- 12 --)
405
	pslld	mm5,WORD_BIT		; mm5=(-- 03 -- 13)
406
	por	mm3,mm7			; mm3=(04 05 14 15)
407
	por	mm1,mm5			; mm1=(02 03 12 13)
408
409
	movq      mm2,[GOTOFF(ebx,PB_CENTERJSAMP)]	; mm2=[PB_CENTERJSAMP]
410
411
	packsswb  mm6,mm3		; mm6=(00 01 10 11 04 05 14 15)
412
	packsswb  mm1,mm0		; mm1=(02 03 12 13 06 07 16 17)
413
	paddb     mm6,mm2
414
	paddb     mm1,mm2
415
416
	movq      mm4,mm6		; transpose coefficients(phase 2)
417
	punpcklwd mm6,mm1		; mm6=(00 01 02 03 10 11 12 13)
418
	punpckhwd mm4,mm1		; mm4=(04 05 06 07 14 15 16 17)
419
420
	movq      mm7,mm6		; transpose coefficients(phase 3)
421
	punpckldq mm6,mm4		; mm6=(00 01 02 03 04 05 06 07)
422
	punpckhdq mm7,mm4		; mm7=(10 11 12 13 14 15 16 17)
423
424
	pushpic	ebx			; save GOT address
425
426
	mov	edx, JSAMPROW [edi+0*SIZEOF_JSAMPROW]
427
	mov	ebx, JSAMPROW [edi+1*SIZEOF_JSAMPROW]
428
	movq	MMWORD [edx+eax*SIZEOF_JSAMPLE], mm6
429
	movq	MMWORD [ebx+eax*SIZEOF_JSAMPLE], mm7
430
431
	poppic	ebx			; restore GOT address
432
433
	add	esi, byte 2*SIZEOF_FAST_FLOAT	; wsptr
434
	add	edi, byte 2*SIZEOF_JSAMPROW
435
	dec	ecx				; ctr
436
	jnz	near .rowloop
437
438
	femms		; empty MMX/3DNow! state
439
440
	pop	edi
441
	pop	esi
442
;	pop	edx		; need not be preserved
443
;	pop	ecx		; need not be preserved
444
	pop	ebx
445
	mov	esp,ebp		; esp <- aligned ebp
446
	pop	esp		; esp <- original ebp
447
	pop	ebp
448
	ret
449
450
; For some reason, the OS X linker does not honor the request to align the
451
; segment unless we do this.
452
	align	16
(-)a/jpeg/simd/jimmxfst.asm (+500 lines)
Line     Link Here 
Line 0    Link Here 
1
;
2
; jimmxfst.asm - fast integer IDCT (MMX)
3
;
4
; Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
5
;
6
; Based on
7
; x86 SIMD extension for IJG JPEG library
8
; Copyright (C) 1999-2006, MIYASAKA Masaru.
9
; For conditions of distribution and use, see copyright notice in jsimdext.inc
10
;
11
; This file should be assembled with NASM (Netwide Assembler),
12
; can *not* be assembled with Microsoft's MASM or any compatible
13
; assembler (including Borland's Turbo Assembler).
14
; NASM is available from http://nasm.sourceforge.net/ or
15
; http://sourceforge.net/project/showfiles.php?group_id=6208
16
;
17
; This file contains a fast, not so accurate integer implementation of
18
; the inverse DCT (Discrete Cosine Transform). The following code is
19
; based directly on the IJG's original jidctfst.c; see the jidctfst.c
20
; for more details.
21
;
22
; [TAB8]
23
24
%include "jsimdext.inc"
25
%include "jdct.inc"
26
27
; --------------------------------------------------------------------------
28
29
%define CONST_BITS	8	; 14 is also OK.
30
%define PASS1_BITS	2
31
32
%if IFAST_SCALE_BITS != PASS1_BITS
33
%error "'IFAST_SCALE_BITS' must be equal to 'PASS1_BITS'."
34
%endif
35
36
%if CONST_BITS == 8
37
F_1_082	equ	277		; FIX(1.082392200)
38
F_1_414	equ	362		; FIX(1.414213562)
39
F_1_847	equ	473		; FIX(1.847759065)
40
F_2_613	equ	669		; FIX(2.613125930)
41
F_1_613	equ	(F_2_613 - 256)	; FIX(2.613125930) - FIX(1)
42
%else
43
; NASM cannot do compile-time arithmetic on floating-point constants.
44
%define	DESCALE(x,n)  (((x)+(1<<((n)-1)))>>(n))
45
F_1_082	equ	DESCALE(1162209775,30-CONST_BITS)	; FIX(1.082392200)
46
F_1_414	equ	DESCALE(1518500249,30-CONST_BITS)	; FIX(1.414213562)
47
F_1_847	equ	DESCALE(1984016188,30-CONST_BITS)	; FIX(1.847759065)
48
F_2_613	equ	DESCALE(2805822602,30-CONST_BITS)	; FIX(2.613125930)
49
F_1_613	equ	(F_2_613 - (1 << CONST_BITS))	; FIX(2.613125930) - FIX(1)
50
%endif
51
52
; --------------------------------------------------------------------------
53
	SECTION	SEG_CONST
54
55
; PRE_MULTIPLY_SCALE_BITS <= 2 (to avoid overflow)
56
; CONST_BITS + CONST_SHIFT + PRE_MULTIPLY_SCALE_BITS == 16 (for pmulhw)
57
58
%define PRE_MULTIPLY_SCALE_BITS   2
59
%define CONST_SHIFT     (16 - PRE_MULTIPLY_SCALE_BITS - CONST_BITS)
60
61
	alignz	16
62
	global	EXTN(jconst_idct_ifast_mmx)
63
64
EXTN(jconst_idct_ifast_mmx):
65
66
PW_F1414	times 4 dw  F_1_414 << CONST_SHIFT
67
PW_F1847	times 4 dw  F_1_847 << CONST_SHIFT
68
PW_MF1613	times 4 dw -F_1_613 << CONST_SHIFT
69
PW_F1082	times 4 dw  F_1_082 << CONST_SHIFT
70
PB_CENTERJSAMP	times 8 db  CENTERJSAMPLE
71
72
	alignz	16
73
74
; --------------------------------------------------------------------------
75
	SECTION	SEG_TEXT
76
	BITS	32
77
;
78
; Perform dequantization and inverse DCT on one block of coefficients.
79
;
80
; GLOBAL(void)
81
; jsimd_idct_ifast_mmx (void * dct_table, JCOEFPTR coef_block,
82
;                       JSAMPARRAY output_buf, JDIMENSION output_col)
83
;
84
85
%define dct_table(b)	(b)+8			; jpeg_component_info * compptr
86
%define coef_block(b)	(b)+12		; JCOEFPTR coef_block
87
%define output_buf(b)	(b)+16		; JSAMPARRAY output_buf
88
%define output_col(b)	(b)+20		; JDIMENSION output_col
89
90
%define original_ebp	ebp+0
91
%define wk(i)		ebp-(WK_NUM-(i))*SIZEOF_MMWORD	; mmword wk[WK_NUM]
92
%define WK_NUM		2
93
%define workspace	wk(0)-DCTSIZE2*SIZEOF_JCOEF
94
					; JCOEF workspace[DCTSIZE2]
95
96
	align	16
97
	global	EXTN(jsimd_idct_ifast_mmx)
98
99
EXTN(jsimd_idct_ifast_mmx):
100
	push	ebp
101
	mov	eax,esp				; eax = original ebp
102
	sub	esp, byte 4
103
	and	esp, byte (-SIZEOF_MMWORD)	; align to 64 bits
104
	mov	[esp],eax
105
	mov	ebp,esp				; ebp = aligned ebp
106
	lea	esp, [workspace]
107
	push	ebx
108
;	push	ecx		; need not be preserved
109
;	push	edx		; need not be preserved
110
	push	esi
111
	push	edi
112
113
	get_GOT	ebx		; get GOT address
114
115
	; ---- Pass 1: process columns from input, store into work array.
116
117
;	mov	eax, [original_ebp]
118
	mov	edx, POINTER [dct_table(eax)]	; quantptr
119
	mov	esi, JCOEFPTR [coef_block(eax)]		; inptr
120
	lea	edi, [workspace]			; JCOEF * wsptr
121
	mov	ecx, DCTSIZE/4				; ctr
122
	alignx	16,7
123
.columnloop:
124
%ifndef NO_ZERO_COLUMN_TEST_IFAST_MMX
125
	mov	eax, DWORD [DWBLOCK(1,0,esi,SIZEOF_JCOEF)]
126
	or	eax, DWORD [DWBLOCK(2,0,esi,SIZEOF_JCOEF)]
127
	jnz	short .columnDCT
128
129
	movq	mm0, MMWORD [MMBLOCK(1,0,esi,SIZEOF_JCOEF)]
130
	movq	mm1, MMWORD [MMBLOCK(2,0,esi,SIZEOF_JCOEF)]
131
	por	mm0, MMWORD [MMBLOCK(3,0,esi,SIZEOF_JCOEF)]
132
	por	mm1, MMWORD [MMBLOCK(4,0,esi,SIZEOF_JCOEF)]
133
	por	mm0, MMWORD [MMBLOCK(5,0,esi,SIZEOF_JCOEF)]
134
	por	mm1, MMWORD [MMBLOCK(6,0,esi,SIZEOF_JCOEF)]
135
	por	mm0, MMWORD [MMBLOCK(7,0,esi,SIZEOF_JCOEF)]
136
	por	mm1,mm0
137
	packsswb mm1,mm1
138
	movd	eax,mm1
139
	test	eax,eax
140
	jnz	short .columnDCT
141
142
	; -- AC terms all zero
143
144
	movq	mm0, MMWORD [MMBLOCK(0,0,esi,SIZEOF_JCOEF)]
145
	pmullw	mm0, MMWORD [MMBLOCK(0,0,edx,SIZEOF_IFAST_MULT_TYPE)]
146
147
	movq      mm2,mm0		; mm0=in0=(00 01 02 03)
148
	punpcklwd mm0,mm0		; mm0=(00 00 01 01)
149
	punpckhwd mm2,mm2		; mm2=(02 02 03 03)
150
151
	movq      mm1,mm0
152
	punpckldq mm0,mm0		; mm0=(00 00 00 00)
153
	punpckhdq mm1,mm1		; mm1=(01 01 01 01)
154
	movq      mm3,mm2
155
	punpckldq mm2,mm2		; mm2=(02 02 02 02)
156
	punpckhdq mm3,mm3		; mm3=(03 03 03 03)
157
158
	movq	MMWORD [MMBLOCK(0,0,edi,SIZEOF_JCOEF)], mm0
159
	movq	MMWORD [MMBLOCK(0,1,edi,SIZEOF_JCOEF)], mm0
160
	movq	MMWORD [MMBLOCK(1,0,edi,SIZEOF_JCOEF)], mm1
161
	movq	MMWORD [MMBLOCK(1,1,edi,SIZEOF_JCOEF)], mm1
162
	movq	MMWORD [MMBLOCK(2,0,edi,SIZEOF_JCOEF)], mm2
163
	movq	MMWORD [MMBLOCK(2,1,edi,SIZEOF_JCOEF)], mm2
164
	movq	MMWORD [MMBLOCK(3,0,edi,SIZEOF_JCOEF)], mm3
165
	movq	MMWORD [MMBLOCK(3,1,edi,SIZEOF_JCOEF)], mm3
166
	jmp	near .nextcolumn
167
	alignx	16,7
168
%endif
169
.columnDCT:
170
171
	; -- Even part
172
173
	movq	mm0, MMWORD [MMBLOCK(0,0,esi,SIZEOF_JCOEF)]
174
	movq	mm1, MMWORD [MMBLOCK(2,0,esi,SIZEOF_JCOEF)]
175
	pmullw	mm0, MMWORD [MMBLOCK(0,0,edx,SIZEOF_IFAST_MULT_TYPE)]
176
	pmullw	mm1, MMWORD [MMBLOCK(2,0,edx,SIZEOF_IFAST_MULT_TYPE)]
177
	movq	mm2, MMWORD [MMBLOCK(4,0,esi,SIZEOF_JCOEF)]
178
	movq	mm3, MMWORD [MMBLOCK(6,0,esi,SIZEOF_JCOEF)]
179
	pmullw	mm2, MMWORD [MMBLOCK(4,0,edx,SIZEOF_IFAST_MULT_TYPE)]
180
	pmullw	mm3, MMWORD [MMBLOCK(6,0,edx,SIZEOF_IFAST_MULT_TYPE)]
181
182
	movq	mm4,mm0
183
	movq	mm5,mm1
184
	psubw	mm0,mm2			; mm0=tmp11
185
	psubw	mm1,mm3
186
	paddw	mm4,mm2			; mm4=tmp10
187
	paddw	mm5,mm3			; mm5=tmp13
188
189
	psllw	mm1,PRE_MULTIPLY_SCALE_BITS
190
	pmulhw	mm1,[GOTOFF(ebx,PW_F1414)]
191
	psubw	mm1,mm5			; mm1=tmp12
192
193
	movq	mm6,mm4
194
	movq	mm7,mm0
195
	psubw	mm4,mm5			; mm4=tmp3
196
	psubw	mm0,mm1			; mm0=tmp2
197
	paddw	mm6,mm5			; mm6=tmp0
198
	paddw	mm7,mm1			; mm7=tmp1
199
200
	movq	MMWORD [wk(1)], mm4	; wk(1)=tmp3
201
	movq	MMWORD [wk(0)], mm0	; wk(0)=tmp2
202
203
	; -- Odd part
204
205
	movq	mm2, MMWORD [MMBLOCK(1,0,esi,SIZEOF_JCOEF)]
206
	movq	mm3, MMWORD [MMBLOCK(3,0,esi,SIZEOF_JCOEF)]
207
	pmullw	mm2, MMWORD [MMBLOCK(1,0,edx,SIZEOF_IFAST_MULT_TYPE)]
208
	pmullw	mm3, MMWORD [MMBLOCK(3,0,edx,SIZEOF_IFAST_MULT_TYPE)]
209
	movq	mm5, MMWORD [MMBLOCK(5,0,esi,SIZEOF_JCOEF)]
210
	movq	mm1, MMWORD [MMBLOCK(7,0,esi,SIZEOF_JCOEF)]
211
	pmullw	mm5, MMWORD [MMBLOCK(5,0,edx,SIZEOF_IFAST_MULT_TYPE)]
212
	pmullw	mm1, MMWORD [MMBLOCK(7,0,edx,SIZEOF_IFAST_MULT_TYPE)]
213
214
	movq	mm4,mm2
215
	movq	mm0,mm5
216
	psubw	mm2,mm1			; mm2=z12
217
	psubw	mm5,mm3			; mm5=z10
218
	paddw	mm4,mm1			; mm4=z11
219
	paddw	mm0,mm3			; mm0=z13
220
221
	movq	mm1,mm5			; mm1=z10(unscaled)
222
	psllw	mm2,PRE_MULTIPLY_SCALE_BITS
223
	psllw	mm5,PRE_MULTIPLY_SCALE_BITS
224
225
	movq	mm3,mm4
226
	psubw	mm4,mm0
227
	paddw	mm3,mm0			; mm3=tmp7
228
229
	psllw	mm4,PRE_MULTIPLY_SCALE_BITS
230
	pmulhw	mm4,[GOTOFF(ebx,PW_F1414)]	; mm4=tmp11
231
232
	; To avoid overflow...
233
	;
234
	; (Original)
235
	; tmp12 = -2.613125930 * z10 + z5;
236
	;
237
	; (This implementation)
238
	; tmp12 = (-1.613125930 - 1) * z10 + z5;
239
	;       = -1.613125930 * z10 - z10 + z5;
240
241
	movq	mm0,mm5
242
	paddw	mm5,mm2
243
	pmulhw	mm5,[GOTOFF(ebx,PW_F1847)]	; mm5=z5
244
	pmulhw	mm0,[GOTOFF(ebx,PW_MF1613)]
245
	pmulhw	mm2,[GOTOFF(ebx,PW_F1082)]
246
	psubw	mm0,mm1
247
	psubw	mm2,mm5			; mm2=tmp10
248
	paddw	mm0,mm5			; mm0=tmp12
249
250
	; -- Final output stage
251
252
	psubw	mm0,mm3			; mm0=tmp6
253
	movq	mm1,mm6
254
	movq	mm5,mm7
255
	paddw	mm6,mm3			; mm6=data0=(00 01 02 03)
256
	paddw	mm7,mm0			; mm7=data1=(10 11 12 13)
257
	psubw	mm1,mm3			; mm1=data7=(70 71 72 73)
258
	psubw	mm5,mm0			; mm5=data6=(60 61 62 63)
259
	psubw	mm4,mm0			; mm4=tmp5
260
261
	movq      mm3,mm6		; transpose coefficients(phase 1)
262
	punpcklwd mm6,mm7		; mm6=(00 10 01 11)
263
	punpckhwd mm3,mm7		; mm3=(02 12 03 13)
264
	movq      mm0,mm5		; transpose coefficients(phase 1)
265
	punpcklwd mm5,mm1		; mm5=(60 70 61 71)
266
	punpckhwd mm0,mm1		; mm0=(62 72 63 73)
267
268
	movq	mm7, MMWORD [wk(0)]	; mm7=tmp2
269
	movq	mm1, MMWORD [wk(1)]	; mm1=tmp3
270
271
	movq	MMWORD [wk(0)], mm5	; wk(0)=(60 70 61 71)
272
	movq	MMWORD [wk(1)], mm0	; wk(1)=(62 72 63 73)
273
274
	paddw	mm2,mm4			; mm2=tmp4
275
	movq	mm5,mm7
276
	movq	mm0,mm1
277
	paddw	mm7,mm4			; mm7=data2=(20 21 22 23)
278
	paddw	mm1,mm2			; mm1=data4=(40 41 42 43)
279
	psubw	mm5,mm4			; mm5=data5=(50 51 52 53)
280
	psubw	mm0,mm2			; mm0=data3=(30 31 32 33)
281
282
	movq      mm4,mm7		; transpose coefficients(phase 1)
283
	punpcklwd mm7,mm0		; mm7=(20 30 21 31)
284
	punpckhwd mm4,mm0		; mm4=(22 32 23 33)
285
	movq      mm2,mm1		; transpose coefficients(phase 1)
286
	punpcklwd mm1,mm5		; mm1=(40 50 41 51)
287
	punpckhwd mm2,mm5		; mm2=(42 52 43 53)
288
289
	movq      mm0,mm6		; transpose coefficients(phase 2)
290
	punpckldq mm6,mm7		; mm6=(00 10 20 30)
291
	punpckhdq mm0,mm7		; mm0=(01 11 21 31)
292
	movq      mm5,mm3		; transpose coefficients(phase 2)
293
	punpckldq mm3,mm4		; mm3=(02 12 22 32)
294
	punpckhdq mm5,mm4		; mm5=(03 13 23 33)
295
296
	movq	mm7, MMWORD [wk(0)]	; mm7=(60 70 61 71)
297
	movq	mm4, MMWORD [wk(1)]	; mm4=(62 72 63 73)
298
299
	movq	MMWORD [MMBLOCK(0,0,edi,SIZEOF_JCOEF)], mm6
300
	movq	MMWORD [MMBLOCK(1,0,edi,SIZEOF_JCOEF)], mm0
301
	movq	MMWORD [MMBLOCK(2,0,edi,SIZEOF_JCOEF)], mm3
302
	movq	MMWORD [MMBLOCK(3,0,edi,SIZEOF_JCOEF)], mm5
303
304
	movq      mm6,mm1		; transpose coefficients(phase 2)
305
	punpckldq mm1,mm7		; mm1=(40 50 60 70)
306
	punpckhdq mm6,mm7		; mm6=(41 51 61 71)
307
	movq      mm0,mm2		; transpose coefficients(phase 2)
308
	punpckldq mm2,mm4		; mm2=(42 52 62 72)
309
	punpckhdq mm0,mm4		; mm0=(43 53 63 73)
310
311
	movq	MMWORD [MMBLOCK(0,1,edi,SIZEOF_JCOEF)], mm1
312
	movq	MMWORD [MMBLOCK(1,1,edi,SIZEOF_JCOEF)], mm6
313
	movq	MMWORD [MMBLOCK(2,1,edi,SIZEOF_JCOEF)], mm2
314
	movq	MMWORD [MMBLOCK(3,1,edi,SIZEOF_JCOEF)], mm0
315
316
.nextcolumn:
317
	add	esi, byte 4*SIZEOF_JCOEF		; coef_block
318
	add	edx, byte 4*SIZEOF_IFAST_MULT_TYPE	; quantptr
319
	add	edi, byte 4*DCTSIZE*SIZEOF_JCOEF	; wsptr
320
	dec	ecx					; ctr
321
	jnz	near .columnloop
322
323
	; ---- Pass 2: process rows from work array, store into output array.
324
325
	mov	eax, [original_ebp]
326
	lea	esi, [workspace]			; JCOEF * wsptr
327
	mov	edi, JSAMPARRAY [output_buf(eax)]	; (JSAMPROW *)
328
	mov	eax, JDIMENSION [output_col(eax)]
329
	mov	ecx, DCTSIZE/4				; ctr
330
	alignx	16,7
331
.rowloop:
332
333
	; -- Even part
334
335
	movq	mm0, MMWORD [MMBLOCK(0,0,esi,SIZEOF_JCOEF)]
336
	movq	mm1, MMWORD [MMBLOCK(2,0,esi,SIZEOF_JCOEF)]
337
	movq	mm2, MMWORD [MMBLOCK(4,0,esi,SIZEOF_JCOEF)]
338
	movq	mm3, MMWORD [MMBLOCK(6,0,esi,SIZEOF_JCOEF)]
339
340
	movq	mm4,mm0
341
	movq	mm5,mm1
342
	psubw	mm0,mm2			; mm0=tmp11
343
	psubw	mm1,mm3
344
	paddw	mm4,mm2			; mm4=tmp10
345
	paddw	mm5,mm3			; mm5=tmp13
346
347
	psllw	mm1,PRE_MULTIPLY_SCALE_BITS
348
	pmulhw	mm1,[GOTOFF(ebx,PW_F1414)]
349
	psubw	mm1,mm5			; mm1=tmp12
350
351
	movq	mm6,mm4
352
	movq	mm7,mm0
353
	psubw	mm4,mm5			; mm4=tmp3
354
	psubw	mm0,mm1			; mm0=tmp2
355
	paddw	mm6,mm5			; mm6=tmp0
356
	paddw	mm7,mm1			; mm7=tmp1
357
358
	movq	MMWORD [wk(1)], mm4	; wk(1)=tmp3
359
	movq	MMWORD [wk(0)], mm0	; wk(0)=tmp2
360
361
	; -- Odd part
362
363
	movq	mm2, MMWORD [MMBLOCK(1,0,esi,SIZEOF_JCOEF)]
364
	movq	mm3, MMWORD [MMBLOCK(3,0,esi,SIZEOF_JCOEF)]
365
	movq	mm5, MMWORD [MMBLOCK(5,0,esi,SIZEOF_JCOEF)]
366
	movq	mm1, MMWORD [MMBLOCK(7,0,esi,SIZEOF_JCOEF)]
367
368
	movq	mm4,mm2
369
	movq	mm0,mm5
370
	psubw	mm2,mm1			; mm2=z12
371
	psubw	mm5,mm3			; mm5=z10
372
	paddw	mm4,mm1			; mm4=z11
373
	paddw	mm0,mm3			; mm0=z13
374
375
	movq	mm1,mm5			; mm1=z10(unscaled)
376
	psllw	mm2,PRE_MULTIPLY_SCALE_BITS
377
	psllw	mm5,PRE_MULTIPLY_SCALE_BITS
378
379
	movq	mm3,mm4
380
	psubw	mm4,mm0
381
	paddw	mm3,mm0			; mm3=tmp7
382
383
	psllw	mm4,PRE_MULTIPLY_SCALE_BITS
384
	pmulhw	mm4,[GOTOFF(ebx,PW_F1414)]	; mm4=tmp11
385
386
	; To avoid overflow...
387
	;
388
	; (Original)
389
	; tmp12 = -2.613125930 * z10 + z5;
390
	;
391
	; (This implementation)
392
	; tmp12 = (-1.613125930 - 1) * z10 + z5;
393
	;       = -1.613125930 * z10 - z10 + z5;
394
395
	movq	mm0,mm5
396
	paddw	mm5,mm2
397
	pmulhw	mm5,[GOTOFF(ebx,PW_F1847)]	; mm5=z5
398
	pmulhw	mm0,[GOTOFF(ebx,PW_MF1613)]
399
	pmulhw	mm2,[GOTOFF(ebx,PW_F1082)]
400
	psubw	mm0,mm1
401
	psubw	mm2,mm5			; mm2=tmp10
402
	paddw	mm0,mm5			; mm0=tmp12
403
404
	; -- Final output stage
405
406
	psubw	mm0,mm3			; mm0=tmp6
407
	movq	mm1,mm6
408
	movq	mm5,mm7
409
	paddw	mm6,mm3			; mm6=data0=(00 10 20 30)
410
	paddw	mm7,mm0			; mm7=data1=(01 11 21 31)
411
	psraw	mm6,(PASS1_BITS+3)	; descale
412
	psraw	mm7,(PASS1_BITS+3)	; descale
413
	psubw	mm1,mm3			; mm1=data7=(07 17 27 37)
414
	psubw	mm5,mm0			; mm5=data6=(06 16 26 36)
415
	psraw	mm1,(PASS1_BITS+3)	; descale
416
	psraw	mm5,(PASS1_BITS+3)	; descale
417
	psubw	mm4,mm0			; mm4=tmp5
418
419
	packsswb  mm6,mm5		; mm6=(00 10 20 30 06 16 26 36)
420
	packsswb  mm7,mm1		; mm7=(01 11 21 31 07 17 27 37)
421
422
	movq	mm3, MMWORD [wk(0)]	; mm3=tmp2
423
	movq	mm0, MMWORD [wk(1)]	; mm0=tmp3
424
425
	paddw	mm2,mm4			; mm2=tmp4
426
	movq	mm5,mm3
427
	movq	mm1,mm0
428
	paddw	mm3,mm4			; mm3=data2=(02 12 22 32)
429
	paddw	mm0,mm2			; mm0=data4=(04 14 24 34)
430
	psraw	mm3,(PASS1_BITS+3)	; descale
431
	psraw	mm0,(PASS1_BITS+3)	; descale
432
	psubw	mm5,mm4			; mm5=data5=(05 15 25 35)
433
	psubw	mm1,mm2			; mm1=data3=(03 13 23 33)
434
	psraw	mm5,(PASS1_BITS+3)	; descale
435
	psraw	mm1,(PASS1_BITS+3)	; descale
436
437
	movq      mm4,[GOTOFF(ebx,PB_CENTERJSAMP)]	; mm4=[PB_CENTERJSAMP]
438
439
	packsswb  mm3,mm0		; mm3=(02 12 22 32 04 14 24 34)
440
	packsswb  mm1,mm5		; mm1=(03 13 23 33 05 15 25 35)
441
442
	paddb     mm6,mm4
443
	paddb     mm7,mm4
444
	paddb     mm3,mm4
445
	paddb     mm1,mm4
446
447
	movq      mm2,mm6		; transpose coefficients(phase 1)
448
	punpcklbw mm6,mm7		; mm6=(00 01 10 11 20 21 30 31)
449
	punpckhbw mm2,mm7		; mm2=(06 07 16 17 26 27 36 37)
450
	movq      mm0,mm3		; transpose coefficients(phase 1)
451
	punpcklbw mm3,mm1		; mm3=(02 03 12 13 22 23 32 33)
452
	punpckhbw mm0,mm1		; mm0=(04 05 14 15 24 25 34 35)
453
454
	movq      mm5,mm6		; transpose coefficients(phase 2)
455
	punpcklwd mm6,mm3		; mm6=(00 01 02 03 10 11 12 13)
456
	punpckhwd mm5,mm3		; mm5=(20 21 22 23 30 31 32 33)
457
	movq      mm4,mm0		; transpose coefficients(phase 2)
458
	punpcklwd mm0,mm2		; mm0=(04 05 06 07 14 15 16 17)
459
	punpckhwd mm4,mm2		; mm4=(24 25 26 27 34 35 36 37)
460
461
	movq      mm7,mm6		; transpose coefficients(phase 3)
462
	punpckldq mm6,mm0		; mm6=(00 01 02 03 04 05 06 07)
463
	punpckhdq mm7,mm0		; mm7=(10 11 12 13 14 15 16 17)
464
	movq      mm1,mm5		; transpose coefficients(phase 3)
465
	punpckldq mm5,mm4		; mm5=(20 21 22 23 24 25 26 27)
466
	punpckhdq mm1,mm4		; mm1=(30 31 32 33 34 35 36 37)
467
468
	pushpic	ebx			; save GOT address
469
470
	mov	edx, JSAMPROW [edi+0*SIZEOF_JSAMPROW]
471
	mov	ebx, JSAMPROW [edi+1*SIZEOF_JSAMPROW]
472
	movq	MMWORD [edx+eax*SIZEOF_JSAMPLE], mm6
473
	movq	MMWORD [ebx+eax*SIZEOF_JSAMPLE], mm7
474
	mov	edx, JSAMPROW [edi+2*SIZEOF_JSAMPROW]
475
	mov	ebx, JSAMPROW [edi+3*SIZEOF_JSAMPROW]
476
	movq	MMWORD [edx+eax*SIZEOF_JSAMPLE], mm5
477
	movq	MMWORD [ebx+eax*SIZEOF_JSAMPLE], mm1
478
479
	poppic	ebx			; restore GOT address
480
481
	add	esi, byte 4*SIZEOF_JCOEF	; wsptr
482
	add	edi, byte 4*SIZEOF_JSAMPROW
483
	dec	ecx				; ctr
484
	jnz	near .rowloop
485
486
	emms		; empty MMX state
487
488
	pop	edi
489
	pop	esi
490
;	pop	edx		; need not be preserved
491
;	pop	ecx		; need not be preserved
492
	pop	ebx
493
	mov	esp,ebp		; esp <- aligned ebp
494
	pop	esp		; esp <- original ebp
495
	pop	ebp
496
	ret
497
498
; For some reason, the OS X linker does not honor the request to align the
499
; segment unless we do this.
500
	align	16
(-)a/jpeg/simd/jimmxint.asm (+852 lines)
Line     Link Here 
Line 0    Link Here 
1
;
2
; jimmxint.asm - accurate integer IDCT (MMX)
3
;
4
; Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
5
;
6
; Based on
7
; x86 SIMD extension for IJG JPEG library
8
; Copyright (C) 1999-2006, MIYASAKA Masaru.
9
; For conditions of distribution and use, see copyright notice in jsimdext.inc
10
;
11
; This file should be assembled with NASM (Netwide Assembler),
12
; can *not* be assembled with Microsoft's MASM or any compatible
13
; assembler (including Borland's Turbo Assembler).
14
; NASM is available from http://nasm.sourceforge.net/ or
15
; http://sourceforge.net/project/showfiles.php?group_id=6208
16
;
17
; This file contains a slow-but-accurate integer implementation of the
18
; inverse DCT (Discrete Cosine Transform). The following code is based
19
; directly on the IJG's original jidctint.c; see the jidctint.c for
20
; more details.
21
;
22
; [TAB8]
23
24
%include "jsimdext.inc"
25
%include "jdct.inc"
26
27
; --------------------------------------------------------------------------
28
29
%define CONST_BITS	13
30
%define PASS1_BITS	2
31
32
%define DESCALE_P1	(CONST_BITS-PASS1_BITS)
33
%define DESCALE_P2	(CONST_BITS+PASS1_BITS+3)
34
35
%if CONST_BITS == 13
36
F_0_298	equ	 2446		; FIX(0.298631336)
37
F_0_390	equ	 3196		; FIX(0.390180644)
38
F_0_541	equ	 4433		; FIX(0.541196100)
39
F_0_765	equ	 6270		; FIX(0.765366865)
40
F_0_899	equ	 7373		; FIX(0.899976223)
41
F_1_175	equ	 9633		; FIX(1.175875602)
42
F_1_501	equ	12299		; FIX(1.501321110)
43
F_1_847	equ	15137		; FIX(1.847759065)
44
F_1_961	equ	16069		; FIX(1.961570560)
45
F_2_053	equ	16819		; FIX(2.053119869)
46
F_2_562	equ	20995		; FIX(2.562915447)
47
F_3_072	equ	25172		; FIX(3.072711026)
48
%else
49
; NASM cannot do compile-time arithmetic on floating-point constants.
50
%define DESCALE(x,n)  (((x)+(1<<((n)-1)))>>(n))
51
F_0_298	equ	DESCALE( 320652955,30-CONST_BITS)	; FIX(0.298631336)
52
F_0_390	equ	DESCALE( 418953276,30-CONST_BITS)	; FIX(0.390180644)
53
F_0_541	equ	DESCALE( 581104887,30-CONST_BITS)	; FIX(0.541196100)
54
F_0_765	equ	DESCALE( 821806413,30-CONST_BITS)	; FIX(0.765366865)
55
F_0_899	equ	DESCALE( 966342111,30-CONST_BITS)	; FIX(0.899976223)
56
F_1_175	equ	DESCALE(1262586813,30-CONST_BITS)	; FIX(1.175875602)
57
F_1_501	equ	DESCALE(1612031267,30-CONST_BITS)	; FIX(1.501321110)
58
F_1_847	equ	DESCALE(1984016188,30-CONST_BITS)	; FIX(1.847759065)
59
F_1_961	equ	DESCALE(2106220350,30-CONST_BITS)	; FIX(1.961570560)
60
F_2_053	equ	DESCALE(2204520673,30-CONST_BITS)	; FIX(2.053119869)
61
F_2_562	equ	DESCALE(2751909506,30-CONST_BITS)	; FIX(2.562915447)
62
F_3_072	equ	DESCALE(3299298341,30-CONST_BITS)	; FIX(3.072711026)
63
%endif
64
65
; --------------------------------------------------------------------------
66
	SECTION	SEG_CONST
67
68
	alignz	16
69
	global	EXTN(jconst_idct_islow_mmx)
70
71
EXTN(jconst_idct_islow_mmx):
72
73
PW_F130_F054	times 2 dw  (F_0_541+F_0_765), F_0_541
74
PW_F054_MF130	times 2 dw  F_0_541, (F_0_541-F_1_847)
75
PW_MF078_F117	times 2 dw  (F_1_175-F_1_961), F_1_175
76
PW_F117_F078	times 2 dw  F_1_175, (F_1_175-F_0_390)
77
PW_MF060_MF089	times 2 dw  (F_0_298-F_0_899),-F_0_899
78
PW_MF089_F060	times 2 dw -F_0_899, (F_1_501-F_0_899)
79
PW_MF050_MF256	times 2 dw  (F_2_053-F_2_562),-F_2_562
80
PW_MF256_F050	times 2 dw -F_2_562, (F_3_072-F_2_562)
81
PD_DESCALE_P1	times 2 dd  1 << (DESCALE_P1-1)
82
PD_DESCALE_P2	times 2 dd  1 << (DESCALE_P2-1)
83
PB_CENTERJSAMP	times 8 db  CENTERJSAMPLE
84
85
	alignz	16
86
87
; --------------------------------------------------------------------------
88
	SECTION	SEG_TEXT
89
	BITS	32
90
;
91
; Perform dequantization and inverse DCT on one block of coefficients.
92
;
93
; GLOBAL(void)
94
; jsimd_idct_islow_mmx (void * dct_table, JCOEFPTR coef_block,
95
;                       JSAMPARRAY output_buf, JDIMENSION output_col)
96
;
97
98
%define dct_table(b)	(b)+8			; jpeg_component_info * compptr
99
%define coef_block(b)	(b)+12		; JCOEFPTR coef_block
100
%define output_buf(b)	(b)+16		; JSAMPARRAY output_buf
101
%define output_col(b)	(b)+20		; JDIMENSION output_col
102
103
%define original_ebp	ebp+0
104
%define wk(i)		ebp-(WK_NUM-(i))*SIZEOF_MMWORD	; mmword wk[WK_NUM]
105
%define WK_NUM		12
106
%define workspace	wk(0)-DCTSIZE2*SIZEOF_JCOEF
107
					; JCOEF workspace[DCTSIZE2]
108
109
	align	16
110
	global	EXTN(jsimd_idct_islow_mmx)
111
112
EXTN(jsimd_idct_islow_mmx):
113
	push	ebp
114
	mov	eax,esp				; eax = original ebp
115
	sub	esp, byte 4
116
	and	esp, byte (-SIZEOF_MMWORD)	; align to 64 bits
117
	mov	[esp],eax
118
	mov	ebp,esp				; ebp = aligned ebp
119
	lea	esp, [workspace]
120
	push	ebx
121
;	push	ecx		; need not be preserved
122
;	push	edx		; need not be preserved
123
	push	esi
124
	push	edi
125
126
	get_GOT	ebx		; get GOT address
127
128
	; ---- Pass 1: process columns from input, store into work array.
129
130
;	mov	eax, [original_ebp]
131
	mov	edx, POINTER [dct_table(eax)]	; quantptr
132
	mov	esi, JCOEFPTR [coef_block(eax)]		; inptr
133
	lea	edi, [workspace]			; JCOEF * wsptr
134
	mov	ecx, DCTSIZE/4				; ctr
135
	alignx	16,7
136
.columnloop:
137
%ifndef NO_ZERO_COLUMN_TEST_ISLOW_MMX
138
	mov	eax, DWORD [DWBLOCK(1,0,esi,SIZEOF_JCOEF)]
139
	or	eax, DWORD [DWBLOCK(2,0,esi,SIZEOF_JCOEF)]
140
	jnz	short .columnDCT
141
142
	movq	mm0, MMWORD [MMBLOCK(1,0,esi,SIZEOF_JCOEF)]
143
	movq	mm1, MMWORD [MMBLOCK(2,0,esi,SIZEOF_JCOEF)]
144
	por	mm0, MMWORD [MMBLOCK(3,0,esi,SIZEOF_JCOEF)]
145
	por	mm1, MMWORD [MMBLOCK(4,0,esi,SIZEOF_JCOEF)]
146
	por	mm0, MMWORD [MMBLOCK(5,0,esi,SIZEOF_JCOEF)]
147
	por	mm1, MMWORD [MMBLOCK(6,0,esi,SIZEOF_JCOEF)]
148
	por	mm0, MMWORD [MMBLOCK(7,0,esi,SIZEOF_JCOEF)]
149
	por	mm1,mm0
150
	packsswb mm1,mm1
151
	movd	eax,mm1
152
	test	eax,eax
153
	jnz	short .columnDCT
154
155
	; -- AC terms all zero
156
157
	movq	mm0, MMWORD [MMBLOCK(0,0,esi,SIZEOF_JCOEF)]
158
	pmullw	mm0, MMWORD [MMBLOCK(0,0,edx,SIZEOF_ISLOW_MULT_TYPE)]
159
160
	psllw	mm0,PASS1_BITS
161
162
	movq      mm2,mm0		; mm0=in0=(00 01 02 03)
163
	punpcklwd mm0,mm0		; mm0=(00 00 01 01)
164
	punpckhwd mm2,mm2		; mm2=(02 02 03 03)
165
166
	movq      mm1,mm0
167
	punpckldq mm0,mm0		; mm0=(00 00 00 00)
168
	punpckhdq mm1,mm1		; mm1=(01 01 01 01)
169
	movq      mm3,mm2
170
	punpckldq mm2,mm2		; mm2=(02 02 02 02)
171
	punpckhdq mm3,mm3		; mm3=(03 03 03 03)
172
173
	movq	MMWORD [MMBLOCK(0,0,edi,SIZEOF_JCOEF)], mm0
174
	movq	MMWORD [MMBLOCK(0,1,edi,SIZEOF_JCOEF)], mm0
175
	movq	MMWORD [MMBLOCK(1,0,edi,SIZEOF_JCOEF)], mm1
176
	movq	MMWORD [MMBLOCK(1,1,edi,SIZEOF_JCOEF)], mm1
177
	movq	MMWORD [MMBLOCK(2,0,edi,SIZEOF_JCOEF)], mm2
178
	movq	MMWORD [MMBLOCK(2,1,edi,SIZEOF_JCOEF)], mm2
179
	movq	MMWORD [MMBLOCK(3,0,edi,SIZEOF_JCOEF)], mm3
180
	movq	MMWORD [MMBLOCK(3,1,edi,SIZEOF_JCOEF)], mm3
181
	jmp	near .nextcolumn
182
	alignx	16,7
183
%endif
184
.columnDCT:
185
186
	; -- Even part
187
188
	movq	mm0, MMWORD [MMBLOCK(0,0,esi,SIZEOF_JCOEF)]
189
	movq	mm1, MMWORD [MMBLOCK(2,0,esi,SIZEOF_JCOEF)]
190
	pmullw	mm0, MMWORD [MMBLOCK(0,0,edx,SIZEOF_ISLOW_MULT_TYPE)]
191
	pmullw	mm1, MMWORD [MMBLOCK(2,0,edx,SIZEOF_ISLOW_MULT_TYPE)]
192
	movq	mm2, MMWORD [MMBLOCK(4,0,esi,SIZEOF_JCOEF)]
193
	movq	mm3, MMWORD [MMBLOCK(6,0,esi,SIZEOF_JCOEF)]
194
	pmullw	mm2, MMWORD [MMBLOCK(4,0,edx,SIZEOF_ISLOW_MULT_TYPE)]
195
	pmullw	mm3, MMWORD [MMBLOCK(6,0,edx,SIZEOF_ISLOW_MULT_TYPE)]
196
197
	; (Original)
198
	; z1 = (z2 + z3) * 0.541196100;
199
	; tmp2 = z1 + z3 * -1.847759065;
200
	; tmp3 = z1 + z2 * 0.765366865;
201
	;
202
	; (This implementation)
203
	; tmp2 = z2 * 0.541196100 + z3 * (0.541196100 - 1.847759065);
204
	; tmp3 = z2 * (0.541196100 + 0.765366865) + z3 * 0.541196100;
205
206
	movq      mm4,mm1		; mm1=in2=z2
207
	movq      mm5,mm1
208
	punpcklwd mm4,mm3		; mm3=in6=z3
209
	punpckhwd mm5,mm3
210
	movq      mm1,mm4
211
	movq      mm3,mm5
212
	pmaddwd   mm4,[GOTOFF(ebx,PW_F130_F054)]	; mm4=tmp3L
213
	pmaddwd   mm5,[GOTOFF(ebx,PW_F130_F054)]	; mm5=tmp3H
214
	pmaddwd   mm1,[GOTOFF(ebx,PW_F054_MF130)]	; mm1=tmp2L
215
	pmaddwd   mm3,[GOTOFF(ebx,PW_F054_MF130)]	; mm3=tmp2H
216
217
	movq      mm6,mm0
218
	paddw     mm0,mm2		; mm0=in0+in4
219
	psubw     mm6,mm2		; mm6=in0-in4
220
221
	pxor      mm7,mm7
222
	pxor      mm2,mm2
223
	punpcklwd mm7,mm0		; mm7=tmp0L
224
	punpckhwd mm2,mm0		; mm2=tmp0H
225
	psrad     mm7,(16-CONST_BITS)	; psrad mm7,16 & pslld mm7,CONST_BITS
226
	psrad     mm2,(16-CONST_BITS)	; psrad mm2,16 & pslld mm2,CONST_BITS
227
228
	movq	mm0,mm7
229
	paddd	mm7,mm4			; mm7=tmp10L
230
	psubd	mm0,mm4			; mm0=tmp13L
231
	movq	mm4,mm2
232
	paddd	mm2,mm5			; mm2=tmp10H
233
	psubd	mm4,mm5			; mm4=tmp13H
234
235
	movq	MMWORD [wk(0)], mm7	; wk(0)=tmp10L
236
	movq	MMWORD [wk(1)], mm2	; wk(1)=tmp10H
237
	movq	MMWORD [wk(2)], mm0	; wk(2)=tmp13L
238
	movq	MMWORD [wk(3)], mm4	; wk(3)=tmp13H
239
240
	pxor      mm5,mm5
241
	pxor      mm7,mm7
242
	punpcklwd mm5,mm6		; mm5=tmp1L
243
	punpckhwd mm7,mm6		; mm7=tmp1H
244
	psrad     mm5,(16-CONST_BITS)	; psrad mm5,16 & pslld mm5,CONST_BITS
245
	psrad     mm7,(16-CONST_BITS)	; psrad mm7,16 & pslld mm7,CONST_BITS
246
247
	movq	mm2,mm5
248
	paddd	mm5,mm1			; mm5=tmp11L
249
	psubd	mm2,mm1			; mm2=tmp12L
250
	movq	mm0,mm7
251
	paddd	mm7,mm3			; mm7=tmp11H
252
	psubd	mm0,mm3			; mm0=tmp12H
253
254
	movq	MMWORD [wk(4)], mm5	; wk(4)=tmp11L
255
	movq	MMWORD [wk(5)], mm7	; wk(5)=tmp11H
256
	movq	MMWORD [wk(6)], mm2	; wk(6)=tmp12L
257
	movq	MMWORD [wk(7)], mm0	; wk(7)=tmp12H
258
259
	; -- Odd part
260
261
	movq	mm4, MMWORD [MMBLOCK(1,0,esi,SIZEOF_JCOEF)]
262
	movq	mm6, MMWORD [MMBLOCK(3,0,esi,SIZEOF_JCOEF)]
263
	pmullw	mm4, MMWORD [MMBLOCK(1,0,edx,SIZEOF_ISLOW_MULT_TYPE)]
264
	pmullw	mm6, MMWORD [MMBLOCK(3,0,edx,SIZEOF_ISLOW_MULT_TYPE)]
265
	movq	mm1, MMWORD [MMBLOCK(5,0,esi,SIZEOF_JCOEF)]
266
	movq	mm3, MMWORD [MMBLOCK(7,0,esi,SIZEOF_JCOEF)]
267
	pmullw	mm1, MMWORD [MMBLOCK(5,0,edx,SIZEOF_ISLOW_MULT_TYPE)]
268
	pmullw	mm3, MMWORD [MMBLOCK(7,0,edx,SIZEOF_ISLOW_MULT_TYPE)]
269
270
	movq	mm5,mm6
271
	movq	mm7,mm4
272
	paddw	mm5,mm3			; mm5=z3
273
	paddw	mm7,mm1			; mm7=z4
274
275
	; (Original)
276
	; z5 = (z3 + z4) * 1.175875602;
277
	; z3 = z3 * -1.961570560;  z4 = z4 * -0.390180644;
278
	; z3 += z5;  z4 += z5;
279
	;
280
	; (This implementation)
281
	; z3 = z3 * (1.175875602 - 1.961570560) + z4 * 1.175875602;
282
	; z4 = z3 * 1.175875602 + z4 * (1.175875602 - 0.390180644);
283
284
	movq      mm2,mm5
285
	movq      mm0,mm5
286
	punpcklwd mm2,mm7
287
	punpckhwd mm0,mm7
288
	movq      mm5,mm2
289
	movq      mm7,mm0
290
	pmaddwd   mm2,[GOTOFF(ebx,PW_MF078_F117)]	; mm2=z3L
291
	pmaddwd   mm0,[GOTOFF(ebx,PW_MF078_F117)]	; mm0=z3H
292
	pmaddwd   mm5,[GOTOFF(ebx,PW_F117_F078)]	; mm5=z4L
293
	pmaddwd   mm7,[GOTOFF(ebx,PW_F117_F078)]	; mm7=z4H
294
295
	movq	MMWORD [wk(10)], mm2	; wk(10)=z3L
296
	movq	MMWORD [wk(11)], mm0	; wk(11)=z3H
297
298
	; (Original)
299
	; z1 = tmp0 + tmp3;  z2 = tmp1 + tmp2;
300
	; tmp0 = tmp0 * 0.298631336;  tmp1 = tmp1 * 2.053119869;
301
	; tmp2 = tmp2 * 3.072711026;  tmp3 = tmp3 * 1.501321110;
302
	; z1 = z1 * -0.899976223;  z2 = z2 * -2.562915447;
303
	; tmp0 += z1 + z3;  tmp1 += z2 + z4;
304
	; tmp2 += z2 + z3;  tmp3 += z1 + z4;
305
	;
306
	; (This implementation)
307
	; tmp0 = tmp0 * (0.298631336 - 0.899976223) + tmp3 * -0.899976223;
308
	; tmp1 = tmp1 * (2.053119869 - 2.562915447) + tmp2 * -2.562915447;
309
	; tmp2 = tmp1 * -2.562915447 + tmp2 * (3.072711026 - 2.562915447);
310
	; tmp3 = tmp0 * -0.899976223 + tmp3 * (1.501321110 - 0.899976223);
311
	; tmp0 += z3;  tmp1 += z4;
312
	; tmp2 += z3;  tmp3 += z4;
313
314
	movq      mm2,mm3
315
	movq      mm0,mm3
316
	punpcklwd mm2,mm4
317
	punpckhwd mm0,mm4
318
	movq      mm3,mm2
319
	movq      mm4,mm0
320
	pmaddwd   mm2,[GOTOFF(ebx,PW_MF060_MF089)]	; mm2=tmp0L
321
	pmaddwd   mm0,[GOTOFF(ebx,PW_MF060_MF089)]	; mm0=tmp0H
322
	pmaddwd   mm3,[GOTOFF(ebx,PW_MF089_F060)]	; mm3=tmp3L
323
	pmaddwd   mm4,[GOTOFF(ebx,PW_MF089_F060)]	; mm4=tmp3H
324
325
	paddd	mm2, MMWORD [wk(10)]	; mm2=tmp0L
326
	paddd	mm0, MMWORD [wk(11)]	; mm0=tmp0H
327
	paddd	mm3,mm5			; mm3=tmp3L
328
	paddd	mm4,mm7			; mm4=tmp3H
329
330
	movq	MMWORD [wk(8)], mm2	; wk(8)=tmp0L
331
	movq	MMWORD [wk(9)], mm0	; wk(9)=tmp0H
332
333
	movq      mm2,mm1
334
	movq      mm0,mm1
335
	punpcklwd mm2,mm6
336
	punpckhwd mm0,mm6
337
	movq      mm1,mm2
338
	movq      mm6,mm0
339
	pmaddwd   mm2,[GOTOFF(ebx,PW_MF050_MF256)]	; mm2=tmp1L
340
	pmaddwd   mm0,[GOTOFF(ebx,PW_MF050_MF256)]	; mm0=tmp1H
341
	pmaddwd   mm1,[GOTOFF(ebx,PW_MF256_F050)]	; mm1=tmp2L
342
	pmaddwd   mm6,[GOTOFF(ebx,PW_MF256_F050)]	; mm6=tmp2H
343
344
	paddd	mm2,mm5			; mm2=tmp1L
345
	paddd	mm0,mm7			; mm0=tmp1H
346
	paddd	mm1, MMWORD [wk(10)]	; mm1=tmp2L
347
	paddd	mm6, MMWORD [wk(11)]	; mm6=tmp2H
348
349
	movq	MMWORD [wk(10)], mm2	; wk(10)=tmp1L
350
	movq	MMWORD [wk(11)], mm0	; wk(11)=tmp1H
351
352
	; -- Final output stage
353
354
	movq	mm5, MMWORD [wk(0)]	; mm5=tmp10L
355
	movq	mm7, MMWORD [wk(1)]	; mm7=tmp10H
356
357
	movq	mm2,mm5
358
	movq	mm0,mm7
359
	paddd	mm5,mm3			; mm5=data0L
360
	paddd	mm7,mm4			; mm7=data0H
361
	psubd	mm2,mm3			; mm2=data7L
362
	psubd	mm0,mm4			; mm0=data7H
363
364
	movq	mm3,[GOTOFF(ebx,PD_DESCALE_P1)]	; mm3=[PD_DESCALE_P1]
365
366
	paddd	mm5,mm3
367
	paddd	mm7,mm3
368
	psrad	mm5,DESCALE_P1
369
	psrad	mm7,DESCALE_P1
370
	paddd	mm2,mm3
371
	paddd	mm0,mm3
372
	psrad	mm2,DESCALE_P1
373
	psrad	mm0,DESCALE_P1
374
375
	packssdw  mm5,mm7		; mm5=data0=(00 01 02 03)
376
	packssdw  mm2,mm0		; mm2=data7=(70 71 72 73)
377
378
	movq	mm4, MMWORD [wk(4)]	; mm4=tmp11L
379
	movq	mm3, MMWORD [wk(5)]	; mm3=tmp11H
380
381
	movq	mm7,mm4
382
	movq	mm0,mm3
383
	paddd	mm4,mm1			; mm4=data1L
384
	paddd	mm3,mm6			; mm3=data1H
385
	psubd	mm7,mm1			; mm7=data6L
386
	psubd	mm0,mm6			; mm0=data6H
387
388
	movq	mm1,[GOTOFF(ebx,PD_DESCALE_P1)]	; mm1=[PD_DESCALE_P1]
389
390
	paddd	mm4,mm1
391
	paddd	mm3,mm1
392
	psrad	mm4,DESCALE_P1
393
	psrad	mm3,DESCALE_P1
394
	paddd	mm7,mm1
395
	paddd	mm0,mm1
396
	psrad	mm7,DESCALE_P1
397
	psrad	mm0,DESCALE_P1
398
399
	packssdw  mm4,mm3		; mm4=data1=(10 11 12 13)
400
	packssdw  mm7,mm0		; mm7=data6=(60 61 62 63)
401
402
	movq      mm6,mm5		; transpose coefficients(phase 1)
403
	punpcklwd mm5,mm4		; mm5=(00 10 01 11)
404
	punpckhwd mm6,mm4		; mm6=(02 12 03 13)
405
	movq      mm1,mm7		; transpose coefficients(phase 1)
406
	punpcklwd mm7,mm2		; mm7=(60 70 61 71)
407
	punpckhwd mm1,mm2		; mm1=(62 72 63 73)
408
409
	movq	mm3, MMWORD [wk(6)]	; mm3=tmp12L
410
	movq	mm0, MMWORD [wk(7)]	; mm0=tmp12H
411
	movq	mm4, MMWORD [wk(10)]	; mm4=tmp1L
412
	movq	mm2, MMWORD [wk(11)]	; mm2=tmp1H
413
414
	movq	MMWORD [wk(0)], mm5	; wk(0)=(00 10 01 11)
415
	movq	MMWORD [wk(1)], mm6	; wk(1)=(02 12 03 13)
416
	movq	MMWORD [wk(4)], mm7	; wk(4)=(60 70 61 71)
417
	movq	MMWORD [wk(5)], mm1	; wk(5)=(62 72 63 73)
418
419
	movq	mm5,mm3
420
	movq	mm6,mm0
421
	paddd	mm3,mm4			; mm3=data2L
422
	paddd	mm0,mm2			; mm0=data2H
423
	psubd	mm5,mm4			; mm5=data5L
424
	psubd	mm6,mm2			; mm6=data5H
425
426
	movq	mm7,[GOTOFF(ebx,PD_DESCALE_P1)]	; mm7=[PD_DESCALE_P1]
427
428
	paddd	mm3,mm7
429
	paddd	mm0,mm7
430
	psrad	mm3,DESCALE_P1
431
	psrad	mm0,DESCALE_P1
432
	paddd	mm5,mm7
433
	paddd	mm6,mm7
434
	psrad	mm5,DESCALE_P1
435
	psrad	mm6,DESCALE_P1
436
437
	packssdw  mm3,mm0		; mm3=data2=(20 21 22 23)
438
	packssdw  mm5,mm6		; mm5=data5=(50 51 52 53)
439
440
	movq	mm1, MMWORD [wk(2)]	; mm1=tmp13L
441
	movq	mm4, MMWORD [wk(3)]	; mm4=tmp13H
442
	movq	mm2, MMWORD [wk(8)]	; mm2=tmp0L
443
	movq	mm7, MMWORD [wk(9)]	; mm7=tmp0H
444
445
	movq	mm0,mm1
446
	movq	mm6,mm4
447
	paddd	mm1,mm2			; mm1=data3L
448
	paddd	mm4,mm7			; mm4=data3H
449
	psubd	mm0,mm2			; mm0=data4L
450
	psubd	mm6,mm7			; mm6=data4H
451
452
	movq	mm2,[GOTOFF(ebx,PD_DESCALE_P1)]	; mm2=[PD_DESCALE_P1]
453
454
	paddd	mm1,mm2
455
	paddd	mm4,mm2
456
	psrad	mm1,DESCALE_P1
457
	psrad	mm4,DESCALE_P1
458
	paddd	mm0,mm2
459
	paddd	mm6,mm2
460
	psrad	mm0,DESCALE_P1
461
	psrad	mm6,DESCALE_P1
462
463
	packssdw  mm1,mm4		; mm1=data3=(30 31 32 33)
464
	packssdw  mm0,mm6		; mm0=data4=(40 41 42 43)
465
466
	movq	mm7, MMWORD [wk(0)]	; mm7=(00 10 01 11)
467
	movq	mm2, MMWORD [wk(1)]	; mm2=(02 12 03 13)
468
469
	movq      mm4,mm3		; transpose coefficients(phase 1)
470
	punpcklwd mm3,mm1		; mm3=(20 30 21 31)
471
	punpckhwd mm4,mm1		; mm4=(22 32 23 33)
472
	movq      mm6,mm0		; transpose coefficients(phase 1)
473
	punpcklwd mm0,mm5		; mm0=(40 50 41 51)
474
	punpckhwd mm6,mm5		; mm6=(42 52 43 53)
475
476
	movq      mm1,mm7		; transpose coefficients(phase 2)
477
	punpckldq mm7,mm3		; mm7=(00 10 20 30)
478
	punpckhdq mm1,mm3		; mm1=(01 11 21 31)
479
	movq      mm5,mm2		; transpose coefficients(phase 2)
480
	punpckldq mm2,mm4		; mm2=(02 12 22 32)
481
	punpckhdq mm5,mm4		; mm5=(03 13 23 33)
482
483
	movq	mm3, MMWORD [wk(4)]	; mm3=(60 70 61 71)
484
	movq	mm4, MMWORD [wk(5)]	; mm4=(62 72 63 73)
485
486
	movq	MMWORD [MMBLOCK(0,0,edi,SIZEOF_JCOEF)], mm7
487
	movq	MMWORD [MMBLOCK(1,0,edi,SIZEOF_JCOEF)], mm1
488
	movq	MMWORD [MMBLOCK(2,0,edi,SIZEOF_JCOEF)], mm2
489
	movq	MMWORD [MMBLOCK(3,0,edi,SIZEOF_JCOEF)], mm5
490
491
	movq      mm7,mm0		; transpose coefficients(phase 2)
492
	punpckldq mm0,mm3		; mm0=(40 50 60 70)
493
	punpckhdq mm7,mm3		; mm7=(41 51 61 71)
494
	movq      mm1,mm6		; transpose coefficients(phase 2)
495
	punpckldq mm6,mm4		; mm6=(42 52 62 72)
496
	punpckhdq mm1,mm4		; mm1=(43 53 63 73)
497
498
	movq	MMWORD [MMBLOCK(0,1,edi,SIZEOF_JCOEF)], mm0
499
	movq	MMWORD [MMBLOCK(1,1,edi,SIZEOF_JCOEF)], mm7
500
	movq	MMWORD [MMBLOCK(2,1,edi,SIZEOF_JCOEF)], mm6
501
	movq	MMWORD [MMBLOCK(3,1,edi,SIZEOF_JCOEF)], mm1
502
503
.nextcolumn:
504
	add	esi, byte 4*SIZEOF_JCOEF		; coef_block
505
	add	edx, byte 4*SIZEOF_ISLOW_MULT_TYPE	; quantptr
506
	add	edi, byte 4*DCTSIZE*SIZEOF_JCOEF	; wsptr
507
	dec	ecx					; ctr
508
	jnz	near .columnloop
509
510
	; ---- Pass 2: process rows from work array, store into output array.
511
512
	mov	eax, [original_ebp]
513
	lea	esi, [workspace]			; JCOEF * wsptr
514
	mov	edi, JSAMPARRAY [output_buf(eax)]	; (JSAMPROW *)
515
	mov	eax, JDIMENSION [output_col(eax)]
516
	mov	ecx, DCTSIZE/4				; ctr
517
	alignx	16,7
518
.rowloop:
519
520
	; -- Even part
521
522
	movq	mm0, MMWORD [MMBLOCK(0,0,esi,SIZEOF_JCOEF)]
523
	movq	mm1, MMWORD [MMBLOCK(2,0,esi,SIZEOF_JCOEF)]
524
	movq	mm2, MMWORD [MMBLOCK(4,0,esi,SIZEOF_JCOEF)]
525
	movq	mm3, MMWORD [MMBLOCK(6,0,esi,SIZEOF_JCOEF)]
526
527
	; (Original)
528
	; z1 = (z2 + z3) * 0.541196100;
529
	; tmp2 = z1 + z3 * -1.847759065;
530
	; tmp3 = z1 + z2 * 0.765366865;
531
	;
532
	; (This implementation)
533
	; tmp2 = z2 * 0.541196100 + z3 * (0.541196100 - 1.847759065);
534
	; tmp3 = z2 * (0.541196100 + 0.765366865) + z3 * 0.541196100;
535
536
	movq      mm4,mm1		; mm1=in2=z2
537
	movq      mm5,mm1
538
	punpcklwd mm4,mm3		; mm3=in6=z3
539
	punpckhwd mm5,mm3
540
	movq      mm1,mm4
541
	movq      mm3,mm5
542
	pmaddwd   mm4,[GOTOFF(ebx,PW_F130_F054)]	; mm4=tmp3L
543
	pmaddwd   mm5,[GOTOFF(ebx,PW_F130_F054)]	; mm5=tmp3H
544
	pmaddwd   mm1,[GOTOFF(ebx,PW_F054_MF130)]	; mm1=tmp2L
545
	pmaddwd   mm3,[GOTOFF(ebx,PW_F054_MF130)]	; mm3=tmp2H
546
547
	movq      mm6,mm0
548
	paddw     mm0,mm2		; mm0=in0+in4
549
	psubw     mm6,mm2		; mm6=in0-in4
550
551
	pxor      mm7,mm7
552
	pxor      mm2,mm2
553
	punpcklwd mm7,mm0		; mm7=tmp0L
554
	punpckhwd mm2,mm0		; mm2=tmp0H
555
	psrad     mm7,(16-CONST_BITS)	; psrad mm7,16 & pslld mm7,CONST_BITS
556
	psrad     mm2,(16-CONST_BITS)	; psrad mm2,16 & pslld mm2,CONST_BITS
557
558
	movq	mm0,mm7
559
	paddd	mm7,mm4			; mm7=tmp10L
560
	psubd	mm0,mm4			; mm0=tmp13L
561
	movq	mm4,mm2
562
	paddd	mm2,mm5			; mm2=tmp10H
563
	psubd	mm4,mm5			; mm4=tmp13H
564
565
	movq	MMWORD [wk(0)], mm7	; wk(0)=tmp10L
566
	movq	MMWORD [wk(1)], mm2	; wk(1)=tmp10H
567
	movq	MMWORD [wk(2)], mm0	; wk(2)=tmp13L
568
	movq	MMWORD [wk(3)], mm4	; wk(3)=tmp13H
569
570
	pxor      mm5,mm5
571
	pxor      mm7,mm7
572
	punpcklwd mm5,mm6		; mm5=tmp1L
573
	punpckhwd mm7,mm6		; mm7=tmp1H
574
	psrad     mm5,(16-CONST_BITS)	; psrad mm5,16 & pslld mm5,CONST_BITS
575
	psrad     mm7,(16-CONST_BITS)	; psrad mm7,16 & pslld mm7,CONST_BITS
576
577
	movq	mm2,mm5
578
	paddd	mm5,mm1			; mm5=tmp11L
579
	psubd	mm2,mm1			; mm2=tmp12L
580
	movq	mm0,mm7
581
	paddd	mm7,mm3			; mm7=tmp11H
582
	psubd	mm0,mm3			; mm0=tmp12H
583
584
	movq	MMWORD [wk(4)], mm5	; wk(4)=tmp11L
585
	movq	MMWORD [wk(5)], mm7	; wk(5)=tmp11H
586
	movq	MMWORD [wk(6)], mm2	; wk(6)=tmp12L
587
	movq	MMWORD [wk(7)], mm0	; wk(7)=tmp12H
588
589
	; -- Odd part
590
591
	movq	mm4, MMWORD [MMBLOCK(1,0,esi,SIZEOF_JCOEF)]
592
	movq	mm6, MMWORD [MMBLOCK(3,0,esi,SIZEOF_JCOEF)]
593
	movq	mm1, MMWORD [MMBLOCK(5,0,esi,SIZEOF_JCOEF)]
594
	movq	mm3, MMWORD [MMBLOCK(7,0,esi,SIZEOF_JCOEF)]
595
596
	movq	mm5,mm6
597
	movq	mm7,mm4
598
	paddw	mm5,mm3			; mm5=z3
599
	paddw	mm7,mm1			; mm7=z4
600
601
	; (Original)
602
	; z5 = (z3 + z4) * 1.175875602;
603
	; z3 = z3 * -1.961570560;  z4 = z4 * -0.390180644;
604
	; z3 += z5;  z4 += z5;
605
	;
606
	; (This implementation)
607
	; z3 = z3 * (1.175875602 - 1.961570560) + z4 * 1.175875602;
608
	; z4 = z3 * 1.175875602 + z4 * (1.175875602 - 0.390180644);
609
610
	movq      mm2,mm5
611
	movq      mm0,mm5
612
	punpcklwd mm2,mm7
613
	punpckhwd mm0,mm7
614
	movq      mm5,mm2
615
	movq      mm7,mm0
616
	pmaddwd   mm2,[GOTOFF(ebx,PW_MF078_F117)]	; mm2=z3L
617
	pmaddwd   mm0,[GOTOFF(ebx,PW_MF078_F117)]	; mm0=z3H
618
	pmaddwd   mm5,[GOTOFF(ebx,PW_F117_F078)]	; mm5=z4L
619
	pmaddwd   mm7,[GOTOFF(ebx,PW_F117_F078)]	; mm7=z4H
620
621
	movq	MMWORD [wk(10)], mm2	; wk(10)=z3L
622
	movq	MMWORD [wk(11)], mm0	; wk(11)=z3H
623
624
	; (Original)
625
	; z1 = tmp0 + tmp3;  z2 = tmp1 + tmp2;
626
	; tmp0 = tmp0 * 0.298631336;  tmp1 = tmp1 * 2.053119869;
627
	; tmp2 = tmp2 * 3.072711026;  tmp3 = tmp3 * 1.501321110;
628
	; z1 = z1 * -0.899976223;  z2 = z2 * -2.562915447;
629
	; tmp0 += z1 + z3;  tmp1 += z2 + z4;
630
	; tmp2 += z2 + z3;  tmp3 += z1 + z4;
631
	;
632
	; (This implementation)
633
	; tmp0 = tmp0 * (0.298631336 - 0.899976223) + tmp3 * -0.899976223;
634
	; tmp1 = tmp1 * (2.053119869 - 2.562915447) + tmp2 * -2.562915447;
635
	; tmp2 = tmp1 * -2.562915447 + tmp2 * (3.072711026 - 2.562915447);
636
	; tmp3 = tmp0 * -0.899976223 + tmp3 * (1.501321110 - 0.899976223);
637
	; tmp0 += z3;  tmp1 += z4;
638
	; tmp2 += z3;  tmp3 += z4;
639
640
	movq      mm2,mm3
641
	movq      mm0,mm3
642
	punpcklwd mm2,mm4
643
	punpckhwd mm0,mm4
644
	movq      mm3,mm2
645
	movq      mm4,mm0
646
	pmaddwd   mm2,[GOTOFF(ebx,PW_MF060_MF089)]	; mm2=tmp0L
647
	pmaddwd   mm0,[GOTOFF(ebx,PW_MF060_MF089)]	; mm0=tmp0H
648
	pmaddwd   mm3,[GOTOFF(ebx,PW_MF089_F060)]	; mm3=tmp3L
649
	pmaddwd   mm4,[GOTOFF(ebx,PW_MF089_F060)]	; mm4=tmp3H
650
651
	paddd	mm2, MMWORD [wk(10)]	; mm2=tmp0L
652
	paddd	mm0, MMWORD [wk(11)]	; mm0=tmp0H
653
	paddd	mm3,mm5			; mm3=tmp3L
654
	paddd	mm4,mm7			; mm4=tmp3H
655
656
	movq	MMWORD [wk(8)], mm2	; wk(8)=tmp0L
657
	movq	MMWORD [wk(9)], mm0	; wk(9)=tmp0H
658
659
	movq      mm2,mm1
660
	movq      mm0,mm1
661
	punpcklwd mm2,mm6
662
	punpckhwd mm0,mm6
663
	movq      mm1,mm2
664
	movq      mm6,mm0
665
	pmaddwd   mm2,[GOTOFF(ebx,PW_MF050_MF256)]	; mm2=tmp1L
666
	pmaddwd   mm0,[GOTOFF(ebx,PW_MF050_MF256)]	; mm0=tmp1H
667
	pmaddwd   mm1,[GOTOFF(ebx,PW_MF256_F050)]	; mm1=tmp2L
668
	pmaddwd   mm6,[GOTOFF(ebx,PW_MF256_F050)]	; mm6=tmp2H
669
670
	paddd	mm2,mm5			; mm2=tmp1L
671
	paddd	mm0,mm7			; mm0=tmp1H
672
	paddd	mm1, MMWORD [wk(10)]	; mm1=tmp2L
673
	paddd	mm6, MMWORD [wk(11)]	; mm6=tmp2H
674
675
	movq	MMWORD [wk(10)], mm2	; wk(10)=tmp1L
676
	movq	MMWORD [wk(11)], mm0	; wk(11)=tmp1H
677
678
	; -- Final output stage
679
680
	movq	mm5, MMWORD [wk(0)]	; mm5=tmp10L
681
	movq	mm7, MMWORD [wk(1)]	; mm7=tmp10H
682
683
	movq	mm2,mm5
684
	movq	mm0,mm7
685
	paddd	mm5,mm3			; mm5=data0L
686
	paddd	mm7,mm4			; mm7=data0H
687
	psubd	mm2,mm3			; mm2=data7L
688
	psubd	mm0,mm4			; mm0=data7H
689
690
	movq	mm3,[GOTOFF(ebx,PD_DESCALE_P2)]	; mm3=[PD_DESCALE_P2]
691
692
	paddd	mm5,mm3
693
	paddd	mm7,mm3
694
	psrad	mm5,DESCALE_P2
695
	psrad	mm7,DESCALE_P2
696
	paddd	mm2,mm3
697
	paddd	mm0,mm3
698
	psrad	mm2,DESCALE_P2
699
	psrad	mm0,DESCALE_P2
700
701
	packssdw  mm5,mm7		; mm5=data0=(00 10 20 30)
702
	packssdw  mm2,mm0		; mm2=data7=(07 17 27 37)
703
704
	movq	mm4, MMWORD [wk(4)]	; mm4=tmp11L
705
	movq	mm3, MMWORD [wk(5)]	; mm3=tmp11H
706
707
	movq	mm7,mm4
708
	movq	mm0,mm3
709
	paddd	mm4,mm1			; mm4=data1L
710
	paddd	mm3,mm6			; mm3=data1H
711
	psubd	mm7,mm1			; mm7=data6L
712
	psubd	mm0,mm6			; mm0=data6H
713
714
	movq	mm1,[GOTOFF(ebx,PD_DESCALE_P2)]	; mm1=[PD_DESCALE_P2]
715
716
	paddd	mm4,mm1
717
	paddd	mm3,mm1
718
	psrad	mm4,DESCALE_P2
719
	psrad	mm3,DESCALE_P2
720
	paddd	mm7,mm1
721
	paddd	mm0,mm1
722
	psrad	mm7,DESCALE_P2
723
	psrad	mm0,DESCALE_P2
724
725
	packssdw  mm4,mm3		; mm4=data1=(01 11 21 31)
726
	packssdw  mm7,mm0		; mm7=data6=(06 16 26 36)
727
728
	packsswb  mm5,mm7		; mm5=(00 10 20 30 06 16 26 36)
729
	packsswb  mm4,mm2		; mm4=(01 11 21 31 07 17 27 37)
730
731
	movq	mm6, MMWORD [wk(6)]	; mm6=tmp12L
732
	movq	mm1, MMWORD [wk(7)]	; mm1=tmp12H
733
	movq	mm3, MMWORD [wk(10)]	; mm3=tmp1L
734
	movq	mm0, MMWORD [wk(11)]	; mm0=tmp1H
735
736
	movq	MMWORD [wk(0)], mm5	; wk(0)=(00 10 20 30 06 16 26 36)
737
	movq	MMWORD [wk(1)], mm4	; wk(1)=(01 11 21 31 07 17 27 37)
738
739
	movq	mm7,mm6
740
	movq	mm2,mm1
741
	paddd	mm6,mm3			; mm6=data2L
742
	paddd	mm1,mm0			; mm1=data2H
743
	psubd	mm7,mm3			; mm7=data5L
744
	psubd	mm2,mm0			; mm2=data5H
745
746
	movq	mm5,[GOTOFF(ebx,PD_DESCALE_P2)]	; mm5=[PD_DESCALE_P2]
747
748
	paddd	mm6,mm5
749
	paddd	mm1,mm5
750
	psrad	mm6,DESCALE_P2
751
	psrad	mm1,DESCALE_P2
752
	paddd	mm7,mm5
753
	paddd	mm2,mm5
754
	psrad	mm7,DESCALE_P2
755
	psrad	mm2,DESCALE_P2
756
757
	packssdw  mm6,mm1		; mm6=data2=(02 12 22 32)
758
	packssdw  mm7,mm2		; mm7=data5=(05 15 25 35)
759
760
	movq	mm4, MMWORD [wk(2)]	; mm4=tmp13L
761
	movq	mm3, MMWORD [wk(3)]	; mm3=tmp13H
762
	movq	mm0, MMWORD [wk(8)]	; mm0=tmp0L
763
	movq	mm5, MMWORD [wk(9)]	; mm5=tmp0H
764
765
	movq	mm1,mm4
766
	movq	mm2,mm3
767
	paddd	mm4,mm0			; mm4=data3L
768
	paddd	mm3,mm5			; mm3=data3H
769
	psubd	mm1,mm0			; mm1=data4L
770
	psubd	mm2,mm5			; mm2=data4H
771
772
	movq	mm0,[GOTOFF(ebx,PD_DESCALE_P2)]	; mm0=[PD_DESCALE_P2]
773
774
	paddd	mm4,mm0
775
	paddd	mm3,mm0
776
	psrad	mm4,DESCALE_P2
777
	psrad	mm3,DESCALE_P2
778
	paddd	mm1,mm0
779
	paddd	mm2,mm0
780
	psrad	mm1,DESCALE_P2
781
	psrad	mm2,DESCALE_P2
782
783
	movq      mm5,[GOTOFF(ebx,PB_CENTERJSAMP)]	; mm5=[PB_CENTERJSAMP]
784
785
	packssdw  mm4,mm3		; mm4=data3=(03 13 23 33)
786
	packssdw  mm1,mm2		; mm1=data4=(04 14 24 34)
787
788
	movq      mm0, MMWORD [wk(0)]	; mm0=(00 10 20 30 06 16 26 36)
789
	movq      mm3, MMWORD [wk(1)]	; mm3=(01 11 21 31 07 17 27 37)
790
791
	packsswb  mm6,mm1		; mm6=(02 12 22 32 04 14 24 34)
792
	packsswb  mm4,mm7		; mm4=(03 13 23 33 05 15 25 35)
793
794
	paddb     mm0,mm5
795
	paddb     mm3,mm5
796
	paddb     mm6,mm5
797
	paddb     mm4,mm5
798
799
	movq      mm2,mm0		; transpose coefficients(phase 1)
800
	punpcklbw mm0,mm3		; mm0=(00 01 10 11 20 21 30 31)
801
	punpckhbw mm2,mm3		; mm2=(06 07 16 17 26 27 36 37)
802
	movq      mm1,mm6		; transpose coefficients(phase 1)
803
	punpcklbw mm6,mm4		; mm6=(02 03 12 13 22 23 32 33)
804
	punpckhbw mm1,mm4		; mm1=(04 05 14 15 24 25 34 35)
805
806
	movq      mm7,mm0		; transpose coefficients(phase 2)
807
	punpcklwd mm0,mm6		; mm0=(00 01 02 03 10 11 12 13)
808
	punpckhwd mm7,mm6		; mm7=(20 21 22 23 30 31 32 33)
809
	movq      mm5,mm1		; transpose coefficients(phase 2)
810
	punpcklwd mm1,mm2		; mm1=(04 05 06 07 14 15 16 17)
811
	punpckhwd mm5,mm2		; mm5=(24 25 26 27 34 35 36 37)
812
813
	movq      mm3,mm0		; transpose coefficients(phase 3)
814
	punpckldq mm0,mm1		; mm0=(00 01 02 03 04 05 06 07)
815
	punpckhdq mm3,mm1		; mm3=(10 11 12 13 14 15 16 17)
816
	movq      mm4,mm7		; transpose coefficients(phase 3)
817
	punpckldq mm7,mm5		; mm7=(20 21 22 23 24 25 26 27)
818
	punpckhdq mm4,mm5		; mm4=(30 31 32 33 34 35 36 37)
819
820
	pushpic	ebx			; save GOT address
821
822
	mov	edx, JSAMPROW [edi+0*SIZEOF_JSAMPROW]
823
	mov	ebx, JSAMPROW [edi+1*SIZEOF_JSAMPROW]
824
	movq	MMWORD [edx+eax*SIZEOF_JSAMPLE], mm0
825
	movq	MMWORD [ebx+eax*SIZEOF_JSAMPLE], mm3
826
	mov	edx, JSAMPROW [edi+2*SIZEOF_JSAMPROW]
827
	mov	ebx, JSAMPROW [edi+3*SIZEOF_JSAMPROW]
828
	movq	MMWORD [edx+eax*SIZEOF_JSAMPLE], mm7
829
	movq	MMWORD [ebx+eax*SIZEOF_JSAMPLE], mm4
830
831
	poppic	ebx			; restore GOT address
832
833
	add	esi, byte 4*SIZEOF_JCOEF	; wsptr
834
	add	edi, byte 4*SIZEOF_JSAMPROW
835
	dec	ecx				; ctr
836
	jnz	near .rowloop
837
838
	emms		; empty MMX state
839
840
	pop	edi
841
	pop	esi
842
;	pop	edx		; need not be preserved
843
;	pop	ecx		; need not be preserved
844
	pop	ebx
845
	mov	esp,ebp		; esp <- aligned ebp
846
	pop	esp		; esp <- original ebp
847
	pop	ebp
848
	ret
849
850
; For some reason, the OS X linker does not honor the request to align the
851
; segment unless we do this.
852
	align	16
(-)a/jpeg/simd/jimmxred.asm (+706 lines)
Line     Link Here 
Line 0    Link Here 
1
;
2
; jimmxred.asm - reduced-size IDCT (MMX)
3
;
4
; Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
5
;
6
; Based on
7
; x86 SIMD extension for IJG JPEG library
8
; Copyright (C) 1999-2006, MIYASAKA Masaru.
9
; For conditions of distribution and use, see copyright notice in jsimdext.inc
10
;
11
; This file should be assembled with NASM (Netwide Assembler),
12
; can *not* be assembled with Microsoft's MASM or any compatible
13
; assembler (including Borland's Turbo Assembler).
14
; NASM is available from http://nasm.sourceforge.net/ or
15
; http://sourceforge.net/project/showfiles.php?group_id=6208
16
;
17
; This file contains inverse-DCT routines that produce reduced-size
18
; output: either 4x4 or 2x2 pixels from an 8x8 DCT block.
19
; The following code is based directly on the IJG's original jidctred.c;
20
; see the jidctred.c for more details.
21
;
22
; [TAB8]
23
24
%include "jsimdext.inc"
25
%include "jdct.inc"
26
27
; --------------------------------------------------------------------------
28
29
%define CONST_BITS	13
30
%define PASS1_BITS	2
31
32
%define DESCALE_P1_4	(CONST_BITS-PASS1_BITS+1)
33
%define DESCALE_P2_4	(CONST_BITS+PASS1_BITS+3+1)
34
%define DESCALE_P1_2	(CONST_BITS-PASS1_BITS+2)
35
%define DESCALE_P2_2	(CONST_BITS+PASS1_BITS+3+2)
36
37
%if CONST_BITS == 13
38
F_0_211	equ	 1730		; FIX(0.211164243)
39
F_0_509	equ	 4176		; FIX(0.509795579)
40
F_0_601	equ	 4926		; FIX(0.601344887)
41
F_0_720	equ	 5906		; FIX(0.720959822)
42
F_0_765	equ	 6270		; FIX(0.765366865)
43
F_0_850	equ	 6967		; FIX(0.850430095)
44
F_0_899	equ	 7373		; FIX(0.899976223)
45
F_1_061	equ	 8697		; FIX(1.061594337)
46
F_1_272	equ	10426		; FIX(1.272758580)
47
F_1_451	equ	11893		; FIX(1.451774981)
48
F_1_847	equ	15137		; FIX(1.847759065)
49
F_2_172	equ	17799		; FIX(2.172734803)
50
F_2_562	equ	20995		; FIX(2.562915447)
51
F_3_624	equ	29692		; FIX(3.624509785)
52
%else
53
; NASM cannot do compile-time arithmetic on floating-point constants.
54
%define DESCALE(x,n)  (((x)+(1<<((n)-1)))>>(n))
55
F_0_211	equ	DESCALE( 226735879,30-CONST_BITS)	; FIX(0.211164243)
56
F_0_509	equ	DESCALE( 547388834,30-CONST_BITS)	; FIX(0.509795579)
57
F_0_601	equ	DESCALE( 645689155,30-CONST_BITS)	; FIX(0.601344887)
58
F_0_720	equ	DESCALE( 774124714,30-CONST_BITS)	; FIX(0.720959822)
59
F_0_765	equ	DESCALE( 821806413,30-CONST_BITS)	; FIX(0.765366865)
60
F_0_850	equ	DESCALE( 913142361,30-CONST_BITS)	; FIX(0.850430095)
61
F_0_899	equ	DESCALE( 966342111,30-CONST_BITS)	; FIX(0.899976223)
62
F_1_061	equ	DESCALE(1139878239,30-CONST_BITS)	; FIX(1.061594337)
63
F_1_272	equ	DESCALE(1366614119,30-CONST_BITS)	; FIX(1.272758580)
64
F_1_451	equ	DESCALE(1558831516,30-CONST_BITS)	; FIX(1.451774981)
65
F_1_847	equ	DESCALE(1984016188,30-CONST_BITS)	; FIX(1.847759065)
66
F_2_172	equ	DESCALE(2332956230,30-CONST_BITS)	; FIX(2.172734803)
67
F_2_562	equ	DESCALE(2751909506,30-CONST_BITS)	; FIX(2.562915447)
68
F_3_624	equ	DESCALE(3891787747,30-CONST_BITS)	; FIX(3.624509785)
69
%endif
70
71
; --------------------------------------------------------------------------
72
	SECTION	SEG_CONST
73
74
	alignz	16
75
	global	EXTN(jconst_idct_red_mmx)
76
77
EXTN(jconst_idct_red_mmx):
78
79
PW_F184_MF076	times 2 dw  F_1_847,-F_0_765
80
PW_F256_F089	times 2 dw  F_2_562, F_0_899
81
PW_F106_MF217	times 2 dw  F_1_061,-F_2_172
82
PW_MF060_MF050	times 2 dw -F_0_601,-F_0_509
83
PW_F145_MF021	times 2 dw  F_1_451,-F_0_211
84
PW_F362_MF127	times 2 dw  F_3_624,-F_1_272
85
PW_F085_MF072	times 2 dw  F_0_850,-F_0_720
86
PD_DESCALE_P1_4	times 2 dd  1 << (DESCALE_P1_4-1)
87
PD_DESCALE_P2_4	times 2 dd  1 << (DESCALE_P2_4-1)
88
PD_DESCALE_P1_2	times 2 dd  1 << (DESCALE_P1_2-1)
89
PD_DESCALE_P2_2	times 2 dd  1 << (DESCALE_P2_2-1)
90
PB_CENTERJSAMP	times 8 db  CENTERJSAMPLE
91
92
	alignz	16
93
94
; --------------------------------------------------------------------------
95
	SECTION	SEG_TEXT
96
	BITS	32
97
;
98
; Perform dequantization and inverse DCT on one block of coefficients,
99
; producing a reduced-size 4x4 output block.
100
;
101
; GLOBAL(void)
102
; jsimd_idct_4x4_mmx (void * dct_table, JCOEFPTR coef_block,
103
;                     JSAMPARRAY output_buf, JDIMENSION output_col)
104
;
105
106
%define dct_table(b)	(b)+8			; void * dct_table
107
%define coef_block(b)	(b)+12		; JCOEFPTR coef_block
108
%define output_buf(b)	(b)+16		; JSAMPARRAY output_buf
109
%define output_col(b)	(b)+20		; JDIMENSION output_col
110
111
%define original_ebp	ebp+0
112
%define wk(i)		ebp-(WK_NUM-(i))*SIZEOF_MMWORD	; mmword wk[WK_NUM]
113
%define WK_NUM		2
114
%define workspace	wk(0)-DCTSIZE2*SIZEOF_JCOEF
115
					; JCOEF workspace[DCTSIZE2]
116
117
	align	16
118
	global	EXTN(jsimd_idct_4x4_mmx)
119
120
EXTN(jsimd_idct_4x4_mmx):
121
	push	ebp
122
	mov	eax,esp				; eax = original ebp
123
	sub	esp, byte 4
124
	and	esp, byte (-SIZEOF_MMWORD)	; align to 64 bits
125
	mov	[esp],eax
126
	mov	ebp,esp				; ebp = aligned ebp
127
	lea	esp, [workspace]
128
	pushpic	ebx
129
;	push	ecx		; need not be preserved
130
;	push	edx		; need not be preserved
131
	push	esi
132
	push	edi
133
134
	get_GOT	ebx		; get GOT address
135
136
	; ---- Pass 1: process columns from input, store into work array.
137
138
;	mov	eax, [original_ebp]
139
	mov	edx, POINTER [dct_table(eax)]	; quantptr
140
	mov	esi, JCOEFPTR [coef_block(eax)]		; inptr
141
	lea	edi, [workspace]			; JCOEF * wsptr
142
	mov	ecx, DCTSIZE/4				; ctr
143
	alignx	16,7
144
.columnloop:
145
%ifndef NO_ZERO_COLUMN_TEST_4X4_MMX
146
	mov	eax, DWORD [DWBLOCK(1,0,esi,SIZEOF_JCOEF)]
147
	or	eax, DWORD [DWBLOCK(2,0,esi,SIZEOF_JCOEF)]
148
	jnz	short .columnDCT
149
150
	movq	mm0, MMWORD [MMBLOCK(1,0,esi,SIZEOF_JCOEF)]
151
	movq	mm1, MMWORD [MMBLOCK(2,0,esi,SIZEOF_JCOEF)]
152
	por	mm0, MMWORD [MMBLOCK(3,0,esi,SIZEOF_JCOEF)]
153
	por	mm1, MMWORD [MMBLOCK(5,0,esi,SIZEOF_JCOEF)]
154
	por	mm0, MMWORD [MMBLOCK(6,0,esi,SIZEOF_JCOEF)]
155
	por	mm1, MMWORD [MMBLOCK(7,0,esi,SIZEOF_JCOEF)]
156
	por	mm0,mm1
157
	packsswb mm0,mm0
158
	movd	eax,mm0
159
	test	eax,eax
160
	jnz	short .columnDCT
161
162
	; -- AC terms all zero
163
164
	movq	mm0, MMWORD [MMBLOCK(0,0,esi,SIZEOF_JCOEF)]
165
	pmullw	mm0, MMWORD [MMBLOCK(0,0,edx,SIZEOF_ISLOW_MULT_TYPE)]
166
167
	psllw	mm0,PASS1_BITS
168
169
	movq      mm2,mm0		; mm0=in0=(00 01 02 03)
170
	punpcklwd mm0,mm0		; mm0=(00 00 01 01)
171
	punpckhwd mm2,mm2		; mm2=(02 02 03 03)
172
173
	movq      mm1,mm0
174
	punpckldq mm0,mm0		; mm0=(00 00 00 00)
175
	punpckhdq mm1,mm1		; mm1=(01 01 01 01)
176
	movq      mm3,mm2
177
	punpckldq mm2,mm2		; mm2=(02 02 02 02)
178
	punpckhdq mm3,mm3		; mm3=(03 03 03 03)
179
180
	movq	MMWORD [MMBLOCK(0,0,edi,SIZEOF_JCOEF)], mm0
181
	movq	MMWORD [MMBLOCK(1,0,edi,SIZEOF_JCOEF)], mm1
182
	movq	MMWORD [MMBLOCK(2,0,edi,SIZEOF_JCOEF)], mm2
183
	movq	MMWORD [MMBLOCK(3,0,edi,SIZEOF_JCOEF)], mm3
184
	jmp	near .nextcolumn
185
	alignx	16,7
186
%endif
187
.columnDCT:
188
189
	; -- Odd part
190
191
	movq	mm0, MMWORD [MMBLOCK(1,0,esi,SIZEOF_JCOEF)]
192
	movq	mm1, MMWORD [MMBLOCK(3,0,esi,SIZEOF_JCOEF)]
193
	pmullw	mm0, MMWORD [MMBLOCK(1,0,edx,SIZEOF_ISLOW_MULT_TYPE)]
194
	pmullw	mm1, MMWORD [MMBLOCK(3,0,edx,SIZEOF_ISLOW_MULT_TYPE)]
195
	movq	mm2, MMWORD [MMBLOCK(5,0,esi,SIZEOF_JCOEF)]
196
	movq	mm3, MMWORD [MMBLOCK(7,0,esi,SIZEOF_JCOEF)]
197
	pmullw	mm2, MMWORD [MMBLOCK(5,0,edx,SIZEOF_ISLOW_MULT_TYPE)]
198
	pmullw	mm3, MMWORD [MMBLOCK(7,0,edx,SIZEOF_ISLOW_MULT_TYPE)]
199
200
	movq      mm4,mm0
201
	movq      mm5,mm0
202
	punpcklwd mm4,mm1
203
	punpckhwd mm5,mm1
204
	movq      mm0,mm4
205
	movq      mm1,mm5
206
	pmaddwd   mm4,[GOTOFF(ebx,PW_F256_F089)]	; mm4=(tmp2L)
207
	pmaddwd   mm5,[GOTOFF(ebx,PW_F256_F089)]	; mm5=(tmp2H)
208
	pmaddwd   mm0,[GOTOFF(ebx,PW_F106_MF217)]	; mm0=(tmp0L)
209
	pmaddwd   mm1,[GOTOFF(ebx,PW_F106_MF217)]	; mm1=(tmp0H)
210
211
	movq      mm6,mm2
212
	movq      mm7,mm2
213
	punpcklwd mm6,mm3
214
	punpckhwd mm7,mm3
215
	movq      mm2,mm6
216
	movq      mm3,mm7
217
	pmaddwd   mm6,[GOTOFF(ebx,PW_MF060_MF050)]	; mm6=(tmp2L)
218
	pmaddwd   mm7,[GOTOFF(ebx,PW_MF060_MF050)]	; mm7=(tmp2H)
219
	pmaddwd   mm2,[GOTOFF(ebx,PW_F145_MF021)]	; mm2=(tmp0L)
220
	pmaddwd   mm3,[GOTOFF(ebx,PW_F145_MF021)]	; mm3=(tmp0H)
221
222
	paddd	mm6,mm4			; mm6=tmp2L
223
	paddd	mm7,mm5			; mm7=tmp2H
224
	paddd	mm2,mm0			; mm2=tmp0L
225
	paddd	mm3,mm1			; mm3=tmp0H
226
227
	movq	MMWORD [wk(0)], mm2	; wk(0)=tmp0L
228
	movq	MMWORD [wk(1)], mm3	; wk(1)=tmp0H
229
230
	; -- Even part
231
232
	movq	mm4, MMWORD [MMBLOCK(0,0,esi,SIZEOF_JCOEF)]
233
	movq	mm5, MMWORD [MMBLOCK(2,0,esi,SIZEOF_JCOEF)]
234
	movq	mm0, MMWORD [MMBLOCK(6,0,esi,SIZEOF_JCOEF)]
235
	pmullw	mm4, MMWORD [MMBLOCK(0,0,edx,SIZEOF_ISLOW_MULT_TYPE)]
236
	pmullw	mm5, MMWORD [MMBLOCK(2,0,edx,SIZEOF_ISLOW_MULT_TYPE)]
237
	pmullw	mm0, MMWORD [MMBLOCK(6,0,edx,SIZEOF_ISLOW_MULT_TYPE)]
238
239
	pxor      mm1,mm1
240
	pxor      mm2,mm2
241
	punpcklwd mm1,mm4		; mm1=tmp0L
242
	punpckhwd mm2,mm4		; mm2=tmp0H
243
	psrad     mm1,(16-CONST_BITS-1)	; psrad mm1,16 & pslld mm1,CONST_BITS+1
244
	psrad     mm2,(16-CONST_BITS-1)	; psrad mm2,16 & pslld mm2,CONST_BITS+1
245
246
	movq      mm3,mm5		; mm5=in2=z2
247
	punpcklwd mm5,mm0		; mm0=in6=z3
248
	punpckhwd mm3,mm0
249
	pmaddwd   mm5,[GOTOFF(ebx,PW_F184_MF076)]	; mm5=tmp2L
250
	pmaddwd   mm3,[GOTOFF(ebx,PW_F184_MF076)]	; mm3=tmp2H
251
252
	movq	mm4,mm1
253
	movq	mm0,mm2
254
	paddd	mm1,mm5			; mm1=tmp10L
255
	paddd	mm2,mm3			; mm2=tmp10H
256
	psubd	mm4,mm5			; mm4=tmp12L
257
	psubd	mm0,mm3			; mm0=tmp12H
258
259
	; -- Final output stage
260
261
	movq	mm5,mm1
262
	movq	mm3,mm2
263
	paddd	mm1,mm6			; mm1=data0L
264
	paddd	mm2,mm7			; mm2=data0H
265
	psubd	mm5,mm6			; mm5=data3L
266
	psubd	mm3,mm7			; mm3=data3H
267
268
	movq	mm6,[GOTOFF(ebx,PD_DESCALE_P1_4)]	; mm6=[PD_DESCALE_P1_4]
269
270
	paddd	mm1,mm6
271
	paddd	mm2,mm6
272
	psrad	mm1,DESCALE_P1_4
273
	psrad	mm2,DESCALE_P1_4
274
	paddd	mm5,mm6
275
	paddd	mm3,mm6
276
	psrad	mm5,DESCALE_P1_4
277
	psrad	mm3,DESCALE_P1_4
278
279
	packssdw  mm1,mm2		; mm1=data0=(00 01 02 03)
280
	packssdw  mm5,mm3		; mm5=data3=(30 31 32 33)
281
282
	movq	mm7, MMWORD [wk(0)]	; mm7=tmp0L
283
	movq	mm6, MMWORD [wk(1)]	; mm6=tmp0H
284
285
	movq	mm2,mm4
286
	movq	mm3,mm0
287
	paddd	mm4,mm7			; mm4=data1L
288
	paddd	mm0,mm6			; mm0=data1H
289
	psubd	mm2,mm7			; mm2=data2L
290
	psubd	mm3,mm6			; mm3=data2H
291
292
	movq	mm7,[GOTOFF(ebx,PD_DESCALE_P1_4)]	; mm7=[PD_DESCALE_P1_4]
293
294
	paddd	mm4,mm7
295
	paddd	mm0,mm7
296
	psrad	mm4,DESCALE_P1_4
297
	psrad	mm0,DESCALE_P1_4
298
	paddd	mm2,mm7
299
	paddd	mm3,mm7
300
	psrad	mm2,DESCALE_P1_4
301
	psrad	mm3,DESCALE_P1_4
302
303
	packssdw  mm4,mm0		; mm4=data1=(10 11 12 13)
304
	packssdw  mm2,mm3		; mm2=data2=(20 21 22 23)
305
306
	movq      mm6,mm1		; transpose coefficients(phase 1)
307
	punpcklwd mm1,mm4		; mm1=(00 10 01 11)
308
	punpckhwd mm6,mm4		; mm6=(02 12 03 13)
309
	movq      mm7,mm2		; transpose coefficients(phase 1)
310
	punpcklwd mm2,mm5		; mm2=(20 30 21 31)
311
	punpckhwd mm7,mm5		; mm7=(22 32 23 33)
312
313
	movq      mm0,mm1		; transpose coefficients(phase 2)
314
	punpckldq mm1,mm2		; mm1=(00 10 20 30)
315
	punpckhdq mm0,mm2		; mm0=(01 11 21 31)
316
	movq      mm3,mm6		; transpose coefficients(phase 2)
317
	punpckldq mm6,mm7		; mm6=(02 12 22 32)
318
	punpckhdq mm3,mm7		; mm3=(03 13 23 33)
319
320
	movq	MMWORD [MMBLOCK(0,0,edi,SIZEOF_JCOEF)], mm1
321
	movq	MMWORD [MMBLOCK(1,0,edi,SIZEOF_JCOEF)], mm0
322
	movq	MMWORD [MMBLOCK(2,0,edi,SIZEOF_JCOEF)], mm6
323
	movq	MMWORD [MMBLOCK(3,0,edi,SIZEOF_JCOEF)], mm3
324
325
.nextcolumn:
326
	add	esi, byte 4*SIZEOF_JCOEF		; coef_block
327
	add	edx, byte 4*SIZEOF_ISLOW_MULT_TYPE	; quantptr
328
	add	edi, byte 4*DCTSIZE*SIZEOF_JCOEF	; wsptr
329
	dec	ecx					; ctr
330
	jnz	near .columnloop
331
332
	; ---- Pass 2: process rows from work array, store into output array.
333
334
	mov	eax, [original_ebp]
335
	lea	esi, [workspace]			; JCOEF * wsptr
336
	mov	edi, JSAMPARRAY [output_buf(eax)]	; (JSAMPROW *)
337
	mov	eax, JDIMENSION [output_col(eax)]
338
339
	; -- Odd part
340
341
	movq	mm0, MMWORD [MMBLOCK(1,0,esi,SIZEOF_JCOEF)]
342
	movq	mm1, MMWORD [MMBLOCK(3,0,esi,SIZEOF_JCOEF)]
343
	movq	mm2, MMWORD [MMBLOCK(5,0,esi,SIZEOF_JCOEF)]
344
	movq	mm3, MMWORD [MMBLOCK(7,0,esi,SIZEOF_JCOEF)]
345
346
	movq      mm4,mm0
347
	movq      mm5,mm0
348
	punpcklwd mm4,mm1
349
	punpckhwd mm5,mm1
350
	movq      mm0,mm4
351
	movq      mm1,mm5
352
	pmaddwd   mm4,[GOTOFF(ebx,PW_F256_F089)]	; mm4=(tmp2L)
353
	pmaddwd   mm5,[GOTOFF(ebx,PW_F256_F089)]	; mm5=(tmp2H)
354
	pmaddwd   mm0,[GOTOFF(ebx,PW_F106_MF217)]	; mm0=(tmp0L)
355
	pmaddwd   mm1,[GOTOFF(ebx,PW_F106_MF217)]	; mm1=(tmp0H)
356
357
	movq      mm6,mm2
358
	movq      mm7,mm2
359
	punpcklwd mm6,mm3
360
	punpckhwd mm7,mm3
361
	movq      mm2,mm6
362
	movq      mm3,mm7
363
	pmaddwd   mm6,[GOTOFF(ebx,PW_MF060_MF050)]	; mm6=(tmp2L)
364
	pmaddwd   mm7,[GOTOFF(ebx,PW_MF060_MF050)]	; mm7=(tmp2H)
365
	pmaddwd   mm2,[GOTOFF(ebx,PW_F145_MF021)]	; mm2=(tmp0L)
366
	pmaddwd   mm3,[GOTOFF(ebx,PW_F145_MF021)]	; mm3=(tmp0H)
367
368
	paddd	mm6,mm4			; mm6=tmp2L
369
	paddd	mm7,mm5			; mm7=tmp2H
370
	paddd	mm2,mm0			; mm2=tmp0L
371
	paddd	mm3,mm1			; mm3=tmp0H
372
373
	movq	MMWORD [wk(0)], mm2	; wk(0)=tmp0L
374
	movq	MMWORD [wk(1)], mm3	; wk(1)=tmp0H
375
376
	; -- Even part
377
378
	movq	mm4, MMWORD [MMBLOCK(0,0,esi,SIZEOF_JCOEF)]
379
	movq	mm5, MMWORD [MMBLOCK(2,0,esi,SIZEOF_JCOEF)]
380
	movq	mm0, MMWORD [MMBLOCK(6,0,esi,SIZEOF_JCOEF)]
381
382
	pxor      mm1,mm1
383
	pxor      mm2,mm2
384
	punpcklwd mm1,mm4		; mm1=tmp0L
385
	punpckhwd mm2,mm4		; mm2=tmp0H
386
	psrad     mm1,(16-CONST_BITS-1)	; psrad mm1,16 & pslld mm1,CONST_BITS+1
387
	psrad     mm2,(16-CONST_BITS-1)	; psrad mm2,16 & pslld mm2,CONST_BITS+1
388
389
	movq      mm3,mm5		; mm5=in2=z2
390
	punpcklwd mm5,mm0		; mm0=in6=z3
391
	punpckhwd mm3,mm0
392
	pmaddwd   mm5,[GOTOFF(ebx,PW_F184_MF076)]	; mm5=tmp2L
393
	pmaddwd   mm3,[GOTOFF(ebx,PW_F184_MF076)]	; mm3=tmp2H
394
395
	movq	mm4,mm1
396
	movq	mm0,mm2
397
	paddd	mm1,mm5			; mm1=tmp10L
398
	paddd	mm2,mm3			; mm2=tmp10H
399
	psubd	mm4,mm5			; mm4=tmp12L
400
	psubd	mm0,mm3			; mm0=tmp12H
401
402
	; -- Final output stage
403
404
	movq	mm5,mm1
405
	movq	mm3,mm2
406
	paddd	mm1,mm6			; mm1=data0L
407
	paddd	mm2,mm7			; mm2=data0H
408
	psubd	mm5,mm6			; mm5=data3L
409
	psubd	mm3,mm7			; mm3=data3H
410
411
	movq	mm6,[GOTOFF(ebx,PD_DESCALE_P2_4)]	; mm6=[PD_DESCALE_P2_4]
412
413
	paddd	mm1,mm6
414
	paddd	mm2,mm6
415
	psrad	mm1,DESCALE_P2_4
416
	psrad	mm2,DESCALE_P2_4
417
	paddd	mm5,mm6
418
	paddd	mm3,mm6
419
	psrad	mm5,DESCALE_P2_4
420
	psrad	mm3,DESCALE_P2_4
421
422
	packssdw  mm1,mm2		; mm1=data0=(00 10 20 30)
423
	packssdw  mm5,mm3		; mm5=data3=(03 13 23 33)
424
425
	movq	mm7, MMWORD [wk(0)]	; mm7=tmp0L
426
	movq	mm6, MMWORD [wk(1)]	; mm6=tmp0H
427
428
	movq	mm2,mm4
429
	movq	mm3,mm0
430
	paddd	mm4,mm7			; mm4=data1L
431
	paddd	mm0,mm6			; mm0=data1H
432
	psubd	mm2,mm7			; mm2=data2L
433
	psubd	mm3,mm6			; mm3=data2H
434
435
	movq	mm7,[GOTOFF(ebx,PD_DESCALE_P2_4)]	; mm7=[PD_DESCALE_P2_4]
436
437
	paddd	mm4,mm7
438
	paddd	mm0,mm7
439
	psrad	mm4,DESCALE_P2_4
440
	psrad	mm0,DESCALE_P2_4
441
	paddd	mm2,mm7
442
	paddd	mm3,mm7
443
	psrad	mm2,DESCALE_P2_4
444
	psrad	mm3,DESCALE_P2_4
445
446
	packssdw  mm4,mm0		; mm4=data1=(01 11 21 31)
447
	packssdw  mm2,mm3		; mm2=data2=(02 12 22 32)
448
449
	movq      mm6,[GOTOFF(ebx,PB_CENTERJSAMP)]	; mm6=[PB_CENTERJSAMP]
450
451
	packsswb  mm1,mm2		; mm1=(00 10 20 30 02 12 22 32)
452
	packsswb  mm4,mm5		; mm4=(01 11 21 31 03 13 23 33)
453
	paddb     mm1,mm6
454
	paddb     mm4,mm6
455
456
	movq      mm7,mm1		; transpose coefficients(phase 1)
457
	punpcklbw mm1,mm4		; mm1=(00 01 10 11 20 21 30 31)
458
	punpckhbw mm7,mm4		; mm7=(02 03 12 13 22 23 32 33)
459
460
	movq      mm0,mm1		; transpose coefficients(phase 2)
461
	punpcklwd mm1,mm7		; mm1=(00 01 02 03 10 11 12 13)
462
	punpckhwd mm0,mm7		; mm0=(20 21 22 23 30 31 32 33)
463
464
	mov	edx, JSAMPROW [edi+0*SIZEOF_JSAMPROW]
465
	mov	esi, JSAMPROW [edi+2*SIZEOF_JSAMPROW]
466
	movd	DWORD [edx+eax*SIZEOF_JSAMPLE], mm1
467
	movd	DWORD [esi+eax*SIZEOF_JSAMPLE], mm0
468
469
	psrlq	mm1,4*BYTE_BIT
470
	psrlq	mm0,4*BYTE_BIT
471
472
	mov	edx, JSAMPROW [edi+1*SIZEOF_JSAMPROW]
473
	mov	esi, JSAMPROW [edi+3*SIZEOF_JSAMPROW]
474
	movd	DWORD [edx+eax*SIZEOF_JSAMPLE], mm1
475
	movd	DWORD [esi+eax*SIZEOF_JSAMPLE], mm0
476
477
	emms		; empty MMX state
478
479
	pop	edi
480
	pop	esi
481
;	pop	edx		; need not be preserved
482
;	pop	ecx		; need not be preserved
483
	poppic	ebx
484
	mov	esp,ebp		; esp <- aligned ebp
485
	pop	esp		; esp <- original ebp
486
	pop	ebp
487
	ret
488
489
490
; --------------------------------------------------------------------------
491
;
492
; Perform dequantization and inverse DCT on one block of coefficients,
493
; producing a reduced-size 2x2 output block.
494
;
495
; GLOBAL(void)
496
; jsimd_idct_2x2_mmx (void * dct_table, JCOEFPTR coef_block,
497
;                     JSAMPARRAY output_buf, JDIMENSION output_col)
498
;
499
500
%define dct_table(b)	(b)+8			; void * dct_table
501
%define coef_block(b)	(b)+12		; JCOEFPTR coef_block
502
%define output_buf(b)	(b)+16		; JSAMPARRAY output_buf
503
%define output_col(b)	(b)+20		; JDIMENSION output_col
504
505
	align	16
506
	global	EXTN(jsimd_idct_2x2_mmx)
507
508
EXTN(jsimd_idct_2x2_mmx):
509
	push	ebp
510
	mov	ebp,esp
511
	push	ebx
512
;	push	ecx		; need not be preserved
513
;	push	edx		; need not be preserved
514
	push	esi
515
	push	edi
516
517
	get_GOT	ebx		; get GOT address
518
519
	; ---- Pass 1: process columns from input.
520
521
	mov	edx, POINTER [dct_table(ebp)]	; quantptr
522
	mov	esi, JCOEFPTR [coef_block(ebp)]		; inptr
523
524
	; | input:                  | result:        |
525
	; | 00 01 ** 03 ** 05 ** 07 |                |
526
	; | 10 11 ** 13 ** 15 ** 17 |                |
527
	; | ** ** ** ** ** ** ** ** |                |
528
	; | 30 31 ** 33 ** 35 ** 37 | A0 A1 A3 A5 A7 |
529
	; | ** ** ** ** ** ** ** ** | B0 B1 B3 B5 B7 |
530
	; | 50 51 ** 53 ** 55 ** 57 |                |
531
	; | ** ** ** ** ** ** ** ** |                |
532
	; | 70 71 ** 73 ** 75 ** 77 |                |
533
534
	; -- Odd part
535
536
	movq	mm0, MMWORD [MMBLOCK(1,0,esi,SIZEOF_JCOEF)]
537
	movq	mm1, MMWORD [MMBLOCK(3,0,esi,SIZEOF_JCOEF)]
538
	pmullw	mm0, MMWORD [MMBLOCK(1,0,edx,SIZEOF_ISLOW_MULT_TYPE)]
539
	pmullw	mm1, MMWORD [MMBLOCK(3,0,edx,SIZEOF_ISLOW_MULT_TYPE)]
540
	movq	mm2, MMWORD [MMBLOCK(5,0,esi,SIZEOF_JCOEF)]
541
	movq	mm3, MMWORD [MMBLOCK(7,0,esi,SIZEOF_JCOEF)]
542
	pmullw	mm2, MMWORD [MMBLOCK(5,0,edx,SIZEOF_ISLOW_MULT_TYPE)]
543
	pmullw	mm3, MMWORD [MMBLOCK(7,0,edx,SIZEOF_ISLOW_MULT_TYPE)]
544
545
	; mm0=(10 11 ** 13), mm1=(30 31 ** 33)
546
	; mm2=(50 51 ** 53), mm3=(70 71 ** 73)
547
548
	pcmpeqd   mm7,mm7
549
	pslld     mm7,WORD_BIT		; mm7={0x0000 0xFFFF 0x0000 0xFFFF}
550
551
	movq      mm4,mm0		; mm4=(10 11 ** 13)
552
	movq      mm5,mm2		; mm5=(50 51 ** 53)
553
	punpcklwd mm4,mm1		; mm4=(10 30 11 31)
554
	punpcklwd mm5,mm3		; mm5=(50 70 51 71)
555
	pmaddwd   mm4,[GOTOFF(ebx,PW_F362_MF127)]
556
	pmaddwd   mm5,[GOTOFF(ebx,PW_F085_MF072)]
557
558
	psrld	mm0,WORD_BIT		; mm0=(11 -- 13 --)
559
	pand	mm1,mm7			; mm1=(-- 31 -- 33)
560
	psrld	mm2,WORD_BIT		; mm2=(51 -- 53 --)
561
	pand	mm3,mm7			; mm3=(-- 71 -- 73)
562
	por	mm0,mm1			; mm0=(11 31 13 33)
563
	por	mm2,mm3			; mm2=(51 71 53 73)
564
	pmaddwd	mm0,[GOTOFF(ebx,PW_F362_MF127)]
565
	pmaddwd	mm2,[GOTOFF(ebx,PW_F085_MF072)]
566
567
	paddd	mm4,mm5			; mm4=tmp0[col0 col1]
568
569
	movq	mm6, MMWORD [MMBLOCK(1,1,esi,SIZEOF_JCOEF)]
570
	movq	mm1, MMWORD [MMBLOCK(3,1,esi,SIZEOF_JCOEF)]
571
	pmullw	mm6, MMWORD [MMBLOCK(1,1,edx,SIZEOF_ISLOW_MULT_TYPE)]
572
	pmullw	mm1, MMWORD [MMBLOCK(3,1,edx,SIZEOF_ISLOW_MULT_TYPE)]
573
	movq	mm3, MMWORD [MMBLOCK(5,1,esi,SIZEOF_JCOEF)]
574
	movq	mm5, MMWORD [MMBLOCK(7,1,esi,SIZEOF_JCOEF)]
575
	pmullw	mm3, MMWORD [MMBLOCK(5,1,edx,SIZEOF_ISLOW_MULT_TYPE)]
576
	pmullw	mm5, MMWORD [MMBLOCK(7,1,edx,SIZEOF_ISLOW_MULT_TYPE)]
577
578
	; mm6=(** 15 ** 17), mm1=(** 35 ** 37)
579
	; mm3=(** 55 ** 57), mm5=(** 75 ** 77)
580
581
	psrld	mm6,WORD_BIT		; mm6=(15 -- 17 --)
582
	pand	mm1,mm7			; mm1=(-- 35 -- 37)
583
	psrld	mm3,WORD_BIT		; mm3=(55 -- 57 --)
584
	pand	mm5,mm7			; mm5=(-- 75 -- 77)
585
	por	mm6,mm1			; mm6=(15 35 17 37)
586
	por	mm3,mm5			; mm3=(55 75 57 77)
587
	pmaddwd	mm6,[GOTOFF(ebx,PW_F362_MF127)]
588
	pmaddwd	mm3,[GOTOFF(ebx,PW_F085_MF072)]
589
590
	paddd	mm0,mm2			; mm0=tmp0[col1 col3]
591
	paddd	mm6,mm3			; mm6=tmp0[col5 col7]
592
593
	; -- Even part
594
595
	movq	mm1, MMWORD [MMBLOCK(0,0,esi,SIZEOF_JCOEF)]
596
	movq	mm5, MMWORD [MMBLOCK(0,1,esi,SIZEOF_JCOEF)]
597
	pmullw	mm1, MMWORD [MMBLOCK(0,0,edx,SIZEOF_ISLOW_MULT_TYPE)]
598
	pmullw	mm5, MMWORD [MMBLOCK(0,1,edx,SIZEOF_ISLOW_MULT_TYPE)]
599
600
	; mm1=(00 01 ** 03), mm5=(** 05 ** 07)
601
602
	movq	mm2,mm1				; mm2=(00 01 ** 03)
603
	pslld	mm1,WORD_BIT			; mm1=(-- 00 -- **)
604
	psrad	mm1,(WORD_BIT-CONST_BITS-2)	; mm1=tmp10[col0 ****]
605
606
	pand	mm2,mm7				; mm2=(-- 01 -- 03)
607
	pand	mm5,mm7				; mm5=(-- 05 -- 07)
608
	psrad	mm2,(WORD_BIT-CONST_BITS-2)	; mm2=tmp10[col1 col3]
609
	psrad	mm5,(WORD_BIT-CONST_BITS-2)	; mm5=tmp10[col5 col7]
610
611
	; -- Final output stage
612
613
	movq      mm3,mm1
614
	paddd     mm1,mm4		; mm1=data0[col0 ****]=(A0 **)
615
	psubd     mm3,mm4		; mm3=data1[col0 ****]=(B0 **)
616
	punpckldq mm1,mm3		; mm1=(A0 B0)
617
618
	movq	mm7,[GOTOFF(ebx,PD_DESCALE_P1_2)]	; mm7=[PD_DESCALE_P1_2]
619
620
	movq	mm4,mm2
621
	movq	mm3,mm5
622
	paddd	mm2,mm0			; mm2=data0[col1 col3]=(A1 A3)
623
	paddd	mm5,mm6			; mm5=data0[col5 col7]=(A5 A7)
624
	psubd	mm4,mm0			; mm4=data1[col1 col3]=(B1 B3)
625
	psubd	mm3,mm6			; mm3=data1[col5 col7]=(B5 B7)
626
627
	paddd	mm1,mm7
628
	psrad	mm1,DESCALE_P1_2
629
630
	paddd	mm2,mm7
631
	paddd	mm5,mm7
632
	psrad	mm2,DESCALE_P1_2
633
	psrad	mm5,DESCALE_P1_2
634
	paddd	mm4,mm7
635
	paddd	mm3,mm7
636
	psrad	mm4,DESCALE_P1_2
637
	psrad	mm3,DESCALE_P1_2
638
639
	; ---- Pass 2: process rows, store into output array.
640
641
	mov	edi, JSAMPARRAY [output_buf(ebp)]	; (JSAMPROW *)
642
	mov	eax, JDIMENSION [output_col(ebp)]
643
644
	; | input:| result:|
645
	; | A0 B0 |        |
646
	; | A1 B1 | C0 C1  |
647
	; | A3 B3 | D0 D1  |
648
	; | A5 B5 |        |
649
	; | A7 B7 |        |
650
651
	; -- Odd part
652
653
	packssdw  mm2,mm4		; mm2=(A1 A3 B1 B3)
654
	packssdw  mm5,mm3		; mm5=(A5 A7 B5 B7)
655
	pmaddwd   mm2,[GOTOFF(ebx,PW_F362_MF127)]
656
	pmaddwd   mm5,[GOTOFF(ebx,PW_F085_MF072)]
657
658
	paddd     mm2,mm5		; mm2=tmp0[row0 row1]
659
660
	; -- Even part
661
662
	pslld     mm1,(CONST_BITS+2)	; mm1=tmp10[row0 row1]
663
664
	; -- Final output stage
665
666
	movq      mm0,[GOTOFF(ebx,PD_DESCALE_P2_2)]	; mm0=[PD_DESCALE_P2_2]
667
668
	movq      mm6,mm1
669
	paddd     mm1,mm2		; mm1=data0[row0 row1]=(C0 C1)
670
	psubd     mm6,mm2		; mm6=data1[row0 row1]=(D0 D1)
671
672
	paddd     mm1,mm0
673
	paddd     mm6,mm0
674
	psrad     mm1,DESCALE_P2_2
675
	psrad     mm6,DESCALE_P2_2
676
677
	movq      mm7,mm1		; transpose coefficients
678
	punpckldq mm1,mm6		; mm1=(C0 D0)
679
	punpckhdq mm7,mm6		; mm7=(C1 D1)
680
681
	packssdw  mm1,mm7		; mm1=(C0 D0 C1 D1)
682
	packsswb  mm1,mm1		; mm1=(C0 D0 C1 D1 C0 D0 C1 D1)
683
	paddb     mm1,[GOTOFF(ebx,PB_CENTERJSAMP)]
684
685
	movd	ecx,mm1
686
	movd	ebx,mm1			; ebx=(C0 D0 C1 D1)
687
	shr	ecx,2*BYTE_BIT		; ecx=(C1 D1 -- --)
688
689
	mov	edx, JSAMPROW [edi+0*SIZEOF_JSAMPROW]
690
	mov	esi, JSAMPROW [edi+1*SIZEOF_JSAMPROW]
691
	mov	WORD [edx+eax*SIZEOF_JSAMPLE], bx
692
	mov	WORD [esi+eax*SIZEOF_JSAMPLE], cx
693
694
	emms		; empty MMX state
695
696
	pop	edi
697
	pop	esi
698
;	pop	edx		; need not be preserved
699
;	pop	ecx		; need not be preserved
700
	pop	ebx
701
	pop	ebp
702
	ret
703
704
; For some reason, the OS X linker does not honor the request to align the
705
; segment unless we do this.
706
	align	16
(-)a/jpeg/simd/jiss2flt-64.asm (+483 lines)
Line     Link Here 
Line 0    Link Here 
1
;
2
; jiss2flt-64.asm - floating-point IDCT (64-bit SSE & SSE2)
3
;
4
; Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
5
; Copyright 2009 D. R. Commander
6
;
7
; Based on
8
; x86 SIMD extension for IJG JPEG library
9
; Copyright (C) 1999-2006, MIYASAKA Masaru.
10
; For conditions of distribution and use, see copyright notice in jsimdext.inc
11
;
12
; This file should be assembled with NASM (Netwide Assembler),
13
; can *not* be assembled with Microsoft's MASM or any compatible
14
; assembler (including Borland's Turbo Assembler).
15
; NASM is available from http://nasm.sourceforge.net/ or
16
; http://sourceforge.net/project/showfiles.php?group_id=6208
17
;
18
; This file contains a floating-point implementation of the inverse DCT
19
; (Discrete Cosine Transform). The following code is based directly on
20
; the IJG's original jidctflt.c; see the jidctflt.c for more details.
21
;
22
; [TAB8]
23
24
%include "jsimdext.inc"
25
%include "jdct.inc"
26
27
; --------------------------------------------------------------------------
28
29
%macro	unpcklps2 2	; %1=(0 1 2 3) / %2=(4 5 6 7) => %1=(0 1 4 5)
30
	shufps	%1,%2,0x44
31
%endmacro
32
33
%macro	unpckhps2 2	; %1=(0 1 2 3) / %2=(4 5 6 7) => %1=(2 3 6 7)
34
	shufps	%1,%2,0xEE
35
%endmacro
36
37
; --------------------------------------------------------------------------
38
	SECTION	SEG_CONST
39
40
	alignz	16
41
	global	EXTN(jconst_idct_float_sse2)
42
43
EXTN(jconst_idct_float_sse2):
44
45
PD_1_414	times 4 dd  1.414213562373095048801689
46
PD_1_847	times 4 dd  1.847759065022573512256366
47
PD_1_082	times 4 dd  1.082392200292393968799446
48
PD_M2_613	times 4 dd -2.613125929752753055713286
49
PD_RNDINT_MAGIC	times 4 dd  100663296.0	; (float)(0x00C00000 << 3)
50
PB_CENTERJSAMP	times 16 db CENTERJSAMPLE
51
52
	alignz	16
53
54
; --------------------------------------------------------------------------
55
	SECTION	SEG_TEXT
56
	BITS	64
57
;
58
; Perform dequantization and inverse DCT on one block of coefficients.
59
;
60
; GLOBAL(void)
61
; jsimd_idct_float_sse2 (void * dct_table, JCOEFPTR coef_block,
62
;                        JSAMPARRAY output_buf, JDIMENSION output_col)
63
;
64
65
; r10 = void * dct_table
66
; r11 = JCOEFPTR coef_block
67
; r12 = JSAMPARRAY output_buf
68
; r13 = JDIMENSION output_col
69
70
%define original_rbp	rbp+0
71
%define wk(i)		rbp-(WK_NUM-(i))*SIZEOF_XMMWORD	; xmmword wk[WK_NUM]
72
%define WK_NUM		2
73
%define workspace	wk(0)-DCTSIZE2*SIZEOF_FAST_FLOAT
74
					; FAST_FLOAT workspace[DCTSIZE2]
75
76
	align	16
77
	global	EXTN(jsimd_idct_float_sse2)
78
79
EXTN(jsimd_idct_float_sse2):
80
	push	rbp
81
	mov	rax,rsp				; rax = original rbp
82
	sub	rsp, byte 4
83
	and	rsp, byte (-SIZEOF_XMMWORD)	; align to 128 bits
84
	mov	[rsp],rax
85
	mov	rbp,rsp				; rbp = aligned rbp
86
	lea	rsp, [workspace]
87
	collect_args
88
	push	rbx
89
90
	; ---- Pass 1: process columns from input, store into work array.
91
92
	mov	rdx, r10	; quantptr
93
	mov	rsi, r11		; inptr
94
	lea	rdi, [workspace]			; FAST_FLOAT * wsptr
95
	mov	rcx, DCTSIZE/4				; ctr
96
.columnloop:
97
%ifndef NO_ZERO_COLUMN_TEST_FLOAT_SSE
98
	mov	eax, DWORD [DWBLOCK(1,0,rsi,SIZEOF_JCOEF)]
99
	or	eax, DWORD [DWBLOCK(2,0,rsi,SIZEOF_JCOEF)]
100
	jnz	near .columnDCT
101
102
	movq	xmm1, XMM_MMWORD [MMBLOCK(1,0,rsi,SIZEOF_JCOEF)]
103
	movq	xmm2, XMM_MMWORD [MMBLOCK(2,0,rsi,SIZEOF_JCOEF)]
104
	movq	xmm3, XMM_MMWORD [MMBLOCK(3,0,rsi,SIZEOF_JCOEF)]
105
	movq	xmm4, XMM_MMWORD [MMBLOCK(4,0,rsi,SIZEOF_JCOEF)]
106
	movq	xmm5, XMM_MMWORD [MMBLOCK(5,0,rsi,SIZEOF_JCOEF)]
107
	movq	xmm6, XMM_MMWORD [MMBLOCK(6,0,rsi,SIZEOF_JCOEF)]
108
	movq	xmm7, XMM_MMWORD [MMBLOCK(7,0,rsi,SIZEOF_JCOEF)]
109
	por	xmm1,xmm2
110
	por	xmm3,xmm4
111
	por	xmm5,xmm6
112
	por	xmm1,xmm3
113
	por	xmm5,xmm7
114
	por	xmm1,xmm5
115
	packsswb xmm1,xmm1
116
	movd	eax,xmm1
117
	test	rax,rax
118
	jnz	short .columnDCT
119
120
	; -- AC terms all zero
121
122
	movq      xmm0, XMM_MMWORD [MMBLOCK(0,0,rsi,SIZEOF_JCOEF)]
123
124
	punpcklwd xmm0,xmm0		; xmm0=(00 00 01 01 02 02 03 03)
125
	psrad     xmm0,(DWORD_BIT-WORD_BIT)	; xmm0=in0=(00 01 02 03)
126
	cvtdq2ps  xmm0,xmm0			; xmm0=in0=(00 01 02 03)
127
128
	mulps	xmm0, XMMWORD [XMMBLOCK(0,0,rdx,SIZEOF_FLOAT_MULT_TYPE)]
129
130
	movaps	xmm1,xmm0
131
	movaps	xmm2,xmm0
132
	movaps	xmm3,xmm0
133
134
	shufps	xmm0,xmm0,0x00			; xmm0=(00 00 00 00)
135
	shufps	xmm1,xmm1,0x55			; xmm1=(01 01 01 01)
136
	shufps	xmm2,xmm2,0xAA			; xmm2=(02 02 02 02)
137
	shufps	xmm3,xmm3,0xFF			; xmm3=(03 03 03 03)
138
139
	movaps	XMMWORD [XMMBLOCK(0,0,rdi,SIZEOF_FAST_FLOAT)], xmm0
140
	movaps	XMMWORD [XMMBLOCK(0,1,rdi,SIZEOF_FAST_FLOAT)], xmm0
141
	movaps	XMMWORD [XMMBLOCK(1,0,rdi,SIZEOF_FAST_FLOAT)], xmm1
142
	movaps	XMMWORD [XMMBLOCK(1,1,rdi,SIZEOF_FAST_FLOAT)], xmm1
143
	movaps	XMMWORD [XMMBLOCK(2,0,rdi,SIZEOF_FAST_FLOAT)], xmm2
144
	movaps	XMMWORD [XMMBLOCK(2,1,rdi,SIZEOF_FAST_FLOAT)], xmm2
145
	movaps	XMMWORD [XMMBLOCK(3,0,rdi,SIZEOF_FAST_FLOAT)], xmm3
146
	movaps	XMMWORD [XMMBLOCK(3,1,rdi,SIZEOF_FAST_FLOAT)], xmm3
147
	jmp	near .nextcolumn
148
%endif
149
.columnDCT:
150
151
	; -- Even part
152
153
	movq      xmm0, XMM_MMWORD [MMBLOCK(0,0,rsi,SIZEOF_JCOEF)]
154
	movq      xmm1, XMM_MMWORD [MMBLOCK(2,0,rsi,SIZEOF_JCOEF)]
155
	movq      xmm2, XMM_MMWORD [MMBLOCK(4,0,rsi,SIZEOF_JCOEF)]
156
	movq      xmm3, XMM_MMWORD [MMBLOCK(6,0,rsi,SIZEOF_JCOEF)]
157
158
	punpcklwd xmm0,xmm0		; xmm0=(00 00 01 01 02 02 03 03)
159
	punpcklwd xmm1,xmm1		; xmm1=(20 20 21 21 22 22 23 23)
160
	psrad     xmm0,(DWORD_BIT-WORD_BIT)	; xmm0=in0=(00 01 02 03)
161
	psrad     xmm1,(DWORD_BIT-WORD_BIT)	; xmm1=in2=(20 21 22 23)
162
	cvtdq2ps  xmm0,xmm0			; xmm0=in0=(00 01 02 03)
163
	cvtdq2ps  xmm1,xmm1			; xmm1=in2=(20 21 22 23)
164
165
	punpcklwd xmm2,xmm2		; xmm2=(40 40 41 41 42 42 43 43)
166
	punpcklwd xmm3,xmm3		; xmm3=(60 60 61 61 62 62 63 63)
167
	psrad     xmm2,(DWORD_BIT-WORD_BIT)	; xmm2=in4=(40 41 42 43)
168
	psrad     xmm3,(DWORD_BIT-WORD_BIT)	; xmm3=in6=(60 61 62 63)
169
	cvtdq2ps  xmm2,xmm2			; xmm2=in4=(40 41 42 43)
170
	cvtdq2ps  xmm3,xmm3			; xmm3=in6=(60 61 62 63)
171
172
	mulps     xmm0, XMMWORD [XMMBLOCK(0,0,rdx,SIZEOF_FLOAT_MULT_TYPE)]
173
	mulps     xmm1, XMMWORD [XMMBLOCK(2,0,rdx,SIZEOF_FLOAT_MULT_TYPE)]
174
	mulps     xmm2, XMMWORD [XMMBLOCK(4,0,rdx,SIZEOF_FLOAT_MULT_TYPE)]
175
	mulps     xmm3, XMMWORD [XMMBLOCK(6,0,rdx,SIZEOF_FLOAT_MULT_TYPE)]
176
177
	movaps	xmm4,xmm0
178
	movaps	xmm5,xmm1
179
	subps	xmm0,xmm2		; xmm0=tmp11
180
	subps	xmm1,xmm3
181
	addps	xmm4,xmm2		; xmm4=tmp10
182
	addps	xmm5,xmm3		; xmm5=tmp13
183
184
	mulps	xmm1,[rel PD_1_414]
185
	subps	xmm1,xmm5		; xmm1=tmp12
186
187
	movaps	xmm6,xmm4
188
	movaps	xmm7,xmm0
189
	subps	xmm4,xmm5		; xmm4=tmp3
190
	subps	xmm0,xmm1		; xmm0=tmp2
191
	addps	xmm6,xmm5		; xmm6=tmp0
192
	addps	xmm7,xmm1		; xmm7=tmp1
193
194
	movaps	XMMWORD [wk(1)], xmm4	; tmp3
195
	movaps	XMMWORD [wk(0)], xmm0	; tmp2
196
197
	; -- Odd part
198
199
	movq      xmm2, XMM_MMWORD [MMBLOCK(1,0,rsi,SIZEOF_JCOEF)]
200
	movq      xmm3, XMM_MMWORD [MMBLOCK(3,0,rsi,SIZEOF_JCOEF)]
201
	movq      xmm5, XMM_MMWORD [MMBLOCK(5,0,rsi,SIZEOF_JCOEF)]
202
	movq      xmm1, XMM_MMWORD [MMBLOCK(7,0,rsi,SIZEOF_JCOEF)]
203
204
	punpcklwd xmm2,xmm2		; xmm2=(10 10 11 11 12 12 13 13)
205
	punpcklwd xmm3,xmm3		; xmm3=(30 30 31 31 32 32 33 33)
206
	psrad     xmm2,(DWORD_BIT-WORD_BIT)	; xmm2=in1=(10 11 12 13)
207
	psrad     xmm3,(DWORD_BIT-WORD_BIT)	; xmm3=in3=(30 31 32 33)
208
	cvtdq2ps  xmm2,xmm2			; xmm2=in1=(10 11 12 13)
209
	cvtdq2ps  xmm3,xmm3			; xmm3=in3=(30 31 32 33)
210
211
	punpcklwd xmm5,xmm5		; xmm5=(50 50 51 51 52 52 53 53)
212
	punpcklwd xmm1,xmm1		; xmm1=(70 70 71 71 72 72 73 73)
213
	psrad     xmm5,(DWORD_BIT-WORD_BIT)	; xmm5=in5=(50 51 52 53)
214
	psrad     xmm1,(DWORD_BIT-WORD_BIT)	; xmm1=in7=(70 71 72 73)
215
	cvtdq2ps  xmm5,xmm5			; xmm5=in5=(50 51 52 53)
216
	cvtdq2ps  xmm1,xmm1			; xmm1=in7=(70 71 72 73)
217
218
	mulps     xmm2, XMMWORD [XMMBLOCK(1,0,rdx,SIZEOF_FLOAT_MULT_TYPE)]
219
	mulps     xmm3, XMMWORD [XMMBLOCK(3,0,rdx,SIZEOF_FLOAT_MULT_TYPE)]
220
	mulps     xmm5, XMMWORD [XMMBLOCK(5,0,rdx,SIZEOF_FLOAT_MULT_TYPE)]
221
	mulps     xmm1, XMMWORD [XMMBLOCK(7,0,rdx,SIZEOF_FLOAT_MULT_TYPE)]
222
223
	movaps	xmm4,xmm2
224
	movaps	xmm0,xmm5
225
	addps	xmm2,xmm1		; xmm2=z11
226
	addps	xmm5,xmm3		; xmm5=z13
227
	subps	xmm4,xmm1		; xmm4=z12
228
	subps	xmm0,xmm3		; xmm0=z10
229
230
	movaps	xmm1,xmm2
231
	subps	xmm2,xmm5
232
	addps	xmm1,xmm5		; xmm1=tmp7
233
234
	mulps	xmm2,[rel PD_1_414]	; xmm2=tmp11
235
236
	movaps	xmm3,xmm0
237
	addps	xmm0,xmm4
238
	mulps	xmm0,[rel PD_1_847]	; xmm0=z5
239
	mulps	xmm3,[rel PD_M2_613]	; xmm3=(z10 * -2.613125930)
240
	mulps	xmm4,[rel PD_1_082]	; xmm4=(z12 * 1.082392200)
241
	addps	xmm3,xmm0		; xmm3=tmp12
242
	subps	xmm4,xmm0		; xmm4=tmp10
243
244
	; -- Final output stage
245
246
	subps	xmm3,xmm1		; xmm3=tmp6
247
	movaps	xmm5,xmm6
248
	movaps	xmm0,xmm7
249
	addps	xmm6,xmm1		; xmm6=data0=(00 01 02 03)
250
	addps	xmm7,xmm3		; xmm7=data1=(10 11 12 13)
251
	subps	xmm5,xmm1		; xmm5=data7=(70 71 72 73)
252
	subps	xmm0,xmm3		; xmm0=data6=(60 61 62 63)
253
	subps	xmm2,xmm3		; xmm2=tmp5
254
255
	movaps    xmm1,xmm6		; transpose coefficients(phase 1)
256
	unpcklps  xmm6,xmm7		; xmm6=(00 10 01 11)
257
	unpckhps  xmm1,xmm7		; xmm1=(02 12 03 13)
258
	movaps    xmm3,xmm0		; transpose coefficients(phase 1)
259
	unpcklps  xmm0,xmm5		; xmm0=(60 70 61 71)
260
	unpckhps  xmm3,xmm5		; xmm3=(62 72 63 73)
261
262
	movaps	xmm7, XMMWORD [wk(0)]	; xmm7=tmp2
263
	movaps	xmm5, XMMWORD [wk(1)]	; xmm5=tmp3
264
265
	movaps	XMMWORD [wk(0)], xmm0	; wk(0)=(60 70 61 71)
266
	movaps	XMMWORD [wk(1)], xmm3	; wk(1)=(62 72 63 73)
267
268
	addps	xmm4,xmm2		; xmm4=tmp4
269
	movaps	xmm0,xmm7
270
	movaps	xmm3,xmm5
271
	addps	xmm7,xmm2		; xmm7=data2=(20 21 22 23)
272
	addps	xmm5,xmm4		; xmm5=data4=(40 41 42 43)
273
	subps	xmm0,xmm2		; xmm0=data5=(50 51 52 53)
274
	subps	xmm3,xmm4		; xmm3=data3=(30 31 32 33)
275
276
	movaps    xmm2,xmm7		; transpose coefficients(phase 1)
277
	unpcklps  xmm7,xmm3		; xmm7=(20 30 21 31)
278
	unpckhps  xmm2,xmm3		; xmm2=(22 32 23 33)
279
	movaps    xmm4,xmm5		; transpose coefficients(phase 1)
280
	unpcklps  xmm5,xmm0		; xmm5=(40 50 41 51)
281
	unpckhps  xmm4,xmm0		; xmm4=(42 52 43 53)
282
283
	movaps    xmm3,xmm6		; transpose coefficients(phase 2)
284
	unpcklps2 xmm6,xmm7		; xmm6=(00 10 20 30)
285
	unpckhps2 xmm3,xmm7		; xmm3=(01 11 21 31)
286
	movaps    xmm0,xmm1		; transpose coefficients(phase 2)
287
	unpcklps2 xmm1,xmm2		; xmm1=(02 12 22 32)
288
	unpckhps2 xmm0,xmm2		; xmm0=(03 13 23 33)
289
290
	movaps	xmm7, XMMWORD [wk(0)]	; xmm7=(60 70 61 71)
291
	movaps	xmm2, XMMWORD [wk(1)]	; xmm2=(62 72 63 73)
292
293
	movaps	XMMWORD [XMMBLOCK(0,0,rdi,SIZEOF_FAST_FLOAT)], xmm6
294
	movaps	XMMWORD [XMMBLOCK(1,0,rdi,SIZEOF_FAST_FLOAT)], xmm3
295
	movaps	XMMWORD [XMMBLOCK(2,0,rdi,SIZEOF_FAST_FLOAT)], xmm1
296
	movaps	XMMWORD [XMMBLOCK(3,0,rdi,SIZEOF_FAST_FLOAT)], xmm0
297
298
	movaps    xmm6,xmm5		; transpose coefficients(phase 2)
299
	unpcklps2 xmm5,xmm7		; xmm5=(40 50 60 70)
300
	unpckhps2 xmm6,xmm7		; xmm6=(41 51 61 71)
301
	movaps    xmm3,xmm4		; transpose coefficients(phase 2)
302
	unpcklps2 xmm4,xmm2		; xmm4=(42 52 62 72)
303
	unpckhps2 xmm3,xmm2		; xmm3=(43 53 63 73)
304
305
	movaps	XMMWORD [XMMBLOCK(0,1,rdi,SIZEOF_FAST_FLOAT)], xmm5
306
	movaps	XMMWORD [XMMBLOCK(1,1,rdi,SIZEOF_FAST_FLOAT)], xmm6
307
	movaps	XMMWORD [XMMBLOCK(2,1,rdi,SIZEOF_FAST_FLOAT)], xmm4
308
	movaps	XMMWORD [XMMBLOCK(3,1,rdi,SIZEOF_FAST_FLOAT)], xmm3
309
310
.nextcolumn:
311
	add	rsi, byte 4*SIZEOF_JCOEF		; coef_block
312
	add	rdx, byte 4*SIZEOF_FLOAT_MULT_TYPE	; quantptr
313
	add	rdi,      4*DCTSIZE*SIZEOF_FAST_FLOAT	; wsptr
314
	dec	rcx					; ctr
315
	jnz	near .columnloop
316
317
	; -- Prefetch the next coefficient block
318
319
	prefetchnta [rsi + (DCTSIZE2-8)*SIZEOF_JCOEF + 0*32]
320
	prefetchnta [rsi + (DCTSIZE2-8)*SIZEOF_JCOEF + 1*32]
321
	prefetchnta [rsi + (DCTSIZE2-8)*SIZEOF_JCOEF + 2*32]
322
	prefetchnta [rsi + (DCTSIZE2-8)*SIZEOF_JCOEF + 3*32]
323
324
	; ---- Pass 2: process rows from work array, store into output array.
325
326
	mov	rax, [original_rbp]
327
	lea	rsi, [workspace]			; FAST_FLOAT * wsptr
328
	mov	rdi, r12	; (JSAMPROW *)
329
	mov	rax, r13
330
	mov	rcx, DCTSIZE/4				; ctr
331
.rowloop:
332
333
	; -- Even part
334
335
	movaps	xmm0, XMMWORD [XMMBLOCK(0,0,rsi,SIZEOF_FAST_FLOAT)]
336
	movaps	xmm1, XMMWORD [XMMBLOCK(2,0,rsi,SIZEOF_FAST_FLOAT)]
337
	movaps	xmm2, XMMWORD [XMMBLOCK(4,0,rsi,SIZEOF_FAST_FLOAT)]
338
	movaps	xmm3, XMMWORD [XMMBLOCK(6,0,rsi,SIZEOF_FAST_FLOAT)]
339
340
	movaps	xmm4,xmm0
341
	movaps	xmm5,xmm1
342
	subps	xmm0,xmm2		; xmm0=tmp11
343
	subps	xmm1,xmm3
344
	addps	xmm4,xmm2		; xmm4=tmp10
345
	addps	xmm5,xmm3		; xmm5=tmp13
346
347
	mulps	xmm1,[rel PD_1_414]
348
	subps	xmm1,xmm5		; xmm1=tmp12
349
350
	movaps	xmm6,xmm4
351
	movaps	xmm7,xmm0
352
	subps	xmm4,xmm5		; xmm4=tmp3
353
	subps	xmm0,xmm1		; xmm0=tmp2
354
	addps	xmm6,xmm5		; xmm6=tmp0
355
	addps	xmm7,xmm1		; xmm7=tmp1
356
357
	movaps	XMMWORD [wk(1)], xmm4	; tmp3
358
	movaps	XMMWORD [wk(0)], xmm0	; tmp2
359
360
	; -- Odd part
361
362
	movaps	xmm2, XMMWORD [XMMBLOCK(1,0,rsi,SIZEOF_FAST_FLOAT)]
363
	movaps	xmm3, XMMWORD [XMMBLOCK(3,0,rsi,SIZEOF_FAST_FLOAT)]
364
	movaps	xmm5, XMMWORD [XMMBLOCK(5,0,rsi,SIZEOF_FAST_FLOAT)]
365
	movaps	xmm1, XMMWORD [XMMBLOCK(7,0,rsi,SIZEOF_FAST_FLOAT)]
366
367
	movaps	xmm4,xmm2
368
	movaps	xmm0,xmm5
369
	addps	xmm2,xmm1		; xmm2=z11
370
	addps	xmm5,xmm3		; xmm5=z13
371
	subps	xmm4,xmm1		; xmm4=z12
372
	subps	xmm0,xmm3		; xmm0=z10
373
374
	movaps	xmm1,xmm2
375
	subps	xmm2,xmm5
376
	addps	xmm1,xmm5		; xmm1=tmp7
377
378
	mulps	xmm2,[rel PD_1_414]	; xmm2=tmp11
379
380
	movaps	xmm3,xmm0
381
	addps	xmm0,xmm4
382
	mulps	xmm0,[rel PD_1_847]	; xmm0=z5
383
	mulps	xmm3,[rel PD_M2_613]	; xmm3=(z10 * -2.613125930)
384
	mulps	xmm4,[rel PD_1_082]	; xmm4=(z12 * 1.082392200)
385
	addps	xmm3,xmm0		; xmm3=tmp12
386
	subps	xmm4,xmm0		; xmm4=tmp10
387
388
	; -- Final output stage
389
390
	subps	xmm3,xmm1		; xmm3=tmp6
391
	movaps	xmm5,xmm6
392
	movaps	xmm0,xmm7
393
	addps	xmm6,xmm1		; xmm6=data0=(00 10 20 30)
394
	addps	xmm7,xmm3		; xmm7=data1=(01 11 21 31)
395
	subps	xmm5,xmm1		; xmm5=data7=(07 17 27 37)
396
	subps	xmm0,xmm3		; xmm0=data6=(06 16 26 36)
397
	subps	xmm2,xmm3		; xmm2=tmp5
398
399
	movaps	xmm1,[rel PD_RNDINT_MAGIC]	; xmm1=[rel PD_RNDINT_MAGIC]
400
	pcmpeqd	xmm3,xmm3
401
	psrld	xmm3,WORD_BIT		; xmm3={0xFFFF 0x0000 0xFFFF 0x0000 ..}
402
403
	addps	xmm6,xmm1	; xmm6=roundint(data0/8)=(00 ** 10 ** 20 ** 30 **)
404
	addps	xmm7,xmm1	; xmm7=roundint(data1/8)=(01 ** 11 ** 21 ** 31 **)
405
	addps	xmm0,xmm1	; xmm0=roundint(data6/8)=(06 ** 16 ** 26 ** 36 **)
406
	addps	xmm5,xmm1	; xmm5=roundint(data7/8)=(07 ** 17 ** 27 ** 37 **)
407
408
	pand	xmm6,xmm3		; xmm6=(00 -- 10 -- 20 -- 30 --)
409
	pslld	xmm7,WORD_BIT		; xmm7=(-- 01 -- 11 -- 21 -- 31)
410
	pand	xmm0,xmm3		; xmm0=(06 -- 16 -- 26 -- 36 --)
411
	pslld	xmm5,WORD_BIT		; xmm5=(-- 07 -- 17 -- 27 -- 37)
412
	por	xmm6,xmm7		; xmm6=(00 01 10 11 20 21 30 31)
413
	por	xmm0,xmm5		; xmm0=(06 07 16 17 26 27 36 37)
414
415
	movaps	xmm1, XMMWORD [wk(0)]	; xmm1=tmp2
416
	movaps	xmm3, XMMWORD [wk(1)]	; xmm3=tmp3
417
418
	addps	xmm4,xmm2		; xmm4=tmp4
419
	movaps	xmm7,xmm1
420
	movaps	xmm5,xmm3
421
	addps	xmm1,xmm2		; xmm1=data2=(02 12 22 32)
422
	addps	xmm3,xmm4		; xmm3=data4=(04 14 24 34)
423
	subps	xmm7,xmm2		; xmm7=data5=(05 15 25 35)
424
	subps	xmm5,xmm4		; xmm5=data3=(03 13 23 33)
425
426
	movaps	xmm2,[rel PD_RNDINT_MAGIC]	; xmm2=[rel PD_RNDINT_MAGIC]
427
	pcmpeqd	xmm4,xmm4
428
	psrld	xmm4,WORD_BIT		; xmm4={0xFFFF 0x0000 0xFFFF 0x0000 ..}
429
430
	addps	xmm3,xmm2	; xmm3=roundint(data4/8)=(04 ** 14 ** 24 ** 34 **)
431
	addps	xmm7,xmm2	; xmm7=roundint(data5/8)=(05 ** 15 ** 25 ** 35 **)
432
	addps	xmm1,xmm2	; xmm1=roundint(data2/8)=(02 ** 12 ** 22 ** 32 **)
433
	addps	xmm5,xmm2	; xmm5=roundint(data3/8)=(03 ** 13 ** 23 ** 33 **)
434
435
	pand	xmm3,xmm4		; xmm3=(04 -- 14 -- 24 -- 34 --)
436
	pslld	xmm7,WORD_BIT		; xmm7=(-- 05 -- 15 -- 25 -- 35)
437
	pand	xmm1,xmm4		; xmm1=(02 -- 12 -- 22 -- 32 --)
438
	pslld	xmm5,WORD_BIT		; xmm5=(-- 03 -- 13 -- 23 -- 33)
439
	por	xmm3,xmm7		; xmm3=(04 05 14 15 24 25 34 35)
440
	por	xmm1,xmm5		; xmm1=(02 03 12 13 22 23 32 33)
441
442
	movdqa    xmm2,[rel PB_CENTERJSAMP]	; xmm2=[rel PB_CENTERJSAMP]
443
444
	packsswb  xmm6,xmm3	; xmm6=(00 01 10 11 20 21 30 31 04 05 14 15 24 25 34 35)
445
	packsswb  xmm1,xmm0	; xmm1=(02 03 12 13 22 23 32 33 06 07 16 17 26 27 36 37)
446
	paddb     xmm6,xmm2
447
	paddb     xmm1,xmm2
448
449
	movdqa    xmm4,xmm6	; transpose coefficients(phase 2)
450
	punpcklwd xmm6,xmm1	; xmm6=(00 01 02 03 10 11 12 13 20 21 22 23 30 31 32 33)
451
	punpckhwd xmm4,xmm1	; xmm4=(04 05 06 07 14 15 16 17 24 25 26 27 34 35 36 37)
452
453
	movdqa    xmm7,xmm6	; transpose coefficients(phase 3)
454
	punpckldq xmm6,xmm4	; xmm6=(00 01 02 03 04 05 06 07 10 11 12 13 14 15 16 17)
455
	punpckhdq xmm7,xmm4	; xmm7=(20 21 22 23 24 25 26 27 30 31 32 33 34 35 36 37)
456
457
	pshufd	xmm5,xmm6,0x4E	; xmm5=(10 11 12 13 14 15 16 17 00 01 02 03 04 05 06 07)
458
	pshufd	xmm3,xmm7,0x4E	; xmm3=(30 31 32 33 34 35 36 37 20 21 22 23 24 25 26 27)
459
460
	mov	rdx, JSAMPROW [rdi+0*SIZEOF_JSAMPROW]
461
	mov	rbx, JSAMPROW [rdi+2*SIZEOF_JSAMPROW]
462
	movq	XMM_MMWORD [rdx+rax*SIZEOF_JSAMPLE], xmm6
463
	movq	XMM_MMWORD [rbx+rax*SIZEOF_JSAMPLE], xmm7
464
	mov	rdx, JSAMPROW [rdi+1*SIZEOF_JSAMPROW]
465
	mov	rbx, JSAMPROW [rdi+3*SIZEOF_JSAMPROW]
466
	movq	XMM_MMWORD [rdx+rax*SIZEOF_JSAMPLE], xmm5
467
	movq	XMM_MMWORD [rbx+rax*SIZEOF_JSAMPLE], xmm3
468
469
	add	rsi, byte 4*SIZEOF_FAST_FLOAT	; wsptr
470
	add	rdi, byte 4*SIZEOF_JSAMPROW
471
	dec	rcx				; ctr
472
	jnz	near .rowloop
473
474
	pop	rbx
475
	uncollect_args
476
	mov	rsp,rbp		; rsp <- aligned rbp
477
	pop	rsp		; rsp <- original rbp
478
	pop	rbp
479
	ret
480
481
; For some reason, the OS X linker does not honor the request to align the
482
; segment unless we do this.
483
	align	16
(-)a/jpeg/simd/jiss2flt.asm (+498 lines)
Line     Link Here 
Line 0    Link Here 
1
;
2
; jiss2flt.asm - floating-point IDCT (SSE & SSE2)
3
;
4
; Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
5
;
6
; Based on
7
; x86 SIMD extension for IJG JPEG library
8
; Copyright (C) 1999-2006, MIYASAKA Masaru.
9
; For conditions of distribution and use, see copyright notice in jsimdext.inc
10
;
11
; This file should be assembled with NASM (Netwide Assembler),
12
; can *not* be assembled with Microsoft's MASM or any compatible
13
; assembler (including Borland's Turbo Assembler).
14
; NASM is available from http://nasm.sourceforge.net/ or
15
; http://sourceforge.net/project/showfiles.php?group_id=6208
16
;
17
; This file contains a floating-point implementation of the inverse DCT
18
; (Discrete Cosine Transform). The following code is based directly on
19
; the IJG's original jidctflt.c; see the jidctflt.c for more details.
20
;
21
; [TAB8]
22
23
%include "jsimdext.inc"
24
%include "jdct.inc"
25
26
; --------------------------------------------------------------------------
27
28
%macro	unpcklps2 2	; %1=(0 1 2 3) / %2=(4 5 6 7) => %1=(0 1 4 5)
29
	shufps	%1,%2,0x44
30
%endmacro
31
32
%macro	unpckhps2 2	; %1=(0 1 2 3) / %2=(4 5 6 7) => %1=(2 3 6 7)
33
	shufps	%1,%2,0xEE
34
%endmacro
35
36
; --------------------------------------------------------------------------
37
	SECTION	SEG_CONST
38
39
	alignz	16
40
	global	EXTN(jconst_idct_float_sse2)
41
42
EXTN(jconst_idct_float_sse2):
43
44
PD_1_414	times 4 dd  1.414213562373095048801689
45
PD_1_847	times 4 dd  1.847759065022573512256366
46
PD_1_082	times 4 dd  1.082392200292393968799446
47
PD_M2_613	times 4 dd -2.613125929752753055713286
48
PD_RNDINT_MAGIC	times 4 dd  100663296.0	; (float)(0x00C00000 << 3)
49
PB_CENTERJSAMP	times 16 db CENTERJSAMPLE
50
51
	alignz	16
52
53
; --------------------------------------------------------------------------
54
	SECTION	SEG_TEXT
55
	BITS	32
56
;
57
; Perform dequantization and inverse DCT on one block of coefficients.
58
;
59
; GLOBAL(void)
60
; jsimd_idct_float_sse2 (void * dct_table, JCOEFPTR coef_block,
61
;                        JSAMPARRAY output_buf, JDIMENSION output_col)
62
;
63
64
%define dct_table(b)	(b)+8			; void * dct_table
65
%define coef_block(b)	(b)+12		; JCOEFPTR coef_block
66
%define output_buf(b)	(b)+16		; JSAMPARRAY output_buf
67
%define output_col(b)	(b)+20		; JDIMENSION output_col
68
69
%define original_ebp	ebp+0
70
%define wk(i)		ebp-(WK_NUM-(i))*SIZEOF_XMMWORD	; xmmword wk[WK_NUM]
71
%define WK_NUM		2
72
%define workspace	wk(0)-DCTSIZE2*SIZEOF_FAST_FLOAT
73
					; FAST_FLOAT workspace[DCTSIZE2]
74
75
	align	16
76
	global	EXTN(jsimd_idct_float_sse2)
77
78
EXTN(jsimd_idct_float_sse2):
79
	push	ebp
80
	mov	eax,esp				; eax = original ebp
81
	sub	esp, byte 4
82
	and	esp, byte (-SIZEOF_XMMWORD)	; align to 128 bits
83
	mov	[esp],eax
84
	mov	ebp,esp				; ebp = aligned ebp
85
	lea	esp, [workspace]
86
	push	ebx
87
;	push	ecx		; need not be preserved
88
;	push	edx		; need not be preserved
89
	push	esi
90
	push	edi
91
92
	get_GOT	ebx		; get GOT address
93
94
	; ---- Pass 1: process columns from input, store into work array.
95
96
;	mov	eax, [original_ebp]
97
	mov	edx, POINTER [dct_table(eax)]	; quantptr
98
	mov	esi, JCOEFPTR [coef_block(eax)]		; inptr
99
	lea	edi, [workspace]			; FAST_FLOAT * wsptr
100
	mov	ecx, DCTSIZE/4				; ctr
101
	alignx	16,7
102
.columnloop:
103
%ifndef NO_ZERO_COLUMN_TEST_FLOAT_SSE
104
	mov	eax, DWORD [DWBLOCK(1,0,esi,SIZEOF_JCOEF)]
105
	or	eax, DWORD [DWBLOCK(2,0,esi,SIZEOF_JCOEF)]
106
	jnz	near .columnDCT
107
108
	movq	xmm1, XMM_MMWORD [MMBLOCK(1,0,esi,SIZEOF_JCOEF)]
109
	movq	xmm2, XMM_MMWORD [MMBLOCK(2,0,esi,SIZEOF_JCOEF)]
110
	movq	xmm3, XMM_MMWORD [MMBLOCK(3,0,esi,SIZEOF_JCOEF)]
111
	movq	xmm4, XMM_MMWORD [MMBLOCK(4,0,esi,SIZEOF_JCOEF)]
112
	movq	xmm5, XMM_MMWORD [MMBLOCK(5,0,esi,SIZEOF_JCOEF)]
113
	movq	xmm6, XMM_MMWORD [MMBLOCK(6,0,esi,SIZEOF_JCOEF)]
114
	movq	xmm7, XMM_MMWORD [MMBLOCK(7,0,esi,SIZEOF_JCOEF)]
115
	por	xmm1,xmm2
116
	por	xmm3,xmm4
117
	por	xmm5,xmm6
118
	por	xmm1,xmm3
119
	por	xmm5,xmm7
120
	por	xmm1,xmm5
121
	packsswb xmm1,xmm1
122
	movd	eax,xmm1
123
	test	eax,eax
124
	jnz	short .columnDCT
125
126
	; -- AC terms all zero
127
128
	movq      xmm0, XMM_MMWORD [MMBLOCK(0,0,esi,SIZEOF_JCOEF)]
129
130
	punpcklwd xmm0,xmm0		; xmm0=(00 00 01 01 02 02 03 03)
131
	psrad     xmm0,(DWORD_BIT-WORD_BIT)	; xmm0=in0=(00 01 02 03)
132
	cvtdq2ps  xmm0,xmm0			; xmm0=in0=(00 01 02 03)
133
134
	mulps	xmm0, XMMWORD [XMMBLOCK(0,0,edx,SIZEOF_FLOAT_MULT_TYPE)]
135
136
	movaps	xmm1,xmm0
137
	movaps	xmm2,xmm0
138
	movaps	xmm3,xmm0
139
140
	shufps	xmm0,xmm0,0x00			; xmm0=(00 00 00 00)
141
	shufps	xmm1,xmm1,0x55			; xmm1=(01 01 01 01)
142
	shufps	xmm2,xmm2,0xAA			; xmm2=(02 02 02 02)
143
	shufps	xmm3,xmm3,0xFF			; xmm3=(03 03 03 03)
144
145
	movaps	XMMWORD [XMMBLOCK(0,0,edi,SIZEOF_FAST_FLOAT)], xmm0
146
	movaps	XMMWORD [XMMBLOCK(0,1,edi,SIZEOF_FAST_FLOAT)], xmm0
147
	movaps	XMMWORD [XMMBLOCK(1,0,edi,SIZEOF_FAST_FLOAT)], xmm1
148
	movaps	XMMWORD [XMMBLOCK(1,1,edi,SIZEOF_FAST_FLOAT)], xmm1
149
	movaps	XMMWORD [XMMBLOCK(2,0,edi,SIZEOF_FAST_FLOAT)], xmm2
150
	movaps	XMMWORD [XMMBLOCK(2,1,edi,SIZEOF_FAST_FLOAT)], xmm2
151
	movaps	XMMWORD [XMMBLOCK(3,0,edi,SIZEOF_FAST_FLOAT)], xmm3
152
	movaps	XMMWORD [XMMBLOCK(3,1,edi,SIZEOF_FAST_FLOAT)], xmm3
153
	jmp	near .nextcolumn
154
	alignx	16,7
155
%endif
156
.columnDCT:
157
158
	; -- Even part
159
160
	movq      xmm0, XMM_MMWORD [MMBLOCK(0,0,esi,SIZEOF_JCOEF)]
161
	movq      xmm1, XMM_MMWORD [MMBLOCK(2,0,esi,SIZEOF_JCOEF)]
162
	movq      xmm2, XMM_MMWORD [MMBLOCK(4,0,esi,SIZEOF_JCOEF)]
163
	movq      xmm3, XMM_MMWORD [MMBLOCK(6,0,esi,SIZEOF_JCOEF)]
164
165
	punpcklwd xmm0,xmm0		; xmm0=(00 00 01 01 02 02 03 03)
166
	punpcklwd xmm1,xmm1		; xmm1=(20 20 21 21 22 22 23 23)
167
	psrad     xmm0,(DWORD_BIT-WORD_BIT)	; xmm0=in0=(00 01 02 03)
168
	psrad     xmm1,(DWORD_BIT-WORD_BIT)	; xmm1=in2=(20 21 22 23)
169
	cvtdq2ps  xmm0,xmm0			; xmm0=in0=(00 01 02 03)
170
	cvtdq2ps  xmm1,xmm1			; xmm1=in2=(20 21 22 23)
171
172
	punpcklwd xmm2,xmm2		; xmm2=(40 40 41 41 42 42 43 43)
173
	punpcklwd xmm3,xmm3		; xmm3=(60 60 61 61 62 62 63 63)
174
	psrad     xmm2,(DWORD_BIT-WORD_BIT)	; xmm2=in4=(40 41 42 43)
175
	psrad     xmm3,(DWORD_BIT-WORD_BIT)	; xmm3=in6=(60 61 62 63)
176
	cvtdq2ps  xmm2,xmm2			; xmm2=in4=(40 41 42 43)
177
	cvtdq2ps  xmm3,xmm3			; xmm3=in6=(60 61 62 63)
178
179
	mulps     xmm0, XMMWORD [XMMBLOCK(0,0,edx,SIZEOF_FLOAT_MULT_TYPE)]
180
	mulps     xmm1, XMMWORD [XMMBLOCK(2,0,edx,SIZEOF_FLOAT_MULT_TYPE)]
181
	mulps     xmm2, XMMWORD [XMMBLOCK(4,0,edx,SIZEOF_FLOAT_MULT_TYPE)]
182
	mulps     xmm3, XMMWORD [XMMBLOCK(6,0,edx,SIZEOF_FLOAT_MULT_TYPE)]
183
184
	movaps	xmm4,xmm0
185
	movaps	xmm5,xmm1
186
	subps	xmm0,xmm2		; xmm0=tmp11
187
	subps	xmm1,xmm3
188
	addps	xmm4,xmm2		; xmm4=tmp10
189
	addps	xmm5,xmm3		; xmm5=tmp13
190
191
	mulps	xmm1,[GOTOFF(ebx,PD_1_414)]
192
	subps	xmm1,xmm5		; xmm1=tmp12
193
194
	movaps	xmm6,xmm4
195
	movaps	xmm7,xmm0
196
	subps	xmm4,xmm5		; xmm4=tmp3
197
	subps	xmm0,xmm1		; xmm0=tmp2
198
	addps	xmm6,xmm5		; xmm6=tmp0
199
	addps	xmm7,xmm1		; xmm7=tmp1
200
201
	movaps	XMMWORD [wk(1)], xmm4	; tmp3
202
	movaps	XMMWORD [wk(0)], xmm0	; tmp2
203
204
	; -- Odd part
205
206
	movq      xmm2, XMM_MMWORD [MMBLOCK(1,0,esi,SIZEOF_JCOEF)]
207
	movq      xmm3, XMM_MMWORD [MMBLOCK(3,0,esi,SIZEOF_JCOEF)]
208
	movq      xmm5, XMM_MMWORD [MMBLOCK(5,0,esi,SIZEOF_JCOEF)]
209
	movq      xmm1, XMM_MMWORD [MMBLOCK(7,0,esi,SIZEOF_JCOEF)]
210
211
	punpcklwd xmm2,xmm2		; xmm2=(10 10 11 11 12 12 13 13)
212
	punpcklwd xmm3,xmm3		; xmm3=(30 30 31 31 32 32 33 33)
213
	psrad     xmm2,(DWORD_BIT-WORD_BIT)	; xmm2=in1=(10 11 12 13)
214
	psrad     xmm3,(DWORD_BIT-WORD_BIT)	; xmm3=in3=(30 31 32 33)
215
	cvtdq2ps  xmm2,xmm2			; xmm2=in1=(10 11 12 13)
216
	cvtdq2ps  xmm3,xmm3			; xmm3=in3=(30 31 32 33)
217
218
	punpcklwd xmm5,xmm5		; xmm5=(50 50 51 51 52 52 53 53)
219
	punpcklwd xmm1,xmm1		; xmm1=(70 70 71 71 72 72 73 73)
220
	psrad     xmm5,(DWORD_BIT-WORD_BIT)	; xmm5=in5=(50 51 52 53)
221
	psrad     xmm1,(DWORD_BIT-WORD_BIT)	; xmm1=in7=(70 71 72 73)
222
	cvtdq2ps  xmm5,xmm5			; xmm5=in5=(50 51 52 53)
223
	cvtdq2ps  xmm1,xmm1			; xmm1=in7=(70 71 72 73)
224
225
	mulps     xmm2, XMMWORD [XMMBLOCK(1,0,edx,SIZEOF_FLOAT_MULT_TYPE)]
226
	mulps     xmm3, XMMWORD [XMMBLOCK(3,0,edx,SIZEOF_FLOAT_MULT_TYPE)]
227
	mulps     xmm5, XMMWORD [XMMBLOCK(5,0,edx,SIZEOF_FLOAT_MULT_TYPE)]
228
	mulps     xmm1, XMMWORD [XMMBLOCK(7,0,edx,SIZEOF_FLOAT_MULT_TYPE)]
229
230
	movaps	xmm4,xmm2
231
	movaps	xmm0,xmm5
232
	addps	xmm2,xmm1		; xmm2=z11
233
	addps	xmm5,xmm3		; xmm5=z13
234
	subps	xmm4,xmm1		; xmm4=z12
235
	subps	xmm0,xmm3		; xmm0=z10
236
237
	movaps	xmm1,xmm2
238
	subps	xmm2,xmm5
239
	addps	xmm1,xmm5		; xmm1=tmp7
240
241
	mulps	xmm2,[GOTOFF(ebx,PD_1_414)]	; xmm2=tmp11
242
243
	movaps	xmm3,xmm0
244
	addps	xmm0,xmm4
245
	mulps	xmm0,[GOTOFF(ebx,PD_1_847)]	; xmm0=z5
246
	mulps	xmm3,[GOTOFF(ebx,PD_M2_613)]	; xmm3=(z10 * -2.613125930)
247
	mulps	xmm4,[GOTOFF(ebx,PD_1_082)]	; xmm4=(z12 * 1.082392200)
248
	addps	xmm3,xmm0		; xmm3=tmp12
249
	subps	xmm4,xmm0		; xmm4=tmp10
250
251
	; -- Final output stage
252
253
	subps	xmm3,xmm1		; xmm3=tmp6
254
	movaps	xmm5,xmm6
255
	movaps	xmm0,xmm7
256
	addps	xmm6,xmm1		; xmm6=data0=(00 01 02 03)
257
	addps	xmm7,xmm3		; xmm7=data1=(10 11 12 13)
258
	subps	xmm5,xmm1		; xmm5=data7=(70 71 72 73)
259
	subps	xmm0,xmm3		; xmm0=data6=(60 61 62 63)
260
	subps	xmm2,xmm3		; xmm2=tmp5
261
262
	movaps    xmm1,xmm6		; transpose coefficients(phase 1)
263
	unpcklps  xmm6,xmm7		; xmm6=(00 10 01 11)
264
	unpckhps  xmm1,xmm7		; xmm1=(02 12 03 13)
265
	movaps    xmm3,xmm0		; transpose coefficients(phase 1)
266
	unpcklps  xmm0,xmm5		; xmm0=(60 70 61 71)
267
	unpckhps  xmm3,xmm5		; xmm3=(62 72 63 73)
268
269
	movaps	xmm7, XMMWORD [wk(0)]	; xmm7=tmp2
270
	movaps	xmm5, XMMWORD [wk(1)]	; xmm5=tmp3
271
272
	movaps	XMMWORD [wk(0)], xmm0	; wk(0)=(60 70 61 71)
273
	movaps	XMMWORD [wk(1)], xmm3	; wk(1)=(62 72 63 73)
274
275
	addps	xmm4,xmm2		; xmm4=tmp4
276
	movaps	xmm0,xmm7
277
	movaps	xmm3,xmm5
278
	addps	xmm7,xmm2		; xmm7=data2=(20 21 22 23)
279
	addps	xmm5,xmm4		; xmm5=data4=(40 41 42 43)
280
	subps	xmm0,xmm2		; xmm0=data5=(50 51 52 53)
281
	subps	xmm3,xmm4		; xmm3=data3=(30 31 32 33)
282
283
	movaps    xmm2,xmm7		; transpose coefficients(phase 1)
284
	unpcklps  xmm7,xmm3		; xmm7=(20 30 21 31)
285
	unpckhps  xmm2,xmm3		; xmm2=(22 32 23 33)
286
	movaps    xmm4,xmm5		; transpose coefficients(phase 1)
287
	unpcklps  xmm5,xmm0		; xmm5=(40 50 41 51)
288
	unpckhps  xmm4,xmm0		; xmm4=(42 52 43 53)
289
290
	movaps    xmm3,xmm6		; transpose coefficients(phase 2)
291
	unpcklps2 xmm6,xmm7		; xmm6=(00 10 20 30)
292
	unpckhps2 xmm3,xmm7		; xmm3=(01 11 21 31)
293
	movaps    xmm0,xmm1		; transpose coefficients(phase 2)
294
	unpcklps2 xmm1,xmm2		; xmm1=(02 12 22 32)
295
	unpckhps2 xmm0,xmm2		; xmm0=(03 13 23 33)
296
297
	movaps	xmm7, XMMWORD [wk(0)]	; xmm7=(60 70 61 71)
298
	movaps	xmm2, XMMWORD [wk(1)]	; xmm2=(62 72 63 73)
299
300
	movaps	XMMWORD [XMMBLOCK(0,0,edi,SIZEOF_FAST_FLOAT)], xmm6
301
	movaps	XMMWORD [XMMBLOCK(1,0,edi,SIZEOF_FAST_FLOAT)], xmm3
302
	movaps	XMMWORD [XMMBLOCK(2,0,edi,SIZEOF_FAST_FLOAT)], xmm1
303
	movaps	XMMWORD [XMMBLOCK(3,0,edi,SIZEOF_FAST_FLOAT)], xmm0
304
305
	movaps    xmm6,xmm5		; transpose coefficients(phase 2)
306
	unpcklps2 xmm5,xmm7		; xmm5=(40 50 60 70)
307
	unpckhps2 xmm6,xmm7		; xmm6=(41 51 61 71)
308
	movaps    xmm3,xmm4		; transpose coefficients(phase 2)
309
	unpcklps2 xmm4,xmm2		; xmm4=(42 52 62 72)
310
	unpckhps2 xmm3,xmm2		; xmm3=(43 53 63 73)
311
312
	movaps	XMMWORD [XMMBLOCK(0,1,edi,SIZEOF_FAST_FLOAT)], xmm5
313
	movaps	XMMWORD [XMMBLOCK(1,1,edi,SIZEOF_FAST_FLOAT)], xmm6
314
	movaps	XMMWORD [XMMBLOCK(2,1,edi,SIZEOF_FAST_FLOAT)], xmm4
315
	movaps	XMMWORD [XMMBLOCK(3,1,edi,SIZEOF_FAST_FLOAT)], xmm3
316
317
.nextcolumn:
318
	add	esi, byte 4*SIZEOF_JCOEF		; coef_block
319
	add	edx, byte 4*SIZEOF_FLOAT_MULT_TYPE	; quantptr
320
	add	edi,      4*DCTSIZE*SIZEOF_FAST_FLOAT	; wsptr
321
	dec	ecx					; ctr
322
	jnz	near .columnloop
323
324
	; -- Prefetch the next coefficient block
325
326
	prefetchnta [esi + (DCTSIZE2-8)*SIZEOF_JCOEF + 0*32]
327
	prefetchnta [esi + (DCTSIZE2-8)*SIZEOF_JCOEF + 1*32]
328
	prefetchnta [esi + (DCTSIZE2-8)*SIZEOF_JCOEF + 2*32]
329
	prefetchnta [esi + (DCTSIZE2-8)*SIZEOF_JCOEF + 3*32]
330
331
	; ---- Pass 2: process rows from work array, store into output array.
332
333
	mov	eax, [original_ebp]
334
	lea	esi, [workspace]			; FAST_FLOAT * wsptr
335
	mov	edi, JSAMPARRAY [output_buf(eax)]	; (JSAMPROW *)
336
	mov	eax, JDIMENSION [output_col(eax)]
337
	mov	ecx, DCTSIZE/4				; ctr
338
	alignx	16,7
339
.rowloop:
340
341
	; -- Even part
342
343
	movaps	xmm0, XMMWORD [XMMBLOCK(0,0,esi,SIZEOF_FAST_FLOAT)]
344
	movaps	xmm1, XMMWORD [XMMBLOCK(2,0,esi,SIZEOF_FAST_FLOAT)]
345
	movaps	xmm2, XMMWORD [XMMBLOCK(4,0,esi,SIZEOF_FAST_FLOAT)]
346
	movaps	xmm3, XMMWORD [XMMBLOCK(6,0,esi,SIZEOF_FAST_FLOAT)]
347
348
	movaps	xmm4,xmm0
349
	movaps	xmm5,xmm1
350
	subps	xmm0,xmm2		; xmm0=tmp11
351
	subps	xmm1,xmm3
352
	addps	xmm4,xmm2		; xmm4=tmp10
353
	addps	xmm5,xmm3		; xmm5=tmp13
354
355
	mulps	xmm1,[GOTOFF(ebx,PD_1_414)]
356
	subps	xmm1,xmm5		; xmm1=tmp12
357
358
	movaps	xmm6,xmm4
359
	movaps	xmm7,xmm0
360
	subps	xmm4,xmm5		; xmm4=tmp3
361
	subps	xmm0,xmm1		; xmm0=tmp2
362
	addps	xmm6,xmm5		; xmm6=tmp0
363
	addps	xmm7,xmm1		; xmm7=tmp1
364
365
	movaps	XMMWORD [wk(1)], xmm4	; tmp3
366
	movaps	XMMWORD [wk(0)], xmm0	; tmp2
367
368
	; -- Odd part
369
370
	movaps	xmm2, XMMWORD [XMMBLOCK(1,0,esi,SIZEOF_FAST_FLOAT)]
371
	movaps	xmm3, XMMWORD [XMMBLOCK(3,0,esi,SIZEOF_FAST_FLOAT)]
372
	movaps	xmm5, XMMWORD [XMMBLOCK(5,0,esi,SIZEOF_FAST_FLOAT)]
373
	movaps	xmm1, XMMWORD [XMMBLOCK(7,0,esi,SIZEOF_FAST_FLOAT)]
374
375
	movaps	xmm4,xmm2
376
	movaps	xmm0,xmm5
377
	addps	xmm2,xmm1		; xmm2=z11
378
	addps	xmm5,xmm3		; xmm5=z13
379
	subps	xmm4,xmm1		; xmm4=z12
380
	subps	xmm0,xmm3		; xmm0=z10
381
382
	movaps	xmm1,xmm2
383
	subps	xmm2,xmm5
384
	addps	xmm1,xmm5		; xmm1=tmp7
385
386
	mulps	xmm2,[GOTOFF(ebx,PD_1_414)]	; xmm2=tmp11
387
388
	movaps	xmm3,xmm0
389
	addps	xmm0,xmm4
390
	mulps	xmm0,[GOTOFF(ebx,PD_1_847)]	; xmm0=z5
391
	mulps	xmm3,[GOTOFF(ebx,PD_M2_613)]	; xmm3=(z10 * -2.613125930)
392
	mulps	xmm4,[GOTOFF(ebx,PD_1_082)]	; xmm4=(z12 * 1.082392200)
393
	addps	xmm3,xmm0		; xmm3=tmp12
394
	subps	xmm4,xmm0		; xmm4=tmp10
395
396
	; -- Final output stage
397
398
	subps	xmm3,xmm1		; xmm3=tmp6
399
	movaps	xmm5,xmm6
400
	movaps	xmm0,xmm7
401
	addps	xmm6,xmm1		; xmm6=data0=(00 10 20 30)
402
	addps	xmm7,xmm3		; xmm7=data1=(01 11 21 31)
403
	subps	xmm5,xmm1		; xmm5=data7=(07 17 27 37)
404
	subps	xmm0,xmm3		; xmm0=data6=(06 16 26 36)
405
	subps	xmm2,xmm3		; xmm2=tmp5
406
407
	movaps	xmm1,[GOTOFF(ebx,PD_RNDINT_MAGIC)]	; xmm1=[PD_RNDINT_MAGIC]
408
	pcmpeqd	xmm3,xmm3
409
	psrld	xmm3,WORD_BIT		; xmm3={0xFFFF 0x0000 0xFFFF 0x0000 ..}
410
411
	addps	xmm6,xmm1	; xmm6=roundint(data0/8)=(00 ** 10 ** 20 ** 30 **)
412
	addps	xmm7,xmm1	; xmm7=roundint(data1/8)=(01 ** 11 ** 21 ** 31 **)
413
	addps	xmm0,xmm1	; xmm0=roundint(data6/8)=(06 ** 16 ** 26 ** 36 **)
414
	addps	xmm5,xmm1	; xmm5=roundint(data7/8)=(07 ** 17 ** 27 ** 37 **)
415
416
	pand	xmm6,xmm3		; xmm6=(00 -- 10 -- 20 -- 30 --)
417
	pslld	xmm7,WORD_BIT		; xmm7=(-- 01 -- 11 -- 21 -- 31)
418
	pand	xmm0,xmm3		; xmm0=(06 -- 16 -- 26 -- 36 --)
419
	pslld	xmm5,WORD_BIT		; xmm5=(-- 07 -- 17 -- 27 -- 37)
420
	por	xmm6,xmm7		; xmm6=(00 01 10 11 20 21 30 31)
421
	por	xmm0,xmm5		; xmm0=(06 07 16 17 26 27 36 37)
422
423
	movaps	xmm1, XMMWORD [wk(0)]	; xmm1=tmp2
424
	movaps	xmm3, XMMWORD [wk(1)]	; xmm3=tmp3
425
426
	addps	xmm4,xmm2		; xmm4=tmp4
427
	movaps	xmm7,xmm1
428
	movaps	xmm5,xmm3
429
	addps	xmm1,xmm2		; xmm1=data2=(02 12 22 32)
430
	addps	xmm3,xmm4		; xmm3=data4=(04 14 24 34)
431
	subps	xmm7,xmm2		; xmm7=data5=(05 15 25 35)
432
	subps	xmm5,xmm4		; xmm5=data3=(03 13 23 33)
433
434
	movaps	xmm2,[GOTOFF(ebx,PD_RNDINT_MAGIC)]	; xmm2=[PD_RNDINT_MAGIC]
435
	pcmpeqd	xmm4,xmm4
436
	psrld	xmm4,WORD_BIT		; xmm4={0xFFFF 0x0000 0xFFFF 0x0000 ..}
437
438
	addps	xmm3,xmm2	; xmm3=roundint(data4/8)=(04 ** 14 ** 24 ** 34 **)
439
	addps	xmm7,xmm2	; xmm7=roundint(data5/8)=(05 ** 15 ** 25 ** 35 **)
440
	addps	xmm1,xmm2	; xmm1=roundint(data2/8)=(02 ** 12 ** 22 ** 32 **)
441
	addps	xmm5,xmm2	; xmm5=roundint(data3/8)=(03 ** 13 ** 23 ** 33 **)
442
443
	pand	xmm3,xmm4		; xmm3=(04 -- 14 -- 24 -- 34 --)
444
	pslld	xmm7,WORD_BIT		; xmm7=(-- 05 -- 15 -- 25 -- 35)
445
	pand	xmm1,xmm4		; xmm1=(02 -- 12 -- 22 -- 32 --)
446
	pslld	xmm5,WORD_BIT		; xmm5=(-- 03 -- 13 -- 23 -- 33)
447
	por	xmm3,xmm7		; xmm3=(04 05 14 15 24 25 34 35)
448
	por	xmm1,xmm5		; xmm1=(02 03 12 13 22 23 32 33)
449
450
	movdqa    xmm2,[GOTOFF(ebx,PB_CENTERJSAMP)]	; xmm2=[PB_CENTERJSAMP]
451
452
	packsswb  xmm6,xmm3	; xmm6=(00 01 10 11 20 21 30 31 04 05 14 15 24 25 34 35)
453
	packsswb  xmm1,xmm0	; xmm1=(02 03 12 13 22 23 32 33 06 07 16 17 26 27 36 37)
454
	paddb     xmm6,xmm2
455
	paddb     xmm1,xmm2
456
457
	movdqa    xmm4,xmm6	; transpose coefficients(phase 2)
458
	punpcklwd xmm6,xmm1	; xmm6=(00 01 02 03 10 11 12 13 20 21 22 23 30 31 32 33)
459
	punpckhwd xmm4,xmm1	; xmm4=(04 05 06 07 14 15 16 17 24 25 26 27 34 35 36 37)
460
461
	movdqa    xmm7,xmm6	; transpose coefficients(phase 3)
462
	punpckldq xmm6,xmm4	; xmm6=(00 01 02 03 04 05 06 07 10 11 12 13 14 15 16 17)
463
	punpckhdq xmm7,xmm4	; xmm7=(20 21 22 23 24 25 26 27 30 31 32 33 34 35 36 37)
464
465
	pshufd	xmm5,xmm6,0x4E	; xmm5=(10 11 12 13 14 15 16 17 00 01 02 03 04 05 06 07)
466
	pshufd	xmm3,xmm7,0x4E	; xmm3=(30 31 32 33 34 35 36 37 20 21 22 23 24 25 26 27)
467
468
	pushpic	ebx			; save GOT address
469
470
	mov	edx, JSAMPROW [edi+0*SIZEOF_JSAMPROW]
471
	mov	ebx, JSAMPROW [edi+2*SIZEOF_JSAMPROW]
472
	movq	XMM_MMWORD [edx+eax*SIZEOF_JSAMPLE], xmm6
473
	movq	XMM_MMWORD [ebx+eax*SIZEOF_JSAMPLE], xmm7
474
	mov	edx, JSAMPROW [edi+1*SIZEOF_JSAMPROW]
475
	mov	ebx, JSAMPROW [edi+3*SIZEOF_JSAMPROW]
476
	movq	XMM_MMWORD [edx+eax*SIZEOF_JSAMPLE], xmm5
477
	movq	XMM_MMWORD [ebx+eax*SIZEOF_JSAMPLE], xmm3
478
479
	poppic	ebx			; restore GOT address
480
481
	add	esi, byte 4*SIZEOF_FAST_FLOAT	; wsptr
482
	add	edi, byte 4*SIZEOF_JSAMPROW
483
	dec	ecx				; ctr
484
	jnz	near .rowloop
485
486
	pop	edi
487
	pop	esi
488
;	pop	edx		; need not be preserved
489
;	pop	ecx		; need not be preserved
490
	pop	ebx
491
	mov	esp,ebp		; esp <- aligned ebp
492
	pop	esp		; esp <- original ebp
493
	pop	ebp
494
	ret
495
496
; For some reason, the OS X linker does not honor the request to align the
497
; segment unless we do this.
498
	align	16
(-)a/jpeg/simd/jiss2fst-64.asm (+492 lines)
Line     Link Here 
Line 0    Link Here 
1
;
2
; jiss2fst-64.asm - fast integer IDCT (64-bit SSE2)
3
;
4
; Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
5
; Copyright 2009 D. R. Commander
6
;
7
; Based on
8
; x86 SIMD extension for IJG JPEG library
9
; Copyright (C) 1999-2006, MIYASAKA Masaru.
10
; For conditions of distribution and use, see copyright notice in jsimdext.inc
11
;
12
; This file should be assembled with NASM (Netwide Assembler),
13
; can *not* be assembled with Microsoft's MASM or any compatible
14
; assembler (including Borland's Turbo Assembler).
15
; NASM is available from http://nasm.sourceforge.net/ or
16
; http://sourceforge.net/projecpt/showfiles.php?group_id=6208
17
;
18
; This file contains a fast, not so accurate integer implementation of
19
; the inverse DCT (Discrete Cosine Transform). The following code is
20
; based directly on the IJG's original jidctfst.c; see the jidctfst.c
21
; for more details.
22
;
23
; [TAB8]
24
25
%include "jsimdext.inc"
26
%include "jdct.inc"
27
28
; --------------------------------------------------------------------------
29
30
%define CONST_BITS	8	; 14 is also OK.
31
%define PASS1_BITS	2
32
33
%if IFAST_SCALE_BITS != PASS1_BITS
34
%error "'IFAST_SCALE_BITS' must be equal to 'PASS1_BITS'."
35
%endif
36
37
%if CONST_BITS == 8
38
F_1_082	equ	277		; FIX(1.082392200)
39
F_1_414	equ	362		; FIX(1.414213562)
40
F_1_847	equ	473		; FIX(1.847759065)
41
F_2_613	equ	669		; FIX(2.613125930)
42
F_1_613	equ	(F_2_613 - 256)	; FIX(2.613125930) - FIX(1)
43
%else
44
; NASM cannot do compile-time arithmetic on floating-point constants.
45
%define	DESCALE(x,n)  (((x)+(1<<((n)-1)))>>(n))
46
F_1_082	equ	DESCALE(1162209775,30-CONST_BITS)	; FIX(1.082392200)
47
F_1_414	equ	DESCALE(1518500249,30-CONST_BITS)	; FIX(1.414213562)
48
F_1_847	equ	DESCALE(1984016188,30-CONST_BITS)	; FIX(1.847759065)
49
F_2_613	equ	DESCALE(2805822602,30-CONST_BITS)	; FIX(2.613125930)
50
F_1_613	equ	(F_2_613 - (1 << CONST_BITS))	; FIX(2.613125930) - FIX(1)
51
%endif
52
53
; --------------------------------------------------------------------------
54
	SECTION	SEG_CONST
55
56
; PRE_MULTIPLY_SCALE_BITS <= 2 (to avoid overflow)
57
; CONST_BITS + CONST_SHIFT + PRE_MULTIPLY_SCALE_BITS == 16 (for pmulhw)
58
59
%define PRE_MULTIPLY_SCALE_BITS   2
60
%define CONST_SHIFT     (16 - PRE_MULTIPLY_SCALE_BITS - CONST_BITS)
61
62
	alignz	16
63
	global	EXTN(jconst_idct_ifast_sse2)
64
65
EXTN(jconst_idct_ifast_sse2):
66
67
PW_F1414	times 8 dw  F_1_414 << CONST_SHIFT
68
PW_F1847	times 8 dw  F_1_847 << CONST_SHIFT
69
PW_MF1613	times 8 dw -F_1_613 << CONST_SHIFT
70
PW_F1082	times 8 dw  F_1_082 << CONST_SHIFT
71
PB_CENTERJSAMP	times 16 db CENTERJSAMPLE
72
73
	alignz	16
74
75
; --------------------------------------------------------------------------
76
	SECTION	SEG_TEXT
77
	BITS	64
78
;
79
; Perform dequantization and inverse DCT on one block of coefficients.
80
;
81
; GLOBAL(void)
82
; jsimd_idct_ifast_sse2 (void * dct_table, JCOEFPTR coef_block,
83
;                       JSAMPARRAY output_buf, JDIMENSION output_col)
84
;
85
86
; r10 = jpeg_component_info * compptr
87
; r11 = JCOEFPTR coef_block
88
; r12 = JSAMPARRAY output_buf
89
; r13 = JDIMENSION output_col
90
91
%define original_rbp	rbp+0
92
%define wk(i)		rbp-(WK_NUM-(i))*SIZEOF_XMMWORD	; xmmword wk[WK_NUM]
93
%define WK_NUM		2
94
95
	align	16
96
	global	EXTN(jsimd_idct_ifast_sse2)
97
98
EXTN(jsimd_idct_ifast_sse2):
99
	push	rbp
100
	mov	rax,rsp				; rax = original rbp
101
	sub	rsp, byte 4
102
	and	rsp, byte (-SIZEOF_XMMWORD)	; align to 128 bits
103
	mov	[rsp],rax
104
	mov	rbp,rsp				; rbp = aligned rbp
105
	lea	rsp, [wk(0)]
106
	collect_args
107
108
	; ---- Pass 1: process columns from input.
109
110
	mov	rdx, r10	; quantptr
111
	mov	rsi, r11		; inptr
112
113
%ifndef NO_ZERO_COLUMN_TEST_IFAST_SSE2
114
	mov	eax, DWORD [DWBLOCK(1,0,rsi,SIZEOF_JCOEF)]
115
	or	eax, DWORD [DWBLOCK(2,0,rsi,SIZEOF_JCOEF)]
116
	jnz	near .columnDCT
117
118
	movdqa	xmm0, XMMWORD [XMMBLOCK(1,0,rsi,SIZEOF_JCOEF)]
119
	movdqa	xmm1, XMMWORD [XMMBLOCK(2,0,rsi,SIZEOF_JCOEF)]
120
	por	xmm0, XMMWORD [XMMBLOCK(3,0,rsi,SIZEOF_JCOEF)]
121
	por	xmm1, XMMWORD [XMMBLOCK(4,0,rsi,SIZEOF_JCOEF)]
122
	por	xmm0, XMMWORD [XMMBLOCK(5,0,rsi,SIZEOF_JCOEF)]
123
	por	xmm1, XMMWORD [XMMBLOCK(6,0,rsi,SIZEOF_JCOEF)]
124
	por	xmm0, XMMWORD [XMMBLOCK(7,0,rsi,SIZEOF_JCOEF)]
125
	por	xmm1,xmm0
126
	packsswb xmm1,xmm1
127
	packsswb xmm1,xmm1
128
	movd	eax,xmm1
129
	test	rax,rax
130
	jnz	short .columnDCT
131
132
	; -- AC terms all zero
133
134
	movdqa	xmm0, XMMWORD [XMMBLOCK(0,0,rsi,SIZEOF_JCOEF)]
135
	pmullw	xmm0, XMMWORD [XMMBLOCK(0,0,rdx,SIZEOF_ISLOW_MULT_TYPE)]
136
137
	movdqa    xmm7,xmm0		; xmm0=in0=(00 01 02 03 04 05 06 07)
138
	punpcklwd xmm0,xmm0		; xmm0=(00 00 01 01 02 02 03 03)
139
	punpckhwd xmm7,xmm7		; xmm7=(04 04 05 05 06 06 07 07)
140
141
	pshufd	xmm6,xmm0,0x00		; xmm6=col0=(00 00 00 00 00 00 00 00)
142
	pshufd	xmm2,xmm0,0x55		; xmm2=col1=(01 01 01 01 01 01 01 01)
143
	pshufd	xmm5,xmm0,0xAA		; xmm5=col2=(02 02 02 02 02 02 02 02)
144
	pshufd	xmm0,xmm0,0xFF		; xmm0=col3=(03 03 03 03 03 03 03 03)
145
	pshufd	xmm1,xmm7,0x00		; xmm1=col4=(04 04 04 04 04 04 04 04)
146
	pshufd	xmm4,xmm7,0x55		; xmm4=col5=(05 05 05 05 05 05 05 05)
147
	pshufd	xmm3,xmm7,0xAA		; xmm3=col6=(06 06 06 06 06 06 06 06)
148
	pshufd	xmm7,xmm7,0xFF		; xmm7=col7=(07 07 07 07 07 07 07 07)
149
150
	movdqa	XMMWORD [wk(0)], xmm2	; wk(0)=col1
151
	movdqa	XMMWORD [wk(1)], xmm0	; wk(1)=col3
152
	jmp	near .column_end
153
%endif
154
.columnDCT:
155
156
	; -- Even part
157
158
	movdqa	xmm0, XMMWORD [XMMBLOCK(0,0,rsi,SIZEOF_JCOEF)]
159
	movdqa	xmm1, XMMWORD [XMMBLOCK(2,0,rsi,SIZEOF_JCOEF)]
160
	pmullw	xmm0, XMMWORD [XMMBLOCK(0,0,rdx,SIZEOF_IFAST_MULT_TYPE)]
161
	pmullw	xmm1, XMMWORD [XMMBLOCK(2,0,rdx,SIZEOF_IFAST_MULT_TYPE)]
162
	movdqa	xmm2, XMMWORD [XMMBLOCK(4,0,rsi,SIZEOF_JCOEF)]
163
	movdqa	xmm3, XMMWORD [XMMBLOCK(6,0,rsi,SIZEOF_JCOEF)]
164
	pmullw	xmm2, XMMWORD [XMMBLOCK(4,0,rdx,SIZEOF_IFAST_MULT_TYPE)]
165
	pmullw	xmm3, XMMWORD [XMMBLOCK(6,0,rdx,SIZEOF_IFAST_MULT_TYPE)]
166
167
	movdqa	xmm4,xmm0
168
	movdqa	xmm5,xmm1
169
	psubw	xmm0,xmm2		; xmm0=tmp11
170
	psubw	xmm1,xmm3
171
	paddw	xmm4,xmm2		; xmm4=tmp10
172
	paddw	xmm5,xmm3		; xmm5=tmp13
173
174
	psllw	xmm1,PRE_MULTIPLY_SCALE_BITS
175
	pmulhw	xmm1,[rel PW_F1414]
176
	psubw	xmm1,xmm5		; xmm1=tmp12
177
178
	movdqa	xmm6,xmm4
179
	movdqa	xmm7,xmm0
180
	psubw	xmm4,xmm5		; xmm4=tmp3
181
	psubw	xmm0,xmm1		; xmm0=tmp2
182
	paddw	xmm6,xmm5		; xmm6=tmp0
183
	paddw	xmm7,xmm1		; xmm7=tmp1
184
185
	movdqa	XMMWORD [wk(1)], xmm4	; wk(1)=tmp3
186
	movdqa	XMMWORD [wk(0)], xmm0	; wk(0)=tmp2
187
188
	; -- Odd part
189
190
	movdqa	xmm2, XMMWORD [XMMBLOCK(1,0,rsi,SIZEOF_JCOEF)]
191
	movdqa	xmm3, XMMWORD [XMMBLOCK(3,0,rsi,SIZEOF_JCOEF)]
192
	pmullw	xmm2, XMMWORD [XMMBLOCK(1,0,rdx,SIZEOF_IFAST_MULT_TYPE)]
193
	pmullw	xmm3, XMMWORD [XMMBLOCK(3,0,rdx,SIZEOF_IFAST_MULT_TYPE)]
194
	movdqa	xmm5, XMMWORD [XMMBLOCK(5,0,rsi,SIZEOF_JCOEF)]
195
	movdqa	xmm1, XMMWORD [XMMBLOCK(7,0,rsi,SIZEOF_JCOEF)]
196
	pmullw	xmm5, XMMWORD [XMMBLOCK(5,0,rdx,SIZEOF_IFAST_MULT_TYPE)]
197
	pmullw	xmm1, XMMWORD [XMMBLOCK(7,0,rdx,SIZEOF_IFAST_MULT_TYPE)]
198
199
	movdqa	xmm4,xmm2
200
	movdqa	xmm0,xmm5
201
	psubw	xmm2,xmm1		; xmm2=z12
202
	psubw	xmm5,xmm3		; xmm5=z10
203
	paddw	xmm4,xmm1		; xmm4=z11
204
	paddw	xmm0,xmm3		; xmm0=z13
205
206
	movdqa	xmm1,xmm5		; xmm1=z10(unscaled)
207
	psllw	xmm2,PRE_MULTIPLY_SCALE_BITS
208
	psllw	xmm5,PRE_MULTIPLY_SCALE_BITS
209
210
	movdqa	xmm3,xmm4
211
	psubw	xmm4,xmm0
212
	paddw	xmm3,xmm0		; xmm3=tmp7
213
214
	psllw	xmm4,PRE_MULTIPLY_SCALE_BITS
215
	pmulhw	xmm4,[rel PW_F1414]	; xmm4=tmp11
216
217
	; To avoid overflow...
218
	;
219
	; (Original)
220
	; tmp12 = -2.613125930 * z10 + z5;
221
	;
222
	; (This implementation)
223
	; tmp12 = (-1.613125930 - 1) * z10 + z5;
224
	;       = -1.613125930 * z10 - z10 + z5;
225
226
	movdqa	xmm0,xmm5
227
	paddw	xmm5,xmm2
228
	pmulhw	xmm5,[rel PW_F1847]	; xmm5=z5
229
	pmulhw	xmm0,[rel PW_MF1613]
230
	pmulhw	xmm2,[rel PW_F1082]
231
	psubw	xmm0,xmm1
232
	psubw	xmm2,xmm5		; xmm2=tmp10
233
	paddw	xmm0,xmm5		; xmm0=tmp12
234
235
	; -- Final output stage
236
237
	psubw	xmm0,xmm3		; xmm0=tmp6
238
	movdqa	xmm1,xmm6
239
	movdqa	xmm5,xmm7
240
	paddw	xmm6,xmm3		; xmm6=data0=(00 01 02 03 04 05 06 07)
241
	paddw	xmm7,xmm0		; xmm7=data1=(10 11 12 13 14 15 16 17)
242
	psubw	xmm1,xmm3		; xmm1=data7=(70 71 72 73 74 75 76 77)
243
	psubw	xmm5,xmm0		; xmm5=data6=(60 61 62 63 64 65 66 67)
244
	psubw	xmm4,xmm0		; xmm4=tmp5
245
246
	movdqa    xmm3,xmm6		; transpose coefficients(phase 1)
247
	punpcklwd xmm6,xmm7		; xmm6=(00 10 01 11 02 12 03 13)
248
	punpckhwd xmm3,xmm7		; xmm3=(04 14 05 15 06 16 07 17)
249
	movdqa    xmm0,xmm5		; transpose coefficients(phase 1)
250
	punpcklwd xmm5,xmm1		; xmm5=(60 70 61 71 62 72 63 73)
251
	punpckhwd xmm0,xmm1		; xmm0=(64 74 65 75 66 76 67 77)
252
253
	movdqa	xmm7, XMMWORD [wk(0)]	; xmm7=tmp2
254
	movdqa	xmm1, XMMWORD [wk(1)]	; xmm1=tmp3
255
256
	movdqa	XMMWORD [wk(0)], xmm5	; wk(0)=(60 70 61 71 62 72 63 73)
257
	movdqa	XMMWORD [wk(1)], xmm0	; wk(1)=(64 74 65 75 66 76 67 77)
258
259
	paddw	xmm2,xmm4		; xmm2=tmp4
260
	movdqa	xmm5,xmm7
261
	movdqa	xmm0,xmm1
262
	paddw	xmm7,xmm4		; xmm7=data2=(20 21 22 23 24 25 26 27)
263
	paddw	xmm1,xmm2		; xmm1=data4=(40 41 42 43 44 45 46 47)
264
	psubw	xmm5,xmm4		; xmm5=data5=(50 51 52 53 54 55 56 57)
265
	psubw	xmm0,xmm2		; xmm0=data3=(30 31 32 33 34 35 36 37)
266
267
	movdqa    xmm4,xmm7		; transpose coefficients(phase 1)
268
	punpcklwd xmm7,xmm0		; xmm7=(20 30 21 31 22 32 23 33)
269
	punpckhwd xmm4,xmm0		; xmm4=(24 34 25 35 26 36 27 37)
270
	movdqa    xmm2,xmm1		; transpose coefficients(phase 1)
271
	punpcklwd xmm1,xmm5		; xmm1=(40 50 41 51 42 52 43 53)
272
	punpckhwd xmm2,xmm5		; xmm2=(44 54 45 55 46 56 47 57)
273
274
	movdqa    xmm0,xmm3		; transpose coefficients(phase 2)
275
	punpckldq xmm3,xmm4		; xmm3=(04 14 24 34 05 15 25 35)
276
	punpckhdq xmm0,xmm4		; xmm0=(06 16 26 36 07 17 27 37)
277
	movdqa    xmm5,xmm6		; transpose coefficients(phase 2)
278
	punpckldq xmm6,xmm7		; xmm6=(00 10 20 30 01 11 21 31)
279
	punpckhdq xmm5,xmm7		; xmm5=(02 12 22 32 03 13 23 33)
280
281
	movdqa	xmm4, XMMWORD [wk(0)]	; xmm4=(60 70 61 71 62 72 63 73)
282
	movdqa	xmm7, XMMWORD [wk(1)]	; xmm7=(64 74 65 75 66 76 67 77)
283
284
	movdqa	XMMWORD [wk(0)], xmm3	; wk(0)=(04 14 24 34 05 15 25 35)
285
	movdqa	XMMWORD [wk(1)], xmm0	; wk(1)=(06 16 26 36 07 17 27 37)
286
287
	movdqa    xmm3,xmm1		; transpose coefficients(phase 2)
288
	punpckldq xmm1,xmm4		; xmm1=(40 50 60 70 41 51 61 71)
289
	punpckhdq xmm3,xmm4		; xmm3=(42 52 62 72 43 53 63 73)
290
	movdqa    xmm0,xmm2		; transpose coefficients(phase 2)
291
	punpckldq xmm2,xmm7		; xmm2=(44 54 64 74 45 55 65 75)
292
	punpckhdq xmm0,xmm7		; xmm0=(46 56 66 76 47 57 67 77)
293
294
	movdqa     xmm4,xmm6		; transpose coefficients(phase 3)
295
	punpcklqdq xmm6,xmm1		; xmm6=col0=(00 10 20 30 40 50 60 70)
296
	punpckhqdq xmm4,xmm1		; xmm4=col1=(01 11 21 31 41 51 61 71)
297
	movdqa     xmm7,xmm5		; transpose coefficients(phase 3)
298
	punpcklqdq xmm5,xmm3		; xmm5=col2=(02 12 22 32 42 52 62 72)
299
	punpckhqdq xmm7,xmm3		; xmm7=col3=(03 13 23 33 43 53 63 73)
300
301
	movdqa	xmm1, XMMWORD [wk(0)]	; xmm1=(04 14 24 34 05 15 25 35)
302
	movdqa	xmm3, XMMWORD [wk(1)]	; xmm3=(06 16 26 36 07 17 27 37)
303
304
	movdqa	XMMWORD [wk(0)], xmm4	; wk(0)=col1
305
	movdqa	XMMWORD [wk(1)], xmm7	; wk(1)=col3
306
307
	movdqa     xmm4,xmm1		; transpose coefficients(phase 3)
308
	punpcklqdq xmm1,xmm2		; xmm1=col4=(04 14 24 34 44 54 64 74)
309
	punpckhqdq xmm4,xmm2		; xmm4=col5=(05 15 25 35 45 55 65 75)
310
	movdqa     xmm7,xmm3		; transpose coefficients(phase 3)
311
	punpcklqdq xmm3,xmm0		; xmm3=col6=(06 16 26 36 46 56 66 76)
312
	punpckhqdq xmm7,xmm0		; xmm7=col7=(07 17 27 37 47 57 67 77)
313
.column_end:
314
315
	; -- Prefetch the next coefficient block
316
317
	prefetchnta [rsi + DCTSIZE2*SIZEOF_JCOEF + 0*32]
318
	prefetchnta [rsi + DCTSIZE2*SIZEOF_JCOEF + 1*32]
319
	prefetchnta [rsi + DCTSIZE2*SIZEOF_JCOEF + 2*32]
320
	prefetchnta [rsi + DCTSIZE2*SIZEOF_JCOEF + 3*32]
321
322
	; ---- Pass 2: process rows from work array, store into output array.
323
324
	mov	rax, [original_rbp]
325
	mov	rdi, r12	; (JSAMPROW *)
326
	mov	rax, r13
327
328
	; -- Even part
329
330
	; xmm6=col0, xmm5=col2, xmm1=col4, xmm3=col6
331
332
	movdqa	xmm2,xmm6
333
	movdqa	xmm0,xmm5
334
	psubw	xmm6,xmm1		; xmm6=tmp11
335
	psubw	xmm5,xmm3
336
	paddw	xmm2,xmm1		; xmm2=tmp10
337
	paddw	xmm0,xmm3		; xmm0=tmp13
338
339
	psllw	xmm5,PRE_MULTIPLY_SCALE_BITS
340
	pmulhw	xmm5,[rel PW_F1414]
341
	psubw	xmm5,xmm0		; xmm5=tmp12
342
343
	movdqa	xmm1,xmm2
344
	movdqa	xmm3,xmm6
345
	psubw	xmm2,xmm0		; xmm2=tmp3
346
	psubw	xmm6,xmm5		; xmm6=tmp2
347
	paddw	xmm1,xmm0		; xmm1=tmp0
348
	paddw	xmm3,xmm5		; xmm3=tmp1
349
350
	movdqa	xmm0, XMMWORD [wk(0)]	; xmm0=col1
351
	movdqa	xmm5, XMMWORD [wk(1)]	; xmm5=col3
352
353
	movdqa	XMMWORD [wk(0)], xmm2	; wk(0)=tmp3
354
	movdqa	XMMWORD [wk(1)], xmm6	; wk(1)=tmp2
355
356
	; -- Odd part
357
358
	; xmm0=col1, xmm5=col3, xmm4=col5, xmm7=col7
359
360
	movdqa	xmm2,xmm0
361
	movdqa	xmm6,xmm4
362
	psubw	xmm0,xmm7		; xmm0=z12
363
	psubw	xmm4,xmm5		; xmm4=z10
364
	paddw	xmm2,xmm7		; xmm2=z11
365
	paddw	xmm6,xmm5		; xmm6=z13
366
367
	movdqa	xmm7,xmm4		; xmm7=z10(unscaled)
368
	psllw	xmm0,PRE_MULTIPLY_SCALE_BITS
369
	psllw	xmm4,PRE_MULTIPLY_SCALE_BITS
370
371
	movdqa	xmm5,xmm2
372
	psubw	xmm2,xmm6
373
	paddw	xmm5,xmm6		; xmm5=tmp7
374
375
	psllw	xmm2,PRE_MULTIPLY_SCALE_BITS
376
	pmulhw	xmm2,[rel PW_F1414]	; xmm2=tmp11
377
378
	; To avoid overflow...
379
	;
380
	; (Original)
381
	; tmp12 = -2.613125930 * z10 + z5;
382
	;
383
	; (This implementation)
384
	; tmp12 = (-1.613125930 - 1) * z10 + z5;
385
	;       = -1.613125930 * z10 - z10 + z5;
386
387
	movdqa	xmm6,xmm4
388
	paddw	xmm4,xmm0
389
	pmulhw	xmm4,[rel PW_F1847]	; xmm4=z5
390
	pmulhw	xmm6,[rel PW_MF1613]
391
	pmulhw	xmm0,[rel PW_F1082]
392
	psubw	xmm6,xmm7
393
	psubw	xmm0,xmm4		; xmm0=tmp10
394
	paddw	xmm6,xmm4		; xmm6=tmp12
395
396
	; -- Final output stage
397
398
	psubw	xmm6,xmm5		; xmm6=tmp6
399
	movdqa	xmm7,xmm1
400
	movdqa	xmm4,xmm3
401
	paddw	xmm1,xmm5		; xmm1=data0=(00 10 20 30 40 50 60 70)
402
	paddw	xmm3,xmm6		; xmm3=data1=(01 11 21 31 41 51 61 71)
403
	psraw	xmm1,(PASS1_BITS+3)	; descale
404
	psraw	xmm3,(PASS1_BITS+3)	; descale
405
	psubw	xmm7,xmm5		; xmm7=data7=(07 17 27 37 47 57 67 77)
406
	psubw	xmm4,xmm6		; xmm4=data6=(06 16 26 36 46 56 66 76)
407
	psraw	xmm7,(PASS1_BITS+3)	; descale
408
	psraw	xmm4,(PASS1_BITS+3)	; descale
409
	psubw	xmm2,xmm6		; xmm2=tmp5
410
411
	packsswb  xmm1,xmm4	; xmm1=(00 10 20 30 40 50 60 70 06 16 26 36 46 56 66 76)
412
	packsswb  xmm3,xmm7	; xmm3=(01 11 21 31 41 51 61 71 07 17 27 37 47 57 67 77)
413
414
	movdqa	xmm5, XMMWORD [wk(1)]	; xmm5=tmp2
415
	movdqa	xmm6, XMMWORD [wk(0)]	; xmm6=tmp3
416
417
	paddw	xmm0,xmm2		; xmm0=tmp4
418
	movdqa	xmm4,xmm5
419
	movdqa	xmm7,xmm6
420
	paddw	xmm5,xmm2		; xmm5=data2=(02 12 22 32 42 52 62 72)
421
	paddw	xmm6,xmm0		; xmm6=data4=(04 14 24 34 44 54 64 74)
422
	psraw	xmm5,(PASS1_BITS+3)	; descale
423
	psraw	xmm6,(PASS1_BITS+3)	; descale
424
	psubw	xmm4,xmm2		; xmm4=data5=(05 15 25 35 45 55 65 75)
425
	psubw	xmm7,xmm0		; xmm7=data3=(03 13 23 33 43 53 63 73)
426
	psraw	xmm4,(PASS1_BITS+3)	; descale
427
	psraw	xmm7,(PASS1_BITS+3)	; descale
428
429
	movdqa    xmm2,[rel PB_CENTERJSAMP]	; xmm2=[rel PB_CENTERJSAMP]
430
431
	packsswb  xmm5,xmm6	; xmm5=(02 12 22 32 42 52 62 72 04 14 24 34 44 54 64 74)
432
	packsswb  xmm7,xmm4	; xmm7=(03 13 23 33 43 53 63 73 05 15 25 35 45 55 65 75)
433
434
	paddb     xmm1,xmm2
435
	paddb     xmm3,xmm2
436
	paddb     xmm5,xmm2
437
	paddb     xmm7,xmm2
438
439
	movdqa    xmm0,xmm1	; transpose coefficients(phase 1)
440
	punpcklbw xmm1,xmm3	; xmm1=(00 01 10 11 20 21 30 31 40 41 50 51 60 61 70 71)
441
	punpckhbw xmm0,xmm3	; xmm0=(06 07 16 17 26 27 36 37 46 47 56 57 66 67 76 77)
442
	movdqa    xmm6,xmm5	; transpose coefficients(phase 1)
443
	punpcklbw xmm5,xmm7	; xmm5=(02 03 12 13 22 23 32 33 42 43 52 53 62 63 72 73)
444
	punpckhbw xmm6,xmm7	; xmm6=(04 05 14 15 24 25 34 35 44 45 54 55 64 65 74 75)
445
446
	movdqa    xmm4,xmm1	; transpose coefficients(phase 2)
447
	punpcklwd xmm1,xmm5	; xmm1=(00 01 02 03 10 11 12 13 20 21 22 23 30 31 32 33)
448
	punpckhwd xmm4,xmm5	; xmm4=(40 41 42 43 50 51 52 53 60 61 62 63 70 71 72 73)
449
	movdqa    xmm2,xmm6	; transpose coefficients(phase 2)
450
	punpcklwd xmm6,xmm0	; xmm6=(04 05 06 07 14 15 16 17 24 25 26 27 34 35 36 37)
451
	punpckhwd xmm2,xmm0	; xmm2=(44 45 46 47 54 55 56 57 64 65 66 67 74 75 76 77)
452
453
	movdqa    xmm3,xmm1	; transpose coefficients(phase 3)
454
	punpckldq xmm1,xmm6	; xmm1=(00 01 02 03 04 05 06 07 10 11 12 13 14 15 16 17)
455
	punpckhdq xmm3,xmm6	; xmm3=(20 21 22 23 24 25 26 27 30 31 32 33 34 35 36 37)
456
	movdqa    xmm7,xmm4	; transpose coefficients(phase 3)
457
	punpckldq xmm4,xmm2	; xmm4=(40 41 42 43 44 45 46 47 50 51 52 53 54 55 56 57)
458
	punpckhdq xmm7,xmm2	; xmm7=(60 61 62 63 64 65 66 67 70 71 72 73 74 75 76 77)
459
460
	pshufd	xmm5,xmm1,0x4E	; xmm5=(10 11 12 13 14 15 16 17 00 01 02 03 04 05 06 07)
461
	pshufd	xmm0,xmm3,0x4E	; xmm0=(30 31 32 33 34 35 36 37 20 21 22 23 24 25 26 27)
462
	pshufd	xmm6,xmm4,0x4E	; xmm6=(50 51 52 53 54 55 56 57 40 41 42 43 44 45 46 47)
463
	pshufd	xmm2,xmm7,0x4E	; xmm2=(70 71 72 73 74 75 76 77 60 61 62 63 64 65 66 67)
464
465
	mov	rdx, JSAMPROW [rdi+0*SIZEOF_JSAMPROW]
466
	mov	rsi, JSAMPROW [rdi+2*SIZEOF_JSAMPROW]
467
	movq	XMM_MMWORD [rdx+rax*SIZEOF_JSAMPLE], xmm1
468
	movq	XMM_MMWORD [rsi+rax*SIZEOF_JSAMPLE], xmm3
469
	mov	rdx, JSAMPROW [rdi+4*SIZEOF_JSAMPROW]
470
	mov	rsi, JSAMPROW [rdi+6*SIZEOF_JSAMPROW]
471
	movq	XMM_MMWORD [rdx+rax*SIZEOF_JSAMPLE], xmm4
472
	movq	XMM_MMWORD [rsi+rax*SIZEOF_JSAMPLE], xmm7
473
474
	mov	rdx, JSAMPROW [rdi+1*SIZEOF_JSAMPROW]
475
	mov	rsi, JSAMPROW [rdi+3*SIZEOF_JSAMPROW]
476
	movq	XMM_MMWORD [rdx+rax*SIZEOF_JSAMPLE], xmm5
477
	movq	XMM_MMWORD [rsi+rax*SIZEOF_JSAMPLE], xmm0
478
	mov	rdx, JSAMPROW [rdi+5*SIZEOF_JSAMPROW]
479
	mov	rsi, JSAMPROW [rdi+7*SIZEOF_JSAMPROW]
480
	movq	XMM_MMWORD [rdx+rax*SIZEOF_JSAMPLE], xmm6
481
	movq	XMM_MMWORD [rsi+rax*SIZEOF_JSAMPLE], xmm2
482
483
	uncollect_args
484
	mov	rsp,rbp		; rsp <- aligned rbp
485
	pop	rsp		; rsp <- original rbp
486
	pop	rbp
487
	ret
488
	ret
489
490
; For some reason, the OS X linker does not honor the request to align the
491
; segment unless we do this.
492
	align	16
(-)a/jpeg/simd/jiss2fst.asm (+502 lines)
Line     Link Here 
Line 0    Link Here 
1
;
2
; jiss2fst.asm - fast integer IDCT (SSE2)
3
;
4
; Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
5
;
6
; Based on
7
; x86 SIMD extension for IJG JPEG library
8
; Copyright (C) 1999-2006, MIYASAKA Masaru.
9
; For conditions of distribution and use, see copyright notice in jsimdext.inc
10
;
11
; This file should be assembled with NASM (Netwide Assembler),
12
; can *not* be assembled with Microsoft's MASM or any compatible
13
; assembler (including Borland's Turbo Assembler).
14
; NASM is available from http://nasm.sourceforge.net/ or
15
; http://sourceforge.net/project/showfiles.php?group_id=6208
16
;
17
; This file contains a fast, not so accurate integer implementation of
18
; the inverse DCT (Discrete Cosine Transform). The following code is
19
; based directly on the IJG's original jidctfst.c; see the jidctfst.c
20
; for more details.
21
;
22
; [TAB8]
23
24
%include "jsimdext.inc"
25
%include "jdct.inc"
26
27
; --------------------------------------------------------------------------
28
29
%define CONST_BITS	8	; 14 is also OK.
30
%define PASS1_BITS	2
31
32
%if IFAST_SCALE_BITS != PASS1_BITS
33
%error "'IFAST_SCALE_BITS' must be equal to 'PASS1_BITS'."
34
%endif
35
36
%if CONST_BITS == 8
37
F_1_082	equ	277		; FIX(1.082392200)
38
F_1_414	equ	362		; FIX(1.414213562)
39
F_1_847	equ	473		; FIX(1.847759065)
40
F_2_613	equ	669		; FIX(2.613125930)
41
F_1_613	equ	(F_2_613 - 256)	; FIX(2.613125930) - FIX(1)
42
%else
43
; NASM cannot do compile-time arithmetic on floating-point constants.
44
%define	DESCALE(x,n)  (((x)+(1<<((n)-1)))>>(n))
45
F_1_082	equ	DESCALE(1162209775,30-CONST_BITS)	; FIX(1.082392200)
46
F_1_414	equ	DESCALE(1518500249,30-CONST_BITS)	; FIX(1.414213562)
47
F_1_847	equ	DESCALE(1984016188,30-CONST_BITS)	; FIX(1.847759065)
48
F_2_613	equ	DESCALE(2805822602,30-CONST_BITS)	; FIX(2.613125930)
49
F_1_613	equ	(F_2_613 - (1 << CONST_BITS))	; FIX(2.613125930) - FIX(1)
50
%endif
51
52
; --------------------------------------------------------------------------
53
	SECTION	SEG_CONST
54
55
; PRE_MULTIPLY_SCALE_BITS <= 2 (to avoid overflow)
56
; CONST_BITS + CONST_SHIFT + PRE_MULTIPLY_SCALE_BITS == 16 (for pmulhw)
57
58
%define PRE_MULTIPLY_SCALE_BITS   2
59
%define CONST_SHIFT     (16 - PRE_MULTIPLY_SCALE_BITS - CONST_BITS)
60
61
	alignz	16
62
	global	EXTN(jconst_idct_ifast_sse2)
63
64
EXTN(jconst_idct_ifast_sse2):
65
66
PW_F1414	times 8 dw  F_1_414 << CONST_SHIFT
67
PW_F1847	times 8 dw  F_1_847 << CONST_SHIFT
68
PW_MF1613	times 8 dw -F_1_613 << CONST_SHIFT
69
PW_F1082	times 8 dw  F_1_082 << CONST_SHIFT
70
PB_CENTERJSAMP	times 16 db CENTERJSAMPLE
71
72
	alignz	16
73
74
; --------------------------------------------------------------------------
75
	SECTION	SEG_TEXT
76
	BITS	32
77
;
78
; Perform dequantization and inverse DCT on one block of coefficients.
79
;
80
; GLOBAL(void)
81
; jsimd_idct_ifast_sse2 (void * dct_table, JCOEFPTR coef_block,
82
;                       JSAMPARRAY output_buf, JDIMENSION output_col)
83
;
84
85
%define dct_table(b)	(b)+8			; jpeg_component_info * compptr
86
%define coef_block(b)	(b)+12		; JCOEFPTR coef_block
87
%define output_buf(b)	(b)+16		; JSAMPARRAY output_buf
88
%define output_col(b)	(b)+20		; JDIMENSION output_col
89
90
%define original_ebp	ebp+0
91
%define wk(i)		ebp-(WK_NUM-(i))*SIZEOF_XMMWORD	; xmmword wk[WK_NUM]
92
%define WK_NUM		2
93
94
	align	16
95
	global	EXTN(jsimd_idct_ifast_sse2)
96
97
EXTN(jsimd_idct_ifast_sse2):
98
	push	ebp
99
	mov	eax,esp				; eax = original ebp
100
	sub	esp, byte 4
101
	and	esp, byte (-SIZEOF_XMMWORD)	; align to 128 bits
102
	mov	[esp],eax
103
	mov	ebp,esp				; ebp = aligned ebp
104
	lea	esp, [wk(0)]
105
	pushpic	ebx
106
;	push	ecx		; unused
107
;	push	edx		; need not be preserved
108
	push	esi
109
	push	edi
110
111
	get_GOT	ebx		; get GOT address
112
113
	; ---- Pass 1: process columns from input.
114
115
;	mov	eax, [original_ebp]
116
	mov	edx, POINTER [dct_table(eax)]	; quantptr
117
	mov	esi, JCOEFPTR [coef_block(eax)]		; inptr
118
119
%ifndef NO_ZERO_COLUMN_TEST_IFAST_SSE2
120
	mov	eax, DWORD [DWBLOCK(1,0,esi,SIZEOF_JCOEF)]
121
	or	eax, DWORD [DWBLOCK(2,0,esi,SIZEOF_JCOEF)]
122
	jnz	near .columnDCT
123
124
	movdqa	xmm0, XMMWORD [XMMBLOCK(1,0,esi,SIZEOF_JCOEF)]
125
	movdqa	xmm1, XMMWORD [XMMBLOCK(2,0,esi,SIZEOF_JCOEF)]
126
	por	xmm0, XMMWORD [XMMBLOCK(3,0,esi,SIZEOF_JCOEF)]
127
	por	xmm1, XMMWORD [XMMBLOCK(4,0,esi,SIZEOF_JCOEF)]
128
	por	xmm0, XMMWORD [XMMBLOCK(5,0,esi,SIZEOF_JCOEF)]
129
	por	xmm1, XMMWORD [XMMBLOCK(6,0,esi,SIZEOF_JCOEF)]
130
	por	xmm0, XMMWORD [XMMBLOCK(7,0,esi,SIZEOF_JCOEF)]
131
	por	xmm1,xmm0
132
	packsswb xmm1,xmm1
133
	packsswb xmm1,xmm1
134
	movd	eax,xmm1
135
	test	eax,eax
136
	jnz	short .columnDCT
137
138
	; -- AC terms all zero
139
140
	movdqa	xmm0, XMMWORD [XMMBLOCK(0,0,esi,SIZEOF_JCOEF)]
141
	pmullw	xmm0, XMMWORD [XMMBLOCK(0,0,edx,SIZEOF_ISLOW_MULT_TYPE)]
142
143
	movdqa    xmm7,xmm0		; xmm0=in0=(00 01 02 03 04 05 06 07)
144
	punpcklwd xmm0,xmm0		; xmm0=(00 00 01 01 02 02 03 03)
145
	punpckhwd xmm7,xmm7		; xmm7=(04 04 05 05 06 06 07 07)
146
147
	pshufd	xmm6,xmm0,0x00		; xmm6=col0=(00 00 00 00 00 00 00 00)
148
	pshufd	xmm2,xmm0,0x55		; xmm2=col1=(01 01 01 01 01 01 01 01)
149
	pshufd	xmm5,xmm0,0xAA		; xmm5=col2=(02 02 02 02 02 02 02 02)
150
	pshufd	xmm0,xmm0,0xFF		; xmm0=col3=(03 03 03 03 03 03 03 03)
151
	pshufd	xmm1,xmm7,0x00		; xmm1=col4=(04 04 04 04 04 04 04 04)
152
	pshufd	xmm4,xmm7,0x55		; xmm4=col5=(05 05 05 05 05 05 05 05)
153
	pshufd	xmm3,xmm7,0xAA		; xmm3=col6=(06 06 06 06 06 06 06 06)
154
	pshufd	xmm7,xmm7,0xFF		; xmm7=col7=(07 07 07 07 07 07 07 07)
155
156
	movdqa	XMMWORD [wk(0)], xmm2	; wk(0)=col1
157
	movdqa	XMMWORD [wk(1)], xmm0	; wk(1)=col3
158
	jmp	near .column_end
159
	alignx	16,7
160
%endif
161
.columnDCT:
162
163
	; -- Even part
164
165
	movdqa	xmm0, XMMWORD [XMMBLOCK(0,0,esi,SIZEOF_JCOEF)]
166
	movdqa	xmm1, XMMWORD [XMMBLOCK(2,0,esi,SIZEOF_JCOEF)]
167
	pmullw	xmm0, XMMWORD [XMMBLOCK(0,0,edx,SIZEOF_IFAST_MULT_TYPE)]
168
	pmullw	xmm1, XMMWORD [XMMBLOCK(2,0,edx,SIZEOF_IFAST_MULT_TYPE)]
169
	movdqa	xmm2, XMMWORD [XMMBLOCK(4,0,esi,SIZEOF_JCOEF)]
170
	movdqa	xmm3, XMMWORD [XMMBLOCK(6,0,esi,SIZEOF_JCOEF)]
171
	pmullw	xmm2, XMMWORD [XMMBLOCK(4,0,edx,SIZEOF_IFAST_MULT_TYPE)]
172
	pmullw	xmm3, XMMWORD [XMMBLOCK(6,0,edx,SIZEOF_IFAST_MULT_TYPE)]
173
174
	movdqa	xmm4,xmm0
175
	movdqa	xmm5,xmm1
176
	psubw	xmm0,xmm2		; xmm0=tmp11
177
	psubw	xmm1,xmm3
178
	paddw	xmm4,xmm2		; xmm4=tmp10
179
	paddw	xmm5,xmm3		; xmm5=tmp13
180
181
	psllw	xmm1,PRE_MULTIPLY_SCALE_BITS
182
	pmulhw	xmm1,[GOTOFF(ebx,PW_F1414)]
183
	psubw	xmm1,xmm5		; xmm1=tmp12
184
185
	movdqa	xmm6,xmm4
186
	movdqa	xmm7,xmm0
187
	psubw	xmm4,xmm5		; xmm4=tmp3
188
	psubw	xmm0,xmm1		; xmm0=tmp2
189
	paddw	xmm6,xmm5		; xmm6=tmp0
190
	paddw	xmm7,xmm1		; xmm7=tmp1
191
192
	movdqa	XMMWORD [wk(1)], xmm4	; wk(1)=tmp3
193
	movdqa	XMMWORD [wk(0)], xmm0	; wk(0)=tmp2
194
195
	; -- Odd part
196
197
	movdqa	xmm2, XMMWORD [XMMBLOCK(1,0,esi,SIZEOF_JCOEF)]
198
	movdqa	xmm3, XMMWORD [XMMBLOCK(3,0,esi,SIZEOF_JCOEF)]
199
	pmullw	xmm2, XMMWORD [XMMBLOCK(1,0,edx,SIZEOF_IFAST_MULT_TYPE)]
200
	pmullw	xmm3, XMMWORD [XMMBLOCK(3,0,edx,SIZEOF_IFAST_MULT_TYPE)]
201
	movdqa	xmm5, XMMWORD [XMMBLOCK(5,0,esi,SIZEOF_JCOEF)]
202
	movdqa	xmm1, XMMWORD [XMMBLOCK(7,0,esi,SIZEOF_JCOEF)]
203
	pmullw	xmm5, XMMWORD [XMMBLOCK(5,0,edx,SIZEOF_IFAST_MULT_TYPE)]
204
	pmullw	xmm1, XMMWORD [XMMBLOCK(7,0,edx,SIZEOF_IFAST_MULT_TYPE)]
205
206
	movdqa	xmm4,xmm2
207
	movdqa	xmm0,xmm5
208
	psubw	xmm2,xmm1		; xmm2=z12
209
	psubw	xmm5,xmm3		; xmm5=z10
210
	paddw	xmm4,xmm1		; xmm4=z11
211
	paddw	xmm0,xmm3		; xmm0=z13
212
213
	movdqa	xmm1,xmm5		; xmm1=z10(unscaled)
214
	psllw	xmm2,PRE_MULTIPLY_SCALE_BITS
215
	psllw	xmm5,PRE_MULTIPLY_SCALE_BITS
216
217
	movdqa	xmm3,xmm4
218
	psubw	xmm4,xmm0
219
	paddw	xmm3,xmm0		; xmm3=tmp7
220
221
	psllw	xmm4,PRE_MULTIPLY_SCALE_BITS
222
	pmulhw	xmm4,[GOTOFF(ebx,PW_F1414)]	; xmm4=tmp11
223
224
	; To avoid overflow...
225
	;
226
	; (Original)
227
	; tmp12 = -2.613125930 * z10 + z5;
228
	;
229
	; (This implementation)
230
	; tmp12 = (-1.613125930 - 1) * z10 + z5;
231
	;       = -1.613125930 * z10 - z10 + z5;
232
233
	movdqa	xmm0,xmm5
234
	paddw	xmm5,xmm2
235
	pmulhw	xmm5,[GOTOFF(ebx,PW_F1847)]	; xmm5=z5
236
	pmulhw	xmm0,[GOTOFF(ebx,PW_MF1613)]
237
	pmulhw	xmm2,[GOTOFF(ebx,PW_F1082)]
238
	psubw	xmm0,xmm1
239
	psubw	xmm2,xmm5		; xmm2=tmp10
240
	paddw	xmm0,xmm5		; xmm0=tmp12
241
242
	; -- Final output stage
243
244
	psubw	xmm0,xmm3		; xmm0=tmp6
245
	movdqa	xmm1,xmm6
246
	movdqa	xmm5,xmm7
247
	paddw	xmm6,xmm3		; xmm6=data0=(00 01 02 03 04 05 06 07)
248
	paddw	xmm7,xmm0		; xmm7=data1=(10 11 12 13 14 15 16 17)
249
	psubw	xmm1,xmm3		; xmm1=data7=(70 71 72 73 74 75 76 77)
250
	psubw	xmm5,xmm0		; xmm5=data6=(60 61 62 63 64 65 66 67)
251
	psubw	xmm4,xmm0		; xmm4=tmp5
252
253
	movdqa    xmm3,xmm6		; transpose coefficients(phase 1)
254
	punpcklwd xmm6,xmm7		; xmm6=(00 10 01 11 02 12 03 13)
255
	punpckhwd xmm3,xmm7		; xmm3=(04 14 05 15 06 16 07 17)
256
	movdqa    xmm0,xmm5		; transpose coefficients(phase 1)
257
	punpcklwd xmm5,xmm1		; xmm5=(60 70 61 71 62 72 63 73)
258
	punpckhwd xmm0,xmm1		; xmm0=(64 74 65 75 66 76 67 77)
259
260
	movdqa	xmm7, XMMWORD [wk(0)]	; xmm7=tmp2
261
	movdqa	xmm1, XMMWORD [wk(1)]	; xmm1=tmp3
262
263
	movdqa	XMMWORD [wk(0)], xmm5	; wk(0)=(60 70 61 71 62 72 63 73)
264
	movdqa	XMMWORD [wk(1)], xmm0	; wk(1)=(64 74 65 75 66 76 67 77)
265
266
	paddw	xmm2,xmm4		; xmm2=tmp4
267
	movdqa	xmm5,xmm7
268
	movdqa	xmm0,xmm1
269
	paddw	xmm7,xmm4		; xmm7=data2=(20 21 22 23 24 25 26 27)
270
	paddw	xmm1,xmm2		; xmm1=data4=(40 41 42 43 44 45 46 47)
271
	psubw	xmm5,xmm4		; xmm5=data5=(50 51 52 53 54 55 56 57)
272
	psubw	xmm0,xmm2		; xmm0=data3=(30 31 32 33 34 35 36 37)
273
274
	movdqa    xmm4,xmm7		; transpose coefficients(phase 1)
275
	punpcklwd xmm7,xmm0		; xmm7=(20 30 21 31 22 32 23 33)
276
	punpckhwd xmm4,xmm0		; xmm4=(24 34 25 35 26 36 27 37)
277
	movdqa    xmm2,xmm1		; transpose coefficients(phase 1)
278
	punpcklwd xmm1,xmm5		; xmm1=(40 50 41 51 42 52 43 53)
279
	punpckhwd xmm2,xmm5		; xmm2=(44 54 45 55 46 56 47 57)
280
281
	movdqa    xmm0,xmm3		; transpose coefficients(phase 2)
282
	punpckldq xmm3,xmm4		; xmm3=(04 14 24 34 05 15 25 35)
283
	punpckhdq xmm0,xmm4		; xmm0=(06 16 26 36 07 17 27 37)
284
	movdqa    xmm5,xmm6		; transpose coefficients(phase 2)
285
	punpckldq xmm6,xmm7		; xmm6=(00 10 20 30 01 11 21 31)
286
	punpckhdq xmm5,xmm7		; xmm5=(02 12 22 32 03 13 23 33)
287
288
	movdqa	xmm4, XMMWORD [wk(0)]	; xmm4=(60 70 61 71 62 72 63 73)
289
	movdqa	xmm7, XMMWORD [wk(1)]	; xmm7=(64 74 65 75 66 76 67 77)
290
291
	movdqa	XMMWORD [wk(0)], xmm3	; wk(0)=(04 14 24 34 05 15 25 35)
292
	movdqa	XMMWORD [wk(1)], xmm0	; wk(1)=(06 16 26 36 07 17 27 37)
293
294
	movdqa    xmm3,xmm1		; transpose coefficients(phase 2)
295
	punpckldq xmm1,xmm4		; xmm1=(40 50 60 70 41 51 61 71)
296
	punpckhdq xmm3,xmm4		; xmm3=(42 52 62 72 43 53 63 73)
297
	movdqa    xmm0,xmm2		; transpose coefficients(phase 2)
298
	punpckldq xmm2,xmm7		; xmm2=(44 54 64 74 45 55 65 75)
299
	punpckhdq xmm0,xmm7		; xmm0=(46 56 66 76 47 57 67 77)
300
301
	movdqa     xmm4,xmm6		; transpose coefficients(phase 3)
302
	punpcklqdq xmm6,xmm1		; xmm6=col0=(00 10 20 30 40 50 60 70)
303
	punpckhqdq xmm4,xmm1		; xmm4=col1=(01 11 21 31 41 51 61 71)
304
	movdqa     xmm7,xmm5		; transpose coefficients(phase 3)
305
	punpcklqdq xmm5,xmm3		; xmm5=col2=(02 12 22 32 42 52 62 72)
306
	punpckhqdq xmm7,xmm3		; xmm7=col3=(03 13 23 33 43 53 63 73)
307
308
	movdqa	xmm1, XMMWORD [wk(0)]	; xmm1=(04 14 24 34 05 15 25 35)
309
	movdqa	xmm3, XMMWORD [wk(1)]	; xmm3=(06 16 26 36 07 17 27 37)
310
311
	movdqa	XMMWORD [wk(0)], xmm4	; wk(0)=col1
312
	movdqa	XMMWORD [wk(1)], xmm7	; wk(1)=col3
313
314
	movdqa     xmm4,xmm1		; transpose coefficients(phase 3)
315
	punpcklqdq xmm1,xmm2		; xmm1=col4=(04 14 24 34 44 54 64 74)
316
	punpckhqdq xmm4,xmm2		; xmm4=col5=(05 15 25 35 45 55 65 75)
317
	movdqa     xmm7,xmm3		; transpose coefficients(phase 3)
318
	punpcklqdq xmm3,xmm0		; xmm3=col6=(06 16 26 36 46 56 66 76)
319
	punpckhqdq xmm7,xmm0		; xmm7=col7=(07 17 27 37 47 57 67 77)
320
.column_end:
321
322
	; -- Prefetch the next coefficient block
323
324
	prefetchnta [esi + DCTSIZE2*SIZEOF_JCOEF + 0*32]
325
	prefetchnta [esi + DCTSIZE2*SIZEOF_JCOEF + 1*32]
326
	prefetchnta [esi + DCTSIZE2*SIZEOF_JCOEF + 2*32]
327
	prefetchnta [esi + DCTSIZE2*SIZEOF_JCOEF + 3*32]
328
329
	; ---- Pass 2: process rows from work array, store into output array.
330
331
	mov	eax, [original_ebp]
332
	mov	edi, JSAMPARRAY [output_buf(eax)]	; (JSAMPROW *)
333
	mov	eax, JDIMENSION [output_col(eax)]
334
335
	; -- Even part
336
337
	; xmm6=col0, xmm5=col2, xmm1=col4, xmm3=col6
338
339
	movdqa	xmm2,xmm6
340
	movdqa	xmm0,xmm5
341
	psubw	xmm6,xmm1		; xmm6=tmp11
342
	psubw	xmm5,xmm3
343
	paddw	xmm2,xmm1		; xmm2=tmp10
344
	paddw	xmm0,xmm3		; xmm0=tmp13
345
346
	psllw	xmm5,PRE_MULTIPLY_SCALE_BITS
347
	pmulhw	xmm5,[GOTOFF(ebx,PW_F1414)]
348
	psubw	xmm5,xmm0		; xmm5=tmp12
349
350
	movdqa	xmm1,xmm2
351
	movdqa	xmm3,xmm6
352
	psubw	xmm2,xmm0		; xmm2=tmp3
353
	psubw	xmm6,xmm5		; xmm6=tmp2
354
	paddw	xmm1,xmm0		; xmm1=tmp0
355
	paddw	xmm3,xmm5		; xmm3=tmp1
356
357
	movdqa	xmm0, XMMWORD [wk(0)]	; xmm0=col1
358
	movdqa	xmm5, XMMWORD [wk(1)]	; xmm5=col3
359
360
	movdqa	XMMWORD [wk(0)], xmm2	; wk(0)=tmp3
361
	movdqa	XMMWORD [wk(1)], xmm6	; wk(1)=tmp2
362
363
	; -- Odd part
364
365
	; xmm0=col1, xmm5=col3, xmm4=col5, xmm7=col7
366
367
	movdqa	xmm2,xmm0
368
	movdqa	xmm6,xmm4
369
	psubw	xmm0,xmm7		; xmm0=z12
370
	psubw	xmm4,xmm5		; xmm4=z10
371
	paddw	xmm2,xmm7		; xmm2=z11
372
	paddw	xmm6,xmm5		; xmm6=z13
373
374
	movdqa	xmm7,xmm4		; xmm7=z10(unscaled)
375
	psllw	xmm0,PRE_MULTIPLY_SCALE_BITS
376
	psllw	xmm4,PRE_MULTIPLY_SCALE_BITS
377
378
	movdqa	xmm5,xmm2
379
	psubw	xmm2,xmm6
380
	paddw	xmm5,xmm6		; xmm5=tmp7
381
382
	psllw	xmm2,PRE_MULTIPLY_SCALE_BITS
383
	pmulhw	xmm2,[GOTOFF(ebx,PW_F1414)]	; xmm2=tmp11
384
385
	; To avoid overflow...
386
	;
387
	; (Original)
388
	; tmp12 = -2.613125930 * z10 + z5;
389
	;
390
	; (This implementation)
391
	; tmp12 = (-1.613125930 - 1) * z10 + z5;
392
	;       = -1.613125930 * z10 - z10 + z5;
393
394
	movdqa	xmm6,xmm4
395
	paddw	xmm4,xmm0
396
	pmulhw	xmm4,[GOTOFF(ebx,PW_F1847)]	; xmm4=z5
397
	pmulhw	xmm6,[GOTOFF(ebx,PW_MF1613)]
398
	pmulhw	xmm0,[GOTOFF(ebx,PW_F1082)]
399
	psubw	xmm6,xmm7
400
	psubw	xmm0,xmm4		; xmm0=tmp10
401
	paddw	xmm6,xmm4		; xmm6=tmp12
402
403
	; -- Final output stage
404
405
	psubw	xmm6,xmm5		; xmm6=tmp6
406
	movdqa	xmm7,xmm1
407
	movdqa	xmm4,xmm3
408
	paddw	xmm1,xmm5		; xmm1=data0=(00 10 20 30 40 50 60 70)
409
	paddw	xmm3,xmm6		; xmm3=data1=(01 11 21 31 41 51 61 71)
410
	psraw	xmm1,(PASS1_BITS+3)	; descale
411
	psraw	xmm3,(PASS1_BITS+3)	; descale
412
	psubw	xmm7,xmm5		; xmm7=data7=(07 17 27 37 47 57 67 77)
413
	psubw	xmm4,xmm6		; xmm4=data6=(06 16 26 36 46 56 66 76)
414
	psraw	xmm7,(PASS1_BITS+3)	; descale
415
	psraw	xmm4,(PASS1_BITS+3)	; descale
416
	psubw	xmm2,xmm6		; xmm2=tmp5
417
418
	packsswb  xmm1,xmm4	; xmm1=(00 10 20 30 40 50 60 70 06 16 26 36 46 56 66 76)
419
	packsswb  xmm3,xmm7	; xmm3=(01 11 21 31 41 51 61 71 07 17 27 37 47 57 67 77)
420
421
	movdqa	xmm5, XMMWORD [wk(1)]	; xmm5=tmp2
422
	movdqa	xmm6, XMMWORD [wk(0)]	; xmm6=tmp3
423
424
	paddw	xmm0,xmm2		; xmm0=tmp4
425
	movdqa	xmm4,xmm5
426
	movdqa	xmm7,xmm6
427
	paddw	xmm5,xmm2		; xmm5=data2=(02 12 22 32 42 52 62 72)
428
	paddw	xmm6,xmm0		; xmm6=data4=(04 14 24 34 44 54 64 74)
429
	psraw	xmm5,(PASS1_BITS+3)	; descale
430
	psraw	xmm6,(PASS1_BITS+3)	; descale
431
	psubw	xmm4,xmm2		; xmm4=data5=(05 15 25 35 45 55 65 75)
432
	psubw	xmm7,xmm0		; xmm7=data3=(03 13 23 33 43 53 63 73)
433
	psraw	xmm4,(PASS1_BITS+3)	; descale
434
	psraw	xmm7,(PASS1_BITS+3)	; descale
435
436
	movdqa    xmm2,[GOTOFF(ebx,PB_CENTERJSAMP)]	; xmm2=[PB_CENTERJSAMP]
437
438
	packsswb  xmm5,xmm6	; xmm5=(02 12 22 32 42 52 62 72 04 14 24 34 44 54 64 74)
439
	packsswb  xmm7,xmm4	; xmm7=(03 13 23 33 43 53 63 73 05 15 25 35 45 55 65 75)
440
441
	paddb     xmm1,xmm2
442
	paddb     xmm3,xmm2
443
	paddb     xmm5,xmm2
444
	paddb     xmm7,xmm2
445
446
	movdqa    xmm0,xmm1	; transpose coefficients(phase 1)
447
	punpcklbw xmm1,xmm3	; xmm1=(00 01 10 11 20 21 30 31 40 41 50 51 60 61 70 71)
448
	punpckhbw xmm0,xmm3	; xmm0=(06 07 16 17 26 27 36 37 46 47 56 57 66 67 76 77)
449
	movdqa    xmm6,xmm5	; transpose coefficients(phase 1)
450
	punpcklbw xmm5,xmm7	; xmm5=(02 03 12 13 22 23 32 33 42 43 52 53 62 63 72 73)
451
	punpckhbw xmm6,xmm7	; xmm6=(04 05 14 15 24 25 34 35 44 45 54 55 64 65 74 75)
452
453
	movdqa    xmm4,xmm1	; transpose coefficients(phase 2)
454
	punpcklwd xmm1,xmm5	; xmm1=(00 01 02 03 10 11 12 13 20 21 22 23 30 31 32 33)
455
	punpckhwd xmm4,xmm5	; xmm4=(40 41 42 43 50 51 52 53 60 61 62 63 70 71 72 73)
456
	movdqa    xmm2,xmm6	; transpose coefficients(phase 2)
457
	punpcklwd xmm6,xmm0	; xmm6=(04 05 06 07 14 15 16 17 24 25 26 27 34 35 36 37)
458
	punpckhwd xmm2,xmm0	; xmm2=(44 45 46 47 54 55 56 57 64 65 66 67 74 75 76 77)
459
460
	movdqa    xmm3,xmm1	; transpose coefficients(phase 3)
461
	punpckldq xmm1,xmm6	; xmm1=(00 01 02 03 04 05 06 07 10 11 12 13 14 15 16 17)
462
	punpckhdq xmm3,xmm6	; xmm3=(20 21 22 23 24 25 26 27 30 31 32 33 34 35 36 37)
463
	movdqa    xmm7,xmm4	; transpose coefficients(phase 3)
464
	punpckldq xmm4,xmm2	; xmm4=(40 41 42 43 44 45 46 47 50 51 52 53 54 55 56 57)
465
	punpckhdq xmm7,xmm2	; xmm7=(60 61 62 63 64 65 66 67 70 71 72 73 74 75 76 77)
466
467
	pshufd	xmm5,xmm1,0x4E	; xmm5=(10 11 12 13 14 15 16 17 00 01 02 03 04 05 06 07)
468
	pshufd	xmm0,xmm3,0x4E	; xmm0=(30 31 32 33 34 35 36 37 20 21 22 23 24 25 26 27)
469
	pshufd	xmm6,xmm4,0x4E	; xmm6=(50 51 52 53 54 55 56 57 40 41 42 43 44 45 46 47)
470
	pshufd	xmm2,xmm7,0x4E	; xmm2=(70 71 72 73 74 75 76 77 60 61 62 63 64 65 66 67)
471
472
	mov	edx, JSAMPROW [edi+0*SIZEOF_JSAMPROW]
473
	mov	esi, JSAMPROW [edi+2*SIZEOF_JSAMPROW]
474
	movq	XMM_MMWORD [edx+eax*SIZEOF_JSAMPLE], xmm1
475
	movq	XMM_MMWORD [esi+eax*SIZEOF_JSAMPLE], xmm3
476
	mov	edx, JSAMPROW [edi+4*SIZEOF_JSAMPROW]
477
	mov	esi, JSAMPROW [edi+6*SIZEOF_JSAMPROW]
478
	movq	XMM_MMWORD [edx+eax*SIZEOF_JSAMPLE], xmm4
479
	movq	XMM_MMWORD [esi+eax*SIZEOF_JSAMPLE], xmm7
480
481
	mov	edx, JSAMPROW [edi+1*SIZEOF_JSAMPROW]
482
	mov	esi, JSAMPROW [edi+3*SIZEOF_JSAMPROW]
483
	movq	XMM_MMWORD [edx+eax*SIZEOF_JSAMPLE], xmm5
484
	movq	XMM_MMWORD [esi+eax*SIZEOF_JSAMPLE], xmm0
485
	mov	edx, JSAMPROW [edi+5*SIZEOF_JSAMPROW]
486
	mov	esi, JSAMPROW [edi+7*SIZEOF_JSAMPROW]
487
	movq	XMM_MMWORD [edx+eax*SIZEOF_JSAMPLE], xmm6
488
	movq	XMM_MMWORD [esi+eax*SIZEOF_JSAMPLE], xmm2
489
490
	pop	edi
491
	pop	esi
492
;	pop	edx		; need not be preserved
493
;	pop	ecx		; unused
494
	poppic	ebx
495
	mov	esp,ebp		; esp <- aligned ebp
496
	pop	esp		; esp <- original ebp
497
	pop	ebp
498
	ret
499
500
; For some reason, the OS X linker does not honor the request to align the
501
; segment unless we do this.
502
	align	16
(-)a/jpeg/simd/jiss2int-64.asm (+848 lines)
Line     Link Here 
Line 0    Link Here 
1
;
2
; jiss2int-64.asm - accurate integer IDCT (64-bit SSE2)
3
;
4
; Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
5
; Copyright 2009 D. R. Commander
6
;
7
; Based on
8
; x86 SIMD extension for IJG JPEG library
9
; Copyright (C) 1999-2006, MIYASAKA Masaru.
10
; For conditions of distribution and use, see copyright notice in jsimdext.inc
11
;
12
; This file should be assembled with NASM (Netwide Assembler),
13
; can *not* be assembled with Microsoft's MASM or any compatible
14
; assembler (including Borland's Turbo Assembler).
15
; NASM is available from http://nasm.sourceforge.net/ or
16
; http://sourceforge.net/project/showfiles.php?group_id=6208
17
;
18
; This file contains a slow-but-accurate integer implementation of the
19
; inverse DCT (Discrete Cosine Transform). The following code is based
20
; directly on the IJG's original jidctint.c; see the jidctint.c for
21
; more details.
22
;
23
; [TAB8]
24
25
%include "jsimdext.inc"
26
%include "jdct.inc"
27
28
; --------------------------------------------------------------------------
29
30
%define CONST_BITS	13
31
%define PASS1_BITS	2
32
33
%define DESCALE_P1	(CONST_BITS-PASS1_BITS)
34
%define DESCALE_P2	(CONST_BITS+PASS1_BITS+3)
35
36
%if CONST_BITS == 13
37
F_0_298	equ	 2446		; FIX(0.298631336)
38
F_0_390	equ	 3196		; FIX(0.390180644)
39
F_0_541	equ	 4433		; FIX(0.541196100)
40
F_0_765	equ	 6270		; FIX(0.765366865)
41
F_0_899	equ	 7373		; FIX(0.899976223)
42
F_1_175	equ	 9633		; FIX(1.175875602)
43
F_1_501	equ	12299		; FIX(1.501321110)
44
F_1_847	equ	15137		; FIX(1.847759065)
45
F_1_961	equ	16069		; FIX(1.961570560)
46
F_2_053	equ	16819		; FIX(2.053119869)
47
F_2_562	equ	20995		; FIX(2.562915447)
48
F_3_072	equ	25172		; FIX(3.072711026)
49
%else
50
; NASM cannot do compile-time arithmetic on floating-point constants.
51
%define DESCALE(x,n)  (((x)+(1<<((n)-1)))>>(n))
52
F_0_298	equ	DESCALE( 320652955,30-CONST_BITS)	; FIX(0.298631336)
53
F_0_390	equ	DESCALE( 418953276,30-CONST_BITS)	; FIX(0.390180644)
54
F_0_541	equ	DESCALE( 581104887,30-CONST_BITS)	; FIX(0.541196100)
55
F_0_765	equ	DESCALE( 821806413,30-CONST_BITS)	; FIX(0.765366865)
56
F_0_899	equ	DESCALE( 966342111,30-CONST_BITS)	; FIX(0.899976223)
57
F_1_175	equ	DESCALE(1262586813,30-CONST_BITS)	; FIX(1.175875602)
58
F_1_501	equ	DESCALE(1612031267,30-CONST_BITS)	; FIX(1.501321110)
59
F_1_847	equ	DESCALE(1984016188,30-CONST_BITS)	; FIX(1.847759065)
60
F_1_961	equ	DESCALE(2106220350,30-CONST_BITS)	; FIX(1.961570560)
61
F_2_053	equ	DESCALE(2204520673,30-CONST_BITS)	; FIX(2.053119869)
62
F_2_562	equ	DESCALE(2751909506,30-CONST_BITS)	; FIX(2.562915447)
63
F_3_072	equ	DESCALE(3299298341,30-CONST_BITS)	; FIX(3.072711026)
64
%endif
65
66
; --------------------------------------------------------------------------
67
	SECTION	SEG_CONST
68
69
	alignz	16
70
	global	EXTN(jconst_idct_islow_sse2)
71
72
EXTN(jconst_idct_islow_sse2):
73
74
PW_F130_F054	times 4 dw  (F_0_541+F_0_765), F_0_541
75
PW_F054_MF130	times 4 dw  F_0_541, (F_0_541-F_1_847)
76
PW_MF078_F117	times 4 dw  (F_1_175-F_1_961), F_1_175
77
PW_F117_F078	times 4 dw  F_1_175, (F_1_175-F_0_390)
78
PW_MF060_MF089	times 4 dw  (F_0_298-F_0_899),-F_0_899
79
PW_MF089_F060	times 4 dw -F_0_899, (F_1_501-F_0_899)
80
PW_MF050_MF256	times 4 dw  (F_2_053-F_2_562),-F_2_562
81
PW_MF256_F050	times 4 dw -F_2_562, (F_3_072-F_2_562)
82
PD_DESCALE_P1	times 4 dd  1 << (DESCALE_P1-1)
83
PD_DESCALE_P2	times 4 dd  1 << (DESCALE_P2-1)
84
PB_CENTERJSAMP	times 16 db CENTERJSAMPLE
85
86
	alignz	16
87
88
; --------------------------------------------------------------------------
89
	SECTION	SEG_TEXT
90
	BITS	64
91
;
92
; Perform dequantization and inverse DCT on one block of coefficients.
93
;
94
; GLOBAL(void)
95
; jsimd_idct_islow_sse2 (void * dct_table, JCOEFPTR coef_block,
96
;                        JSAMPARRAY output_buf, JDIMENSION output_col)
97
;
98
99
; r10 = jpeg_component_info * compptr
100
; r11 = JCOEFPTR coef_block
101
; r12 = JSAMPARRAY output_buf
102
; r13 = JDIMENSION output_col
103
104
%define original_rbp	rbp+0
105
%define wk(i)		rbp-(WK_NUM-(i))*SIZEOF_XMMWORD	; xmmword wk[WK_NUM]
106
%define WK_NUM		12
107
108
	align	16
109
	global	EXTN(jsimd_idct_islow_sse2)
110
111
EXTN(jsimd_idct_islow_sse2):
112
	push	rbp
113
	mov	rax,rsp				; rax = original rbp
114
	sub	rsp, byte 4
115
	and	rsp, byte (-SIZEOF_XMMWORD)	; align to 128 bits
116
	mov	[rsp],rax
117
	mov	rbp,rsp				; rbp = aligned rbp
118
	lea	rsp, [wk(0)]
119
	collect_args
120
121
	; ---- Pass 1: process columns from input.
122
123
	mov	rdx, r10	; quantptr
124
	mov	rsi, r11		; inptr
125
126
%ifndef NO_ZERO_COLUMN_TEST_ISLOW_SSE2
127
	mov	eax, DWORD [DWBLOCK(1,0,rsi,SIZEOF_JCOEF)]
128
	or	eax, DWORD [DWBLOCK(2,0,rsi,SIZEOF_JCOEF)]
129
	jnz	near .columnDCT
130
131
	movdqa	xmm0, XMMWORD [XMMBLOCK(1,0,rsi,SIZEOF_JCOEF)]
132
	movdqa	xmm1, XMMWORD [XMMBLOCK(2,0,rsi,SIZEOF_JCOEF)]
133
	por	xmm0, XMMWORD [XMMBLOCK(3,0,rsi,SIZEOF_JCOEF)]
134
	por	xmm1, XMMWORD [XMMBLOCK(4,0,rsi,SIZEOF_JCOEF)]
135
	por	xmm0, XMMWORD [XMMBLOCK(5,0,rsi,SIZEOF_JCOEF)]
136
	por	xmm1, XMMWORD [XMMBLOCK(6,0,rsi,SIZEOF_JCOEF)]
137
	por	xmm0, XMMWORD [XMMBLOCK(7,0,rsi,SIZEOF_JCOEF)]
138
	por	xmm1,xmm0
139
	packsswb xmm1,xmm1
140
	packsswb xmm1,xmm1
141
	movd	eax,xmm1
142
	test	rax,rax
143
	jnz	short .columnDCT
144
145
	; -- AC terms all zero
146
147
	movdqa	xmm5, XMMWORD [XMMBLOCK(0,0,rsi,SIZEOF_JCOEF)]
148
	pmullw	xmm5, XMMWORD [XMMBLOCK(0,0,rdx,SIZEOF_ISLOW_MULT_TYPE)]
149
150
	psllw	xmm5,PASS1_BITS
151
152
	movdqa    xmm4,xmm5		; xmm5=in0=(00 01 02 03 04 05 06 07)
153
	punpcklwd xmm5,xmm5		; xmm5=(00 00 01 01 02 02 03 03)
154
	punpckhwd xmm4,xmm4		; xmm4=(04 04 05 05 06 06 07 07)
155
156
	pshufd	xmm7,xmm5,0x00		; xmm7=col0=(00 00 00 00 00 00 00 00)
157
	pshufd	xmm6,xmm5,0x55		; xmm6=col1=(01 01 01 01 01 01 01 01)
158
	pshufd	xmm1,xmm5,0xAA		; xmm1=col2=(02 02 02 02 02 02 02 02)
159
	pshufd	xmm5,xmm5,0xFF		; xmm5=col3=(03 03 03 03 03 03 03 03)
160
	pshufd	xmm0,xmm4,0x00		; xmm0=col4=(04 04 04 04 04 04 04 04)
161
	pshufd	xmm3,xmm4,0x55		; xmm3=col5=(05 05 05 05 05 05 05 05)
162
	pshufd	xmm2,xmm4,0xAA		; xmm2=col6=(06 06 06 06 06 06 06 06)
163
	pshufd	xmm4,xmm4,0xFF		; xmm4=col7=(07 07 07 07 07 07 07 07)
164
165
	movdqa	XMMWORD [wk(8)], xmm6	; wk(8)=col1
166
	movdqa	XMMWORD [wk(9)], xmm5	; wk(9)=col3
167
	movdqa	XMMWORD [wk(10)], xmm3	; wk(10)=col5
168
	movdqa	XMMWORD [wk(11)], xmm4	; wk(11)=col7
169
	jmp	near .column_end
170
%endif
171
.columnDCT:
172
173
	; -- Even part
174
175
	movdqa	xmm0, XMMWORD [XMMBLOCK(0,0,rsi,SIZEOF_JCOEF)]
176
	movdqa	xmm1, XMMWORD [XMMBLOCK(2,0,rsi,SIZEOF_JCOEF)]
177
	pmullw	xmm0, XMMWORD [XMMBLOCK(0,0,rdx,SIZEOF_ISLOW_MULT_TYPE)]
178
	pmullw	xmm1, XMMWORD [XMMBLOCK(2,0,rdx,SIZEOF_ISLOW_MULT_TYPE)]
179
	movdqa	xmm2, XMMWORD [XMMBLOCK(4,0,rsi,SIZEOF_JCOEF)]
180
	movdqa	xmm3, XMMWORD [XMMBLOCK(6,0,rsi,SIZEOF_JCOEF)]
181
	pmullw	xmm2, XMMWORD [XMMBLOCK(4,0,rdx,SIZEOF_ISLOW_MULT_TYPE)]
182
	pmullw	xmm3, XMMWORD [XMMBLOCK(6,0,rdx,SIZEOF_ISLOW_MULT_TYPE)]
183
184
	; (Original)
185
	; z1 = (z2 + z3) * 0.541196100;
186
	; tmp2 = z1 + z3 * -1.847759065;
187
	; tmp3 = z1 + z2 * 0.765366865;
188
	;
189
	; (This implementation)
190
	; tmp2 = z2 * 0.541196100 + z3 * (0.541196100 - 1.847759065);
191
	; tmp3 = z2 * (0.541196100 + 0.765366865) + z3 * 0.541196100;
192
193
	movdqa    xmm4,xmm1		; xmm1=in2=z2
194
	movdqa    xmm5,xmm1
195
	punpcklwd xmm4,xmm3		; xmm3=in6=z3
196
	punpckhwd xmm5,xmm3
197
	movdqa    xmm1,xmm4
198
	movdqa    xmm3,xmm5
199
	pmaddwd   xmm4,[rel PW_F130_F054]	; xmm4=tmp3L
200
	pmaddwd   xmm5,[rel PW_F130_F054]	; xmm5=tmp3H
201
	pmaddwd   xmm1,[rel PW_F054_MF130]	; xmm1=tmp2L
202
	pmaddwd   xmm3,[rel PW_F054_MF130]	; xmm3=tmp2H
203
204
	movdqa    xmm6,xmm0
205
	paddw     xmm0,xmm2		; xmm0=in0+in4
206
	psubw     xmm6,xmm2		; xmm6=in0-in4
207
208
	pxor      xmm7,xmm7
209
	pxor      xmm2,xmm2
210
	punpcklwd xmm7,xmm0		; xmm7=tmp0L
211
	punpckhwd xmm2,xmm0		; xmm2=tmp0H
212
	psrad     xmm7,(16-CONST_BITS)	; psrad xmm7,16 & pslld xmm7,CONST_BITS
213
	psrad     xmm2,(16-CONST_BITS)	; psrad xmm2,16 & pslld xmm2,CONST_BITS
214
215
	movdqa	xmm0,xmm7
216
	paddd	xmm7,xmm4		; xmm7=tmp10L
217
	psubd	xmm0,xmm4		; xmm0=tmp13L
218
	movdqa	xmm4,xmm2
219
	paddd	xmm2,xmm5		; xmm2=tmp10H
220
	psubd	xmm4,xmm5		; xmm4=tmp13H
221
222
	movdqa	XMMWORD [wk(0)], xmm7	; wk(0)=tmp10L
223
	movdqa	XMMWORD [wk(1)], xmm2	; wk(1)=tmp10H
224
	movdqa	XMMWORD [wk(2)], xmm0	; wk(2)=tmp13L
225
	movdqa	XMMWORD [wk(3)], xmm4	; wk(3)=tmp13H
226
227
	pxor      xmm5,xmm5
228
	pxor      xmm7,xmm7
229
	punpcklwd xmm5,xmm6		; xmm5=tmp1L
230
	punpckhwd xmm7,xmm6		; xmm7=tmp1H
231
	psrad     xmm5,(16-CONST_BITS)	; psrad xmm5,16 & pslld xmm5,CONST_BITS
232
	psrad     xmm7,(16-CONST_BITS)	; psrad xmm7,16 & pslld xmm7,CONST_BITS
233
234
	movdqa	xmm2,xmm5
235
	paddd	xmm5,xmm1		; xmm5=tmp11L
236
	psubd	xmm2,xmm1		; xmm2=tmp12L
237
	movdqa	xmm0,xmm7
238
	paddd	xmm7,xmm3		; xmm7=tmp11H
239
	psubd	xmm0,xmm3		; xmm0=tmp12H
240
241
	movdqa	XMMWORD [wk(4)], xmm5	; wk(4)=tmp11L
242
	movdqa	XMMWORD [wk(5)], xmm7	; wk(5)=tmp11H
243
	movdqa	XMMWORD [wk(6)], xmm2	; wk(6)=tmp12L
244
	movdqa	XMMWORD [wk(7)], xmm0	; wk(7)=tmp12H
245
246
	; -- Odd part
247
248
	movdqa	xmm4, XMMWORD [XMMBLOCK(1,0,rsi,SIZEOF_JCOEF)]
249
	movdqa	xmm6, XMMWORD [XMMBLOCK(3,0,rsi,SIZEOF_JCOEF)]
250
	pmullw	xmm4, XMMWORD [XMMBLOCK(1,0,rdx,SIZEOF_ISLOW_MULT_TYPE)]
251
	pmullw	xmm6, XMMWORD [XMMBLOCK(3,0,rdx,SIZEOF_ISLOW_MULT_TYPE)]
252
	movdqa	xmm1, XMMWORD [XMMBLOCK(5,0,rsi,SIZEOF_JCOEF)]
253
	movdqa	xmm3, XMMWORD [XMMBLOCK(7,0,rsi,SIZEOF_JCOEF)]
254
	pmullw	xmm1, XMMWORD [XMMBLOCK(5,0,rdx,SIZEOF_ISLOW_MULT_TYPE)]
255
	pmullw	xmm3, XMMWORD [XMMBLOCK(7,0,rdx,SIZEOF_ISLOW_MULT_TYPE)]
256
257
	movdqa	xmm5,xmm6
258
	movdqa	xmm7,xmm4
259
	paddw	xmm5,xmm3		; xmm5=z3
260
	paddw	xmm7,xmm1		; xmm7=z4
261
262
	; (Original)
263
	; z5 = (z3 + z4) * 1.175875602;
264
	; z3 = z3 * -1.961570560;  z4 = z4 * -0.390180644;
265
	; z3 += z5;  z4 += z5;
266
	;
267
	; (This implementation)
268
	; z3 = z3 * (1.175875602 - 1.961570560) + z4 * 1.175875602;
269
	; z4 = z3 * 1.175875602 + z4 * (1.175875602 - 0.390180644);
270
271
	movdqa    xmm2,xmm5
272
	movdqa    xmm0,xmm5
273
	punpcklwd xmm2,xmm7
274
	punpckhwd xmm0,xmm7
275
	movdqa    xmm5,xmm2
276
	movdqa    xmm7,xmm0
277
	pmaddwd   xmm2,[rel PW_MF078_F117]	; xmm2=z3L
278
	pmaddwd   xmm0,[rel PW_MF078_F117]	; xmm0=z3H
279
	pmaddwd   xmm5,[rel PW_F117_F078]	; xmm5=z4L
280
	pmaddwd   xmm7,[rel PW_F117_F078]	; xmm7=z4H
281
282
	movdqa	XMMWORD [wk(10)], xmm2	; wk(10)=z3L
283
	movdqa	XMMWORD [wk(11)], xmm0	; wk(11)=z3H
284
285
	; (Original)
286
	; z1 = tmp0 + tmp3;  z2 = tmp1 + tmp2;
287
	; tmp0 = tmp0 * 0.298631336;  tmp1 = tmp1 * 2.053119869;
288
	; tmp2 = tmp2 * 3.072711026;  tmp3 = tmp3 * 1.501321110;
289
	; z1 = z1 * -0.899976223;  z2 = z2 * -2.562915447;
290
	; tmp0 += z1 + z3;  tmp1 += z2 + z4;
291
	; tmp2 += z2 + z3;  tmp3 += z1 + z4;
292
	;
293
	; (This implementation)
294
	; tmp0 = tmp0 * (0.298631336 - 0.899976223) + tmp3 * -0.899976223;
295
	; tmp1 = tmp1 * (2.053119869 - 2.562915447) + tmp2 * -2.562915447;
296
	; tmp2 = tmp1 * -2.562915447 + tmp2 * (3.072711026 - 2.562915447);
297
	; tmp3 = tmp0 * -0.899976223 + tmp3 * (1.501321110 - 0.899976223);
298
	; tmp0 += z3;  tmp1 += z4;
299
	; tmp2 += z3;  tmp3 += z4;
300
301
	movdqa    xmm2,xmm3
302
	movdqa    xmm0,xmm3
303
	punpcklwd xmm2,xmm4
304
	punpckhwd xmm0,xmm4
305
	movdqa    xmm3,xmm2
306
	movdqa    xmm4,xmm0
307
	pmaddwd   xmm2,[rel PW_MF060_MF089]	; xmm2=tmp0L
308
	pmaddwd   xmm0,[rel PW_MF060_MF089]	; xmm0=tmp0H
309
	pmaddwd   xmm3,[rel PW_MF089_F060]	; xmm3=tmp3L
310
	pmaddwd   xmm4,[rel PW_MF089_F060]	; xmm4=tmp3H
311
312
	paddd	xmm2, XMMWORD [wk(10)]	; xmm2=tmp0L
313
	paddd	xmm0, XMMWORD [wk(11)]	; xmm0=tmp0H
314
	paddd	xmm3,xmm5		; xmm3=tmp3L
315
	paddd	xmm4,xmm7		; xmm4=tmp3H
316
317
	movdqa	XMMWORD [wk(8)], xmm2	; wk(8)=tmp0L
318
	movdqa	XMMWORD [wk(9)], xmm0	; wk(9)=tmp0H
319
320
	movdqa    xmm2,xmm1
321
	movdqa    xmm0,xmm1
322
	punpcklwd xmm2,xmm6
323
	punpckhwd xmm0,xmm6
324
	movdqa    xmm1,xmm2
325
	movdqa    xmm6,xmm0
326
	pmaddwd   xmm2,[rel PW_MF050_MF256]	; xmm2=tmp1L
327
	pmaddwd   xmm0,[rel PW_MF050_MF256]	; xmm0=tmp1H
328
	pmaddwd   xmm1,[rel PW_MF256_F050]	; xmm1=tmp2L
329
	pmaddwd   xmm6,[rel PW_MF256_F050]	; xmm6=tmp2H
330
331
	paddd	xmm2,xmm5		; xmm2=tmp1L
332
	paddd	xmm0,xmm7		; xmm0=tmp1H
333
	paddd	xmm1, XMMWORD [wk(10)]	; xmm1=tmp2L
334
	paddd	xmm6, XMMWORD [wk(11)]	; xmm6=tmp2H
335
336
	movdqa	XMMWORD [wk(10)], xmm2	; wk(10)=tmp1L
337
	movdqa	XMMWORD [wk(11)], xmm0	; wk(11)=tmp1H
338
339
	; -- Final output stage
340
341
	movdqa	xmm5, XMMWORD [wk(0)]	; xmm5=tmp10L
342
	movdqa	xmm7, XMMWORD [wk(1)]	; xmm7=tmp10H
343
344
	movdqa	xmm2,xmm5
345
	movdqa	xmm0,xmm7
346
	paddd	xmm5,xmm3		; xmm5=data0L
347
	paddd	xmm7,xmm4		; xmm7=data0H
348
	psubd	xmm2,xmm3		; xmm2=data7L
349
	psubd	xmm0,xmm4		; xmm0=data7H
350
351
	movdqa	xmm3,[rel PD_DESCALE_P1]	; xmm3=[rel PD_DESCALE_P1]
352
353
	paddd	xmm5,xmm3
354
	paddd	xmm7,xmm3
355
	psrad	xmm5,DESCALE_P1
356
	psrad	xmm7,DESCALE_P1
357
	paddd	xmm2,xmm3
358
	paddd	xmm0,xmm3
359
	psrad	xmm2,DESCALE_P1
360
	psrad	xmm0,DESCALE_P1
361
362
	packssdw  xmm5,xmm7		; xmm5=data0=(00 01 02 03 04 05 06 07)
363
	packssdw  xmm2,xmm0		; xmm2=data7=(70 71 72 73 74 75 76 77)
364
365
	movdqa	xmm4, XMMWORD [wk(4)]	; xmm4=tmp11L
366
	movdqa	xmm3, XMMWORD [wk(5)]	; xmm3=tmp11H
367
368
	movdqa	xmm7,xmm4
369
	movdqa	xmm0,xmm3
370
	paddd	xmm4,xmm1		; xmm4=data1L
371
	paddd	xmm3,xmm6		; xmm3=data1H
372
	psubd	xmm7,xmm1		; xmm7=data6L
373
	psubd	xmm0,xmm6		; xmm0=data6H
374
375
	movdqa	xmm1,[rel PD_DESCALE_P1]	; xmm1=[rel PD_DESCALE_P1]
376
377
	paddd	xmm4,xmm1
378
	paddd	xmm3,xmm1
379
	psrad	xmm4,DESCALE_P1
380
	psrad	xmm3,DESCALE_P1
381
	paddd	xmm7,xmm1
382
	paddd	xmm0,xmm1
383
	psrad	xmm7,DESCALE_P1
384
	psrad	xmm0,DESCALE_P1
385
386
	packssdw  xmm4,xmm3		; xmm4=data1=(10 11 12 13 14 15 16 17)
387
	packssdw  xmm7,xmm0		; xmm7=data6=(60 61 62 63 64 65 66 67)
388
389
	movdqa    xmm6,xmm5		; transpose coefficients(phase 1)
390
	punpcklwd xmm5,xmm4		; xmm5=(00 10 01 11 02 12 03 13)
391
	punpckhwd xmm6,xmm4		; xmm6=(04 14 05 15 06 16 07 17)
392
	movdqa    xmm1,xmm7		; transpose coefficients(phase 1)
393
	punpcklwd xmm7,xmm2		; xmm7=(60 70 61 71 62 72 63 73)
394
	punpckhwd xmm1,xmm2		; xmm1=(64 74 65 75 66 76 67 77)
395
396
	movdqa	xmm3, XMMWORD [wk(6)]	; xmm3=tmp12L
397
	movdqa	xmm0, XMMWORD [wk(7)]	; xmm0=tmp12H
398
	movdqa	xmm4, XMMWORD [wk(10)]	; xmm4=tmp1L
399
	movdqa	xmm2, XMMWORD [wk(11)]	; xmm2=tmp1H
400
401
	movdqa	XMMWORD [wk(0)], xmm5	; wk(0)=(00 10 01 11 02 12 03 13)
402
	movdqa	XMMWORD [wk(1)], xmm6	; wk(1)=(04 14 05 15 06 16 07 17)
403
	movdqa	XMMWORD [wk(4)], xmm7	; wk(4)=(60 70 61 71 62 72 63 73)
404
	movdqa	XMMWORD [wk(5)], xmm1	; wk(5)=(64 74 65 75 66 76 67 77)
405
406
	movdqa	xmm5,xmm3
407
	movdqa	xmm6,xmm0
408
	paddd	xmm3,xmm4		; xmm3=data2L
409
	paddd	xmm0,xmm2		; xmm0=data2H
410
	psubd	xmm5,xmm4		; xmm5=data5L
411
	psubd	xmm6,xmm2		; xmm6=data5H
412
413
	movdqa	xmm7,[rel PD_DESCALE_P1]	; xmm7=[rel PD_DESCALE_P1]
414
415
	paddd	xmm3,xmm7
416
	paddd	xmm0,xmm7
417
	psrad	xmm3,DESCALE_P1
418
	psrad	xmm0,DESCALE_P1
419
	paddd	xmm5,xmm7
420
	paddd	xmm6,xmm7
421
	psrad	xmm5,DESCALE_P1
422
	psrad	xmm6,DESCALE_P1
423
424
	packssdw  xmm3,xmm0		; xmm3=data2=(20 21 22 23 24 25 26 27)
425
	packssdw  xmm5,xmm6		; xmm5=data5=(50 51 52 53 54 55 56 57)
426
427
	movdqa	xmm1, XMMWORD [wk(2)]	; xmm1=tmp13L
428
	movdqa	xmm4, XMMWORD [wk(3)]	; xmm4=tmp13H
429
	movdqa	xmm2, XMMWORD [wk(8)]	; xmm2=tmp0L
430
	movdqa	xmm7, XMMWORD [wk(9)]	; xmm7=tmp0H
431
432
	movdqa	xmm0,xmm1
433
	movdqa	xmm6,xmm4
434
	paddd	xmm1,xmm2		; xmm1=data3L
435
	paddd	xmm4,xmm7		; xmm4=data3H
436
	psubd	xmm0,xmm2		; xmm0=data4L
437
	psubd	xmm6,xmm7		; xmm6=data4H
438
439
	movdqa	xmm2,[rel PD_DESCALE_P1]	; xmm2=[rel PD_DESCALE_P1]
440
441
	paddd	xmm1,xmm2
442
	paddd	xmm4,xmm2
443
	psrad	xmm1,DESCALE_P1
444
	psrad	xmm4,DESCALE_P1
445
	paddd	xmm0,xmm2
446
	paddd	xmm6,xmm2
447
	psrad	xmm0,DESCALE_P1
448
	psrad	xmm6,DESCALE_P1
449
450
	packssdw  xmm1,xmm4		; xmm1=data3=(30 31 32 33 34 35 36 37)
451
	packssdw  xmm0,xmm6		; xmm0=data4=(40 41 42 43 44 45 46 47)
452
453
	movdqa	xmm7, XMMWORD [wk(0)]	; xmm7=(00 10 01 11 02 12 03 13)
454
	movdqa	xmm2, XMMWORD [wk(1)]	; xmm2=(04 14 05 15 06 16 07 17)
455
456
	movdqa    xmm4,xmm3		; transpose coefficients(phase 1)
457
	punpcklwd xmm3,xmm1		; xmm3=(20 30 21 31 22 32 23 33)
458
	punpckhwd xmm4,xmm1		; xmm4=(24 34 25 35 26 36 27 37)
459
	movdqa    xmm6,xmm0		; transpose coefficients(phase 1)
460
	punpcklwd xmm0,xmm5		; xmm0=(40 50 41 51 42 52 43 53)
461
	punpckhwd xmm6,xmm5		; xmm6=(44 54 45 55 46 56 47 57)
462
463
	movdqa    xmm1,xmm7		; transpose coefficients(phase 2)
464
	punpckldq xmm7,xmm3		; xmm7=(00 10 20 30 01 11 21 31)
465
	punpckhdq xmm1,xmm3		; xmm1=(02 12 22 32 03 13 23 33)
466
	movdqa    xmm5,xmm2		; transpose coefficients(phase 2)
467
	punpckldq xmm2,xmm4		; xmm2=(04 14 24 34 05 15 25 35)
468
	punpckhdq xmm5,xmm4		; xmm5=(06 16 26 36 07 17 27 37)
469
470
	movdqa	xmm3, XMMWORD [wk(4)]	; xmm3=(60 70 61 71 62 72 63 73)
471
	movdqa	xmm4, XMMWORD [wk(5)]	; xmm4=(64 74 65 75 66 76 67 77)
472
473
	movdqa	XMMWORD [wk(6)], xmm2	; wk(6)=(04 14 24 34 05 15 25 35)
474
	movdqa	XMMWORD [wk(7)], xmm5	; wk(7)=(06 16 26 36 07 17 27 37)
475
476
	movdqa    xmm2,xmm0		; transpose coefficients(phase 2)
477
	punpckldq xmm0,xmm3		; xmm0=(40 50 60 70 41 51 61 71)
478
	punpckhdq xmm2,xmm3		; xmm2=(42 52 62 72 43 53 63 73)
479
	movdqa    xmm5,xmm6		; transpose coefficients(phase 2)
480
	punpckldq xmm6,xmm4		; xmm6=(44 54 64 74 45 55 65 75)
481
	punpckhdq xmm5,xmm4		; xmm5=(46 56 66 76 47 57 67 77)
482
483
	movdqa     xmm3,xmm7		; transpose coefficients(phase 3)
484
	punpcklqdq xmm7,xmm0		; xmm7=col0=(00 10 20 30 40 50 60 70)
485
	punpckhqdq xmm3,xmm0		; xmm3=col1=(01 11 21 31 41 51 61 71)
486
	movdqa     xmm4,xmm1		; transpose coefficients(phase 3)
487
	punpcklqdq xmm1,xmm2		; xmm1=col2=(02 12 22 32 42 52 62 72)
488
	punpckhqdq xmm4,xmm2		; xmm4=col3=(03 13 23 33 43 53 63 73)
489
490
	movdqa	xmm0, XMMWORD [wk(6)]	; xmm0=(04 14 24 34 05 15 25 35)
491
	movdqa	xmm2, XMMWORD [wk(7)]	; xmm2=(06 16 26 36 07 17 27 37)
492
493
	movdqa	XMMWORD [wk(8)], xmm3	; wk(8)=col1
494
	movdqa	XMMWORD [wk(9)], xmm4	; wk(9)=col3
495
496
	movdqa     xmm3,xmm0		; transpose coefficients(phase 3)
497
	punpcklqdq xmm0,xmm6		; xmm0=col4=(04 14 24 34 44 54 64 74)
498
	punpckhqdq xmm3,xmm6		; xmm3=col5=(05 15 25 35 45 55 65 75)
499
	movdqa     xmm4,xmm2		; transpose coefficients(phase 3)
500
	punpcklqdq xmm2,xmm5		; xmm2=col6=(06 16 26 36 46 56 66 76)
501
	punpckhqdq xmm4,xmm5		; xmm4=col7=(07 17 27 37 47 57 67 77)
502
503
	movdqa	XMMWORD [wk(10)], xmm3	; wk(10)=col5
504
	movdqa	XMMWORD [wk(11)], xmm4	; wk(11)=col7
505
.column_end:
506
507
	; -- Prefetch the next coefficient block
508
509
	prefetchnta [rsi + DCTSIZE2*SIZEOF_JCOEF + 0*32]
510
	prefetchnta [rsi + DCTSIZE2*SIZEOF_JCOEF + 1*32]
511
	prefetchnta [rsi + DCTSIZE2*SIZEOF_JCOEF + 2*32]
512
	prefetchnta [rsi + DCTSIZE2*SIZEOF_JCOEF + 3*32]
513
514
	; ---- Pass 2: process rows from work array, store into output array.
515
516
	mov	rax, [original_rbp]
517
	mov	rdi, r12	; (JSAMPROW *)
518
	mov	rax, r13
519
520
	; -- Even part
521
522
	; xmm7=col0, xmm1=col2, xmm0=col4, xmm2=col6
523
524
	; (Original)
525
	; z1 = (z2 + z3) * 0.541196100;
526
	; tmp2 = z1 + z3 * -1.847759065;
527
	; tmp3 = z1 + z2 * 0.765366865;
528
	;
529
	; (This implementation)
530
	; tmp2 = z2 * 0.541196100 + z3 * (0.541196100 - 1.847759065);
531
	; tmp3 = z2 * (0.541196100 + 0.765366865) + z3 * 0.541196100;
532
533
	movdqa    xmm6,xmm1		; xmm1=in2=z2
534
	movdqa    xmm5,xmm1
535
	punpcklwd xmm6,xmm2		; xmm2=in6=z3
536
	punpckhwd xmm5,xmm2
537
	movdqa    xmm1,xmm6
538
	movdqa    xmm2,xmm5
539
	pmaddwd   xmm6,[rel PW_F130_F054]	; xmm6=tmp3L
540
	pmaddwd   xmm5,[rel PW_F130_F054]	; xmm5=tmp3H
541
	pmaddwd   xmm1,[rel PW_F054_MF130]	; xmm1=tmp2L
542
	pmaddwd   xmm2,[rel PW_F054_MF130]	; xmm2=tmp2H
543
544
	movdqa    xmm3,xmm7
545
	paddw     xmm7,xmm0		; xmm7=in0+in4
546
	psubw     xmm3,xmm0		; xmm3=in0-in4
547
548
	pxor      xmm4,xmm4
549
	pxor      xmm0,xmm0
550
	punpcklwd xmm4,xmm7		; xmm4=tmp0L
551
	punpckhwd xmm0,xmm7		; xmm0=tmp0H
552
	psrad     xmm4,(16-CONST_BITS)	; psrad xmm4,16 & pslld xmm4,CONST_BITS
553
	psrad     xmm0,(16-CONST_BITS)	; psrad xmm0,16 & pslld xmm0,CONST_BITS
554
555
	movdqa	xmm7,xmm4
556
	paddd	xmm4,xmm6		; xmm4=tmp10L
557
	psubd	xmm7,xmm6		; xmm7=tmp13L
558
	movdqa	xmm6,xmm0
559
	paddd	xmm0,xmm5		; xmm0=tmp10H
560
	psubd	xmm6,xmm5		; xmm6=tmp13H
561
562
	movdqa	XMMWORD [wk(0)], xmm4	; wk(0)=tmp10L
563
	movdqa	XMMWORD [wk(1)], xmm0	; wk(1)=tmp10H
564
	movdqa	XMMWORD [wk(2)], xmm7	; wk(2)=tmp13L
565
	movdqa	XMMWORD [wk(3)], xmm6	; wk(3)=tmp13H
566
567
	pxor      xmm5,xmm5
568
	pxor      xmm4,xmm4
569
	punpcklwd xmm5,xmm3		; xmm5=tmp1L
570
	punpckhwd xmm4,xmm3		; xmm4=tmp1H
571
	psrad     xmm5,(16-CONST_BITS)	; psrad xmm5,16 & pslld xmm5,CONST_BITS
572
	psrad     xmm4,(16-CONST_BITS)	; psrad xmm4,16 & pslld xmm4,CONST_BITS
573
574
	movdqa	xmm0,xmm5
575
	paddd	xmm5,xmm1		; xmm5=tmp11L
576
	psubd	xmm0,xmm1		; xmm0=tmp12L
577
	movdqa	xmm7,xmm4
578
	paddd	xmm4,xmm2		; xmm4=tmp11H
579
	psubd	xmm7,xmm2		; xmm7=tmp12H
580
581
	movdqa	XMMWORD [wk(4)], xmm5	; wk(4)=tmp11L
582
	movdqa	XMMWORD [wk(5)], xmm4	; wk(5)=tmp11H
583
	movdqa	XMMWORD [wk(6)], xmm0	; wk(6)=tmp12L
584
	movdqa	XMMWORD [wk(7)], xmm7	; wk(7)=tmp12H
585
586
	; -- Odd part
587
588
	movdqa	xmm6, XMMWORD [wk(9)]	; xmm6=col3
589
	movdqa	xmm3, XMMWORD [wk(8)]	; xmm3=col1
590
	movdqa	xmm1, XMMWORD [wk(11)]	; xmm1=col7
591
	movdqa	xmm2, XMMWORD [wk(10)]	; xmm2=col5
592
593
	movdqa	xmm5,xmm6
594
	movdqa	xmm4,xmm3
595
	paddw	xmm5,xmm1		; xmm5=z3
596
	paddw	xmm4,xmm2		; xmm4=z4
597
598
	; (Original)
599
	; z5 = (z3 + z4) * 1.175875602;
600
	; z3 = z3 * -1.961570560;  z4 = z4 * -0.390180644;
601
	; z3 += z5;  z4 += z5;
602
	;
603
	; (This implementation)
604
	; z3 = z3 * (1.175875602 - 1.961570560) + z4 * 1.175875602;
605
	; z4 = z3 * 1.175875602 + z4 * (1.175875602 - 0.390180644);
606
607
	movdqa    xmm0,xmm5
608
	movdqa    xmm7,xmm5
609
	punpcklwd xmm0,xmm4
610
	punpckhwd xmm7,xmm4
611
	movdqa    xmm5,xmm0
612
	movdqa    xmm4,xmm7
613
	pmaddwd   xmm0,[rel PW_MF078_F117]	; xmm0=z3L
614
	pmaddwd   xmm7,[rel PW_MF078_F117]	; xmm7=z3H
615
	pmaddwd   xmm5,[rel PW_F117_F078]	; xmm5=z4L
616
	pmaddwd   xmm4,[rel PW_F117_F078]	; xmm4=z4H
617
618
	movdqa	XMMWORD [wk(10)], xmm0	; wk(10)=z3L
619
	movdqa	XMMWORD [wk(11)], xmm7	; wk(11)=z3H
620
621
	; (Original)
622
	; z1 = tmp0 + tmp3;  z2 = tmp1 + tmp2;
623
	; tmp0 = tmp0 * 0.298631336;  tmp1 = tmp1 * 2.053119869;
624
	; tmp2 = tmp2 * 3.072711026;  tmp3 = tmp3 * 1.501321110;
625
	; z1 = z1 * -0.899976223;  z2 = z2 * -2.562915447;
626
	; tmp0 += z1 + z3;  tmp1 += z2 + z4;
627
	; tmp2 += z2 + z3;  tmp3 += z1 + z4;
628
	;
629
	; (This implementation)
630
	; tmp0 = tmp0 * (0.298631336 - 0.899976223) + tmp3 * -0.899976223;
631
	; tmp1 = tmp1 * (2.053119869 - 2.562915447) + tmp2 * -2.562915447;
632
	; tmp2 = tmp1 * -2.562915447 + tmp2 * (3.072711026 - 2.562915447);
633
	; tmp3 = tmp0 * -0.899976223 + tmp3 * (1.501321110 - 0.899976223);
634
	; tmp0 += z3;  tmp1 += z4;
635
	; tmp2 += z3;  tmp3 += z4;
636
637
	movdqa    xmm0,xmm1
638
	movdqa    xmm7,xmm1
639
	punpcklwd xmm0,xmm3
640
	punpckhwd xmm7,xmm3
641
	movdqa    xmm1,xmm0
642
	movdqa    xmm3,xmm7
643
	pmaddwd   xmm0,[rel PW_MF060_MF089]	; xmm0=tmp0L
644
	pmaddwd   xmm7,[rel PW_MF060_MF089]	; xmm7=tmp0H
645
	pmaddwd   xmm1,[rel PW_MF089_F060]	; xmm1=tmp3L
646
	pmaddwd   xmm3,[rel PW_MF089_F060]	; xmm3=tmp3H
647
648
	paddd	xmm0, XMMWORD [wk(10)]	; xmm0=tmp0L
649
	paddd	xmm7, XMMWORD [wk(11)]	; xmm7=tmp0H
650
	paddd	xmm1,xmm5		; xmm1=tmp3L
651
	paddd	xmm3,xmm4		; xmm3=tmp3H
652
653
	movdqa	XMMWORD [wk(8)], xmm0	; wk(8)=tmp0L
654
	movdqa	XMMWORD [wk(9)], xmm7	; wk(9)=tmp0H
655
656
	movdqa    xmm0,xmm2
657
	movdqa    xmm7,xmm2
658
	punpcklwd xmm0,xmm6
659
	punpckhwd xmm7,xmm6
660
	movdqa    xmm2,xmm0
661
	movdqa    xmm6,xmm7
662
	pmaddwd   xmm0,[rel PW_MF050_MF256]	; xmm0=tmp1L
663
	pmaddwd   xmm7,[rel PW_MF050_MF256]	; xmm7=tmp1H
664
	pmaddwd   xmm2,[rel PW_MF256_F050]	; xmm2=tmp2L
665
	pmaddwd   xmm6,[rel PW_MF256_F050]	; xmm6=tmp2H
666
667
	paddd	xmm0,xmm5		; xmm0=tmp1L
668
	paddd	xmm7,xmm4		; xmm7=tmp1H
669
	paddd	xmm2, XMMWORD [wk(10)]	; xmm2=tmp2L
670
	paddd	xmm6, XMMWORD [wk(11)]	; xmm6=tmp2H
671
672
	movdqa	XMMWORD [wk(10)], xmm0	; wk(10)=tmp1L
673
	movdqa	XMMWORD [wk(11)], xmm7	; wk(11)=tmp1H
674
675
	; -- Final output stage
676
677
	movdqa	xmm5, XMMWORD [wk(0)]	; xmm5=tmp10L
678
	movdqa	xmm4, XMMWORD [wk(1)]	; xmm4=tmp10H
679
680
	movdqa	xmm0,xmm5
681
	movdqa	xmm7,xmm4
682
	paddd	xmm5,xmm1		; xmm5=data0L
683
	paddd	xmm4,xmm3		; xmm4=data0H
684
	psubd	xmm0,xmm1		; xmm0=data7L
685
	psubd	xmm7,xmm3		; xmm7=data7H
686
687
	movdqa	xmm1,[rel PD_DESCALE_P2]	; xmm1=[rel PD_DESCALE_P2]
688
689
	paddd	xmm5,xmm1
690
	paddd	xmm4,xmm1
691
	psrad	xmm5,DESCALE_P2
692
	psrad	xmm4,DESCALE_P2
693
	paddd	xmm0,xmm1
694
	paddd	xmm7,xmm1
695
	psrad	xmm0,DESCALE_P2
696
	psrad	xmm7,DESCALE_P2
697
698
	packssdw  xmm5,xmm4		; xmm5=data0=(00 10 20 30 40 50 60 70)
699
	packssdw  xmm0,xmm7		; xmm0=data7=(07 17 27 37 47 57 67 77)
700
701
	movdqa	xmm3, XMMWORD [wk(4)]	; xmm3=tmp11L
702
	movdqa	xmm1, XMMWORD [wk(5)]	; xmm1=tmp11H
703
704
	movdqa	xmm4,xmm3
705
	movdqa	xmm7,xmm1
706
	paddd	xmm3,xmm2		; xmm3=data1L
707
	paddd	xmm1,xmm6		; xmm1=data1H
708
	psubd	xmm4,xmm2		; xmm4=data6L
709
	psubd	xmm7,xmm6		; xmm7=data6H
710
711
	movdqa	xmm2,[rel PD_DESCALE_P2]	; xmm2=[rel PD_DESCALE_P2]
712
713
	paddd	xmm3,xmm2
714
	paddd	xmm1,xmm2
715
	psrad	xmm3,DESCALE_P2
716
	psrad	xmm1,DESCALE_P2
717
	paddd	xmm4,xmm2
718
	paddd	xmm7,xmm2
719
	psrad	xmm4,DESCALE_P2
720
	psrad	xmm7,DESCALE_P2
721
722
	packssdw  xmm3,xmm1		; xmm3=data1=(01 11 21 31 41 51 61 71)
723
	packssdw  xmm4,xmm7		; xmm4=data6=(06 16 26 36 46 56 66 76)
724
725
	packsswb  xmm5,xmm4		; xmm5=(00 10 20 30 40 50 60 70 06 16 26 36 46 56 66 76)
726
	packsswb  xmm3,xmm0		; xmm3=(01 11 21 31 41 51 61 71 07 17 27 37 47 57 67 77)
727
728
	movdqa	xmm6, XMMWORD [wk(6)]	; xmm6=tmp12L
729
	movdqa	xmm2, XMMWORD [wk(7)]	; xmm2=tmp12H
730
	movdqa	xmm1, XMMWORD [wk(10)]	; xmm1=tmp1L
731
	movdqa	xmm7, XMMWORD [wk(11)]	; xmm7=tmp1H
732
733
	movdqa	XMMWORD [wk(0)], xmm5	; wk(0)=(00 10 20 30 40 50 60 70 06 16 26 36 46 56 66 76)
734
	movdqa	XMMWORD [wk(1)], xmm3	; wk(1)=(01 11 21 31 41 51 61 71 07 17 27 37 47 57 67 77)
735
736
	movdqa	xmm4,xmm6
737
	movdqa	xmm0,xmm2
738
	paddd	xmm6,xmm1		; xmm6=data2L
739
	paddd	xmm2,xmm7		; xmm2=data2H
740
	psubd	xmm4,xmm1		; xmm4=data5L
741
	psubd	xmm0,xmm7		; xmm0=data5H
742
743
	movdqa	xmm5,[rel PD_DESCALE_P2]	; xmm5=[rel PD_DESCALE_P2]
744
745
	paddd	xmm6,xmm5
746
	paddd	xmm2,xmm5
747
	psrad	xmm6,DESCALE_P2
748
	psrad	xmm2,DESCALE_P2
749
	paddd	xmm4,xmm5
750
	paddd	xmm0,xmm5
751
	psrad	xmm4,DESCALE_P2
752
	psrad	xmm0,DESCALE_P2
753
754
	packssdw  xmm6,xmm2		; xmm6=data2=(02 12 22 32 42 52 62 72)
755
	packssdw  xmm4,xmm0		; xmm4=data5=(05 15 25 35 45 55 65 75)
756
757
	movdqa	xmm3, XMMWORD [wk(2)]	; xmm3=tmp13L
758
	movdqa	xmm1, XMMWORD [wk(3)]	; xmm1=tmp13H
759
	movdqa	xmm7, XMMWORD [wk(8)]	; xmm7=tmp0L
760
	movdqa	xmm5, XMMWORD [wk(9)]	; xmm5=tmp0H
761
762
	movdqa	xmm2,xmm3
763
	movdqa	xmm0,xmm1
764
	paddd	xmm3,xmm7		; xmm3=data3L
765
	paddd	xmm1,xmm5		; xmm1=data3H
766
	psubd	xmm2,xmm7		; xmm2=data4L
767
	psubd	xmm0,xmm5		; xmm0=data4H
768
769
	movdqa	xmm7,[rel PD_DESCALE_P2]	; xmm7=[rel PD_DESCALE_P2]
770
771
	paddd	xmm3,xmm7
772
	paddd	xmm1,xmm7
773
	psrad	xmm3,DESCALE_P2
774
	psrad	xmm1,DESCALE_P2
775
	paddd	xmm2,xmm7
776
	paddd	xmm0,xmm7
777
	psrad	xmm2,DESCALE_P2
778
	psrad	xmm0,DESCALE_P2
779
780
	movdqa    xmm5,[rel PB_CENTERJSAMP]	; xmm5=[rel PB_CENTERJSAMP]
781
782
	packssdw  xmm3,xmm1		; xmm3=data3=(03 13 23 33 43 53 63 73)
783
	packssdw  xmm2,xmm0		; xmm2=data4=(04 14 24 34 44 54 64 74)
784
785
	movdqa    xmm7, XMMWORD [wk(0)]	; xmm7=(00 10 20 30 40 50 60 70 06 16 26 36 46 56 66 76)
786
	movdqa    xmm1, XMMWORD [wk(1)]	; xmm1=(01 11 21 31 41 51 61 71 07 17 27 37 47 57 67 77)
787
788
	packsswb  xmm6,xmm2		; xmm6=(02 12 22 32 42 52 62 72 04 14 24 34 44 54 64 74)
789
	packsswb  xmm3,xmm4		; xmm3=(03 13 23 33 43 53 63 73 05 15 25 35 45 55 65 75)
790
791
	paddb     xmm7,xmm5
792
	paddb     xmm1,xmm5
793
	paddb     xmm6,xmm5
794
	paddb     xmm3,xmm5
795
796
	movdqa    xmm0,xmm7	; transpose coefficients(phase 1)
797
	punpcklbw xmm7,xmm1	; xmm7=(00 01 10 11 20 21 30 31 40 41 50 51 60 61 70 71)
798
	punpckhbw xmm0,xmm1	; xmm0=(06 07 16 17 26 27 36 37 46 47 56 57 66 67 76 77)
799
	movdqa    xmm2,xmm6	; transpose coefficients(phase 1)
800
	punpcklbw xmm6,xmm3	; xmm6=(02 03 12 13 22 23 32 33 42 43 52 53 62 63 72 73)
801
	punpckhbw xmm2,xmm3	; xmm2=(04 05 14 15 24 25 34 35 44 45 54 55 64 65 74 75)
802
803
	movdqa    xmm4,xmm7	; transpose coefficients(phase 2)
804
	punpcklwd xmm7,xmm6	; xmm7=(00 01 02 03 10 11 12 13 20 21 22 23 30 31 32 33)
805
	punpckhwd xmm4,xmm6	; xmm4=(40 41 42 43 50 51 52 53 60 61 62 63 70 71 72 73)
806
	movdqa    xmm5,xmm2	; transpose coefficients(phase 2)
807
	punpcklwd xmm2,xmm0	; xmm2=(04 05 06 07 14 15 16 17 24 25 26 27 34 35 36 37)
808
	punpckhwd xmm5,xmm0	; xmm5=(44 45 46 47 54 55 56 57 64 65 66 67 74 75 76 77)
809
810
	movdqa    xmm1,xmm7	; transpose coefficients(phase 3)
811
	punpckldq xmm7,xmm2	; xmm7=(00 01 02 03 04 05 06 07 10 11 12 13 14 15 16 17)
812
	punpckhdq xmm1,xmm2	; xmm1=(20 21 22 23 24 25 26 27 30 31 32 33 34 35 36 37)
813
	movdqa    xmm3,xmm4	; transpose coefficients(phase 3)
814
	punpckldq xmm4,xmm5	; xmm4=(40 41 42 43 44 45 46 47 50 51 52 53 54 55 56 57)
815
	punpckhdq xmm3,xmm5	; xmm3=(60 61 62 63 64 65 66 67 70 71 72 73 74 75 76 77)
816
817
	pshufd	xmm6,xmm7,0x4E	; xmm6=(10 11 12 13 14 15 16 17 00 01 02 03 04 05 06 07)
818
	pshufd	xmm0,xmm1,0x4E	; xmm0=(30 31 32 33 34 35 36 37 20 21 22 23 24 25 26 27)
819
	pshufd	xmm2,xmm4,0x4E	; xmm2=(50 51 52 53 54 55 56 57 40 41 42 43 44 45 46 47)
820
	pshufd	xmm5,xmm3,0x4E	; xmm5=(70 71 72 73 74 75 76 77 60 61 62 63 64 65 66 67)
821
822
	mov	rdx, JSAMPROW [rdi+0*SIZEOF_JSAMPROW]
823
	mov	rsi, JSAMPROW [rdi+2*SIZEOF_JSAMPROW]
824
	movq	XMM_MMWORD [rdx+rax*SIZEOF_JSAMPLE], xmm7
825
	movq	XMM_MMWORD [rsi+rax*SIZEOF_JSAMPLE], xmm1
826
	mov	rdx, JSAMPROW [rdi+4*SIZEOF_JSAMPROW]
827
	mov	rsi, JSAMPROW [rdi+6*SIZEOF_JSAMPROW]
828
	movq	XMM_MMWORD [rdx+rax*SIZEOF_JSAMPLE], xmm4
829
	movq	XMM_MMWORD [rsi+rax*SIZEOF_JSAMPLE], xmm3
830
831
	mov	rdx, JSAMPROW [rdi+1*SIZEOF_JSAMPROW]
832
	mov	rsi, JSAMPROW [rdi+3*SIZEOF_JSAMPROW]
833
	movq	XMM_MMWORD [rdx+rax*SIZEOF_JSAMPLE], xmm6
834
	movq	XMM_MMWORD [rsi+rax*SIZEOF_JSAMPLE], xmm0
835
	mov	rdx, JSAMPROW [rdi+5*SIZEOF_JSAMPROW]
836
	mov	rsi, JSAMPROW [rdi+7*SIZEOF_JSAMPROW]
837
	movq	XMM_MMWORD [rdx+rax*SIZEOF_JSAMPLE], xmm2
838
	movq	XMM_MMWORD [rsi+rax*SIZEOF_JSAMPLE], xmm5
839
840
	uncollect_args
841
	mov	rsp,rbp		; rsp <- aligned rbp
842
	pop	rsp		; rsp <- original rbp
843
	pop	rbp
844
	ret
845
846
; For some reason, the OS X linker does not honor the request to align the
847
; segment unless we do this.
848
	align	16
(-)a/jpeg/simd/jiss2int.asm (+859 lines)
Line     Link Here 
Line 0    Link Here 
1
;
2
; jiss2int.asm - accurate integer IDCT (SSE2)
3
;
4
; Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
5
;
6
; Based on
7
; x86 SIMD extension for IJG JPEG library
8
; Copyright (C) 1999-2006, MIYASAKA Masaru.
9
; For conditions of distribution and use, see copyright notice in jsimdext.inc
10
;
11
; This file should be assembled with NASM (Netwide Assembler),
12
; can *not* be assembled with Microsoft's MASM or any compatible
13
; assembler (including Borland's Turbo Assembler).
14
; NASM is available from http://nasm.sourceforge.net/ or
15
; http://sourceforge.net/project/showfiles.php?group_id=6208
16
;
17
; This file contains a slow-but-accurate integer implementation of the
18
; inverse DCT (Discrete Cosine Transform). The following code is based
19
; directly on the IJG's original jidctint.c; see the jidctint.c for
20
; more details.
21
;
22
; [TAB8]
23
24
%include "jsimdext.inc"
25
%include "jdct.inc"
26
27
; --------------------------------------------------------------------------
28
29
%define CONST_BITS	13
30
%define PASS1_BITS	2
31
32
%define DESCALE_P1	(CONST_BITS-PASS1_BITS)
33
%define DESCALE_P2	(CONST_BITS+PASS1_BITS+3)
34
35
%if CONST_BITS == 13
36
F_0_298	equ	 2446		; FIX(0.298631336)
37
F_0_390	equ	 3196		; FIX(0.390180644)
38
F_0_541	equ	 4433		; FIX(0.541196100)
39
F_0_765	equ	 6270		; FIX(0.765366865)
40
F_0_899	equ	 7373		; FIX(0.899976223)
41
F_1_175	equ	 9633		; FIX(1.175875602)
42
F_1_501	equ	12299		; FIX(1.501321110)
43
F_1_847	equ	15137		; FIX(1.847759065)
44
F_1_961	equ	16069		; FIX(1.961570560)
45
F_2_053	equ	16819		; FIX(2.053119869)
46
F_2_562	equ	20995		; FIX(2.562915447)
47
F_3_072	equ	25172		; FIX(3.072711026)
48
%else
49
; NASM cannot do compile-time arithmetic on floating-point constants.
50
%define DESCALE(x,n)  (((x)+(1<<((n)-1)))>>(n))
51
F_0_298	equ	DESCALE( 320652955,30-CONST_BITS)	; FIX(0.298631336)
52
F_0_390	equ	DESCALE( 418953276,30-CONST_BITS)	; FIX(0.390180644)
53
F_0_541	equ	DESCALE( 581104887,30-CONST_BITS)	; FIX(0.541196100)
54
F_0_765	equ	DESCALE( 821806413,30-CONST_BITS)	; FIX(0.765366865)
55
F_0_899	equ	DESCALE( 966342111,30-CONST_BITS)	; FIX(0.899976223)
56
F_1_175	equ	DESCALE(1262586813,30-CONST_BITS)	; FIX(1.175875602)
57
F_1_501	equ	DESCALE(1612031267,30-CONST_BITS)	; FIX(1.501321110)
58
F_1_847	equ	DESCALE(1984016188,30-CONST_BITS)	; FIX(1.847759065)
59
F_1_961	equ	DESCALE(2106220350,30-CONST_BITS)	; FIX(1.961570560)
60
F_2_053	equ	DESCALE(2204520673,30-CONST_BITS)	; FIX(2.053119869)
61
F_2_562	equ	DESCALE(2751909506,30-CONST_BITS)	; FIX(2.562915447)
62
F_3_072	equ	DESCALE(3299298341,30-CONST_BITS)	; FIX(3.072711026)
63
%endif
64
65
; --------------------------------------------------------------------------
66
	SECTION	SEG_CONST
67
68
	alignz	16
69
	global	EXTN(jconst_idct_islow_sse2)
70
71
EXTN(jconst_idct_islow_sse2):
72
73
PW_F130_F054	times 4 dw  (F_0_541+F_0_765), F_0_541
74
PW_F054_MF130	times 4 dw  F_0_541, (F_0_541-F_1_847)
75
PW_MF078_F117	times 4 dw  (F_1_175-F_1_961), F_1_175
76
PW_F117_F078	times 4 dw  F_1_175, (F_1_175-F_0_390)
77
PW_MF060_MF089	times 4 dw  (F_0_298-F_0_899),-F_0_899
78
PW_MF089_F060	times 4 dw -F_0_899, (F_1_501-F_0_899)
79
PW_MF050_MF256	times 4 dw  (F_2_053-F_2_562),-F_2_562
80
PW_MF256_F050	times 4 dw -F_2_562, (F_3_072-F_2_562)
81
PD_DESCALE_P1	times 4 dd  1 << (DESCALE_P1-1)
82
PD_DESCALE_P2	times 4 dd  1 << (DESCALE_P2-1)
83
PB_CENTERJSAMP	times 16 db CENTERJSAMPLE
84
85
	alignz	16
86
87
; --------------------------------------------------------------------------
88
	SECTION	SEG_TEXT
89
	BITS	32
90
;
91
; Perform dequantization and inverse DCT on one block of coefficients.
92
;
93
; GLOBAL(void)
94
; jsimd_idct_islow_sse2 (void * dct_table, JCOEFPTR coef_block,
95
;                        JSAMPARRAY output_buf, JDIMENSION output_col)
96
;
97
98
%define dct_table(b)	(b)+8			; jpeg_component_info * compptr
99
%define coef_block(b)	(b)+12		; JCOEFPTR coef_block
100
%define output_buf(b)	(b)+16		; JSAMPARRAY output_buf
101
%define output_col(b)	(b)+20		; JDIMENSION output_col
102
103
%define original_ebp	ebp+0
104
%define wk(i)		ebp-(WK_NUM-(i))*SIZEOF_XMMWORD	; xmmword wk[WK_NUM]
105
%define WK_NUM		12
106
107
	align	16
108
	global	EXTN(jsimd_idct_islow_sse2)
109
110
EXTN(jsimd_idct_islow_sse2):
111
	push	ebp
112
	mov	eax,esp				; eax = original ebp
113
	sub	esp, byte 4
114
	and	esp, byte (-SIZEOF_XMMWORD)	; align to 128 bits
115
	mov	[esp],eax
116
	mov	ebp,esp				; ebp = aligned ebp
117
	lea	esp, [wk(0)]
118
	pushpic	ebx
119
;	push	ecx		; unused
120
;	push	edx		; need not be preserved
121
	push	esi
122
	push	edi
123
124
	get_GOT	ebx		; get GOT address
125
126
	; ---- Pass 1: process columns from input.
127
128
;	mov	eax, [original_ebp]
129
	mov	edx, POINTER [dct_table(eax)]	; quantptr
130
	mov	esi, JCOEFPTR [coef_block(eax)]		; inptr
131
132
%ifndef NO_ZERO_COLUMN_TEST_ISLOW_SSE2
133
	mov	eax, DWORD [DWBLOCK(1,0,esi,SIZEOF_JCOEF)]
134
	or	eax, DWORD [DWBLOCK(2,0,esi,SIZEOF_JCOEF)]
135
	jnz	near .columnDCT
136
137
	movdqa	xmm0, XMMWORD [XMMBLOCK(1,0,esi,SIZEOF_JCOEF)]
138
	movdqa	xmm1, XMMWORD [XMMBLOCK(2,0,esi,SIZEOF_JCOEF)]
139
	por	xmm0, XMMWORD [XMMBLOCK(3,0,esi,SIZEOF_JCOEF)]
140
	por	xmm1, XMMWORD [XMMBLOCK(4,0,esi,SIZEOF_JCOEF)]
141
	por	xmm0, XMMWORD [XMMBLOCK(5,0,esi,SIZEOF_JCOEF)]
142
	por	xmm1, XMMWORD [XMMBLOCK(6,0,esi,SIZEOF_JCOEF)]
143
	por	xmm0, XMMWORD [XMMBLOCK(7,0,esi,SIZEOF_JCOEF)]
144
	por	xmm1,xmm0
145
	packsswb xmm1,xmm1
146
	packsswb xmm1,xmm1
147
	movd	eax,xmm1
148
	test	eax,eax
149
	jnz	short .columnDCT
150
151
	; -- AC terms all zero
152
153
	movdqa	xmm5, XMMWORD [XMMBLOCK(0,0,esi,SIZEOF_JCOEF)]
154
	pmullw	xmm5, XMMWORD [XMMBLOCK(0,0,edx,SIZEOF_ISLOW_MULT_TYPE)]
155
156
	psllw	xmm5,PASS1_BITS
157
158
	movdqa    xmm4,xmm5		; xmm5=in0=(00 01 02 03 04 05 06 07)
159
	punpcklwd xmm5,xmm5		; xmm5=(00 00 01 01 02 02 03 03)
160
	punpckhwd xmm4,xmm4		; xmm4=(04 04 05 05 06 06 07 07)
161
162
	pshufd	xmm7,xmm5,0x00		; xmm7=col0=(00 00 00 00 00 00 00 00)
163
	pshufd	xmm6,xmm5,0x55		; xmm6=col1=(01 01 01 01 01 01 01 01)
164
	pshufd	xmm1,xmm5,0xAA		; xmm1=col2=(02 02 02 02 02 02 02 02)
165
	pshufd	xmm5,xmm5,0xFF		; xmm5=col3=(03 03 03 03 03 03 03 03)
166
	pshufd	xmm0,xmm4,0x00		; xmm0=col4=(04 04 04 04 04 04 04 04)
167
	pshufd	xmm3,xmm4,0x55		; xmm3=col5=(05 05 05 05 05 05 05 05)
168
	pshufd	xmm2,xmm4,0xAA		; xmm2=col6=(06 06 06 06 06 06 06 06)
169
	pshufd	xmm4,xmm4,0xFF		; xmm4=col7=(07 07 07 07 07 07 07 07)
170
171
	movdqa	XMMWORD [wk(8)], xmm6	; wk(8)=col1
172
	movdqa	XMMWORD [wk(9)], xmm5	; wk(9)=col3
173
	movdqa	XMMWORD [wk(10)], xmm3	; wk(10)=col5
174
	movdqa	XMMWORD [wk(11)], xmm4	; wk(11)=col7
175
	jmp	near .column_end
176
	alignx	16,7
177
%endif
178
.columnDCT:
179
180
	; -- Even part
181
182
	movdqa	xmm0, XMMWORD [XMMBLOCK(0,0,esi,SIZEOF_JCOEF)]
183
	movdqa	xmm1, XMMWORD [XMMBLOCK(2,0,esi,SIZEOF_JCOEF)]
184
	pmullw	xmm0, XMMWORD [XMMBLOCK(0,0,edx,SIZEOF_ISLOW_MULT_TYPE)]
185
	pmullw	xmm1, XMMWORD [XMMBLOCK(2,0,edx,SIZEOF_ISLOW_MULT_TYPE)]
186
	movdqa	xmm2, XMMWORD [XMMBLOCK(4,0,esi,SIZEOF_JCOEF)]
187
	movdqa	xmm3, XMMWORD [XMMBLOCK(6,0,esi,SIZEOF_JCOEF)]
188
	pmullw	xmm2, XMMWORD [XMMBLOCK(4,0,edx,SIZEOF_ISLOW_MULT_TYPE)]
189
	pmullw	xmm3, XMMWORD [XMMBLOCK(6,0,edx,SIZEOF_ISLOW_MULT_TYPE)]
190
191
	; (Original)
192
	; z1 = (z2 + z3) * 0.541196100;
193
	; tmp2 = z1 + z3 * -1.847759065;
194
	; tmp3 = z1 + z2 * 0.765366865;
195
	;
196
	; (This implementation)
197
	; tmp2 = z2 * 0.541196100 + z3 * (0.541196100 - 1.847759065);
198
	; tmp3 = z2 * (0.541196100 + 0.765366865) + z3 * 0.541196100;
199
200
	movdqa    xmm4,xmm1		; xmm1=in2=z2
201
	movdqa    xmm5,xmm1
202
	punpcklwd xmm4,xmm3		; xmm3=in6=z3
203
	punpckhwd xmm5,xmm3
204
	movdqa    xmm1,xmm4
205
	movdqa    xmm3,xmm5
206
	pmaddwd   xmm4,[GOTOFF(ebx,PW_F130_F054)]	; xmm4=tmp3L
207
	pmaddwd   xmm5,[GOTOFF(ebx,PW_F130_F054)]	; xmm5=tmp3H
208
	pmaddwd   xmm1,[GOTOFF(ebx,PW_F054_MF130)]	; xmm1=tmp2L
209
	pmaddwd   xmm3,[GOTOFF(ebx,PW_F054_MF130)]	; xmm3=tmp2H
210
211
	movdqa    xmm6,xmm0
212
	paddw     xmm0,xmm2		; xmm0=in0+in4
213
	psubw     xmm6,xmm2		; xmm6=in0-in4
214
215
	pxor      xmm7,xmm7
216
	pxor      xmm2,xmm2
217
	punpcklwd xmm7,xmm0		; xmm7=tmp0L
218
	punpckhwd xmm2,xmm0		; xmm2=tmp0H
219
	psrad     xmm7,(16-CONST_BITS)	; psrad xmm7,16 & pslld xmm7,CONST_BITS
220
	psrad     xmm2,(16-CONST_BITS)	; psrad xmm2,16 & pslld xmm2,CONST_BITS
221
222
	movdqa	xmm0,xmm7
223
	paddd	xmm7,xmm4		; xmm7=tmp10L
224
	psubd	xmm0,xmm4		; xmm0=tmp13L
225
	movdqa	xmm4,xmm2
226
	paddd	xmm2,xmm5		; xmm2=tmp10H
227
	psubd	xmm4,xmm5		; xmm4=tmp13H
228
229
	movdqa	XMMWORD [wk(0)], xmm7	; wk(0)=tmp10L
230
	movdqa	XMMWORD [wk(1)], xmm2	; wk(1)=tmp10H
231
	movdqa	XMMWORD [wk(2)], xmm0	; wk(2)=tmp13L
232
	movdqa	XMMWORD [wk(3)], xmm4	; wk(3)=tmp13H
233
234
	pxor      xmm5,xmm5
235
	pxor      xmm7,xmm7
236
	punpcklwd xmm5,xmm6		; xmm5=tmp1L
237
	punpckhwd xmm7,xmm6		; xmm7=tmp1H
238
	psrad     xmm5,(16-CONST_BITS)	; psrad xmm5,16 & pslld xmm5,CONST_BITS
239
	psrad     xmm7,(16-CONST_BITS)	; psrad xmm7,16 & pslld xmm7,CONST_BITS
240
241
	movdqa	xmm2,xmm5
242
	paddd	xmm5,xmm1		; xmm5=tmp11L
243
	psubd	xmm2,xmm1		; xmm2=tmp12L
244
	movdqa	xmm0,xmm7
245
	paddd	xmm7,xmm3		; xmm7=tmp11H
246
	psubd	xmm0,xmm3		; xmm0=tmp12H
247
248
	movdqa	XMMWORD [wk(4)], xmm5	; wk(4)=tmp11L
249
	movdqa	XMMWORD [wk(5)], xmm7	; wk(5)=tmp11H
250
	movdqa	XMMWORD [wk(6)], xmm2	; wk(6)=tmp12L
251
	movdqa	XMMWORD [wk(7)], xmm0	; wk(7)=tmp12H
252
253
	; -- Odd part
254
255
	movdqa	xmm4, XMMWORD [XMMBLOCK(1,0,esi,SIZEOF_JCOEF)]
256
	movdqa	xmm6, XMMWORD [XMMBLOCK(3,0,esi,SIZEOF_JCOEF)]
257
	pmullw	xmm4, XMMWORD [XMMBLOCK(1,0,edx,SIZEOF_ISLOW_MULT_TYPE)]
258
	pmullw	xmm6, XMMWORD [XMMBLOCK(3,0,edx,SIZEOF_ISLOW_MULT_TYPE)]
259
	movdqa	xmm1, XMMWORD [XMMBLOCK(5,0,esi,SIZEOF_JCOEF)]
260
	movdqa	xmm3, XMMWORD [XMMBLOCK(7,0,esi,SIZEOF_JCOEF)]
261
	pmullw	xmm1, XMMWORD [XMMBLOCK(5,0,edx,SIZEOF_ISLOW_MULT_TYPE)]
262
	pmullw	xmm3, XMMWORD [XMMBLOCK(7,0,edx,SIZEOF_ISLOW_MULT_TYPE)]
263
264
	movdqa	xmm5,xmm6
265
	movdqa	xmm7,xmm4
266
	paddw	xmm5,xmm3		; xmm5=z3
267
	paddw	xmm7,xmm1		; xmm7=z4
268
269
	; (Original)
270
	; z5 = (z3 + z4) * 1.175875602;
271
	; z3 = z3 * -1.961570560;  z4 = z4 * -0.390180644;
272
	; z3 += z5;  z4 += z5;
273
	;
274
	; (This implementation)
275
	; z3 = z3 * (1.175875602 - 1.961570560) + z4 * 1.175875602;
276
	; z4 = z3 * 1.175875602 + z4 * (1.175875602 - 0.390180644);
277
278
	movdqa    xmm2,xmm5
279
	movdqa    xmm0,xmm5
280
	punpcklwd xmm2,xmm7
281
	punpckhwd xmm0,xmm7
282
	movdqa    xmm5,xmm2
283
	movdqa    xmm7,xmm0
284
	pmaddwd   xmm2,[GOTOFF(ebx,PW_MF078_F117)]	; xmm2=z3L
285
	pmaddwd   xmm0,[GOTOFF(ebx,PW_MF078_F117)]	; xmm0=z3H
286
	pmaddwd   xmm5,[GOTOFF(ebx,PW_F117_F078)]	; xmm5=z4L
287
	pmaddwd   xmm7,[GOTOFF(ebx,PW_F117_F078)]	; xmm7=z4H
288
289
	movdqa	XMMWORD [wk(10)], xmm2	; wk(10)=z3L
290
	movdqa	XMMWORD [wk(11)], xmm0	; wk(11)=z3H
291
292
	; (Original)
293
	; z1 = tmp0 + tmp3;  z2 = tmp1 + tmp2;
294
	; tmp0 = tmp0 * 0.298631336;  tmp1 = tmp1 * 2.053119869;
295
	; tmp2 = tmp2 * 3.072711026;  tmp3 = tmp3 * 1.501321110;
296
	; z1 = z1 * -0.899976223;  z2 = z2 * -2.562915447;
297
	; tmp0 += z1 + z3;  tmp1 += z2 + z4;
298
	; tmp2 += z2 + z3;  tmp3 += z1 + z4;
299
	;
300
	; (This implementation)
301
	; tmp0 = tmp0 * (0.298631336 - 0.899976223) + tmp3 * -0.899976223;
302
	; tmp1 = tmp1 * (2.053119869 - 2.562915447) + tmp2 * -2.562915447;
303
	; tmp2 = tmp1 * -2.562915447 + tmp2 * (3.072711026 - 2.562915447);
304
	; tmp3 = tmp0 * -0.899976223 + tmp3 * (1.501321110 - 0.899976223);
305
	; tmp0 += z3;  tmp1 += z4;
306
	; tmp2 += z3;  tmp3 += z4;
307
308
	movdqa    xmm2,xmm3
309
	movdqa    xmm0,xmm3
310
	punpcklwd xmm2,xmm4
311
	punpckhwd xmm0,xmm4
312
	movdqa    xmm3,xmm2
313
	movdqa    xmm4,xmm0
314
	pmaddwd   xmm2,[GOTOFF(ebx,PW_MF060_MF089)]	; xmm2=tmp0L
315
	pmaddwd   xmm0,[GOTOFF(ebx,PW_MF060_MF089)]	; xmm0=tmp0H
316
	pmaddwd   xmm3,[GOTOFF(ebx,PW_MF089_F060)]	; xmm3=tmp3L
317
	pmaddwd   xmm4,[GOTOFF(ebx,PW_MF089_F060)]	; xmm4=tmp3H
318
319
	paddd	xmm2, XMMWORD [wk(10)]	; xmm2=tmp0L
320
	paddd	xmm0, XMMWORD [wk(11)]	; xmm0=tmp0H
321
	paddd	xmm3,xmm5		; xmm3=tmp3L
322
	paddd	xmm4,xmm7		; xmm4=tmp3H
323
324
	movdqa	XMMWORD [wk(8)], xmm2	; wk(8)=tmp0L
325
	movdqa	XMMWORD [wk(9)], xmm0	; wk(9)=tmp0H
326
327
	movdqa    xmm2,xmm1
328
	movdqa    xmm0,xmm1
329
	punpcklwd xmm2,xmm6
330
	punpckhwd xmm0,xmm6
331
	movdqa    xmm1,xmm2
332
	movdqa    xmm6,xmm0
333
	pmaddwd   xmm2,[GOTOFF(ebx,PW_MF050_MF256)]	; xmm2=tmp1L
334
	pmaddwd   xmm0,[GOTOFF(ebx,PW_MF050_MF256)]	; xmm0=tmp1H
335
	pmaddwd   xmm1,[GOTOFF(ebx,PW_MF256_F050)]	; xmm1=tmp2L
336
	pmaddwd   xmm6,[GOTOFF(ebx,PW_MF256_F050)]	; xmm6=tmp2H
337
338
	paddd	xmm2,xmm5		; xmm2=tmp1L
339
	paddd	xmm0,xmm7		; xmm0=tmp1H
340
	paddd	xmm1, XMMWORD [wk(10)]	; xmm1=tmp2L
341
	paddd	xmm6, XMMWORD [wk(11)]	; xmm6=tmp2H
342
343
	movdqa	XMMWORD [wk(10)], xmm2	; wk(10)=tmp1L
344
	movdqa	XMMWORD [wk(11)], xmm0	; wk(11)=tmp1H
345
346
	; -- Final output stage
347
348
	movdqa	xmm5, XMMWORD [wk(0)]	; xmm5=tmp10L
349
	movdqa	xmm7, XMMWORD [wk(1)]	; xmm7=tmp10H
350
351
	movdqa	xmm2,xmm5
352
	movdqa	xmm0,xmm7
353
	paddd	xmm5,xmm3		; xmm5=data0L
354
	paddd	xmm7,xmm4		; xmm7=data0H
355
	psubd	xmm2,xmm3		; xmm2=data7L
356
	psubd	xmm0,xmm4		; xmm0=data7H
357
358
	movdqa	xmm3,[GOTOFF(ebx,PD_DESCALE_P1)]	; xmm3=[PD_DESCALE_P1]
359
360
	paddd	xmm5,xmm3
361
	paddd	xmm7,xmm3
362
	psrad	xmm5,DESCALE_P1
363
	psrad	xmm7,DESCALE_P1
364
	paddd	xmm2,xmm3
365
	paddd	xmm0,xmm3
366
	psrad	xmm2,DESCALE_P1
367
	psrad	xmm0,DESCALE_P1
368
369
	packssdw  xmm5,xmm7		; xmm5=data0=(00 01 02 03 04 05 06 07)
370
	packssdw  xmm2,xmm0		; xmm2=data7=(70 71 72 73 74 75 76 77)
371
372
	movdqa	xmm4, XMMWORD [wk(4)]	; xmm4=tmp11L
373
	movdqa	xmm3, XMMWORD [wk(5)]	; xmm3=tmp11H
374
375
	movdqa	xmm7,xmm4
376
	movdqa	xmm0,xmm3
377
	paddd	xmm4,xmm1		; xmm4=data1L
378
	paddd	xmm3,xmm6		; xmm3=data1H
379
	psubd	xmm7,xmm1		; xmm7=data6L
380
	psubd	xmm0,xmm6		; xmm0=data6H
381
382
	movdqa	xmm1,[GOTOFF(ebx,PD_DESCALE_P1)]	; xmm1=[PD_DESCALE_P1]
383
384
	paddd	xmm4,xmm1
385
	paddd	xmm3,xmm1
386
	psrad	xmm4,DESCALE_P1
387
	psrad	xmm3,DESCALE_P1
388
	paddd	xmm7,xmm1
389
	paddd	xmm0,xmm1
390
	psrad	xmm7,DESCALE_P1
391
	psrad	xmm0,DESCALE_P1
392
393
	packssdw  xmm4,xmm3		; xmm4=data1=(10 11 12 13 14 15 16 17)
394
	packssdw  xmm7,xmm0		; xmm7=data6=(60 61 62 63 64 65 66 67)
395
396
	movdqa    xmm6,xmm5		; transpose coefficients(phase 1)
397
	punpcklwd xmm5,xmm4		; xmm5=(00 10 01 11 02 12 03 13)
398
	punpckhwd xmm6,xmm4		; xmm6=(04 14 05 15 06 16 07 17)
399
	movdqa    xmm1,xmm7		; transpose coefficients(phase 1)
400
	punpcklwd xmm7,xmm2		; xmm7=(60 70 61 71 62 72 63 73)
401
	punpckhwd xmm1,xmm2		; xmm1=(64 74 65 75 66 76 67 77)
402
403
	movdqa	xmm3, XMMWORD [wk(6)]	; xmm3=tmp12L
404
	movdqa	xmm0, XMMWORD [wk(7)]	; xmm0=tmp12H
405
	movdqa	xmm4, XMMWORD [wk(10)]	; xmm4=tmp1L
406
	movdqa	xmm2, XMMWORD [wk(11)]	; xmm2=tmp1H
407
408
	movdqa	XMMWORD [wk(0)], xmm5	; wk(0)=(00 10 01 11 02 12 03 13)
409
	movdqa	XMMWORD [wk(1)], xmm6	; wk(1)=(04 14 05 15 06 16 07 17)
410
	movdqa	XMMWORD [wk(4)], xmm7	; wk(4)=(60 70 61 71 62 72 63 73)
411
	movdqa	XMMWORD [wk(5)], xmm1	; wk(5)=(64 74 65 75 66 76 67 77)
412
413
	movdqa	xmm5,xmm3
414
	movdqa	xmm6,xmm0
415
	paddd	xmm3,xmm4		; xmm3=data2L
416
	paddd	xmm0,xmm2		; xmm0=data2H
417
	psubd	xmm5,xmm4		; xmm5=data5L
418
	psubd	xmm6,xmm2		; xmm6=data5H
419
420
	movdqa	xmm7,[GOTOFF(ebx,PD_DESCALE_P1)]	; xmm7=[PD_DESCALE_P1]
421
422
	paddd	xmm3,xmm7
423
	paddd	xmm0,xmm7
424
	psrad	xmm3,DESCALE_P1
425
	psrad	xmm0,DESCALE_P1
426
	paddd	xmm5,xmm7
427
	paddd	xmm6,xmm7
428
	psrad	xmm5,DESCALE_P1
429
	psrad	xmm6,DESCALE_P1
430
431
	packssdw  xmm3,xmm0		; xmm3=data2=(20 21 22 23 24 25 26 27)
432
	packssdw  xmm5,xmm6		; xmm5=data5=(50 51 52 53 54 55 56 57)
433
434
	movdqa	xmm1, XMMWORD [wk(2)]	; xmm1=tmp13L
435
	movdqa	xmm4, XMMWORD [wk(3)]	; xmm4=tmp13H
436
	movdqa	xmm2, XMMWORD [wk(8)]	; xmm2=tmp0L
437
	movdqa	xmm7, XMMWORD [wk(9)]	; xmm7=tmp0H
438
439
	movdqa	xmm0,xmm1
440
	movdqa	xmm6,xmm4
441
	paddd	xmm1,xmm2		; xmm1=data3L
442
	paddd	xmm4,xmm7		; xmm4=data3H
443
	psubd	xmm0,xmm2		; xmm0=data4L
444
	psubd	xmm6,xmm7		; xmm6=data4H
445
446
	movdqa	xmm2,[GOTOFF(ebx,PD_DESCALE_P1)]	; xmm2=[PD_DESCALE_P1]
447
448
	paddd	xmm1,xmm2
449
	paddd	xmm4,xmm2
450
	psrad	xmm1,DESCALE_P1
451
	psrad	xmm4,DESCALE_P1
452
	paddd	xmm0,xmm2
453
	paddd	xmm6,xmm2
454
	psrad	xmm0,DESCALE_P1
455
	psrad	xmm6,DESCALE_P1
456
457
	packssdw  xmm1,xmm4		; xmm1=data3=(30 31 32 33 34 35 36 37)
458
	packssdw  xmm0,xmm6		; xmm0=data4=(40 41 42 43 44 45 46 47)
459
460
	movdqa	xmm7, XMMWORD [wk(0)]	; xmm7=(00 10 01 11 02 12 03 13)
461
	movdqa	xmm2, XMMWORD [wk(1)]	; xmm2=(04 14 05 15 06 16 07 17)
462
463
	movdqa    xmm4,xmm3		; transpose coefficients(phase 1)
464
	punpcklwd xmm3,xmm1		; xmm3=(20 30 21 31 22 32 23 33)
465
	punpckhwd xmm4,xmm1		; xmm4=(24 34 25 35 26 36 27 37)
466
	movdqa    xmm6,xmm0		; transpose coefficients(phase 1)
467
	punpcklwd xmm0,xmm5		; xmm0=(40 50 41 51 42 52 43 53)
468
	punpckhwd xmm6,xmm5		; xmm6=(44 54 45 55 46 56 47 57)
469
470
	movdqa    xmm1,xmm7		; transpose coefficients(phase 2)
471
	punpckldq xmm7,xmm3		; xmm7=(00 10 20 30 01 11 21 31)
472
	punpckhdq xmm1,xmm3		; xmm1=(02 12 22 32 03 13 23 33)
473
	movdqa    xmm5,xmm2		; transpose coefficients(phase 2)
474
	punpckldq xmm2,xmm4		; xmm2=(04 14 24 34 05 15 25 35)
475
	punpckhdq xmm5,xmm4		; xmm5=(06 16 26 36 07 17 27 37)
476
477
	movdqa	xmm3, XMMWORD [wk(4)]	; xmm3=(60 70 61 71 62 72 63 73)
478
	movdqa	xmm4, XMMWORD [wk(5)]	; xmm4=(64 74 65 75 66 76 67 77)
479
480
	movdqa	XMMWORD [wk(6)], xmm2	; wk(6)=(04 14 24 34 05 15 25 35)
481
	movdqa	XMMWORD [wk(7)], xmm5	; wk(7)=(06 16 26 36 07 17 27 37)
482
483
	movdqa    xmm2,xmm0		; transpose coefficients(phase 2)
484
	punpckldq xmm0,xmm3		; xmm0=(40 50 60 70 41 51 61 71)
485
	punpckhdq xmm2,xmm3		; xmm2=(42 52 62 72 43 53 63 73)
486
	movdqa    xmm5,xmm6		; transpose coefficients(phase 2)
487
	punpckldq xmm6,xmm4		; xmm6=(44 54 64 74 45 55 65 75)
488
	punpckhdq xmm5,xmm4		; xmm5=(46 56 66 76 47 57 67 77)
489
490
	movdqa     xmm3,xmm7		; transpose coefficients(phase 3)
491
	punpcklqdq xmm7,xmm0		; xmm7=col0=(00 10 20 30 40 50 60 70)
492
	punpckhqdq xmm3,xmm0		; xmm3=col1=(01 11 21 31 41 51 61 71)
493
	movdqa     xmm4,xmm1		; transpose coefficients(phase 3)
494
	punpcklqdq xmm1,xmm2		; xmm1=col2=(02 12 22 32 42 52 62 72)
495
	punpckhqdq xmm4,xmm2		; xmm4=col3=(03 13 23 33 43 53 63 73)
496
497
	movdqa	xmm0, XMMWORD [wk(6)]	; xmm0=(04 14 24 34 05 15 25 35)
498
	movdqa	xmm2, XMMWORD [wk(7)]	; xmm2=(06 16 26 36 07 17 27 37)
499
500
	movdqa	XMMWORD [wk(8)], xmm3	; wk(8)=col1
501
	movdqa	XMMWORD [wk(9)], xmm4	; wk(9)=col3
502
503
	movdqa     xmm3,xmm0		; transpose coefficients(phase 3)
504
	punpcklqdq xmm0,xmm6		; xmm0=col4=(04 14 24 34 44 54 64 74)
505
	punpckhqdq xmm3,xmm6		; xmm3=col5=(05 15 25 35 45 55 65 75)
506
	movdqa     xmm4,xmm2		; transpose coefficients(phase 3)
507
	punpcklqdq xmm2,xmm5		; xmm2=col6=(06 16 26 36 46 56 66 76)
508
	punpckhqdq xmm4,xmm5		; xmm4=col7=(07 17 27 37 47 57 67 77)
509
510
	movdqa	XMMWORD [wk(10)], xmm3	; wk(10)=col5
511
	movdqa	XMMWORD [wk(11)], xmm4	; wk(11)=col7
512
.column_end:
513
514
	; -- Prefetch the next coefficient block
515
516
	prefetchnta [esi + DCTSIZE2*SIZEOF_JCOEF + 0*32]
517
	prefetchnta [esi + DCTSIZE2*SIZEOF_JCOEF + 1*32]
518
	prefetchnta [esi + DCTSIZE2*SIZEOF_JCOEF + 2*32]
519
	prefetchnta [esi + DCTSIZE2*SIZEOF_JCOEF + 3*32]
520
521
	; ---- Pass 2: process rows from work array, store into output array.
522
523
	mov	eax, [original_ebp]
524
	mov	edi, JSAMPARRAY [output_buf(eax)]	; (JSAMPROW *)
525
	mov	eax, JDIMENSION [output_col(eax)]
526
527
	; -- Even part
528
529
	; xmm7=col0, xmm1=col2, xmm0=col4, xmm2=col6
530
531
	; (Original)
532
	; z1 = (z2 + z3) * 0.541196100;
533
	; tmp2 = z1 + z3 * -1.847759065;
534
	; tmp3 = z1 + z2 * 0.765366865;
535
	;
536
	; (This implementation)
537
	; tmp2 = z2 * 0.541196100 + z3 * (0.541196100 - 1.847759065);
538
	; tmp3 = z2 * (0.541196100 + 0.765366865) + z3 * 0.541196100;
539
540
	movdqa    xmm6,xmm1		; xmm1=in2=z2
541
	movdqa    xmm5,xmm1
542
	punpcklwd xmm6,xmm2		; xmm2=in6=z3
543
	punpckhwd xmm5,xmm2
544
	movdqa    xmm1,xmm6
545
	movdqa    xmm2,xmm5
546
	pmaddwd   xmm6,[GOTOFF(ebx,PW_F130_F054)]	; xmm6=tmp3L
547
	pmaddwd   xmm5,[GOTOFF(ebx,PW_F130_F054)]	; xmm5=tmp3H
548
	pmaddwd   xmm1,[GOTOFF(ebx,PW_F054_MF130)]	; xmm1=tmp2L
549
	pmaddwd   xmm2,[GOTOFF(ebx,PW_F054_MF130)]	; xmm2=tmp2H
550
551
	movdqa    xmm3,xmm7
552
	paddw     xmm7,xmm0		; xmm7=in0+in4
553
	psubw     xmm3,xmm0		; xmm3=in0-in4
554
555
	pxor      xmm4,xmm4
556
	pxor      xmm0,xmm0
557
	punpcklwd xmm4,xmm7		; xmm4=tmp0L
558
	punpckhwd xmm0,xmm7		; xmm0=tmp0H
559
	psrad     xmm4,(16-CONST_BITS)	; psrad xmm4,16 & pslld xmm4,CONST_BITS
560
	psrad     xmm0,(16-CONST_BITS)	; psrad xmm0,16 & pslld xmm0,CONST_BITS
561
562
	movdqa	xmm7,xmm4
563
	paddd	xmm4,xmm6		; xmm4=tmp10L
564
	psubd	xmm7,xmm6		; xmm7=tmp13L
565
	movdqa	xmm6,xmm0
566
	paddd	xmm0,xmm5		; xmm0=tmp10H
567
	psubd	xmm6,xmm5		; xmm6=tmp13H
568
569
	movdqa	XMMWORD [wk(0)], xmm4	; wk(0)=tmp10L
570
	movdqa	XMMWORD [wk(1)], xmm0	; wk(1)=tmp10H
571
	movdqa	XMMWORD [wk(2)], xmm7	; wk(2)=tmp13L
572
	movdqa	XMMWORD [wk(3)], xmm6	; wk(3)=tmp13H
573
574
	pxor      xmm5,xmm5
575
	pxor      xmm4,xmm4
576
	punpcklwd xmm5,xmm3		; xmm5=tmp1L
577
	punpckhwd xmm4,xmm3		; xmm4=tmp1H
578
	psrad     xmm5,(16-CONST_BITS)	; psrad xmm5,16 & pslld xmm5,CONST_BITS
579
	psrad     xmm4,(16-CONST_BITS)	; psrad xmm4,16 & pslld xmm4,CONST_BITS
580
581
	movdqa	xmm0,xmm5
582
	paddd	xmm5,xmm1		; xmm5=tmp11L
583
	psubd	xmm0,xmm1		; xmm0=tmp12L
584
	movdqa	xmm7,xmm4
585
	paddd	xmm4,xmm2		; xmm4=tmp11H
586
	psubd	xmm7,xmm2		; xmm7=tmp12H
587
588
	movdqa	XMMWORD [wk(4)], xmm5	; wk(4)=tmp11L
589
	movdqa	XMMWORD [wk(5)], xmm4	; wk(5)=tmp11H
590
	movdqa	XMMWORD [wk(6)], xmm0	; wk(6)=tmp12L
591
	movdqa	XMMWORD [wk(7)], xmm7	; wk(7)=tmp12H
592
593
	; -- Odd part
594
595
	movdqa	xmm6, XMMWORD [wk(9)]	; xmm6=col3
596
	movdqa	xmm3, XMMWORD [wk(8)]	; xmm3=col1
597
	movdqa	xmm1, XMMWORD [wk(11)]	; xmm1=col7
598
	movdqa	xmm2, XMMWORD [wk(10)]	; xmm2=col5
599
600
	movdqa	xmm5,xmm6
601
	movdqa	xmm4,xmm3
602
	paddw	xmm5,xmm1		; xmm5=z3
603
	paddw	xmm4,xmm2		; xmm4=z4
604
605
	; (Original)
606
	; z5 = (z3 + z4) * 1.175875602;
607
	; z3 = z3 * -1.961570560;  z4 = z4 * -0.390180644;
608
	; z3 += z5;  z4 += z5;
609
	;
610
	; (This implementation)
611
	; z3 = z3 * (1.175875602 - 1.961570560) + z4 * 1.175875602;
612
	; z4 = z3 * 1.175875602 + z4 * (1.175875602 - 0.390180644);
613
614
	movdqa    xmm0,xmm5
615
	movdqa    xmm7,xmm5
616
	punpcklwd xmm0,xmm4
617
	punpckhwd xmm7,xmm4
618
	movdqa    xmm5,xmm0
619
	movdqa    xmm4,xmm7
620
	pmaddwd   xmm0,[GOTOFF(ebx,PW_MF078_F117)]	; xmm0=z3L
621
	pmaddwd   xmm7,[GOTOFF(ebx,PW_MF078_F117)]	; xmm7=z3H
622
	pmaddwd   xmm5,[GOTOFF(ebx,PW_F117_F078)]	; xmm5=z4L
623
	pmaddwd   xmm4,[GOTOFF(ebx,PW_F117_F078)]	; xmm4=z4H
624
625
	movdqa	XMMWORD [wk(10)], xmm0	; wk(10)=z3L
626
	movdqa	XMMWORD [wk(11)], xmm7	; wk(11)=z3H
627
628
	; (Original)
629
	; z1 = tmp0 + tmp3;  z2 = tmp1 + tmp2;
630
	; tmp0 = tmp0 * 0.298631336;  tmp1 = tmp1 * 2.053119869;
631
	; tmp2 = tmp2 * 3.072711026;  tmp3 = tmp3 * 1.501321110;
632
	; z1 = z1 * -0.899976223;  z2 = z2 * -2.562915447;
633
	; tmp0 += z1 + z3;  tmp1 += z2 + z4;
634
	; tmp2 += z2 + z3;  tmp3 += z1 + z4;
635
	;
636
	; (This implementation)
637
	; tmp0 = tmp0 * (0.298631336 - 0.899976223) + tmp3 * -0.899976223;
638
	; tmp1 = tmp1 * (2.053119869 - 2.562915447) + tmp2 * -2.562915447;
639
	; tmp2 = tmp1 * -2.562915447 + tmp2 * (3.072711026 - 2.562915447);
640
	; tmp3 = tmp0 * -0.899976223 + tmp3 * (1.501321110 - 0.899976223);
641
	; tmp0 += z3;  tmp1 += z4;
642
	; tmp2 += z3;  tmp3 += z4;
643
644
	movdqa    xmm0,xmm1
645
	movdqa    xmm7,xmm1
646
	punpcklwd xmm0,xmm3
647
	punpckhwd xmm7,xmm3
648
	movdqa    xmm1,xmm0
649
	movdqa    xmm3,xmm7
650
	pmaddwd   xmm0,[GOTOFF(ebx,PW_MF060_MF089)]	; xmm0=tmp0L
651
	pmaddwd   xmm7,[GOTOFF(ebx,PW_MF060_MF089)]	; xmm7=tmp0H
652
	pmaddwd   xmm1,[GOTOFF(ebx,PW_MF089_F060)]	; xmm1=tmp3L
653
	pmaddwd   xmm3,[GOTOFF(ebx,PW_MF089_F060)]	; xmm3=tmp3H
654
655
	paddd	xmm0, XMMWORD [wk(10)]	; xmm0=tmp0L
656
	paddd	xmm7, XMMWORD [wk(11)]	; xmm7=tmp0H
657
	paddd	xmm1,xmm5		; xmm1=tmp3L
658
	paddd	xmm3,xmm4		; xmm3=tmp3H
659
660
	movdqa	XMMWORD [wk(8)], xmm0	; wk(8)=tmp0L
661
	movdqa	XMMWORD [wk(9)], xmm7	; wk(9)=tmp0H
662
663
	movdqa    xmm0,xmm2
664
	movdqa    xmm7,xmm2
665
	punpcklwd xmm0,xmm6
666
	punpckhwd xmm7,xmm6
667
	movdqa    xmm2,xmm0
668
	movdqa    xmm6,xmm7
669
	pmaddwd   xmm0,[GOTOFF(ebx,PW_MF050_MF256)]	; xmm0=tmp1L
670
	pmaddwd   xmm7,[GOTOFF(ebx,PW_MF050_MF256)]	; xmm7=tmp1H
671
	pmaddwd   xmm2,[GOTOFF(ebx,PW_MF256_F050)]	; xmm2=tmp2L
672
	pmaddwd   xmm6,[GOTOFF(ebx,PW_MF256_F050)]	; xmm6=tmp2H
673
674
	paddd	xmm0,xmm5		; xmm0=tmp1L
675
	paddd	xmm7,xmm4		; xmm7=tmp1H
676
	paddd	xmm2, XMMWORD [wk(10)]	; xmm2=tmp2L
677
	paddd	xmm6, XMMWORD [wk(11)]	; xmm6=tmp2H
678
679
	movdqa	XMMWORD [wk(10)], xmm0	; wk(10)=tmp1L
680
	movdqa	XMMWORD [wk(11)], xmm7	; wk(11)=tmp1H
681
682
	; -- Final output stage
683
684
	movdqa	xmm5, XMMWORD [wk(0)]	; xmm5=tmp10L
685
	movdqa	xmm4, XMMWORD [wk(1)]	; xmm4=tmp10H
686
687
	movdqa	xmm0,xmm5
688
	movdqa	xmm7,xmm4
689
	paddd	xmm5,xmm1		; xmm5=data0L
690
	paddd	xmm4,xmm3		; xmm4=data0H
691
	psubd	xmm0,xmm1		; xmm0=data7L
692
	psubd	xmm7,xmm3		; xmm7=data7H
693
694
	movdqa	xmm1,[GOTOFF(ebx,PD_DESCALE_P2)]	; xmm1=[PD_DESCALE_P2]
695
696
	paddd	xmm5,xmm1
697
	paddd	xmm4,xmm1
698
	psrad	xmm5,DESCALE_P2
699
	psrad	xmm4,DESCALE_P2
700
	paddd	xmm0,xmm1
701
	paddd	xmm7,xmm1
702
	psrad	xmm0,DESCALE_P2
703
	psrad	xmm7,DESCALE_P2
704
705
	packssdw  xmm5,xmm4		; xmm5=data0=(00 10 20 30 40 50 60 70)
706
	packssdw  xmm0,xmm7		; xmm0=data7=(07 17 27 37 47 57 67 77)
707
708
	movdqa	xmm3, XMMWORD [wk(4)]	; xmm3=tmp11L
709
	movdqa	xmm1, XMMWORD [wk(5)]	; xmm1=tmp11H
710
711
	movdqa	xmm4,xmm3
712
	movdqa	xmm7,xmm1
713
	paddd	xmm3,xmm2		; xmm3=data1L
714
	paddd	xmm1,xmm6		; xmm1=data1H
715
	psubd	xmm4,xmm2		; xmm4=data6L
716
	psubd	xmm7,xmm6		; xmm7=data6H
717
718
	movdqa	xmm2,[GOTOFF(ebx,PD_DESCALE_P2)]	; xmm2=[PD_DESCALE_P2]
719
720
	paddd	xmm3,xmm2
721
	paddd	xmm1,xmm2
722
	psrad	xmm3,DESCALE_P2
723
	psrad	xmm1,DESCALE_P2
724
	paddd	xmm4,xmm2
725
	paddd	xmm7,xmm2
726
	psrad	xmm4,DESCALE_P2
727
	psrad	xmm7,DESCALE_P2
728
729
	packssdw  xmm3,xmm1		; xmm3=data1=(01 11 21 31 41 51 61 71)
730
	packssdw  xmm4,xmm7		; xmm4=data6=(06 16 26 36 46 56 66 76)
731
732
	packsswb  xmm5,xmm4		; xmm5=(00 10 20 30 40 50 60 70 06 16 26 36 46 56 66 76)
733
	packsswb  xmm3,xmm0		; xmm3=(01 11 21 31 41 51 61 71 07 17 27 37 47 57 67 77)
734
735
	movdqa	xmm6, XMMWORD [wk(6)]	; xmm6=tmp12L
736
	movdqa	xmm2, XMMWORD [wk(7)]	; xmm2=tmp12H
737
	movdqa	xmm1, XMMWORD [wk(10)]	; xmm1=tmp1L
738
	movdqa	xmm7, XMMWORD [wk(11)]	; xmm7=tmp1H
739
740
	movdqa	XMMWORD [wk(0)], xmm5	; wk(0)=(00 10 20 30 40 50 60 70 06 16 26 36 46 56 66 76)
741
	movdqa	XMMWORD [wk(1)], xmm3	; wk(1)=(01 11 21 31 41 51 61 71 07 17 27 37 47 57 67 77)
742
743
	movdqa	xmm4,xmm6
744
	movdqa	xmm0,xmm2
745
	paddd	xmm6,xmm1		; xmm6=data2L
746
	paddd	xmm2,xmm7		; xmm2=data2H
747
	psubd	xmm4,xmm1		; xmm4=data5L
748
	psubd	xmm0,xmm7		; xmm0=data5H
749
750
	movdqa	xmm5,[GOTOFF(ebx,PD_DESCALE_P2)]	; xmm5=[PD_DESCALE_P2]
751
752
	paddd	xmm6,xmm5
753
	paddd	xmm2,xmm5
754
	psrad	xmm6,DESCALE_P2
755
	psrad	xmm2,DESCALE_P2
756
	paddd	xmm4,xmm5
757
	paddd	xmm0,xmm5
758
	psrad	xmm4,DESCALE_P2
759
	psrad	xmm0,DESCALE_P2
760
761
	packssdw  xmm6,xmm2		; xmm6=data2=(02 12 22 32 42 52 62 72)
762
	packssdw  xmm4,xmm0		; xmm4=data5=(05 15 25 35 45 55 65 75)
763
764
	movdqa	xmm3, XMMWORD [wk(2)]	; xmm3=tmp13L
765
	movdqa	xmm1, XMMWORD [wk(3)]	; xmm1=tmp13H
766
	movdqa	xmm7, XMMWORD [wk(8)]	; xmm7=tmp0L
767
	movdqa	xmm5, XMMWORD [wk(9)]	; xmm5=tmp0H
768
769
	movdqa	xmm2,xmm3
770
	movdqa	xmm0,xmm1
771
	paddd	xmm3,xmm7		; xmm3=data3L
772
	paddd	xmm1,xmm5		; xmm1=data3H
773
	psubd	xmm2,xmm7		; xmm2=data4L
774
	psubd	xmm0,xmm5		; xmm0=data4H
775
776
	movdqa	xmm7,[GOTOFF(ebx,PD_DESCALE_P2)]	; xmm7=[PD_DESCALE_P2]
777
778
	paddd	xmm3,xmm7
779
	paddd	xmm1,xmm7
780
	psrad	xmm3,DESCALE_P2
781
	psrad	xmm1,DESCALE_P2
782
	paddd	xmm2,xmm7
783
	paddd	xmm0,xmm7
784
	psrad	xmm2,DESCALE_P2
785
	psrad	xmm0,DESCALE_P2
786
787
	movdqa    xmm5,[GOTOFF(ebx,PB_CENTERJSAMP)]	; xmm5=[PB_CENTERJSAMP]
788
789
	packssdw  xmm3,xmm1		; xmm3=data3=(03 13 23 33 43 53 63 73)
790
	packssdw  xmm2,xmm0		; xmm2=data4=(04 14 24 34 44 54 64 74)
791
792
	movdqa    xmm7, XMMWORD [wk(0)]	; xmm7=(00 10 20 30 40 50 60 70 06 16 26 36 46 56 66 76)
793
	movdqa    xmm1, XMMWORD [wk(1)]	; xmm1=(01 11 21 31 41 51 61 71 07 17 27 37 47 57 67 77)
794
795
	packsswb  xmm6,xmm2		; xmm6=(02 12 22 32 42 52 62 72 04 14 24 34 44 54 64 74)
796
	packsswb  xmm3,xmm4		; xmm3=(03 13 23 33 43 53 63 73 05 15 25 35 45 55 65 75)
797
798
	paddb     xmm7,xmm5
799
	paddb     xmm1,xmm5
800
	paddb     xmm6,xmm5
801
	paddb     xmm3,xmm5
802
803
	movdqa    xmm0,xmm7	; transpose coefficients(phase 1)
804
	punpcklbw xmm7,xmm1	; xmm7=(00 01 10 11 20 21 30 31 40 41 50 51 60 61 70 71)
805
	punpckhbw xmm0,xmm1	; xmm0=(06 07 16 17 26 27 36 37 46 47 56 57 66 67 76 77)
806
	movdqa    xmm2,xmm6	; transpose coefficients(phase 1)
807
	punpcklbw xmm6,xmm3	; xmm6=(02 03 12 13 22 23 32 33 42 43 52 53 62 63 72 73)
808
	punpckhbw xmm2,xmm3	; xmm2=(04 05 14 15 24 25 34 35 44 45 54 55 64 65 74 75)
809
810
	movdqa    xmm4,xmm7	; transpose coefficients(phase 2)
811
	punpcklwd xmm7,xmm6	; xmm7=(00 01 02 03 10 11 12 13 20 21 22 23 30 31 32 33)
812
	punpckhwd xmm4,xmm6	; xmm4=(40 41 42 43 50 51 52 53 60 61 62 63 70 71 72 73)
813
	movdqa    xmm5,xmm2	; transpose coefficients(phase 2)
814
	punpcklwd xmm2,xmm0	; xmm2=(04 05 06 07 14 15 16 17 24 25 26 27 34 35 36 37)
815
	punpckhwd xmm5,xmm0	; xmm5=(44 45 46 47 54 55 56 57 64 65 66 67 74 75 76 77)
816
817
	movdqa    xmm1,xmm7	; transpose coefficients(phase 3)
818
	punpckldq xmm7,xmm2	; xmm7=(00 01 02 03 04 05 06 07 10 11 12 13 14 15 16 17)
819
	punpckhdq xmm1,xmm2	; xmm1=(20 21 22 23 24 25 26 27 30 31 32 33 34 35 36 37)
820
	movdqa    xmm3,xmm4	; transpose coefficients(phase 3)
821
	punpckldq xmm4,xmm5	; xmm4=(40 41 42 43 44 45 46 47 50 51 52 53 54 55 56 57)
822
	punpckhdq xmm3,xmm5	; xmm3=(60 61 62 63 64 65 66 67 70 71 72 73 74 75 76 77)
823
824
	pshufd	xmm6,xmm7,0x4E	; xmm6=(10 11 12 13 14 15 16 17 00 01 02 03 04 05 06 07)
825
	pshufd	xmm0,xmm1,0x4E	; xmm0=(30 31 32 33 34 35 36 37 20 21 22 23 24 25 26 27)
826
	pshufd	xmm2,xmm4,0x4E	; xmm2=(50 51 52 53 54 55 56 57 40 41 42 43 44 45 46 47)
827
	pshufd	xmm5,xmm3,0x4E	; xmm5=(70 71 72 73 74 75 76 77 60 61 62 63 64 65 66 67)
828
829
	mov	edx, JSAMPROW [edi+0*SIZEOF_JSAMPROW]
830
	mov	esi, JSAMPROW [edi+2*SIZEOF_JSAMPROW]
831
	movq	XMM_MMWORD [edx+eax*SIZEOF_JSAMPLE], xmm7
832
	movq	XMM_MMWORD [esi+eax*SIZEOF_JSAMPLE], xmm1
833
	mov	edx, JSAMPROW [edi+4*SIZEOF_JSAMPROW]
834
	mov	esi, JSAMPROW [edi+6*SIZEOF_JSAMPROW]
835
	movq	XMM_MMWORD [edx+eax*SIZEOF_JSAMPLE], xmm4
836
	movq	XMM_MMWORD [esi+eax*SIZEOF_JSAMPLE], xmm3
837
838
	mov	edx, JSAMPROW [edi+1*SIZEOF_JSAMPROW]
839
	mov	esi, JSAMPROW [edi+3*SIZEOF_JSAMPROW]
840
	movq	XMM_MMWORD [edx+eax*SIZEOF_JSAMPLE], xmm6
841
	movq	XMM_MMWORD [esi+eax*SIZEOF_JSAMPLE], xmm0
842
	mov	edx, JSAMPROW [edi+5*SIZEOF_JSAMPROW]
843
	mov	esi, JSAMPROW [edi+7*SIZEOF_JSAMPROW]
844
	movq	XMM_MMWORD [edx+eax*SIZEOF_JSAMPLE], xmm2
845
	movq	XMM_MMWORD [esi+eax*SIZEOF_JSAMPLE], xmm5
846
847
	pop	edi
848
	pop	esi
849
;	pop	edx		; need not be preserved
850
;	pop	ecx		; unused
851
	poppic	ebx
852
	mov	esp,ebp		; esp <- aligned ebp
853
	pop	esp		; esp <- original ebp
854
	pop	ebp
855
	ret
856
857
; For some reason, the OS X linker does not honor the request to align the
858
; segment unless we do this.
859
	align	16
(-)a/jpeg/simd/jiss2red-64.asm (+576 lines)
Line     Link Here 
Line 0    Link Here 
1
;
2
; jiss2red-64.asm - reduced-size IDCT (64-bit SSE2)
3
;
4
; Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
5
; Copyright 2009 D. R. Commander
6
;
7
; Based on
8
; x86 SIMD extension for IJG JPEG library
9
; Copyright (C) 1999-2006, MIYASAKA Masaru.
10
; For conditions of distribution and use, see copyright notice in jsimdext.inc
11
;
12
; This file should be assembled with NASM (Netwide Assembler),
13
; can *not* be assembled with Microsoft's MASM or any compatible
14
; assembler (including Borland's Turbo Assembler).
15
; NASM is available from http://nasm.sourceforge.net/ or
16
; http://sourceforge.net/project/showfiles.php?group_id=6208
17
;
18
; This file contains inverse-DCT routines that produce reduced-size
19
; output: either 4x4 or 2x2 pixels from an 8x8 DCT block.
20
; The following code is based directly on the IJG's original jidctred.c;
21
; see the jidctred.c for more details.
22
;
23
; [TAB8]
24
25
%include "jsimdext.inc"
26
%include "jdct.inc"
27
28
; --------------------------------------------------------------------------
29
30
%define CONST_BITS	13
31
%define PASS1_BITS	2
32
33
%define DESCALE_P1_4	(CONST_BITS-PASS1_BITS+1)
34
%define DESCALE_P2_4	(CONST_BITS+PASS1_BITS+3+1)
35
%define DESCALE_P1_2	(CONST_BITS-PASS1_BITS+2)
36
%define DESCALE_P2_2	(CONST_BITS+PASS1_BITS+3+2)
37
38
%if CONST_BITS == 13
39
F_0_211	equ	 1730		; FIX(0.211164243)
40
F_0_509	equ	 4176		; FIX(0.509795579)
41
F_0_601	equ	 4926		; FIX(0.601344887)
42
F_0_720	equ	 5906		; FIX(0.720959822)
43
F_0_765	equ	 6270		; FIX(0.765366865)
44
F_0_850	equ	 6967		; FIX(0.850430095)
45
F_0_899	equ	 7373		; FIX(0.899976223)
46
F_1_061	equ	 8697		; FIX(1.061594337)
47
F_1_272	equ	10426		; FIX(1.272758580)
48
F_1_451	equ	11893		; FIX(1.451774981)
49
F_1_847	equ	15137		; FIX(1.847759065)
50
F_2_172	equ	17799		; FIX(2.172734803)
51
F_2_562	equ	20995		; FIX(2.562915447)
52
F_3_624	equ	29692		; FIX(3.624509785)
53
%else
54
; NASM cannot do compile-time arithmetic on floating-point constants.
55
%define DESCALE(x,n)  (((x)+(1<<((n)-1)))>>(n))
56
F_0_211	equ	DESCALE( 226735879,30-CONST_BITS)	; FIX(0.211164243)
57
F_0_509	equ	DESCALE( 547388834,30-CONST_BITS)	; FIX(0.509795579)
58
F_0_601	equ	DESCALE( 645689155,30-CONST_BITS)	; FIX(0.601344887)
59
F_0_720	equ	DESCALE( 774124714,30-CONST_BITS)	; FIX(0.720959822)
60
F_0_765	equ	DESCALE( 821806413,30-CONST_BITS)	; FIX(0.765366865)
61
F_0_850	equ	DESCALE( 913142361,30-CONST_BITS)	; FIX(0.850430095)
62
F_0_899	equ	DESCALE( 966342111,30-CONST_BITS)	; FIX(0.899976223)
63
F_1_061	equ	DESCALE(1139878239,30-CONST_BITS)	; FIX(1.061594337)
64
F_1_272	equ	DESCALE(1366614119,30-CONST_BITS)	; FIX(1.272758580)
65
F_1_451	equ	DESCALE(1558831516,30-CONST_BITS)	; FIX(1.451774981)
66
F_1_847	equ	DESCALE(1984016188,30-CONST_BITS)	; FIX(1.847759065)
67
F_2_172	equ	DESCALE(2332956230,30-CONST_BITS)	; FIX(2.172734803)
68
F_2_562	equ	DESCALE(2751909506,30-CONST_BITS)	; FIX(2.562915447)
69
F_3_624	equ	DESCALE(3891787747,30-CONST_BITS)	; FIX(3.624509785)
70
%endif
71
72
; --------------------------------------------------------------------------
73
	SECTION	SEG_CONST
74
75
	alignz	16
76
	global	EXTN(jconst_idct_red_sse2)
77
78
EXTN(jconst_idct_red_sse2):
79
80
PW_F184_MF076	times 4 dw  F_1_847,-F_0_765
81
PW_F256_F089	times 4 dw  F_2_562, F_0_899
82
PW_F106_MF217	times 4 dw  F_1_061,-F_2_172
83
PW_MF060_MF050	times 4 dw -F_0_601,-F_0_509
84
PW_F145_MF021	times 4 dw  F_1_451,-F_0_211
85
PW_F362_MF127	times 4 dw  F_3_624,-F_1_272
86
PW_F085_MF072	times 4 dw  F_0_850,-F_0_720
87
PD_DESCALE_P1_4	times 4 dd  1 << (DESCALE_P1_4-1)
88
PD_DESCALE_P2_4	times 4 dd  1 << (DESCALE_P2_4-1)
89
PD_DESCALE_P1_2	times 4 dd  1 << (DESCALE_P1_2-1)
90
PD_DESCALE_P2_2	times 4 dd  1 << (DESCALE_P2_2-1)
91
PB_CENTERJSAMP	times 16 db CENTERJSAMPLE
92
93
	alignz	16
94
95
; --------------------------------------------------------------------------
96
	SECTION	SEG_TEXT
97
	BITS	64
98
;
99
; Perform dequantization and inverse DCT on one block of coefficients,
100
; producing a reduced-size 4x4 output block.
101
;
102
; GLOBAL(void)
103
; jsimd_idct_4x4_sse2 (void * dct_table, JCOEFPTR coef_block,
104
;                      JSAMPARRAY output_buf, JDIMENSION output_col)
105
;
106
107
; r10 = void * dct_table
108
; r11 = JCOEFPTR coef_block
109
; r12 = JSAMPARRAY output_buf
110
; r13 = JDIMENSION output_col
111
112
%define original_rbp	rbp+0
113
%define wk(i)		rbp-(WK_NUM-(i))*SIZEOF_XMMWORD	; xmmword wk[WK_NUM]
114
%define WK_NUM		2
115
116
	align	16
117
	global	EXTN(jsimd_idct_4x4_sse2)
118
119
EXTN(jsimd_idct_4x4_sse2):
120
	push	rbp
121
	mov	rax,rsp				; rax = original rbp
122
	sub	rsp, byte 4
123
	and	rsp, byte (-SIZEOF_XMMWORD)	; align to 128 bits
124
	mov	[rsp],rax
125
	mov	rbp,rsp				; rbp = aligned rbp
126
	lea	rsp, [wk(0)]
127
	collect_args
128
129
	; ---- Pass 1: process columns from input.
130
131
	mov	rdx, r10	; quantptr
132
	mov	rsi, r11		; inptr
133
134
%ifndef NO_ZERO_COLUMN_TEST_4X4_SSE2
135
	mov	eax, DWORD [DWBLOCK(1,0,rsi,SIZEOF_JCOEF)]
136
	or	eax, DWORD [DWBLOCK(2,0,rsi,SIZEOF_JCOEF)]
137
	jnz	short .columnDCT
138
139
	movdqa	xmm0, XMMWORD [XMMBLOCK(1,0,rsi,SIZEOF_JCOEF)]
140
	movdqa	xmm1, XMMWORD [XMMBLOCK(2,0,rsi,SIZEOF_JCOEF)]
141
	por	xmm0, XMMWORD [XMMBLOCK(3,0,rsi,SIZEOF_JCOEF)]
142
	por	xmm1, XMMWORD [XMMBLOCK(5,0,rsi,SIZEOF_JCOEF)]
143
	por	xmm0, XMMWORD [XMMBLOCK(6,0,rsi,SIZEOF_JCOEF)]
144
	por	xmm1, XMMWORD [XMMBLOCK(7,0,rsi,SIZEOF_JCOEF)]
145
	por	xmm0,xmm1
146
	packsswb xmm0,xmm0
147
	packsswb xmm0,xmm0
148
	movd	eax,xmm0
149
	test	rax,rax
150
	jnz	short .columnDCT
151
152
	; -- AC terms all zero
153
154
	movdqa	xmm0, XMMWORD [XMMBLOCK(0,0,rsi,SIZEOF_JCOEF)]
155
	pmullw	xmm0, XMMWORD [XMMBLOCK(0,0,rdx,SIZEOF_ISLOW_MULT_TYPE)]
156
157
	psllw	xmm0,PASS1_BITS
158
159
	movdqa    xmm3,xmm0	; xmm0=in0=(00 01 02 03 04 05 06 07)
160
	punpcklwd xmm0,xmm0	; xmm0=(00 00 01 01 02 02 03 03)
161
	punpckhwd xmm3,xmm3	; xmm3=(04 04 05 05 06 06 07 07)
162
163
	pshufd	xmm1,xmm0,0x50	; xmm1=[col0 col1]=(00 00 00 00 01 01 01 01)
164
	pshufd	xmm0,xmm0,0xFA	; xmm0=[col2 col3]=(02 02 02 02 03 03 03 03)
165
	pshufd	xmm6,xmm3,0x50	; xmm6=[col4 col5]=(04 04 04 04 05 05 05 05)
166
	pshufd	xmm3,xmm3,0xFA	; xmm3=[col6 col7]=(06 06 06 06 07 07 07 07)
167
168
	jmp	near .column_end
169
%endif
170
.columnDCT:
171
172
	; -- Odd part
173
174
	movdqa	xmm0, XMMWORD [XMMBLOCK(1,0,rsi,SIZEOF_JCOEF)]
175
	movdqa	xmm1, XMMWORD [XMMBLOCK(3,0,rsi,SIZEOF_JCOEF)]
176
	pmullw	xmm0, XMMWORD [XMMBLOCK(1,0,rdx,SIZEOF_ISLOW_MULT_TYPE)]
177
	pmullw	xmm1, XMMWORD [XMMBLOCK(3,0,rdx,SIZEOF_ISLOW_MULT_TYPE)]
178
	movdqa	xmm2, XMMWORD [XMMBLOCK(5,0,rsi,SIZEOF_JCOEF)]
179
	movdqa	xmm3, XMMWORD [XMMBLOCK(7,0,rsi,SIZEOF_JCOEF)]
180
	pmullw	xmm2, XMMWORD [XMMBLOCK(5,0,rdx,SIZEOF_ISLOW_MULT_TYPE)]
181
	pmullw	xmm3, XMMWORD [XMMBLOCK(7,0,rdx,SIZEOF_ISLOW_MULT_TYPE)]
182
183
	movdqa    xmm4,xmm0
184
	movdqa    xmm5,xmm0
185
	punpcklwd xmm4,xmm1
186
	punpckhwd xmm5,xmm1
187
	movdqa    xmm0,xmm4
188
	movdqa    xmm1,xmm5
189
	pmaddwd   xmm4,[rel PW_F256_F089]	; xmm4=(tmp2L)
190
	pmaddwd   xmm5,[rel PW_F256_F089]	; xmm5=(tmp2H)
191
	pmaddwd   xmm0,[rel PW_F106_MF217]	; xmm0=(tmp0L)
192
	pmaddwd   xmm1,[rel PW_F106_MF217]	; xmm1=(tmp0H)
193
194
	movdqa    xmm6,xmm2
195
	movdqa    xmm7,xmm2
196
	punpcklwd xmm6,xmm3
197
	punpckhwd xmm7,xmm3
198
	movdqa    xmm2,xmm6
199
	movdqa    xmm3,xmm7
200
	pmaddwd   xmm6,[rel PW_MF060_MF050]	; xmm6=(tmp2L)
201
	pmaddwd   xmm7,[rel PW_MF060_MF050]	; xmm7=(tmp2H)
202
	pmaddwd   xmm2,[rel PW_F145_MF021]	; xmm2=(tmp0L)
203
	pmaddwd   xmm3,[rel PW_F145_MF021]	; xmm3=(tmp0H)
204
205
	paddd	xmm6,xmm4		; xmm6=tmp2L
206
	paddd	xmm7,xmm5		; xmm7=tmp2H
207
	paddd	xmm2,xmm0		; xmm2=tmp0L
208
	paddd	xmm3,xmm1		; xmm3=tmp0H
209
210
	movdqa	XMMWORD [wk(0)], xmm2	; wk(0)=tmp0L
211
	movdqa	XMMWORD [wk(1)], xmm3	; wk(1)=tmp0H
212
213
	; -- Even part
214
215
	movdqa	xmm4, XMMWORD [XMMBLOCK(0,0,rsi,SIZEOF_JCOEF)]
216
	movdqa	xmm5, XMMWORD [XMMBLOCK(2,0,rsi,SIZEOF_JCOEF)]
217
	movdqa	xmm0, XMMWORD [XMMBLOCK(6,0,rsi,SIZEOF_JCOEF)]
218
	pmullw	xmm4, XMMWORD [XMMBLOCK(0,0,rdx,SIZEOF_ISLOW_MULT_TYPE)]
219
	pmullw	xmm5, XMMWORD [XMMBLOCK(2,0,rdx,SIZEOF_ISLOW_MULT_TYPE)]
220
	pmullw	xmm0, XMMWORD [XMMBLOCK(6,0,rdx,SIZEOF_ISLOW_MULT_TYPE)]
221
222
	pxor      xmm1,xmm1
223
	pxor      xmm2,xmm2
224
	punpcklwd xmm1,xmm4		; xmm1=tmp0L
225
	punpckhwd xmm2,xmm4		; xmm2=tmp0H
226
	psrad     xmm1,(16-CONST_BITS-1) ; psrad xmm1,16 & pslld xmm1,CONST_BITS+1
227
	psrad     xmm2,(16-CONST_BITS-1) ; psrad xmm2,16 & pslld xmm2,CONST_BITS+1
228
229
	movdqa    xmm3,xmm5		; xmm5=in2=z2
230
	punpcklwd xmm5,xmm0		; xmm0=in6=z3
231
	punpckhwd xmm3,xmm0
232
	pmaddwd   xmm5,[rel PW_F184_MF076]	; xmm5=tmp2L
233
	pmaddwd   xmm3,[rel PW_F184_MF076]	; xmm3=tmp2H
234
235
	movdqa	xmm4,xmm1
236
	movdqa	xmm0,xmm2
237
	paddd	xmm1,xmm5		; xmm1=tmp10L
238
	paddd	xmm2,xmm3		; xmm2=tmp10H
239
	psubd	xmm4,xmm5		; xmm4=tmp12L
240
	psubd	xmm0,xmm3		; xmm0=tmp12H
241
242
	; -- Final output stage
243
244
	movdqa	xmm5,xmm1
245
	movdqa	xmm3,xmm2
246
	paddd	xmm1,xmm6		; xmm1=data0L
247
	paddd	xmm2,xmm7		; xmm2=data0H
248
	psubd	xmm5,xmm6		; xmm5=data3L
249
	psubd	xmm3,xmm7		; xmm3=data3H
250
251
	movdqa	xmm6,[rel PD_DESCALE_P1_4]	; xmm6=[rel PD_DESCALE_P1_4]
252
253
	paddd	xmm1,xmm6
254
	paddd	xmm2,xmm6
255
	psrad	xmm1,DESCALE_P1_4
256
	psrad	xmm2,DESCALE_P1_4
257
	paddd	xmm5,xmm6
258
	paddd	xmm3,xmm6
259
	psrad	xmm5,DESCALE_P1_4
260
	psrad	xmm3,DESCALE_P1_4
261
262
	packssdw  xmm1,xmm2		; xmm1=data0=(00 01 02 03 04 05 06 07)
263
	packssdw  xmm5,xmm3		; xmm5=data3=(30 31 32 33 34 35 36 37)
264
265
	movdqa	xmm7, XMMWORD [wk(0)]	; xmm7=tmp0L
266
	movdqa	xmm6, XMMWORD [wk(1)]	; xmm6=tmp0H
267
268
	movdqa	xmm2,xmm4
269
	movdqa	xmm3,xmm0
270
	paddd	xmm4,xmm7		; xmm4=data1L
271
	paddd	xmm0,xmm6		; xmm0=data1H
272
	psubd	xmm2,xmm7		; xmm2=data2L
273
	psubd	xmm3,xmm6		; xmm3=data2H
274
275
	movdqa	xmm7,[rel PD_DESCALE_P1_4]	; xmm7=[rel PD_DESCALE_P1_4]
276
277
	paddd	xmm4,xmm7
278
	paddd	xmm0,xmm7
279
	psrad	xmm4,DESCALE_P1_4
280
	psrad	xmm0,DESCALE_P1_4
281
	paddd	xmm2,xmm7
282
	paddd	xmm3,xmm7
283
	psrad	xmm2,DESCALE_P1_4
284
	psrad	xmm3,DESCALE_P1_4
285
286
	packssdw  xmm4,xmm0		; xmm4=data1=(10 11 12 13 14 15 16 17)
287
	packssdw  xmm2,xmm3		; xmm2=data2=(20 21 22 23 24 25 26 27)
288
289
	movdqa    xmm6,xmm1	; transpose coefficients(phase 1)
290
	punpcklwd xmm1,xmm4	; xmm1=(00 10 01 11 02 12 03 13)
291
	punpckhwd xmm6,xmm4	; xmm6=(04 14 05 15 06 16 07 17)
292
	movdqa    xmm7,xmm2	; transpose coefficients(phase 1)
293
	punpcklwd xmm2,xmm5	; xmm2=(20 30 21 31 22 32 23 33)
294
	punpckhwd xmm7,xmm5	; xmm7=(24 34 25 35 26 36 27 37)
295
296
	movdqa    xmm0,xmm1	; transpose coefficients(phase 2)
297
	punpckldq xmm1,xmm2	; xmm1=[col0 col1]=(00 10 20 30 01 11 21 31)
298
	punpckhdq xmm0,xmm2	; xmm0=[col2 col3]=(02 12 22 32 03 13 23 33)
299
	movdqa    xmm3,xmm6	; transpose coefficients(phase 2)
300
	punpckldq xmm6,xmm7	; xmm6=[col4 col5]=(04 14 24 34 05 15 25 35)
301
	punpckhdq xmm3,xmm7	; xmm3=[col6 col7]=(06 16 26 36 07 17 27 37)
302
.column_end:
303
304
	; -- Prefetch the next coefficient block
305
306
	prefetchnta [rsi + DCTSIZE2*SIZEOF_JCOEF + 0*32]
307
	prefetchnta [rsi + DCTSIZE2*SIZEOF_JCOEF + 1*32]
308
	prefetchnta [rsi + DCTSIZE2*SIZEOF_JCOEF + 2*32]
309
	prefetchnta [rsi + DCTSIZE2*SIZEOF_JCOEF + 3*32]
310
311
	; ---- Pass 2: process rows, store into output array.
312
313
	mov	rax, [original_rbp]
314
	mov	rdi, r12	; (JSAMPROW *)
315
	mov	rax, r13
316
317
	; -- Even part
318
319
	pxor      xmm4,xmm4
320
	punpcklwd xmm4,xmm1		; xmm4=tmp0
321
	psrad     xmm4,(16-CONST_BITS-1) ; psrad xmm4,16 & pslld xmm4,CONST_BITS+1
322
323
	; -- Odd part
324
325
	punpckhwd xmm1,xmm0
326
	punpckhwd xmm6,xmm3
327
	movdqa    xmm5,xmm1
328
	movdqa    xmm2,xmm6
329
	pmaddwd   xmm1,[rel PW_F256_F089]	; xmm1=(tmp2)
330
	pmaddwd   xmm6,[rel PW_MF060_MF050]	; xmm6=(tmp2)
331
	pmaddwd   xmm5,[rel PW_F106_MF217]	; xmm5=(tmp0)
332
	pmaddwd   xmm2,[rel PW_F145_MF021]	; xmm2=(tmp0)
333
334
	paddd     xmm6,xmm1		; xmm6=tmp2
335
	paddd     xmm2,xmm5		; xmm2=tmp0
336
337
	; -- Even part
338
339
	punpcklwd xmm0,xmm3
340
	pmaddwd   xmm0,[rel PW_F184_MF076]	; xmm0=tmp2
341
342
	movdqa    xmm7,xmm4
343
	paddd     xmm4,xmm0		; xmm4=tmp10
344
	psubd     xmm7,xmm0		; xmm7=tmp12
345
346
	; -- Final output stage
347
348
	movdqa	xmm1,[rel PD_DESCALE_P2_4]	; xmm1=[rel PD_DESCALE_P2_4]
349
350
	movdqa	xmm5,xmm4
351
	movdqa	xmm3,xmm7
352
	paddd	xmm4,xmm6		; xmm4=data0=(00 10 20 30)
353
	paddd	xmm7,xmm2		; xmm7=data1=(01 11 21 31)
354
	psubd	xmm5,xmm6		; xmm5=data3=(03 13 23 33)
355
	psubd	xmm3,xmm2		; xmm3=data2=(02 12 22 32)
356
357
	paddd	xmm4,xmm1
358
	paddd	xmm7,xmm1
359
	psrad	xmm4,DESCALE_P2_4
360
	psrad	xmm7,DESCALE_P2_4
361
	paddd	xmm5,xmm1
362
	paddd	xmm3,xmm1
363
	psrad	xmm5,DESCALE_P2_4
364
	psrad	xmm3,DESCALE_P2_4
365
366
	packssdw  xmm4,xmm3		; xmm4=(00 10 20 30 02 12 22 32)
367
	packssdw  xmm7,xmm5		; xmm7=(01 11 21 31 03 13 23 33)
368
369
	movdqa    xmm0,xmm4		; transpose coefficients(phase 1)
370
	punpcklwd xmm4,xmm7		; xmm4=(00 01 10 11 20 21 30 31)
371
	punpckhwd xmm0,xmm7		; xmm0=(02 03 12 13 22 23 32 33)
372
373
	movdqa    xmm6,xmm4		; transpose coefficients(phase 2)
374
	punpckldq xmm4,xmm0		; xmm4=(00 01 02 03 10 11 12 13)
375
	punpckhdq xmm6,xmm0		; xmm6=(20 21 22 23 30 31 32 33)
376
377
	packsswb  xmm4,xmm6		; xmm4=(00 01 02 03 10 11 12 13 20 ..)
378
	paddb     xmm4,[rel PB_CENTERJSAMP]
379
380
	pshufd    xmm2,xmm4,0x39	; xmm2=(10 11 12 13 20 21 22 23 30 ..)
381
	pshufd    xmm1,xmm4,0x4E	; xmm1=(20 21 22 23 30 31 32 33 00 ..)
382
	pshufd    xmm3,xmm4,0x93	; xmm3=(30 31 32 33 00 01 02 03 10 ..)
383
384
	mov	rdx, JSAMPROW [rdi+0*SIZEOF_JSAMPROW]
385
	mov	rsi, JSAMPROW [rdi+1*SIZEOF_JSAMPROW]
386
	movd	XMM_DWORD [rdx+rax*SIZEOF_JSAMPLE], xmm4
387
	movd	XMM_DWORD [rsi+rax*SIZEOF_JSAMPLE], xmm2
388
	mov	rdx, JSAMPROW [rdi+2*SIZEOF_JSAMPROW]
389
	mov	rsi, JSAMPROW [rdi+3*SIZEOF_JSAMPROW]
390
	movd	XMM_DWORD [rdx+rax*SIZEOF_JSAMPLE], xmm1
391
	movd	XMM_DWORD [rsi+rax*SIZEOF_JSAMPLE], xmm3
392
393
	uncollect_args
394
	mov	rsp,rbp		; rsp <- aligned rbp
395
	pop	rsp		; rsp <- original rbp
396
	pop	rbp
397
	ret
398
399
400
; --------------------------------------------------------------------------
401
;
402
; Perform dequantization and inverse DCT on one block of coefficients,
403
; producing a reduced-size 2x2 output block.
404
;
405
; GLOBAL(void)
406
; jsimd_idct_2x2_sse2 (void * dct_table, JCOEFPTR coef_block,
407
;                      JSAMPARRAY output_buf, JDIMENSION output_col)
408
;
409
410
; r10 = void * dct_table
411
; r11 = JCOEFPTR coef_block
412
; r12 = JSAMPARRAY output_buf
413
; r13 = JDIMENSION output_col
414
415
	align	16
416
	global	EXTN(jsimd_idct_2x2_sse2)
417
418
EXTN(jsimd_idct_2x2_sse2):
419
	push	rbp
420
	mov	rax,rsp
421
	mov	rbp,rsp
422
	collect_args
423
	push	rbx
424
425
	; ---- Pass 1: process columns from input.
426
427
	mov	rdx, r10	; quantptr
428
	mov	rsi, r11		; inptr
429
430
	; | input:                  | result:        |
431
	; | 00 01 ** 03 ** 05 ** 07 |                |
432
	; | 10 11 ** 13 ** 15 ** 17 |                |
433
	; | ** ** ** ** ** ** ** ** |                |
434
	; | 30 31 ** 33 ** 35 ** 37 | A0 A1 A3 A5 A7 |
435
	; | ** ** ** ** ** ** ** ** | B0 B1 B3 B5 B7 |
436
	; | 50 51 ** 53 ** 55 ** 57 |                |
437
	; | ** ** ** ** ** ** ** ** |                |
438
	; | 70 71 ** 73 ** 75 ** 77 |                |
439
440
	; -- Odd part
441
442
	movdqa	xmm0, XMMWORD [XMMBLOCK(1,0,rsi,SIZEOF_JCOEF)]
443
	movdqa	xmm1, XMMWORD [XMMBLOCK(3,0,rsi,SIZEOF_JCOEF)]
444
	pmullw	xmm0, XMMWORD [XMMBLOCK(1,0,rdx,SIZEOF_ISLOW_MULT_TYPE)]
445
	pmullw	xmm1, XMMWORD [XMMBLOCK(3,0,rdx,SIZEOF_ISLOW_MULT_TYPE)]
446
	movdqa	xmm2, XMMWORD [XMMBLOCK(5,0,rsi,SIZEOF_JCOEF)]
447
	movdqa	xmm3, XMMWORD [XMMBLOCK(7,0,rsi,SIZEOF_JCOEF)]
448
	pmullw	xmm2, XMMWORD [XMMBLOCK(5,0,rdx,SIZEOF_ISLOW_MULT_TYPE)]
449
	pmullw	xmm3, XMMWORD [XMMBLOCK(7,0,rdx,SIZEOF_ISLOW_MULT_TYPE)]
450
451
	; xmm0=(10 11 ** 13 ** 15 ** 17), xmm1=(30 31 ** 33 ** 35 ** 37)
452
	; xmm2=(50 51 ** 53 ** 55 ** 57), xmm3=(70 71 ** 73 ** 75 ** 77)
453
454
	pcmpeqd   xmm7,xmm7
455
	pslld     xmm7,WORD_BIT		; xmm7={0x0000 0xFFFF 0x0000 0xFFFF ..}
456
457
	movdqa    xmm4,xmm0		; xmm4=(10 11 ** 13 ** 15 ** 17)
458
	movdqa    xmm5,xmm2		; xmm5=(50 51 ** 53 ** 55 ** 57)
459
	punpcklwd xmm4,xmm1		; xmm4=(10 30 11 31 ** ** 13 33)
460
	punpcklwd xmm5,xmm3		; xmm5=(50 70 51 71 ** ** 53 73)
461
	pmaddwd   xmm4,[rel PW_F362_MF127]
462
	pmaddwd   xmm5,[rel PW_F085_MF072]
463
464
	psrld	xmm0,WORD_BIT		; xmm0=(11 -- 13 -- 15 -- 17 --)
465
	pand	xmm1,xmm7		; xmm1=(-- 31 -- 33 -- 35 -- 37)
466
	psrld	xmm2,WORD_BIT		; xmm2=(51 -- 53 -- 55 -- 57 --)
467
	pand	xmm3,xmm7		; xmm3=(-- 71 -- 73 -- 75 -- 77)
468
	por	xmm0,xmm1		; xmm0=(11 31 13 33 15 35 17 37)
469
	por	xmm2,xmm3		; xmm2=(51 71 53 73 55 75 57 77)
470
	pmaddwd	xmm0,[rel PW_F362_MF127]
471
	pmaddwd	xmm2,[rel PW_F085_MF072]
472
473
	paddd	xmm4,xmm5		; xmm4=tmp0[col0 col1 **** col3]
474
	paddd	xmm0,xmm2		; xmm0=tmp0[col1 col3 col5 col7]
475
476
	; -- Even part
477
478
	movdqa	xmm6, XMMWORD [XMMBLOCK(0,0,rsi,SIZEOF_JCOEF)]
479
	pmullw	xmm6, XMMWORD [XMMBLOCK(0,0,rdx,SIZEOF_ISLOW_MULT_TYPE)]
480
481
	; xmm6=(00 01 ** 03 ** 05 ** 07)
482
483
	movdqa	xmm1,xmm6		; xmm1=(00 01 ** 03 ** 05 ** 07)
484
	pslld	xmm6,WORD_BIT		; xmm6=(-- 00 -- ** -- ** -- **)
485
	pand	xmm1,xmm7		; xmm1=(-- 01 -- 03 -- 05 -- 07)
486
	psrad	xmm6,(WORD_BIT-CONST_BITS-2) ; xmm6=tmp10[col0 **** **** ****]
487
	psrad	xmm1,(WORD_BIT-CONST_BITS-2) ; xmm1=tmp10[col1 col3 col5 col7]
488
489
	; -- Final output stage
490
491
	movdqa	xmm3,xmm6
492
	movdqa	xmm5,xmm1
493
	paddd	xmm6,xmm4	; xmm6=data0[col0 **** **** ****]=(A0 ** ** **)
494
	paddd	xmm1,xmm0	; xmm1=data0[col1 col3 col5 col7]=(A1 A3 A5 A7)
495
	psubd	xmm3,xmm4	; xmm3=data1[col0 **** **** ****]=(B0 ** ** **)
496
	psubd	xmm5,xmm0	; xmm5=data1[col1 col3 col5 col7]=(B1 B3 B5 B7)
497
498
	movdqa	xmm2,[rel PD_DESCALE_P1_2]	; xmm2=[rel PD_DESCALE_P1_2]
499
500
	punpckldq  xmm6,xmm3		; xmm6=(A0 B0 ** **)
501
502
	movdqa     xmm7,xmm1
503
	punpcklqdq xmm1,xmm5		; xmm1=(A1 A3 B1 B3)
504
	punpckhqdq xmm7,xmm5		; xmm7=(A5 A7 B5 B7)
505
506
	paddd	xmm6,xmm2
507
	psrad	xmm6,DESCALE_P1_2
508
509
	paddd	xmm1,xmm2
510
	paddd	xmm7,xmm2
511
	psrad	xmm1,DESCALE_P1_2
512
	psrad	xmm7,DESCALE_P1_2
513
514
	; -- Prefetch the next coefficient block
515
516
	prefetchnta [rsi + DCTSIZE2*SIZEOF_JCOEF + 0*32]
517
	prefetchnta [rsi + DCTSIZE2*SIZEOF_JCOEF + 1*32]
518
	prefetchnta [rsi + DCTSIZE2*SIZEOF_JCOEF + 2*32]
519
	prefetchnta [rsi + DCTSIZE2*SIZEOF_JCOEF + 3*32]
520
521
	; ---- Pass 2: process rows, store into output array.
522
523
	mov	rdi, r12	; (JSAMPROW *)
524
	mov	rax, r13
525
526
	; | input:| result:|
527
	; | A0 B0 |        |
528
	; | A1 B1 | C0 C1  |
529
	; | A3 B3 | D0 D1  |
530
	; | A5 B5 |        |
531
	; | A7 B7 |        |
532
533
	; -- Odd part
534
535
	packssdw  xmm1,xmm1		; xmm1=(A1 A3 B1 B3 A1 A3 B1 B3)
536
	packssdw  xmm7,xmm7		; xmm7=(A5 A7 B5 B7 A5 A7 B5 B7)
537
	pmaddwd   xmm1,[rel PW_F362_MF127]
538
	pmaddwd   xmm7,[rel PW_F085_MF072]
539
540
	paddd     xmm1,xmm7		; xmm1=tmp0[row0 row1 row0 row1]
541
542
	; -- Even part
543
544
	pslld     xmm6,(CONST_BITS+2)	; xmm6=tmp10[row0 row1 **** ****]
545
546
	; -- Final output stage
547
548
	movdqa    xmm4,xmm6
549
	paddd     xmm6,xmm1	; xmm6=data0[row0 row1 **** ****]=(C0 C1 ** **)
550
	psubd     xmm4,xmm1	; xmm4=data1[row0 row1 **** ****]=(D0 D1 ** **)
551
552
	punpckldq xmm6,xmm4	; xmm6=(C0 D0 C1 D1)
553
554
	paddd     xmm6,[rel PD_DESCALE_P2_2]
555
	psrad     xmm6,DESCALE_P2_2
556
557
	packssdw  xmm6,xmm6		; xmm6=(C0 D0 C1 D1 C0 D0 C1 D1)
558
	packsswb  xmm6,xmm6		; xmm6=(C0 D0 C1 D1 C0 D0 C1 D1 ..)
559
	paddb     xmm6,[rel PB_CENTERJSAMP]
560
561
	pextrw	ebx,xmm6,0x00		; ebx=(C0 D0 -- --)
562
	pextrw	ecx,xmm6,0x01		; ecx=(C1 D1 -- --)
563
564
	mov	rdx, JSAMPROW [rdi+0*SIZEOF_JSAMPROW]
565
	mov	rsi, JSAMPROW [rdi+1*SIZEOF_JSAMPROW]
566
	mov	WORD [rdx+rax*SIZEOF_JSAMPLE], bx
567
	mov	WORD [rsi+rax*SIZEOF_JSAMPLE], cx
568
569
	pop	rbx
570
	uncollect_args
571
	pop	rbp
572
	ret
573
574
; For some reason, the OS X linker does not honor the request to align the
575
; segment unless we do this.
576
	align	16
(-)a/jpeg/simd/jiss2red.asm (+594 lines)
Line     Link Here 
Line 0    Link Here 
1
;
2
; jiss2red.asm - reduced-size IDCT (SSE2)
3
;
4
; Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
5
;
6
; Based on
7
; x86 SIMD extension for IJG JPEG library
8
; Copyright (C) 1999-2006, MIYASAKA Masaru.
9
; For conditions of distribution and use, see copyright notice in jsimdext.inc
10
;
11
; This file should be assembled with NASM (Netwide Assembler),
12
; can *not* be assembled with Microsoft's MASM or any compatible
13
; assembler (including Borland's Turbo Assembler).
14
; NASM is available from http://nasm.sourceforge.net/ or
15
; http://sourceforge.net/project/showfiles.php?group_id=6208
16
;
17
; This file contains inverse-DCT routines that produce reduced-size
18
; output: either 4x4 or 2x2 pixels from an 8x8 DCT block.
19
; The following code is based directly on the IJG's original jidctred.c;
20
; see the jidctred.c for more details.
21
;
22
; [TAB8]
23
24
%include "jsimdext.inc"
25
%include "jdct.inc"
26
27
; --------------------------------------------------------------------------
28
29
%define CONST_BITS	13
30
%define PASS1_BITS	2
31
32
%define DESCALE_P1_4	(CONST_BITS-PASS1_BITS+1)
33
%define DESCALE_P2_4	(CONST_BITS+PASS1_BITS+3+1)
34
%define DESCALE_P1_2	(CONST_BITS-PASS1_BITS+2)
35
%define DESCALE_P2_2	(CONST_BITS+PASS1_BITS+3+2)
36
37
%if CONST_BITS == 13
38
F_0_211	equ	 1730		; FIX(0.211164243)
39
F_0_509	equ	 4176		; FIX(0.509795579)
40
F_0_601	equ	 4926		; FIX(0.601344887)
41
F_0_720	equ	 5906		; FIX(0.720959822)
42
F_0_765	equ	 6270		; FIX(0.765366865)
43
F_0_850	equ	 6967		; FIX(0.850430095)
44
F_0_899	equ	 7373		; FIX(0.899976223)
45
F_1_061	equ	 8697		; FIX(1.061594337)
46
F_1_272	equ	10426		; FIX(1.272758580)
47
F_1_451	equ	11893		; FIX(1.451774981)
48
F_1_847	equ	15137		; FIX(1.847759065)
49
F_2_172	equ	17799		; FIX(2.172734803)
50
F_2_562	equ	20995		; FIX(2.562915447)
51
F_3_624	equ	29692		; FIX(3.624509785)
52
%else
53
; NASM cannot do compile-time arithmetic on floating-point constants.
54
%define DESCALE(x,n)  (((x)+(1<<((n)-1)))>>(n))
55
F_0_211	equ	DESCALE( 226735879,30-CONST_BITS)	; FIX(0.211164243)
56
F_0_509	equ	DESCALE( 547388834,30-CONST_BITS)	; FIX(0.509795579)
57
F_0_601	equ	DESCALE( 645689155,30-CONST_BITS)	; FIX(0.601344887)
58
F_0_720	equ	DESCALE( 774124714,30-CONST_BITS)	; FIX(0.720959822)
59
F_0_765	equ	DESCALE( 821806413,30-CONST_BITS)	; FIX(0.765366865)
60
F_0_850	equ	DESCALE( 913142361,30-CONST_BITS)	; FIX(0.850430095)
61
F_0_899	equ	DESCALE( 966342111,30-CONST_BITS)	; FIX(0.899976223)
62
F_1_061	equ	DESCALE(1139878239,30-CONST_BITS)	; FIX(1.061594337)
63
F_1_272	equ	DESCALE(1366614119,30-CONST_BITS)	; FIX(1.272758580)
64
F_1_451	equ	DESCALE(1558831516,30-CONST_BITS)	; FIX(1.451774981)
65
F_1_847	equ	DESCALE(1984016188,30-CONST_BITS)	; FIX(1.847759065)
66
F_2_172	equ	DESCALE(2332956230,30-CONST_BITS)	; FIX(2.172734803)
67
F_2_562	equ	DESCALE(2751909506,30-CONST_BITS)	; FIX(2.562915447)
68
F_3_624	equ	DESCALE(3891787747,30-CONST_BITS)	; FIX(3.624509785)
69
%endif
70
71
; --------------------------------------------------------------------------
72
	SECTION	SEG_CONST
73
74
	alignz	16
75
	global	EXTN(jconst_idct_red_sse2)
76
77
EXTN(jconst_idct_red_sse2):
78
79
PW_F184_MF076	times 4 dw  F_1_847,-F_0_765
80
PW_F256_F089	times 4 dw  F_2_562, F_0_899
81
PW_F106_MF217	times 4 dw  F_1_061,-F_2_172
82
PW_MF060_MF050	times 4 dw -F_0_601,-F_0_509
83
PW_F145_MF021	times 4 dw  F_1_451,-F_0_211
84
PW_F362_MF127	times 4 dw  F_3_624,-F_1_272
85
PW_F085_MF072	times 4 dw  F_0_850,-F_0_720
86
PD_DESCALE_P1_4	times 4 dd  1 << (DESCALE_P1_4-1)
87
PD_DESCALE_P2_4	times 4 dd  1 << (DESCALE_P2_4-1)
88
PD_DESCALE_P1_2	times 4 dd  1 << (DESCALE_P1_2-1)
89
PD_DESCALE_P2_2	times 4 dd  1 << (DESCALE_P2_2-1)
90
PB_CENTERJSAMP	times 16 db CENTERJSAMPLE
91
92
	alignz	16
93
94
; --------------------------------------------------------------------------
95
	SECTION	SEG_TEXT
96
	BITS	32
97
;
98
; Perform dequantization and inverse DCT on one block of coefficients,
99
; producing a reduced-size 4x4 output block.
100
;
101
; GLOBAL(void)
102
; jsimd_idct_4x4_sse2 (void * dct_table, JCOEFPTR coef_block,
103
;                      JSAMPARRAY output_buf, JDIMENSION output_col)
104
;
105
106
%define dct_table(b)	(b)+8			; void * dct_table
107
%define coef_block(b)	(b)+12		; JCOEFPTR coef_block
108
%define output_buf(b)	(b)+16		; JSAMPARRAY output_buf
109
%define output_col(b)	(b)+20		; JDIMENSION output_col
110
111
%define original_ebp	ebp+0
112
%define wk(i)		ebp-(WK_NUM-(i))*SIZEOF_XMMWORD	; xmmword wk[WK_NUM]
113
%define WK_NUM		2
114
115
	align	16
116
	global	EXTN(jsimd_idct_4x4_sse2)
117
118
EXTN(jsimd_idct_4x4_sse2):
119
	push	ebp
120
	mov	eax,esp				; eax = original ebp
121
	sub	esp, byte 4
122
	and	esp, byte (-SIZEOF_XMMWORD)	; align to 128 bits
123
	mov	[esp],eax
124
	mov	ebp,esp				; ebp = aligned ebp
125
	lea	esp, [wk(0)]
126
	pushpic	ebx
127
;	push	ecx		; unused
128
;	push	edx		; need not be preserved
129
	push	esi
130
	push	edi
131
132
	get_GOT	ebx		; get GOT address
133
134
	; ---- Pass 1: process columns from input.
135
136
;	mov	eax, [original_ebp]
137
	mov	edx, POINTER [dct_table(eax)]	; quantptr
138
	mov	esi, JCOEFPTR [coef_block(eax)]		; inptr
139
140
%ifndef NO_ZERO_COLUMN_TEST_4X4_SSE2
141
	mov	eax, DWORD [DWBLOCK(1,0,esi,SIZEOF_JCOEF)]
142
	or	eax, DWORD [DWBLOCK(2,0,esi,SIZEOF_JCOEF)]
143
	jnz	short .columnDCT
144
145
	movdqa	xmm0, XMMWORD [XMMBLOCK(1,0,esi,SIZEOF_JCOEF)]
146
	movdqa	xmm1, XMMWORD [XMMBLOCK(2,0,esi,SIZEOF_JCOEF)]
147
	por	xmm0, XMMWORD [XMMBLOCK(3,0,esi,SIZEOF_JCOEF)]
148
	por	xmm1, XMMWORD [XMMBLOCK(5,0,esi,SIZEOF_JCOEF)]
149
	por	xmm0, XMMWORD [XMMBLOCK(6,0,esi,SIZEOF_JCOEF)]
150
	por	xmm1, XMMWORD [XMMBLOCK(7,0,esi,SIZEOF_JCOEF)]
151
	por	xmm0,xmm1
152
	packsswb xmm0,xmm0
153
	packsswb xmm0,xmm0
154
	movd	eax,xmm0
155
	test	eax,eax
156
	jnz	short .columnDCT
157
158
	; -- AC terms all zero
159
160
	movdqa	xmm0, XMMWORD [XMMBLOCK(0,0,esi,SIZEOF_JCOEF)]
161
	pmullw	xmm0, XMMWORD [XMMBLOCK(0,0,edx,SIZEOF_ISLOW_MULT_TYPE)]
162
163
	psllw	xmm0,PASS1_BITS
164
165
	movdqa    xmm3,xmm0	; xmm0=in0=(00 01 02 03 04 05 06 07)
166
	punpcklwd xmm0,xmm0	; xmm0=(00 00 01 01 02 02 03 03)
167
	punpckhwd xmm3,xmm3	; xmm3=(04 04 05 05 06 06 07 07)
168
169
	pshufd	xmm1,xmm0,0x50	; xmm1=[col0 col1]=(00 00 00 00 01 01 01 01)
170
	pshufd	xmm0,xmm0,0xFA	; xmm0=[col2 col3]=(02 02 02 02 03 03 03 03)
171
	pshufd	xmm6,xmm3,0x50	; xmm6=[col4 col5]=(04 04 04 04 05 05 05 05)
172
	pshufd	xmm3,xmm3,0xFA	; xmm3=[col6 col7]=(06 06 06 06 07 07 07 07)
173
174
	jmp	near .column_end
175
	alignx	16,7
176
%endif
177
.columnDCT:
178
179
	; -- Odd part
180
181
	movdqa	xmm0, XMMWORD [XMMBLOCK(1,0,esi,SIZEOF_JCOEF)]
182
	movdqa	xmm1, XMMWORD [XMMBLOCK(3,0,esi,SIZEOF_JCOEF)]
183
	pmullw	xmm0, XMMWORD [XMMBLOCK(1,0,edx,SIZEOF_ISLOW_MULT_TYPE)]
184
	pmullw	xmm1, XMMWORD [XMMBLOCK(3,0,edx,SIZEOF_ISLOW_MULT_TYPE)]
185
	movdqa	xmm2, XMMWORD [XMMBLOCK(5,0,esi,SIZEOF_JCOEF)]
186
	movdqa	xmm3, XMMWORD [XMMBLOCK(7,0,esi,SIZEOF_JCOEF)]
187
	pmullw	xmm2, XMMWORD [XMMBLOCK(5,0,edx,SIZEOF_ISLOW_MULT_TYPE)]
188
	pmullw	xmm3, XMMWORD [XMMBLOCK(7,0,edx,SIZEOF_ISLOW_MULT_TYPE)]
189
190
	movdqa    xmm4,xmm0
191
	movdqa    xmm5,xmm0
192
	punpcklwd xmm4,xmm1
193
	punpckhwd xmm5,xmm1
194
	movdqa    xmm0,xmm4
195
	movdqa    xmm1,xmm5
196
	pmaddwd   xmm4,[GOTOFF(ebx,PW_F256_F089)]	; xmm4=(tmp2L)
197
	pmaddwd   xmm5,[GOTOFF(ebx,PW_F256_F089)]	; xmm5=(tmp2H)
198
	pmaddwd   xmm0,[GOTOFF(ebx,PW_F106_MF217)]	; xmm0=(tmp0L)
199
	pmaddwd   xmm1,[GOTOFF(ebx,PW_F106_MF217)]	; xmm1=(tmp0H)
200
201
	movdqa    xmm6,xmm2
202
	movdqa    xmm7,xmm2
203
	punpcklwd xmm6,xmm3
204
	punpckhwd xmm7,xmm3
205
	movdqa    xmm2,xmm6
206
	movdqa    xmm3,xmm7
207
	pmaddwd   xmm6,[GOTOFF(ebx,PW_MF060_MF050)]	; xmm6=(tmp2L)
208
	pmaddwd   xmm7,[GOTOFF(ebx,PW_MF060_MF050)]	; xmm7=(tmp2H)
209
	pmaddwd   xmm2,[GOTOFF(ebx,PW_F145_MF021)]	; xmm2=(tmp0L)
210
	pmaddwd   xmm3,[GOTOFF(ebx,PW_F145_MF021)]	; xmm3=(tmp0H)
211
212
	paddd	xmm6,xmm4		; xmm6=tmp2L
213
	paddd	xmm7,xmm5		; xmm7=tmp2H
214
	paddd	xmm2,xmm0		; xmm2=tmp0L
215
	paddd	xmm3,xmm1		; xmm3=tmp0H
216
217
	movdqa	XMMWORD [wk(0)], xmm2	; wk(0)=tmp0L
218
	movdqa	XMMWORD [wk(1)], xmm3	; wk(1)=tmp0H
219
220
	; -- Even part
221
222
	movdqa	xmm4, XMMWORD [XMMBLOCK(0,0,esi,SIZEOF_JCOEF)]
223
	movdqa	xmm5, XMMWORD [XMMBLOCK(2,0,esi,SIZEOF_JCOEF)]
224
	movdqa	xmm0, XMMWORD [XMMBLOCK(6,0,esi,SIZEOF_JCOEF)]
225
	pmullw	xmm4, XMMWORD [XMMBLOCK(0,0,edx,SIZEOF_ISLOW_MULT_TYPE)]
226
	pmullw	xmm5, XMMWORD [XMMBLOCK(2,0,edx,SIZEOF_ISLOW_MULT_TYPE)]
227
	pmullw	xmm0, XMMWORD [XMMBLOCK(6,0,edx,SIZEOF_ISLOW_MULT_TYPE)]
228
229
	pxor      xmm1,xmm1
230
	pxor      xmm2,xmm2
231
	punpcklwd xmm1,xmm4		; xmm1=tmp0L
232
	punpckhwd xmm2,xmm4		; xmm2=tmp0H
233
	psrad     xmm1,(16-CONST_BITS-1) ; psrad xmm1,16 & pslld xmm1,CONST_BITS+1
234
	psrad     xmm2,(16-CONST_BITS-1) ; psrad xmm2,16 & pslld xmm2,CONST_BITS+1
235
236
	movdqa    xmm3,xmm5		; xmm5=in2=z2
237
	punpcklwd xmm5,xmm0		; xmm0=in6=z3
238
	punpckhwd xmm3,xmm0
239
	pmaddwd   xmm5,[GOTOFF(ebx,PW_F184_MF076)]	; xmm5=tmp2L
240
	pmaddwd   xmm3,[GOTOFF(ebx,PW_F184_MF076)]	; xmm3=tmp2H
241
242
	movdqa	xmm4,xmm1
243
	movdqa	xmm0,xmm2
244
	paddd	xmm1,xmm5		; xmm1=tmp10L
245
	paddd	xmm2,xmm3		; xmm2=tmp10H
246
	psubd	xmm4,xmm5		; xmm4=tmp12L
247
	psubd	xmm0,xmm3		; xmm0=tmp12H
248
249
	; -- Final output stage
250
251
	movdqa	xmm5,xmm1
252
	movdqa	xmm3,xmm2
253
	paddd	xmm1,xmm6		; xmm1=data0L
254
	paddd	xmm2,xmm7		; xmm2=data0H
255
	psubd	xmm5,xmm6		; xmm5=data3L
256
	psubd	xmm3,xmm7		; xmm3=data3H
257
258
	movdqa	xmm6,[GOTOFF(ebx,PD_DESCALE_P1_4)]	; xmm6=[PD_DESCALE_P1_4]
259
260
	paddd	xmm1,xmm6
261
	paddd	xmm2,xmm6
262
	psrad	xmm1,DESCALE_P1_4
263
	psrad	xmm2,DESCALE_P1_4
264
	paddd	xmm5,xmm6
265
	paddd	xmm3,xmm6
266
	psrad	xmm5,DESCALE_P1_4
267
	psrad	xmm3,DESCALE_P1_4
268
269
	packssdw  xmm1,xmm2		; xmm1=data0=(00 01 02 03 04 05 06 07)
270
	packssdw  xmm5,xmm3		; xmm5=data3=(30 31 32 33 34 35 36 37)
271
272
	movdqa	xmm7, XMMWORD [wk(0)]	; xmm7=tmp0L
273
	movdqa	xmm6, XMMWORD [wk(1)]	; xmm6=tmp0H
274
275
	movdqa	xmm2,xmm4
276
	movdqa	xmm3,xmm0
277
	paddd	xmm4,xmm7		; xmm4=data1L
278
	paddd	xmm0,xmm6		; xmm0=data1H
279
	psubd	xmm2,xmm7		; xmm2=data2L
280
	psubd	xmm3,xmm6		; xmm3=data2H
281
282
	movdqa	xmm7,[GOTOFF(ebx,PD_DESCALE_P1_4)]	; xmm7=[PD_DESCALE_P1_4]
283
284
	paddd	xmm4,xmm7
285
	paddd	xmm0,xmm7
286
	psrad	xmm4,DESCALE_P1_4
287
	psrad	xmm0,DESCALE_P1_4
288
	paddd	xmm2,xmm7
289
	paddd	xmm3,xmm7
290
	psrad	xmm2,DESCALE_P1_4
291
	psrad	xmm3,DESCALE_P1_4
292
293
	packssdw  xmm4,xmm0		; xmm4=data1=(10 11 12 13 14 15 16 17)
294
	packssdw  xmm2,xmm3		; xmm2=data2=(20 21 22 23 24 25 26 27)
295
296
	movdqa    xmm6,xmm1	; transpose coefficients(phase 1)
297
	punpcklwd xmm1,xmm4	; xmm1=(00 10 01 11 02 12 03 13)
298
	punpckhwd xmm6,xmm4	; xmm6=(04 14 05 15 06 16 07 17)
299
	movdqa    xmm7,xmm2	; transpose coefficients(phase 1)
300
	punpcklwd xmm2,xmm5	; xmm2=(20 30 21 31 22 32 23 33)
301
	punpckhwd xmm7,xmm5	; xmm7=(24 34 25 35 26 36 27 37)
302
303
	movdqa    xmm0,xmm1	; transpose coefficients(phase 2)
304
	punpckldq xmm1,xmm2	; xmm1=[col0 col1]=(00 10 20 30 01 11 21 31)
305
	punpckhdq xmm0,xmm2	; xmm0=[col2 col3]=(02 12 22 32 03 13 23 33)
306
	movdqa    xmm3,xmm6	; transpose coefficients(phase 2)
307
	punpckldq xmm6,xmm7	; xmm6=[col4 col5]=(04 14 24 34 05 15 25 35)
308
	punpckhdq xmm3,xmm7	; xmm3=[col6 col7]=(06 16 26 36 07 17 27 37)
309
.column_end:
310
311
	; -- Prefetch the next coefficient block
312
313
	prefetchnta [esi + DCTSIZE2*SIZEOF_JCOEF + 0*32]
314
	prefetchnta [esi + DCTSIZE2*SIZEOF_JCOEF + 1*32]
315
	prefetchnta [esi + DCTSIZE2*SIZEOF_JCOEF + 2*32]
316
	prefetchnta [esi + DCTSIZE2*SIZEOF_JCOEF + 3*32]
317
318
	; ---- Pass 2: process rows, store into output array.
319
320
	mov	eax, [original_ebp]
321
	mov	edi, JSAMPARRAY [output_buf(eax)]	; (JSAMPROW *)
322
	mov	eax, JDIMENSION [output_col(eax)]
323
324
	; -- Even part
325
326
	pxor      xmm4,xmm4
327
	punpcklwd xmm4,xmm1		; xmm4=tmp0
328
	psrad     xmm4,(16-CONST_BITS-1) ; psrad xmm4,16 & pslld xmm4,CONST_BITS+1
329
330
	; -- Odd part
331
332
	punpckhwd xmm1,xmm0
333
	punpckhwd xmm6,xmm3
334
	movdqa    xmm5,xmm1
335
	movdqa    xmm2,xmm6
336
	pmaddwd   xmm1,[GOTOFF(ebx,PW_F256_F089)]	; xmm1=(tmp2)
337
	pmaddwd   xmm6,[GOTOFF(ebx,PW_MF060_MF050)]	; xmm6=(tmp2)
338
	pmaddwd   xmm5,[GOTOFF(ebx,PW_F106_MF217)]	; xmm5=(tmp0)
339
	pmaddwd   xmm2,[GOTOFF(ebx,PW_F145_MF021)]	; xmm2=(tmp0)
340
341
	paddd     xmm6,xmm1		; xmm6=tmp2
342
	paddd     xmm2,xmm5		; xmm2=tmp0
343
344
	; -- Even part
345
346
	punpcklwd xmm0,xmm3
347
	pmaddwd   xmm0,[GOTOFF(ebx,PW_F184_MF076)]	; xmm0=tmp2
348
349
	movdqa    xmm7,xmm4
350
	paddd     xmm4,xmm0		; xmm4=tmp10
351
	psubd     xmm7,xmm0		; xmm7=tmp12
352
353
	; -- Final output stage
354
355
	movdqa	xmm1,[GOTOFF(ebx,PD_DESCALE_P2_4)]	; xmm1=[PD_DESCALE_P2_4]
356
357
	movdqa	xmm5,xmm4
358
	movdqa	xmm3,xmm7
359
	paddd	xmm4,xmm6		; xmm4=data0=(00 10 20 30)
360
	paddd	xmm7,xmm2		; xmm7=data1=(01 11 21 31)
361
	psubd	xmm5,xmm6		; xmm5=data3=(03 13 23 33)
362
	psubd	xmm3,xmm2		; xmm3=data2=(02 12 22 32)
363
364
	paddd	xmm4,xmm1
365
	paddd	xmm7,xmm1
366
	psrad	xmm4,DESCALE_P2_4
367
	psrad	xmm7,DESCALE_P2_4
368
	paddd	xmm5,xmm1
369
	paddd	xmm3,xmm1
370
	psrad	xmm5,DESCALE_P2_4
371
	psrad	xmm3,DESCALE_P2_4
372
373
	packssdw  xmm4,xmm3		; xmm4=(00 10 20 30 02 12 22 32)
374
	packssdw  xmm7,xmm5		; xmm7=(01 11 21 31 03 13 23 33)
375
376
	movdqa    xmm0,xmm4		; transpose coefficients(phase 1)
377
	punpcklwd xmm4,xmm7		; xmm4=(00 01 10 11 20 21 30 31)
378
	punpckhwd xmm0,xmm7		; xmm0=(02 03 12 13 22 23 32 33)
379
380
	movdqa    xmm6,xmm4		; transpose coefficients(phase 2)
381
	punpckldq xmm4,xmm0		; xmm4=(00 01 02 03 10 11 12 13)
382
	punpckhdq xmm6,xmm0		; xmm6=(20 21 22 23 30 31 32 33)
383
384
	packsswb  xmm4,xmm6		; xmm4=(00 01 02 03 10 11 12 13 20 ..)
385
	paddb     xmm4,[GOTOFF(ebx,PB_CENTERJSAMP)]
386
387
	pshufd    xmm2,xmm4,0x39	; xmm2=(10 11 12 13 20 21 22 23 30 ..)
388
	pshufd    xmm1,xmm4,0x4E	; xmm1=(20 21 22 23 30 31 32 33 00 ..)
389
	pshufd    xmm3,xmm4,0x93	; xmm3=(30 31 32 33 00 01 02 03 10 ..)
390
391
	mov	edx, JSAMPROW [edi+0*SIZEOF_JSAMPROW]
392
	mov	esi, JSAMPROW [edi+1*SIZEOF_JSAMPROW]
393
	movd	XMM_DWORD [edx+eax*SIZEOF_JSAMPLE], xmm4
394
	movd	XMM_DWORD [esi+eax*SIZEOF_JSAMPLE], xmm2
395
	mov	edx, JSAMPROW [edi+2*SIZEOF_JSAMPROW]
396
	mov	esi, JSAMPROW [edi+3*SIZEOF_JSAMPROW]
397
	movd	XMM_DWORD [edx+eax*SIZEOF_JSAMPLE], xmm1
398
	movd	XMM_DWORD [esi+eax*SIZEOF_JSAMPLE], xmm3
399
400
	pop	edi
401
	pop	esi
402
;	pop	edx		; need not be preserved
403
;	pop	ecx		; unused
404
	poppic	ebx
405
	mov	esp,ebp		; esp <- aligned ebp
406
	pop	esp		; esp <- original ebp
407
	pop	ebp
408
	ret
409
410
411
; --------------------------------------------------------------------------
412
;
413
; Perform dequantization and inverse DCT on one block of coefficients,
414
; producing a reduced-size 2x2 output block.
415
;
416
; GLOBAL(void)
417
; jsimd_idct_2x2_sse2 (void * dct_table, JCOEFPTR coef_block,
418
;                      JSAMPARRAY output_buf, JDIMENSION output_col)
419
;
420
421
%define dct_table(b)	(b)+8			; void * dct_table
422
%define coef_block(b)	(b)+12		; JCOEFPTR coef_block
423
%define output_buf(b)	(b)+16		; JSAMPARRAY output_buf
424
%define output_col(b)	(b)+20		; JDIMENSION output_col
425
426
	align	16
427
	global	EXTN(jsimd_idct_2x2_sse2)
428
429
EXTN(jsimd_idct_2x2_sse2):
430
	push	ebp
431
	mov	ebp,esp
432
	push	ebx
433
;	push	ecx		; need not be preserved
434
;	push	edx		; need not be preserved
435
	push	esi
436
	push	edi
437
438
	get_GOT	ebx		; get GOT address
439
440
	; ---- Pass 1: process columns from input.
441
442
	mov	edx, POINTER [dct_table(ebp)]	; quantptr
443
	mov	esi, JCOEFPTR [coef_block(ebp)]		; inptr
444
445
	; | input:                  | result:        |
446
	; | 00 01 ** 03 ** 05 ** 07 |                |
447
	; | 10 11 ** 13 ** 15 ** 17 |                |
448
	; | ** ** ** ** ** ** ** ** |                |
449
	; | 30 31 ** 33 ** 35 ** 37 | A0 A1 A3 A5 A7 |
450
	; | ** ** ** ** ** ** ** ** | B0 B1 B3 B5 B7 |
451
	; | 50 51 ** 53 ** 55 ** 57 |                |
452
	; | ** ** ** ** ** ** ** ** |                |
453
	; | 70 71 ** 73 ** 75 ** 77 |                |
454
455
	; -- Odd part
456
457
	movdqa	xmm0, XMMWORD [XMMBLOCK(1,0,esi,SIZEOF_JCOEF)]
458
	movdqa	xmm1, XMMWORD [XMMBLOCK(3,0,esi,SIZEOF_JCOEF)]
459
	pmullw	xmm0, XMMWORD [XMMBLOCK(1,0,edx,SIZEOF_ISLOW_MULT_TYPE)]
460
	pmullw	xmm1, XMMWORD [XMMBLOCK(3,0,edx,SIZEOF_ISLOW_MULT_TYPE)]
461
	movdqa	xmm2, XMMWORD [XMMBLOCK(5,0,esi,SIZEOF_JCOEF)]
462
	movdqa	xmm3, XMMWORD [XMMBLOCK(7,0,esi,SIZEOF_JCOEF)]
463
	pmullw	xmm2, XMMWORD [XMMBLOCK(5,0,edx,SIZEOF_ISLOW_MULT_TYPE)]
464
	pmullw	xmm3, XMMWORD [XMMBLOCK(7,0,edx,SIZEOF_ISLOW_MULT_TYPE)]
465
466
	; xmm0=(10 11 ** 13 ** 15 ** 17), xmm1=(30 31 ** 33 ** 35 ** 37)
467
	; xmm2=(50 51 ** 53 ** 55 ** 57), xmm3=(70 71 ** 73 ** 75 ** 77)
468
469
	pcmpeqd   xmm7,xmm7
470
	pslld     xmm7,WORD_BIT		; xmm7={0x0000 0xFFFF 0x0000 0xFFFF ..}
471
472
	movdqa    xmm4,xmm0		; xmm4=(10 11 ** 13 ** 15 ** 17)
473
	movdqa    xmm5,xmm2		; xmm5=(50 51 ** 53 ** 55 ** 57)
474
	punpcklwd xmm4,xmm1		; xmm4=(10 30 11 31 ** ** 13 33)
475
	punpcklwd xmm5,xmm3		; xmm5=(50 70 51 71 ** ** 53 73)
476
	pmaddwd   xmm4,[GOTOFF(ebx,PW_F362_MF127)]
477
	pmaddwd   xmm5,[GOTOFF(ebx,PW_F085_MF072)]
478
479
	psrld	xmm0,WORD_BIT		; xmm0=(11 -- 13 -- 15 -- 17 --)
480
	pand	xmm1,xmm7		; xmm1=(-- 31 -- 33 -- 35 -- 37)
481
	psrld	xmm2,WORD_BIT		; xmm2=(51 -- 53 -- 55 -- 57 --)
482
	pand	xmm3,xmm7		; xmm3=(-- 71 -- 73 -- 75 -- 77)
483
	por	xmm0,xmm1		; xmm0=(11 31 13 33 15 35 17 37)
484
	por	xmm2,xmm3		; xmm2=(51 71 53 73 55 75 57 77)
485
	pmaddwd	xmm0,[GOTOFF(ebx,PW_F362_MF127)]
486
	pmaddwd	xmm2,[GOTOFF(ebx,PW_F085_MF072)]
487
488
	paddd	xmm4,xmm5		; xmm4=tmp0[col0 col1 **** col3]
489
	paddd	xmm0,xmm2		; xmm0=tmp0[col1 col3 col5 col7]
490
491
	; -- Even part
492
493
	movdqa	xmm6, XMMWORD [XMMBLOCK(0,0,esi,SIZEOF_JCOEF)]
494
	pmullw	xmm6, XMMWORD [XMMBLOCK(0,0,edx,SIZEOF_ISLOW_MULT_TYPE)]
495
496
	; xmm6=(00 01 ** 03 ** 05 ** 07)
497
498
	movdqa	xmm1,xmm6		; xmm1=(00 01 ** 03 ** 05 ** 07)
499
	pslld	xmm6,WORD_BIT		; xmm6=(-- 00 -- ** -- ** -- **)
500
	pand	xmm1,xmm7		; xmm1=(-- 01 -- 03 -- 05 -- 07)
501
	psrad	xmm6,(WORD_BIT-CONST_BITS-2) ; xmm6=tmp10[col0 **** **** ****]
502
	psrad	xmm1,(WORD_BIT-CONST_BITS-2) ; xmm1=tmp10[col1 col3 col5 col7]
503
504
	; -- Final output stage
505
506
	movdqa	xmm3,xmm6
507
	movdqa	xmm5,xmm1
508
	paddd	xmm6,xmm4	; xmm6=data0[col0 **** **** ****]=(A0 ** ** **)
509
	paddd	xmm1,xmm0	; xmm1=data0[col1 col3 col5 col7]=(A1 A3 A5 A7)
510
	psubd	xmm3,xmm4	; xmm3=data1[col0 **** **** ****]=(B0 ** ** **)
511
	psubd	xmm5,xmm0	; xmm5=data1[col1 col3 col5 col7]=(B1 B3 B5 B7)
512
513
	movdqa	xmm2,[GOTOFF(ebx,PD_DESCALE_P1_2)]	; xmm2=[PD_DESCALE_P1_2]
514
515
	punpckldq  xmm6,xmm3		; xmm6=(A0 B0 ** **)
516
517
	movdqa     xmm7,xmm1
518
	punpcklqdq xmm1,xmm5		; xmm1=(A1 A3 B1 B3)
519
	punpckhqdq xmm7,xmm5		; xmm7=(A5 A7 B5 B7)
520
521
	paddd	xmm6,xmm2
522
	psrad	xmm6,DESCALE_P1_2
523
524
	paddd	xmm1,xmm2
525
	paddd	xmm7,xmm2
526
	psrad	xmm1,DESCALE_P1_2
527
	psrad	xmm7,DESCALE_P1_2
528
529
	; -- Prefetch the next coefficient block
530
531
	prefetchnta [esi + DCTSIZE2*SIZEOF_JCOEF + 0*32]
532
	prefetchnta [esi + DCTSIZE2*SIZEOF_JCOEF + 1*32]
533
	prefetchnta [esi + DCTSIZE2*SIZEOF_JCOEF + 2*32]
534
	prefetchnta [esi + DCTSIZE2*SIZEOF_JCOEF + 3*32]
535
536
	; ---- Pass 2: process rows, store into output array.
537
538
	mov	edi, JSAMPARRAY [output_buf(ebp)]	; (JSAMPROW *)
539
	mov	eax, JDIMENSION [output_col(ebp)]
540
541
	; | input:| result:|
542
	; | A0 B0 |        |
543
	; | A1 B1 | C0 C1  |
544
	; | A3 B3 | D0 D1  |
545
	; | A5 B5 |        |
546
	; | A7 B7 |        |
547
548
	; -- Odd part
549
550
	packssdw  xmm1,xmm1		; xmm1=(A1 A3 B1 B3 A1 A3 B1 B3)
551
	packssdw  xmm7,xmm7		; xmm7=(A5 A7 B5 B7 A5 A7 B5 B7)
552
	pmaddwd   xmm1,[GOTOFF(ebx,PW_F362_MF127)]
553
	pmaddwd   xmm7,[GOTOFF(ebx,PW_F085_MF072)]
554
555
	paddd     xmm1,xmm7		; xmm1=tmp0[row0 row1 row0 row1]
556
557
	; -- Even part
558
559
	pslld     xmm6,(CONST_BITS+2)	; xmm6=tmp10[row0 row1 **** ****]
560
561
	; -- Final output stage
562
563
	movdqa    xmm4,xmm6
564
	paddd     xmm6,xmm1	; xmm6=data0[row0 row1 **** ****]=(C0 C1 ** **)
565
	psubd     xmm4,xmm1	; xmm4=data1[row0 row1 **** ****]=(D0 D1 ** **)
566
567
	punpckldq xmm6,xmm4	; xmm6=(C0 D0 C1 D1)
568
569
	paddd     xmm6,[GOTOFF(ebx,PD_DESCALE_P2_2)]
570
	psrad     xmm6,DESCALE_P2_2
571
572
	packssdw  xmm6,xmm6		; xmm6=(C0 D0 C1 D1 C0 D0 C1 D1)
573
	packsswb  xmm6,xmm6		; xmm6=(C0 D0 C1 D1 C0 D0 C1 D1 ..)
574
	paddb     xmm6,[GOTOFF(ebx,PB_CENTERJSAMP)]
575
576
	pextrw	ebx,xmm6,0x00		; ebx=(C0 D0 -- --)
577
	pextrw	ecx,xmm6,0x01		; ecx=(C1 D1 -- --)
578
579
	mov	edx, JSAMPROW [edi+0*SIZEOF_JSAMPROW]
580
	mov	esi, JSAMPROW [edi+1*SIZEOF_JSAMPROW]
581
	mov	WORD [edx+eax*SIZEOF_JSAMPLE], bx
582
	mov	WORD [esi+eax*SIZEOF_JSAMPLE], cx
583
584
	pop	edi
585
	pop	esi
586
;	pop	edx		; need not be preserved
587
;	pop	ecx		; need not be preserved
588
	pop	ebx
589
	pop	ebp
590
	ret
591
592
; For some reason, the OS X linker does not honor the request to align the
593
; segment unless we do this.
594
	align	16
(-)a/jpeg/simd/jisseflt.asm (+572 lines)
Line     Link Here 
Line 0    Link Here 
1
;
2
; jisseflt.asm - floating-point IDCT (SSE & MMX)
3
;
4
; Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
5
;
6
; Based on
7
; x86 SIMD extension for IJG JPEG library
8
; Copyright (C) 1999-2006, MIYASAKA Masaru.
9
; For conditions of distribution and use, see copyright notice in jsimdext.inc
10
;
11
; This file should be assembled with NASM (Netwide Assembler),
12
; can *not* be assembled with Microsoft's MASM or any compatible
13
; assembler (including Borland's Turbo Assembler).
14
; NASM is available from http://nasm.sourceforge.net/ or
15
; http://sourceforge.net/project/showfiles.php?group_id=6208
16
;
17
; This file contains a floating-point implementation of the inverse DCT
18
; (Discrete Cosine Transform). The following code is based directly on
19
; the IJG's original jidctflt.c; see the jidctflt.c for more details.
20
;
21
; [TAB8]
22
23
%include "jsimdext.inc"
24
%include "jdct.inc"
25
26
; --------------------------------------------------------------------------
27
28
%macro	unpcklps2 2	; %1=(0 1 2 3) / %2=(4 5 6 7) => %1=(0 1 4 5)
29
	shufps	%1,%2,0x44
30
%endmacro
31
32
%macro	unpckhps2 2	; %1=(0 1 2 3) / %2=(4 5 6 7) => %1=(2 3 6 7)
33
	shufps	%1,%2,0xEE
34
%endmacro
35
36
; --------------------------------------------------------------------------
37
	SECTION	SEG_CONST
38
39
	alignz	16
40
	global	EXTN(jconst_idct_float_sse)
41
42
EXTN(jconst_idct_float_sse):
43
44
PD_1_414	times 4 dd  1.414213562373095048801689
45
PD_1_847	times 4 dd  1.847759065022573512256366
46
PD_1_082	times 4 dd  1.082392200292393968799446
47
PD_M2_613	times 4 dd -2.613125929752753055713286
48
PD_0_125	times 4 dd  0.125	; 1/8
49
PB_CENTERJSAMP	times 8 db  CENTERJSAMPLE
50
51
	alignz	16
52
53
; --------------------------------------------------------------------------
54
	SECTION	SEG_TEXT
55
	BITS	32
56
;
57
; Perform dequantization and inverse DCT on one block of coefficients.
58
;
59
; GLOBAL(void)
60
; jsimd_idct_float_sse (void * dct_table, JCOEFPTR coef_block,
61
;                       JSAMPARRAY output_buf, JDIMENSION output_col)
62
;
63
64
%define dct_table(b)	(b)+8			; void * dct_table
65
%define coef_block(b)	(b)+12		; JCOEFPTR coef_block
66
%define output_buf(b)	(b)+16		; JSAMPARRAY output_buf
67
%define output_col(b)	(b)+20		; JDIMENSION output_col
68
69
%define original_ebp	ebp+0
70
%define wk(i)		ebp-(WK_NUM-(i))*SIZEOF_XMMWORD	; xmmword wk[WK_NUM]
71
%define WK_NUM		2
72
%define workspace	wk(0)-DCTSIZE2*SIZEOF_FAST_FLOAT
73
					; FAST_FLOAT workspace[DCTSIZE2]
74
75
	align	16
76
	global	EXTN(jsimd_idct_float_sse)
77
78
EXTN(jsimd_idct_float_sse):
79
	push	ebp
80
	mov	eax,esp				; eax = original ebp
81
	sub	esp, byte 4
82
	and	esp, byte (-SIZEOF_XMMWORD)	; align to 128 bits
83
	mov	[esp],eax
84
	mov	ebp,esp				; ebp = aligned ebp
85
	lea	esp, [workspace]
86
	push	ebx
87
;	push	ecx		; need not be preserved
88
;	push	edx		; need not be preserved
89
	push	esi
90
	push	edi
91
92
	get_GOT	ebx		; get GOT address
93
94
	; ---- Pass 1: process columns from input, store into work array.
95
96
;	mov	eax, [original_ebp]
97
	mov	edx, POINTER [dct_table(eax)]	; quantptr
98
	mov	esi, JCOEFPTR [coef_block(eax)]		; inptr
99
	lea	edi, [workspace]			; FAST_FLOAT * wsptr
100
	mov	ecx, DCTSIZE/4				; ctr
101
	alignx	16,7
102
.columnloop:
103
%ifndef NO_ZERO_COLUMN_TEST_FLOAT_SSE
104
	mov	eax, DWORD [DWBLOCK(1,0,esi,SIZEOF_JCOEF)]
105
	or	eax, DWORD [DWBLOCK(2,0,esi,SIZEOF_JCOEF)]
106
	jnz	near .columnDCT
107
108
	movq	mm0, MMWORD [MMBLOCK(1,0,esi,SIZEOF_JCOEF)]
109
	movq	mm1, MMWORD [MMBLOCK(2,0,esi,SIZEOF_JCOEF)]
110
	por	mm0, MMWORD [MMBLOCK(3,0,esi,SIZEOF_JCOEF)]
111
	por	mm1, MMWORD [MMBLOCK(4,0,esi,SIZEOF_JCOEF)]
112
	por	mm0, MMWORD [MMBLOCK(5,0,esi,SIZEOF_JCOEF)]
113
	por	mm1, MMWORD [MMBLOCK(6,0,esi,SIZEOF_JCOEF)]
114
	por	mm0, MMWORD [MMBLOCK(7,0,esi,SIZEOF_JCOEF)]
115
	por	mm1,mm0
116
	packsswb mm1,mm1
117
	movd	eax,mm1
118
	test	eax,eax
119
	jnz	short .columnDCT
120
121
	; -- AC terms all zero
122
123
	movq      mm0, MMWORD [MMBLOCK(0,0,esi,SIZEOF_JCOEF)]
124
125
	punpckhwd mm1,mm0			; mm1=(** 02 ** 03)
126
	punpcklwd mm0,mm0			; mm0=(00 00 01 01)
127
	psrad     mm1,(DWORD_BIT-WORD_BIT)	; mm1=in0H=(02 03)
128
	psrad     mm0,(DWORD_BIT-WORD_BIT)	; mm0=in0L=(00 01)
129
	cvtpi2ps  xmm3,mm1			; xmm3=(02 03 ** **)
130
	cvtpi2ps  xmm0,mm0			; xmm0=(00 01 ** **)
131
	movlhps   xmm0,xmm3			; xmm0=in0=(00 01 02 03)
132
133
	mulps	xmm0, XMMWORD [XMMBLOCK(0,0,edx,SIZEOF_FLOAT_MULT_TYPE)]
134
135
	movaps	xmm1,xmm0
136
	movaps	xmm2,xmm0
137
	movaps	xmm3,xmm0
138
139
	shufps	xmm0,xmm0,0x00			; xmm0=(00 00 00 00)
140
	shufps	xmm1,xmm1,0x55			; xmm1=(01 01 01 01)
141
	shufps	xmm2,xmm2,0xAA			; xmm2=(02 02 02 02)
142
	shufps	xmm3,xmm3,0xFF			; xmm3=(03 03 03 03)
143
144
	movaps	XMMWORD [XMMBLOCK(0,0,edi,SIZEOF_FAST_FLOAT)], xmm0
145
	movaps	XMMWORD [XMMBLOCK(0,1,edi,SIZEOF_FAST_FLOAT)], xmm0
146
	movaps	XMMWORD [XMMBLOCK(1,0,edi,SIZEOF_FAST_FLOAT)], xmm1
147
	movaps	XMMWORD [XMMBLOCK(1,1,edi,SIZEOF_FAST_FLOAT)], xmm1
148
	movaps	XMMWORD [XMMBLOCK(2,0,edi,SIZEOF_FAST_FLOAT)], xmm2
149
	movaps	XMMWORD [XMMBLOCK(2,1,edi,SIZEOF_FAST_FLOAT)], xmm2
150
	movaps	XMMWORD [XMMBLOCK(3,0,edi,SIZEOF_FAST_FLOAT)], xmm3
151
	movaps	XMMWORD [XMMBLOCK(3,1,edi,SIZEOF_FAST_FLOAT)], xmm3
152
	jmp	near .nextcolumn
153
	alignx	16,7
154
%endif
155
.columnDCT:
156
157
	; -- Even part
158
159
	movq      mm0, MMWORD [MMBLOCK(0,0,esi,SIZEOF_JCOEF)]
160
	movq      mm1, MMWORD [MMBLOCK(2,0,esi,SIZEOF_JCOEF)]
161
	movq      mm2, MMWORD [MMBLOCK(4,0,esi,SIZEOF_JCOEF)]
162
	movq      mm3, MMWORD [MMBLOCK(6,0,esi,SIZEOF_JCOEF)]
163
164
	punpckhwd mm4,mm0			; mm4=(** 02 ** 03)
165
	punpcklwd mm0,mm0			; mm0=(00 00 01 01)
166
	punpckhwd mm5,mm1			; mm5=(** 22 ** 23)
167
	punpcklwd mm1,mm1			; mm1=(20 20 21 21)
168
169
	psrad     mm4,(DWORD_BIT-WORD_BIT)	; mm4=in0H=(02 03)
170
	psrad     mm0,(DWORD_BIT-WORD_BIT)	; mm0=in0L=(00 01)
171
	cvtpi2ps  xmm4,mm4			; xmm4=(02 03 ** **)
172
	cvtpi2ps  xmm0,mm0			; xmm0=(00 01 ** **)
173
	psrad     mm5,(DWORD_BIT-WORD_BIT)	; mm5=in2H=(22 23)
174
	psrad     mm1,(DWORD_BIT-WORD_BIT)	; mm1=in2L=(20 21)
175
	cvtpi2ps  xmm5,mm5			; xmm5=(22 23 ** **)
176
	cvtpi2ps  xmm1,mm1			; xmm1=(20 21 ** **)
177
178
	punpckhwd mm6,mm2			; mm6=(** 42 ** 43)
179
	punpcklwd mm2,mm2			; mm2=(40 40 41 41)
180
	punpckhwd mm7,mm3			; mm7=(** 62 ** 63)
181
	punpcklwd mm3,mm3			; mm3=(60 60 61 61)
182
183
	psrad     mm6,(DWORD_BIT-WORD_BIT)	; mm6=in4H=(42 43)
184
	psrad     mm2,(DWORD_BIT-WORD_BIT)	; mm2=in4L=(40 41)
185
	cvtpi2ps  xmm6,mm6			; xmm6=(42 43 ** **)
186
	cvtpi2ps  xmm2,mm2			; xmm2=(40 41 ** **)
187
	psrad     mm7,(DWORD_BIT-WORD_BIT)	; mm7=in6H=(62 63)
188
	psrad     mm3,(DWORD_BIT-WORD_BIT)	; mm3=in6L=(60 61)
189
	cvtpi2ps  xmm7,mm7			; xmm7=(62 63 ** **)
190
	cvtpi2ps  xmm3,mm3			; xmm3=(60 61 ** **)
191
192
	movlhps   xmm0,xmm4			; xmm0=in0=(00 01 02 03)
193
	movlhps   xmm1,xmm5			; xmm1=in2=(20 21 22 23)
194
	mulps     xmm0, XMMWORD [XMMBLOCK(0,0,edx,SIZEOF_FLOAT_MULT_TYPE)]
195
	mulps     xmm1, XMMWORD [XMMBLOCK(2,0,edx,SIZEOF_FLOAT_MULT_TYPE)]
196
197
	movlhps   xmm2,xmm6			; xmm2=in4=(40 41 42 43)
198
	movlhps   xmm3,xmm7			; xmm3=in6=(60 61 62 63)
199
	mulps     xmm2, XMMWORD [XMMBLOCK(4,0,edx,SIZEOF_FLOAT_MULT_TYPE)]
200
	mulps     xmm3, XMMWORD [XMMBLOCK(6,0,edx,SIZEOF_FLOAT_MULT_TYPE)]
201
202
	movaps	xmm4,xmm0
203
	movaps	xmm5,xmm1
204
	subps	xmm0,xmm2		; xmm0=tmp11
205
	subps	xmm1,xmm3
206
	addps	xmm4,xmm2		; xmm4=tmp10
207
	addps	xmm5,xmm3		; xmm5=tmp13
208
209
	mulps	xmm1,[GOTOFF(ebx,PD_1_414)]
210
	subps	xmm1,xmm5		; xmm1=tmp12
211
212
	movaps	xmm6,xmm4
213
	movaps	xmm7,xmm0
214
	subps	xmm4,xmm5		; xmm4=tmp3
215
	subps	xmm0,xmm1		; xmm0=tmp2
216
	addps	xmm6,xmm5		; xmm6=tmp0
217
	addps	xmm7,xmm1		; xmm7=tmp1
218
219
	movaps	XMMWORD [wk(1)], xmm4	; tmp3
220
	movaps	XMMWORD [wk(0)], xmm0	; tmp2
221
222
	; -- Odd part
223
224
	movq      mm4, MMWORD [MMBLOCK(1,0,esi,SIZEOF_JCOEF)]
225
	movq      mm0, MMWORD [MMBLOCK(3,0,esi,SIZEOF_JCOEF)]
226
	movq      mm5, MMWORD [MMBLOCK(5,0,esi,SIZEOF_JCOEF)]
227
	movq      mm1, MMWORD [MMBLOCK(7,0,esi,SIZEOF_JCOEF)]
228
229
	punpckhwd mm6,mm4			; mm6=(** 12 ** 13)
230
	punpcklwd mm4,mm4			; mm4=(10 10 11 11)
231
	punpckhwd mm2,mm0			; mm2=(** 32 ** 33)
232
	punpcklwd mm0,mm0			; mm0=(30 30 31 31)
233
234
	psrad     mm6,(DWORD_BIT-WORD_BIT)	; mm6=in1H=(12 13)
235
	psrad     mm4,(DWORD_BIT-WORD_BIT)	; mm4=in1L=(10 11)
236
	cvtpi2ps  xmm4,mm6			; xmm4=(12 13 ** **)
237
	cvtpi2ps  xmm2,mm4			; xmm2=(10 11 ** **)
238
	psrad     mm2,(DWORD_BIT-WORD_BIT)	; mm2=in3H=(32 33)
239
	psrad     mm0,(DWORD_BIT-WORD_BIT)	; mm0=in3L=(30 31)
240
	cvtpi2ps  xmm0,mm2			; xmm0=(32 33 ** **)
241
	cvtpi2ps  xmm3,mm0			; xmm3=(30 31 ** **)
242
243
	punpckhwd mm7,mm5			; mm7=(** 52 ** 53)
244
	punpcklwd mm5,mm5			; mm5=(50 50 51 51)
245
	punpckhwd mm3,mm1			; mm3=(** 72 ** 73)
246
	punpcklwd mm1,mm1			; mm1=(70 70 71 71)
247
248
	movlhps   xmm2,xmm4			; xmm2=in1=(10 11 12 13)
249
	movlhps   xmm3,xmm0			; xmm3=in3=(30 31 32 33)
250
251
	psrad     mm7,(DWORD_BIT-WORD_BIT)	; mm7=in5H=(52 53)
252
	psrad     mm5,(DWORD_BIT-WORD_BIT)	; mm5=in5L=(50 51)
253
	cvtpi2ps  xmm4,mm7			; xmm4=(52 53 ** **)
254
	cvtpi2ps  xmm5,mm5			; xmm5=(50 51 ** **)
255
	psrad     mm3,(DWORD_BIT-WORD_BIT)	; mm3=in7H=(72 73)
256
	psrad     mm1,(DWORD_BIT-WORD_BIT)	; mm1=in7L=(70 71)
257
	cvtpi2ps  xmm0,mm3			; xmm0=(72 73 ** **)
258
	cvtpi2ps  xmm1,mm1			; xmm1=(70 71 ** **)
259
260
	mulps     xmm2, XMMWORD [XMMBLOCK(1,0,edx,SIZEOF_FLOAT_MULT_TYPE)]
261
	mulps     xmm3, XMMWORD [XMMBLOCK(3,0,edx,SIZEOF_FLOAT_MULT_TYPE)]
262
263
	movlhps   xmm5,xmm4			; xmm5=in5=(50 51 52 53)
264
	movlhps   xmm1,xmm0			; xmm1=in7=(70 71 72 73)
265
	mulps     xmm5, XMMWORD [XMMBLOCK(5,0,edx,SIZEOF_FLOAT_MULT_TYPE)]
266
	mulps     xmm1, XMMWORD [XMMBLOCK(7,0,edx,SIZEOF_FLOAT_MULT_TYPE)]
267
268
	movaps	xmm4,xmm2
269
	movaps	xmm0,xmm5
270
	addps	xmm2,xmm1		; xmm2=z11
271
	addps	xmm5,xmm3		; xmm5=z13
272
	subps	xmm4,xmm1		; xmm4=z12
273
	subps	xmm0,xmm3		; xmm0=z10
274
275
	movaps	xmm1,xmm2
276
	subps	xmm2,xmm5
277
	addps	xmm1,xmm5		; xmm1=tmp7
278
279
	mulps	xmm2,[GOTOFF(ebx,PD_1_414)]	; xmm2=tmp11
280
281
	movaps	xmm3,xmm0
282
	addps	xmm0,xmm4
283
	mulps	xmm0,[GOTOFF(ebx,PD_1_847)]	; xmm0=z5
284
	mulps	xmm3,[GOTOFF(ebx,PD_M2_613)]	; xmm3=(z10 * -2.613125930)
285
	mulps	xmm4,[GOTOFF(ebx,PD_1_082)]	; xmm4=(z12 * 1.082392200)
286
	addps	xmm3,xmm0		; xmm3=tmp12
287
	subps	xmm4,xmm0		; xmm4=tmp10
288
289
	; -- Final output stage
290
291
	subps	xmm3,xmm1		; xmm3=tmp6
292
	movaps	xmm5,xmm6
293
	movaps	xmm0,xmm7
294
	addps	xmm6,xmm1		; xmm6=data0=(00 01 02 03)
295
	addps	xmm7,xmm3		; xmm7=data1=(10 11 12 13)
296
	subps	xmm5,xmm1		; xmm5=data7=(70 71 72 73)
297
	subps	xmm0,xmm3		; xmm0=data6=(60 61 62 63)
298
	subps	xmm2,xmm3		; xmm2=tmp5
299
300
	movaps    xmm1,xmm6		; transpose coefficients(phase 1)
301
	unpcklps  xmm6,xmm7		; xmm6=(00 10 01 11)
302
	unpckhps  xmm1,xmm7		; xmm1=(02 12 03 13)
303
	movaps    xmm3,xmm0		; transpose coefficients(phase 1)
304
	unpcklps  xmm0,xmm5		; xmm0=(60 70 61 71)
305
	unpckhps  xmm3,xmm5		; xmm3=(62 72 63 73)
306
307
	movaps	xmm7, XMMWORD [wk(0)]	; xmm7=tmp2
308
	movaps	xmm5, XMMWORD [wk(1)]	; xmm5=tmp3
309
310
	movaps	XMMWORD [wk(0)], xmm0	; wk(0)=(60 70 61 71)
311
	movaps	XMMWORD [wk(1)], xmm3	; wk(1)=(62 72 63 73)
312
313
	addps	xmm4,xmm2		; xmm4=tmp4
314
	movaps	xmm0,xmm7
315
	movaps	xmm3,xmm5
316
	addps	xmm7,xmm2		; xmm7=data2=(20 21 22 23)
317
	addps	xmm5,xmm4		; xmm5=data4=(40 41 42 43)
318
	subps	xmm0,xmm2		; xmm0=data5=(50 51 52 53)
319
	subps	xmm3,xmm4		; xmm3=data3=(30 31 32 33)
320
321
	movaps    xmm2,xmm7		; transpose coefficients(phase 1)
322
	unpcklps  xmm7,xmm3		; xmm7=(20 30 21 31)
323
	unpckhps  xmm2,xmm3		; xmm2=(22 32 23 33)
324
	movaps    xmm4,xmm5		; transpose coefficients(phase 1)
325
	unpcklps  xmm5,xmm0		; xmm5=(40 50 41 51)
326
	unpckhps  xmm4,xmm0		; xmm4=(42 52 43 53)
327
328
	movaps    xmm3,xmm6		; transpose coefficients(phase 2)
329
	unpcklps2 xmm6,xmm7		; xmm6=(00 10 20 30)
330
	unpckhps2 xmm3,xmm7		; xmm3=(01 11 21 31)
331
	movaps    xmm0,xmm1		; transpose coefficients(phase 2)
332
	unpcklps2 xmm1,xmm2		; xmm1=(02 12 22 32)
333
	unpckhps2 xmm0,xmm2		; xmm0=(03 13 23 33)
334
335
	movaps	xmm7, XMMWORD [wk(0)]	; xmm7=(60 70 61 71)
336
	movaps	xmm2, XMMWORD [wk(1)]	; xmm2=(62 72 63 73)
337
338
	movaps	XMMWORD [XMMBLOCK(0,0,edi,SIZEOF_FAST_FLOAT)], xmm6
339
	movaps	XMMWORD [XMMBLOCK(1,0,edi,SIZEOF_FAST_FLOAT)], xmm3
340
	movaps	XMMWORD [XMMBLOCK(2,0,edi,SIZEOF_FAST_FLOAT)], xmm1
341
	movaps	XMMWORD [XMMBLOCK(3,0,edi,SIZEOF_FAST_FLOAT)], xmm0
342
343
	movaps    xmm6,xmm5		; transpose coefficients(phase 2)
344
	unpcklps2 xmm5,xmm7		; xmm5=(40 50 60 70)
345
	unpckhps2 xmm6,xmm7		; xmm6=(41 51 61 71)
346
	movaps    xmm3,xmm4		; transpose coefficients(phase 2)
347
	unpcklps2 xmm4,xmm2		; xmm4=(42 52 62 72)
348
	unpckhps2 xmm3,xmm2		; xmm3=(43 53 63 73)
349
350
	movaps	XMMWORD [XMMBLOCK(0,1,edi,SIZEOF_FAST_FLOAT)], xmm5
351
	movaps	XMMWORD [XMMBLOCK(1,1,edi,SIZEOF_FAST_FLOAT)], xmm6
352
	movaps	XMMWORD [XMMBLOCK(2,1,edi,SIZEOF_FAST_FLOAT)], xmm4
353
	movaps	XMMWORD [XMMBLOCK(3,1,edi,SIZEOF_FAST_FLOAT)], xmm3
354
355
.nextcolumn:
356
	add	esi, byte 4*SIZEOF_JCOEF		; coef_block
357
	add	edx, byte 4*SIZEOF_FLOAT_MULT_TYPE	; quantptr
358
	add	edi,      4*DCTSIZE*SIZEOF_FAST_FLOAT	; wsptr
359
	dec	ecx					; ctr
360
	jnz	near .columnloop
361
362
	; -- Prefetch the next coefficient block
363
364
	prefetchnta [esi + (DCTSIZE2-8)*SIZEOF_JCOEF + 0*32]
365
	prefetchnta [esi + (DCTSIZE2-8)*SIZEOF_JCOEF + 1*32]
366
	prefetchnta [esi + (DCTSIZE2-8)*SIZEOF_JCOEF + 2*32]
367
	prefetchnta [esi + (DCTSIZE2-8)*SIZEOF_JCOEF + 3*32]
368
369
	; ---- Pass 2: process rows from work array, store into output array.
370
371
	mov	eax, [original_ebp]
372
	lea	esi, [workspace]			; FAST_FLOAT * wsptr
373
	mov	edi, JSAMPARRAY [output_buf(eax)]	; (JSAMPROW *)
374
	mov	eax, JDIMENSION [output_col(eax)]
375
	mov	ecx, DCTSIZE/4				; ctr
376
	alignx	16,7
377
.rowloop:
378
379
	; -- Even part
380
381
	movaps	xmm0, XMMWORD [XMMBLOCK(0,0,esi,SIZEOF_FAST_FLOAT)]
382
	movaps	xmm1, XMMWORD [XMMBLOCK(2,0,esi,SIZEOF_FAST_FLOAT)]
383
	movaps	xmm2, XMMWORD [XMMBLOCK(4,0,esi,SIZEOF_FAST_FLOAT)]
384
	movaps	xmm3, XMMWORD [XMMBLOCK(6,0,esi,SIZEOF_FAST_FLOAT)]
385
386
	movaps	xmm4,xmm0
387
	movaps	xmm5,xmm1
388
	subps	xmm0,xmm2		; xmm0=tmp11
389
	subps	xmm1,xmm3
390
	addps	xmm4,xmm2		; xmm4=tmp10
391
	addps	xmm5,xmm3		; xmm5=tmp13
392
393
	mulps	xmm1,[GOTOFF(ebx,PD_1_414)]
394
	subps	xmm1,xmm5		; xmm1=tmp12
395
396
	movaps	xmm6,xmm4
397
	movaps	xmm7,xmm0
398
	subps	xmm4,xmm5		; xmm4=tmp3
399
	subps	xmm0,xmm1		; xmm0=tmp2
400
	addps	xmm6,xmm5		; xmm6=tmp0
401
	addps	xmm7,xmm1		; xmm7=tmp1
402
403
	movaps	XMMWORD [wk(1)], xmm4	; tmp3
404
	movaps	XMMWORD [wk(0)], xmm0	; tmp2
405
406
	; -- Odd part
407
408
	movaps	xmm2, XMMWORD [XMMBLOCK(1,0,esi,SIZEOF_FAST_FLOAT)]
409
	movaps	xmm3, XMMWORD [XMMBLOCK(3,0,esi,SIZEOF_FAST_FLOAT)]
410
	movaps	xmm5, XMMWORD [XMMBLOCK(5,0,esi,SIZEOF_FAST_FLOAT)]
411
	movaps	xmm1, XMMWORD [XMMBLOCK(7,0,esi,SIZEOF_FAST_FLOAT)]
412
413
	movaps	xmm4,xmm2
414
	movaps	xmm0,xmm5
415
	addps	xmm2,xmm1		; xmm2=z11
416
	addps	xmm5,xmm3		; xmm5=z13
417
	subps	xmm4,xmm1		; xmm4=z12
418
	subps	xmm0,xmm3		; xmm0=z10
419
420
	movaps	xmm1,xmm2
421
	subps	xmm2,xmm5
422
	addps	xmm1,xmm5		; xmm1=tmp7
423
424
	mulps	xmm2,[GOTOFF(ebx,PD_1_414)]	; xmm2=tmp11
425
426
	movaps	xmm3,xmm0
427
	addps	xmm0,xmm4
428
	mulps	xmm0,[GOTOFF(ebx,PD_1_847)]	; xmm0=z5
429
	mulps	xmm3,[GOTOFF(ebx,PD_M2_613)]	; xmm3=(z10 * -2.613125930)
430
	mulps	xmm4,[GOTOFF(ebx,PD_1_082)]	; xmm4=(z12 * 1.082392200)
431
	addps	xmm3,xmm0		; xmm3=tmp12
432
	subps	xmm4,xmm0		; xmm4=tmp10
433
434
	; -- Final output stage
435
436
	subps	xmm3,xmm1		; xmm3=tmp6
437
	movaps	xmm5,xmm6
438
	movaps	xmm0,xmm7
439
	addps	xmm6,xmm1		; xmm6=data0=(00 10 20 30)
440
	addps	xmm7,xmm3		; xmm7=data1=(01 11 21 31)
441
	subps	xmm5,xmm1		; xmm5=data7=(07 17 27 37)
442
	subps	xmm0,xmm3		; xmm0=data6=(06 16 26 36)
443
	subps	xmm2,xmm3		; xmm2=tmp5
444
445
	movaps	xmm1,[GOTOFF(ebx,PD_0_125)]	; xmm1=[PD_0_125]
446
447
	mulps	xmm6,xmm1		; descale(1/8)
448
	mulps	xmm7,xmm1		; descale(1/8)
449
	mulps	xmm5,xmm1		; descale(1/8)
450
	mulps	xmm0,xmm1		; descale(1/8)
451
452
	movhlps   xmm3,xmm6
453
	movhlps   xmm1,xmm7
454
	cvtps2pi  mm0,xmm6		; round to int32, mm0=data0L=(00 10)
455
	cvtps2pi  mm1,xmm7		; round to int32, mm1=data1L=(01 11)
456
	cvtps2pi  mm2,xmm3		; round to int32, mm2=data0H=(20 30)
457
	cvtps2pi  mm3,xmm1		; round to int32, mm3=data1H=(21 31)
458
	packssdw  mm0,mm2		; mm0=data0=(00 10 20 30)
459
	packssdw  mm1,mm3		; mm1=data1=(01 11 21 31)
460
461
	movhlps   xmm6,xmm5
462
	movhlps   xmm7,xmm0
463
	cvtps2pi  mm4,xmm5		; round to int32, mm4=data7L=(07 17)
464
	cvtps2pi  mm5,xmm0		; round to int32, mm5=data6L=(06 16)
465
	cvtps2pi  mm6,xmm6		; round to int32, mm6=data7H=(27 37)
466
	cvtps2pi  mm7,xmm7		; round to int32, mm7=data6H=(26 36)
467
	packssdw  mm4,mm6		; mm4=data7=(07 17 27 37)
468
	packssdw  mm5,mm7		; mm5=data6=(06 16 26 36)
469
470
	packsswb  mm0,mm5		; mm0=(00 10 20 30 06 16 26 36)
471
	packsswb  mm1,mm4		; mm1=(01 11 21 31 07 17 27 37)
472
473
	movaps	xmm3, XMMWORD [wk(0)]	; xmm3=tmp2
474
	movaps	xmm1, XMMWORD [wk(1)]	; xmm1=tmp3
475
476
	movaps	xmm6,[GOTOFF(ebx,PD_0_125)]	; xmm6=[PD_0_125]
477
478
	addps	xmm4,xmm2		; xmm4=tmp4
479
	movaps	xmm5,xmm3
480
	movaps	xmm0,xmm1
481
	addps	xmm3,xmm2		; xmm3=data2=(02 12 22 32)
482
	addps	xmm1,xmm4		; xmm1=data4=(04 14 24 34)
483
	subps	xmm5,xmm2		; xmm5=data5=(05 15 25 35)
484
	subps	xmm0,xmm4		; xmm0=data3=(03 13 23 33)
485
486
	mulps	xmm3,xmm6		; descale(1/8)
487
	mulps	xmm1,xmm6		; descale(1/8)
488
	mulps	xmm5,xmm6		; descale(1/8)
489
	mulps	xmm0,xmm6		; descale(1/8)
490
491
	movhlps   xmm7,xmm3
492
	movhlps   xmm2,xmm1
493
	cvtps2pi  mm2,xmm3		; round to int32, mm2=data2L=(02 12)
494
	cvtps2pi  mm3,xmm1		; round to int32, mm3=data4L=(04 14)
495
	cvtps2pi  mm6,xmm7		; round to int32, mm6=data2H=(22 32)
496
	cvtps2pi  mm7,xmm2		; round to int32, mm7=data4H=(24 34)
497
	packssdw  mm2,mm6		; mm2=data2=(02 12 22 32)
498
	packssdw  mm3,mm7		; mm3=data4=(04 14 24 34)
499
500
	movhlps   xmm4,xmm5
501
	movhlps   xmm6,xmm0
502
	cvtps2pi  mm5,xmm5		; round to int32, mm5=data5L=(05 15)
503
	cvtps2pi  mm4,xmm0		; round to int32, mm4=data3L=(03 13)
504
	cvtps2pi  mm6,xmm4		; round to int32, mm6=data5H=(25 35)
505
	cvtps2pi  mm7,xmm6		; round to int32, mm7=data3H=(23 33)
506
	packssdw  mm5,mm6		; mm5=data5=(05 15 25 35)
507
	packssdw  mm4,mm7		; mm4=data3=(03 13 23 33)
508
509
	movq      mm6,[GOTOFF(ebx,PB_CENTERJSAMP)]	; mm6=[PB_CENTERJSAMP]
510
511
	packsswb  mm2,mm3		; mm2=(02 12 22 32 04 14 24 34)
512
	packsswb  mm4,mm5		; mm4=(03 13 23 33 05 15 25 35)
513
514
	paddb     mm0,mm6
515
	paddb     mm1,mm6
516
	paddb     mm2,mm6
517
	paddb     mm4,mm6
518
519
	movq      mm7,mm0		; transpose coefficients(phase 1)
520
	punpcklbw mm0,mm1		; mm0=(00 01 10 11 20 21 30 31)
521
	punpckhbw mm7,mm1		; mm7=(06 07 16 17 26 27 36 37)
522
	movq      mm3,mm2		; transpose coefficients(phase 1)
523
	punpcklbw mm2,mm4		; mm2=(02 03 12 13 22 23 32 33)
524
	punpckhbw mm3,mm4		; mm3=(04 05 14 15 24 25 34 35)
525
526
	movq      mm5,mm0		; transpose coefficients(phase 2)
527
	punpcklwd mm0,mm2		; mm0=(00 01 02 03 10 11 12 13)
528
	punpckhwd mm5,mm2		; mm5=(20 21 22 23 30 31 32 33)
529
	movq      mm6,mm3		; transpose coefficients(phase 2)
530
	punpcklwd mm3,mm7		; mm3=(04 05 06 07 14 15 16 17)
531
	punpckhwd mm6,mm7		; mm6=(24 25 26 27 34 35 36 37)
532
533
	movq      mm1,mm0		; transpose coefficients(phase 3)
534
	punpckldq mm0,mm3		; mm0=(00 01 02 03 04 05 06 07)
535
	punpckhdq mm1,mm3		; mm1=(10 11 12 13 14 15 16 17)
536
	movq      mm4,mm5		; transpose coefficients(phase 3)
537
	punpckldq mm5,mm6		; mm5=(20 21 22 23 24 25 26 27)
538
	punpckhdq mm4,mm6		; mm4=(30 31 32 33 34 35 36 37)
539
540
	pushpic	ebx			; save GOT address
541
542
	mov	edx, JSAMPROW [edi+0*SIZEOF_JSAMPROW]
543
	mov	ebx, JSAMPROW [edi+1*SIZEOF_JSAMPROW]
544
	movq	MMWORD [edx+eax*SIZEOF_JSAMPLE], mm0
545
	movq	MMWORD [ebx+eax*SIZEOF_JSAMPLE], mm1
546
	mov	edx, JSAMPROW [edi+2*SIZEOF_JSAMPROW]
547
	mov	ebx, JSAMPROW [edi+3*SIZEOF_JSAMPROW]
548
	movq	MMWORD [edx+eax*SIZEOF_JSAMPLE], mm5
549
	movq	MMWORD [ebx+eax*SIZEOF_JSAMPLE], mm4
550
551
	poppic	ebx			; restore GOT address
552
553
	add	esi, byte 4*SIZEOF_FAST_FLOAT	; wsptr
554
	add	edi, byte 4*SIZEOF_JSAMPROW
555
	dec	ecx				; ctr
556
	jnz	near .rowloop
557
558
	emms		; empty MMX state
559
560
	pop	edi
561
	pop	esi
562
;	pop	edx		; need not be preserved
563
;	pop	ecx		; need not be preserved
564
	pop	ebx
565
	mov	esp,ebp		; esp <- aligned ebp
566
	pop	esp		; esp <- original ebp
567
	pop	ebp
568
	ret
569
570
; For some reason, the OS X linker does not honor the request to align the
571
; segment unless we do this.
572
	align	16
(-)a/jpeg/simd/jsimd.h (+503 lines)
Line     Link Here 
Line 0    Link Here 
1
/*
2
 * simd/jsimd.h
3
 *
4
 * Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
5
 * 
6
 * Based on the x86 SIMD extension for IJG JPEG library,
7
 * Copyright (C) 1999-2006, MIYASAKA Masaru.
8
 *
9
 */
10
11
/* Bitmask for supported acceleration methods */
12
13
#define JSIMD_NONE    0x00
14
#define JSIMD_MMX     0x01
15
#define JSIMD_3DNOW   0x02
16
#define JSIMD_SSE     0x04
17
#define JSIMD_SSE2    0x08
18
19
/* Short forms of external names for systems with brain-damaged linkers. */
20
21
#ifdef NEED_SHORT_EXTERNAL_NAMES
22
#define jpeg_simd_cpu_support                 jSiCpuSupport
23
#define jsimd_rgb_ycc_convert_mmx             jSRGBYCCM
24
#define jsimd_extrgb_ycc_convert_mmx          jSEXTRGBYCCM
25
#define jsimd_extrgbx_ycc_convert_mmx         jSEXTRGBXYCCM
26
#define jsimd_extbgr_ycc_convert_mmx          jSEXTBGRYCCM
27
#define jsimd_extbgrx_ycc_convert_mmx         jSEXTBGRXYCCM
28
#define jsimd_extxbgr_ycc_convert_mmx         jSEXTXBGRYCCM
29
#define jsimd_extxrgb_ycc_convert_mmx         jSEXTXRGBYCCM
30
#define jsimd_ycc_rgb_convert_mmx             jSYCCRGBM
31
#define jsimd_ycc_extrgb_convert_mmx          jSYCCEXTRGBM
32
#define jsimd_ycc_extrgbx_convert_mmx         jSYCCEXTRGBXM
33
#define jsimd_ycc_extbgr_convert_mmx          jSYCCEXTBGRM
34
#define jsimd_ycc_extbgrx_convert_mmx         jSYCCEXTBGRXM
35
#define jsimd_ycc_extxbgr_convert_mmx         jSYCCEXTXBGRM
36
#define jsimd_ycc_extxrgb_convert_mmx         jSYCCEXTXRGBM
37
#define jconst_rgb_ycc_convert_sse2           jSCRGBYCCS2
38
#define jsimd_rgb_ycc_convert_sse2            jSRGBYCCS2
39
#define jsimd_extrgb_ycc_convert_sse2         jSEXTRGBYCCS2
40
#define jsimd_extrgbx_ycc_convert_sse2        jSEXTRGBXYCCS2
41
#define jsimd_extbgr_ycc_convert_sse2         jSEXTBGRYCCS2
42
#define jsimd_extbgrx_ycc_convert_sse2        jSEXTBGRXYCCS2
43
#define jsimd_extxbgr_ycc_convert_sse2        jSEXTXBGRYCCS2
44
#define jsimd_extxrgb_ycc_convert_sse2        jSEXTXRGBYCCS2
45
#define jconst_ycc_rgb_convert_sse2           jSCYCCRGBS2
46
#define jsimd_ycc_rgb_convert_sse2            jSYCCRGBS2
47
#define jsimd_ycc_extrgb_convert_sse2         jSYCCEXTRGBS2
48
#define jsimd_ycc_extrgbx_convert_sse2        jSYCCEXTRGBXS2
49
#define jsimd_ycc_extbgr_convert_sse2         jSYCCEXTBGRS2
50
#define jsimd_ycc_extbgrx_convert_sse2        jSYCCEXTBGRXS2
51
#define jsimd_ycc_extxbgr_convert_sse2        jSYCCEXTXBGRS2
52
#define jsimd_ycc_extxrgb_convert_sse2        jSYCCEXTXRGBS2
53
#define jsimd_h2v2_downsample_mmx             jSDnH2V2M
54
#define jsimd_h2v1_downsample_mmx             jSDnH2V1M
55
#define jsimd_h2v2_downsample_sse2            jSDnH2V2S2
56
#define jsimd_h2v1_downsample_sse2            jSDnH2V1S2
57
#define jsimd_h2v2_upsample_mmx               jSUpH2V2M
58
#define jsimd_h2v1_upsample_mmx               jSUpH2V1M
59
#define jsimd_h2v2_fancy_upsample_mmx         jSFUpH2V2M
60
#define jsimd_h2v1_fancy_upsample_mmx         jSFUpH2V1M
61
#define jsimd_h2v2_merged_upsample_mmx        jSMUpH2V2M
62
#define jsimd_h2v2_extrgb_merged_upsample_mmx jSMUpH2V2EXTRGBM
63
#define jsimd_h2v2_extrgbx_merged_upsample_mmx jSMUpH2V2EXTRGBXM
64
#define jsimd_h2v2_extbgr_merged_upsample_mmx jSMUpH2V2EXTBGRM
65
#define jsimd_h2v2_extbgrx_merged_upsample_mmx jSMUpH2V2EXTBGRXM
66
#define jsimd_h2v2_extxbgr_merged_upsample_mmx jSMUpH2V2EXTXBGRM
67
#define jsimd_h2v2_extxrgb_merged_upsample_mmx jSMUpH2V2EXTXRGBM
68
#define jsimd_h2v1_merged_upsample_mmx        jSMUpH2V1M
69
#define jsimd_h2v1_extrgb_merged_upsample_mmx jSMUpH2V1EXTRGBM
70
#define jsimd_h2v1_extrgbx_merged_upsample_mmx jSMUpH2V1EXTRGBXM
71
#define jsimd_h2v1_extbgr_merged_upsample_mmx jSMUpH2V1EXTBGRM
72
#define jsimd_h2v1_extbgrx_merged_upsample_mmx jSMUpH2V1EXTBGRXM
73
#define jsimd_h2v1_extxbgr_merged_upsample_mmx jSMUpH2V1EXTXBGRM
74
#define jsimd_h2v1_extxrgb_merged_upsample_mmx jSMUpH2V1EXTXRGBM
75
#define jsimd_h2v2_upsample_sse2              jSUpH2V2S2
76
#define jsimd_h2v1_upsample_sse2              jSUpH2V1S2
77
#define jconst_fancy_upsample_sse2            jSCFUpS2
78
#define jsimd_h2v2_fancy_upsample_sse2        jSFUpH2V2S2
79
#define jsimd_h2v1_fancy_upsample_sse2        jSFUpH2V1S2
80
#define jconst_merged_upsample_sse2           jSCMUpS2
81
#define jsimd_h2v2_merged_upsample_sse2       jSMUpH2V2S2
82
#define jsimd_h2v2_extrgb_merged_upsample_sse2 jSMUpH2V2EXTRGBS2
83
#define jsimd_h2v2_extrgbx_merged_upsample_sse2 jSMUpH2V2EXTRGBXS2
84
#define jsimd_h2v2_extbgr_merged_upsample_sse2 jSMUpH2V2EXTBGRS2
85
#define jsimd_h2v2_extbgrx_merged_upsample_sse2 jSMUpH2V2EXTBGRXS2
86
#define jsimd_h2v2_extxbgr_merged_upsample_sse2 jSMUpH2V2EXTXBGRS2
87
#define jsimd_h2v2_extxrgb_merged_upsample_sse2 jSMUpH2V2EXTXRGBS2
88
#define jsimd_h2v1_merged_upsample_sse2       jSMUpH2V1S2
89
#define jsimd_h2v1_extrgb_merged_upsample_sse2 jSMUpH2V1EXTRGBS2
90
#define jsimd_h2v1_extrgbx_merged_upsample_sse2 jSMUpH2V1EXTRGBXS2
91
#define jsimd_h2v1_extbgr_merged_upsample_sse2 jSMUpH2V1EXTBGRS2
92
#define jsimd_h2v1_extbgrx_merged_upsample_sse2 jSMUpH2V1EXTBGRXS2
93
#define jsimd_h2v1_extxbgr_merged_upsample_sse2 jSMUpH2V1EXTXBGRS2
94
#define jsimd_h2v1_extxrgb_merged_upsample_sse2 jSMUpH2V1EXTXRGBS2
95
#define jsimd_convsamp_mmx                    jSConvM
96
#define jsimd_convsamp_sse2                   jSConvS2
97
#define jsimd_convsamp_float_3dnow            jSConvF3D
98
#define jsimd_convsamp_float_sse              jSConvFS
99
#define jsimd_convsamp_float_sse2             jSConvFS2
100
#define jsimd_fdct_islow_mmx                  jSFDMIS
101
#define jsimd_fdct_ifast_mmx                  jSFDMIF
102
#define jconst_fdct_islow_sse2                jSCFDS2IS
103
#define jsimd_fdct_islow_sse2                 jSFDS2IS
104
#define jconst_fdct_ifast_sse2                jSCFDS2IF
105
#define jsimd_fdct_ifast_sse2                 jSFDS2IF
106
#define jsimd_fdct_float_3dnow                jSFD3DF
107
#define jconst_fdct_float_sse                 jSCFDSF
108
#define jsimd_fdct_float_sse                  jSFDSF
109
#define jsimd_quantize_mmx                    jSQuantM
110
#define jsimd_quantize_sse2                   jSQuantS2
111
#define jsimd_quantize_float_3dnow            jSQuantF3D
112
#define jsimd_quantize_float_sse              jSQuantFS
113
#define jsimd_quantize_float_sse2             jSQuantFS2
114
#define jsimd_idct_2x2_mmx                    jSIDM22
115
#define jsimd_idct_4x4_mmx                    jSIDM44
116
#define jconst_idct_red_sse2                  jSCIDS2R
117
#define jsimd_idct_2x2_sse2                   jSIDS222
118
#define jsimd_idct_4x4_sse2                   jSIDS244
119
#define jsimd_idct_islow_mmx                  jSIDMIS
120
#define jsimd_idct_ifast_mmx                  jSIDMIF
121
#define jconst_idct_islow_sse2                jSCIDS2IS
122
#define jsimd_idct_islow_sse2                 jSIDS2IS
123
#define jconst_idct_ifast_sse2                jSCIDS2IF
124
#define jsimd_idct_ifast_sse2                 jSIDS2IF
125
#define jsimd_idct_float_3dnow                jSID3DF
126
#define jconst_fdct_float_sse                 jSCIDSF
127
#define jsimd_idct_float_sse                  jSIDSF
128
#define jconst_fdct_float_sse2                jSCIDS2F
129
#define jsimd_idct_float_sse2                 jSIDS2F
130
#endif /* NEED_SHORT_EXTERNAL_NAMES */
131
132
/* SIMD Ext: retrieve SIMD/CPU information */
133
EXTERN(unsigned int) jpeg_simd_cpu_support JPP((void));
134
135
/* SIMD Color Space Conversion */
136
EXTERN(void) jsimd_rgb_ycc_convert_mmx
137
        JPP((JDIMENSION img_width,
138
             JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
139
             JDIMENSION output_row, int num_rows));
140
EXTERN(void) jsimd_extrgb_ycc_convert_mmx
141
        JPP((JDIMENSION img_width,
142
             JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
143
             JDIMENSION output_row, int num_rows));
144
EXTERN(void) jsimd_extrgbx_ycc_convert_mmx
145
        JPP((JDIMENSION img_width,
146
             JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
147
             JDIMENSION output_row, int num_rows));
148
EXTERN(void) jsimd_extbgr_ycc_convert_mmx
149
        JPP((JDIMENSION img_width,
150
             JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
151
             JDIMENSION output_row, int num_rows));
152
EXTERN(void) jsimd_extbgrx_ycc_convert_mmx
153
        JPP((JDIMENSION img_width,
154
             JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
155
             JDIMENSION output_row, int num_rows));
156
EXTERN(void) jsimd_extxbgr_ycc_convert_mmx
157
        JPP((JDIMENSION img_width,
158
             JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
159
             JDIMENSION output_row, int num_rows));
160
EXTERN(void) jsimd_extxrgb_ycc_convert_mmx
161
        JPP((JDIMENSION img_width,
162
             JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
163
             JDIMENSION output_row, int num_rows));
164
165
EXTERN(void) jsimd_ycc_rgb_convert_mmx
166
        JPP((JDIMENSION out_width,
167
             JSAMPIMAGE input_buf, JDIMENSION input_row,
168
             JSAMPARRAY output_buf, int num_rows));
169
EXTERN(void) jsimd_ycc_extrgb_convert_mmx
170
        JPP((JDIMENSION out_width,
171
             JSAMPIMAGE input_buf, JDIMENSION input_row,
172
             JSAMPARRAY output_buf, int num_rows));
173
EXTERN(void) jsimd_ycc_extrgbx_convert_mmx
174
        JPP((JDIMENSION out_width,
175
             JSAMPIMAGE input_buf, JDIMENSION input_row,
176
             JSAMPARRAY output_buf, int num_rows));
177
EXTERN(void) jsimd_ycc_extbgr_convert_mmx
178
        JPP((JDIMENSION out_width,
179
             JSAMPIMAGE input_buf, JDIMENSION input_row,
180
             JSAMPARRAY output_buf, int num_rows));
181
EXTERN(void) jsimd_ycc_extbgrx_convert_mmx
182
        JPP((JDIMENSION out_width,
183
             JSAMPIMAGE input_buf, JDIMENSION input_row,
184
             JSAMPARRAY output_buf, int num_rows));
185
EXTERN(void) jsimd_ycc_extxbgr_convert_mmx
186
        JPP((JDIMENSION out_width,
187
             JSAMPIMAGE input_buf, JDIMENSION input_row,
188
             JSAMPARRAY output_buf, int num_rows));
189
EXTERN(void) jsimd_ycc_extxrgb_convert_mmx
190
        JPP((JDIMENSION out_width,
191
             JSAMPIMAGE input_buf, JDIMENSION input_row,
192
             JSAMPARRAY output_buf, int num_rows));
193
194
extern const int jconst_rgb_ycc_convert_sse2[];
195
EXTERN(void) jsimd_rgb_ycc_convert_sse2
196
        JPP((JDIMENSION img_width,
197
             JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
198
             JDIMENSION output_row, int num_rows));
199
EXTERN(void) jsimd_extrgb_ycc_convert_sse2
200
        JPP((JDIMENSION img_width,
201
             JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
202
             JDIMENSION output_row, int num_rows));
203
EXTERN(void) jsimd_extrgbx_ycc_convert_sse2
204
        JPP((JDIMENSION img_width,
205
             JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
206
             JDIMENSION output_row, int num_rows));
207
EXTERN(void) jsimd_extbgr_ycc_convert_sse2
208
        JPP((JDIMENSION img_width,
209
             JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
210
             JDIMENSION output_row, int num_rows));
211
EXTERN(void) jsimd_extbgrx_ycc_convert_sse2
212
        JPP((JDIMENSION img_width,
213
             JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
214
             JDIMENSION output_row, int num_rows));
215
EXTERN(void) jsimd_extxbgr_ycc_convert_sse2
216
        JPP((JDIMENSION img_width,
217
             JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
218
             JDIMENSION output_row, int num_rows));
219
EXTERN(void) jsimd_extxrgb_ycc_convert_sse2
220
        JPP((JDIMENSION img_width,
221
             JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
222
             JDIMENSION output_row, int num_rows));
223
224
extern const int jconst_ycc_rgb_convert_sse2[];
225
EXTERN(void) jsimd_ycc_rgb_convert_sse2
226
        JPP((JDIMENSION out_width,
227
             JSAMPIMAGE input_buf, JDIMENSION input_row,
228
             JSAMPARRAY output_buf, int num_rows));
229
EXTERN(void) jsimd_ycc_extrgb_convert_sse2
230
        JPP((JDIMENSION out_width,
231
             JSAMPIMAGE input_buf, JDIMENSION input_row,
232
             JSAMPARRAY output_buf, int num_rows));
233
EXTERN(void) jsimd_ycc_extrgbx_convert_sse2
234
        JPP((JDIMENSION out_width,
235
             JSAMPIMAGE input_buf, JDIMENSION input_row,
236
             JSAMPARRAY output_buf, int num_rows));
237
EXTERN(void) jsimd_ycc_extbgr_convert_sse2
238
        JPP((JDIMENSION out_width,
239
             JSAMPIMAGE input_buf, JDIMENSION input_row,
240
             JSAMPARRAY output_buf, int num_rows));
241
EXTERN(void) jsimd_ycc_extbgrx_convert_sse2
242
        JPP((JDIMENSION out_width,
243
             JSAMPIMAGE input_buf, JDIMENSION input_row,
244
             JSAMPARRAY output_buf, int num_rows));
245
EXTERN(void) jsimd_ycc_extxbgr_convert_sse2
246
        JPP((JDIMENSION out_width,
247
             JSAMPIMAGE input_buf, JDIMENSION input_row,
248
             JSAMPARRAY output_buf, int num_rows));
249
EXTERN(void) jsimd_ycc_extxrgb_convert_sse2
250
        JPP((JDIMENSION out_width,
251
             JSAMPIMAGE input_buf, JDIMENSION input_row,
252
             JSAMPARRAY output_buf, int num_rows));
253
254
/* SIMD Downsample */
255
EXTERN(void) jsimd_h2v2_downsample_mmx
256
        JPP((JDIMENSION image_width, int max_v_samp_factor,
257
             JDIMENSION v_samp_factor, JDIMENSION width_blocks,
258
             JSAMPARRAY input_data, JSAMPARRAY output_data));
259
EXTERN(void) jsimd_h2v1_downsample_mmx
260
        JPP((JDIMENSION image_width, int max_v_samp_factor,
261
             JDIMENSION v_samp_factor, JDIMENSION width_blocks,
262
             JSAMPARRAY input_data, JSAMPARRAY output_data));
263
264
EXTERN(void) jsimd_h2v2_downsample_sse2
265
        JPP((JDIMENSION image_width, int max_v_samp_factor,
266
             JDIMENSION v_samp_factor, JDIMENSION width_blocks,
267
             JSAMPARRAY input_data, JSAMPARRAY output_data));
268
EXTERN(void) jsimd_h2v1_downsample_sse2
269
        JPP((JDIMENSION image_width, int max_v_samp_factor,
270
             JDIMENSION v_samp_factor, JDIMENSION width_blocks,
271
             JSAMPARRAY input_data, JSAMPARRAY output_data));
272
273
/* SIMD Upsample */
274
EXTERN(void) jsimd_h2v2_upsample_mmx
275
        JPP((int max_v_samp_factor, JDIMENSION output_width,
276
             JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr));
277
EXTERN(void) jsimd_h2v1_upsample_mmx
278
        JPP((int max_v_samp_factor, JDIMENSION output_width,
279
             JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr));
280
281
EXTERN(void) jsimd_h2v2_fancy_upsample_mmx
282
        JPP((int max_v_samp_factor, JDIMENSION downsampled_width,
283
             JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr));
284
EXTERN(void) jsimd_h2v1_fancy_upsample_mmx
285
        JPP((int max_v_samp_factor, JDIMENSION downsampled_width,
286
             JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr));
287
288
EXTERN(void) jsimd_h2v2_merged_upsample_mmx
289
        JPP((JDIMENSION output_width, JSAMPIMAGE input_buf,
290
             JDIMENSION in_row_group_ctr, JSAMPARRAY output_buf));
291
EXTERN(void) jsimd_h2v2_extrgb_merged_upsample_mmx
292
        JPP((JDIMENSION output_width, JSAMPIMAGE input_buf,
293
             JDIMENSION in_row_group_ctr, JSAMPARRAY output_buf));
294
EXTERN(void) jsimd_h2v2_extrgbx_merged_upsample_mmx
295
        JPP((JDIMENSION output_width, JSAMPIMAGE input_buf,
296
             JDIMENSION in_row_group_ctr, JSAMPARRAY output_buf));
297
EXTERN(void) jsimd_h2v2_extbgr_merged_upsample_mmx
298
        JPP((JDIMENSION output_width, JSAMPIMAGE input_buf,
299
             JDIMENSION in_row_group_ctr, JSAMPARRAY output_buf));
300
EXTERN(void) jsimd_h2v2_extbgrx_merged_upsample_mmx
301
        JPP((JDIMENSION output_width, JSAMPIMAGE input_buf,
302
             JDIMENSION in_row_group_ctr, JSAMPARRAY output_buf));
303
EXTERN(void) jsimd_h2v2_extxbgr_merged_upsample_mmx
304
        JPP((JDIMENSION output_width, JSAMPIMAGE input_buf,
305
             JDIMENSION in_row_group_ctr, JSAMPARRAY output_buf));
306
EXTERN(void) jsimd_h2v2_extxrgb_merged_upsample_mmx
307
        JPP((JDIMENSION output_width, JSAMPIMAGE input_buf,
308
             JDIMENSION in_row_group_ctr, JSAMPARRAY output_buf));
309
EXTERN(void) jsimd_h2v1_merged_upsample_mmx
310
        JPP((JDIMENSION output_width, JSAMPIMAGE input_buf,
311
             JDIMENSION in_row_group_ctr, JSAMPARRAY output_buf));
312
EXTERN(void) jsimd_h2v1_extrgb_merged_upsample_mmx
313
        JPP((JDIMENSION output_width, JSAMPIMAGE input_buf,
314
             JDIMENSION in_row_group_ctr, JSAMPARRAY output_buf));
315
EXTERN(void) jsimd_h2v1_extrgbx_merged_upsample_mmx
316
        JPP((JDIMENSION output_width, JSAMPIMAGE input_buf,
317
             JDIMENSION in_row_group_ctr, JSAMPARRAY output_buf));
318
EXTERN(void) jsimd_h2v1_extbgr_merged_upsample_mmx
319
        JPP((JDIMENSION output_width, JSAMPIMAGE input_buf,
320
             JDIMENSION in_row_group_ctr, JSAMPARRAY output_buf));
321
EXTERN(void) jsimd_h2v1_extbgrx_merged_upsample_mmx
322
        JPP((JDIMENSION output_width, JSAMPIMAGE input_buf,
323
             JDIMENSION in_row_group_ctr, JSAMPARRAY output_buf));
324
EXTERN(void) jsimd_h2v1_extxbgr_merged_upsample_mmx
325
        JPP((JDIMENSION output_width, JSAMPIMAGE input_buf,
326
             JDIMENSION in_row_group_ctr, JSAMPARRAY output_buf));
327
EXTERN(void) jsimd_h2v1_extxrgb_merged_upsample_mmx
328
        JPP((JDIMENSION output_width, JSAMPIMAGE input_buf,
329
             JDIMENSION in_row_group_ctr, JSAMPARRAY output_buf));
330
331
EXTERN(void) jsimd_h2v2_upsample_sse2
332
        JPP((int max_v_samp_factor, JDIMENSION output_width,
333
             JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr));
334
EXTERN(void) jsimd_h2v1_upsample_sse2
335
        JPP((int max_v_samp_factor, JDIMENSION output_width,
336
             JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr));
337
338
extern const int jconst_fancy_upsample_sse2[];
339
EXTERN(void) jsimd_h2v2_fancy_upsample_sse2
340
        JPP((int max_v_samp_factor, JDIMENSION downsampled_width,
341
             JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr));
342
EXTERN(void) jsimd_h2v1_fancy_upsample_sse2
343
        JPP((int max_v_samp_factor, JDIMENSION downsampled_width,
344
             JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr));
345
346
extern const int jconst_merged_upsample_sse2[];
347
EXTERN(void) jsimd_h2v2_merged_upsample_sse2
348
        JPP((JDIMENSION output_width, JSAMPIMAGE input_buf,
349
             JDIMENSION in_row_group_ctr, JSAMPARRAY output_buf));
350
EXTERN(void) jsimd_h2v2_extrgb_merged_upsample_sse2
351
        JPP((JDIMENSION output_width, JSAMPIMAGE input_buf,
352
             JDIMENSION in_row_group_ctr, JSAMPARRAY output_buf));
353
EXTERN(void) jsimd_h2v2_extrgbx_merged_upsample_sse2
354
        JPP((JDIMENSION output_width, JSAMPIMAGE input_buf,
355
             JDIMENSION in_row_group_ctr, JSAMPARRAY output_buf));
356
EXTERN(void) jsimd_h2v2_extbgr_merged_upsample_sse2
357
        JPP((JDIMENSION output_width, JSAMPIMAGE input_buf,
358
             JDIMENSION in_row_group_ctr, JSAMPARRAY output_buf));
359
EXTERN(void) jsimd_h2v2_extbgrx_merged_upsample_sse2
360
        JPP((JDIMENSION output_width, JSAMPIMAGE input_buf,
361
             JDIMENSION in_row_group_ctr, JSAMPARRAY output_buf));
362
EXTERN(void) jsimd_h2v2_extxbgr_merged_upsample_sse2
363
        JPP((JDIMENSION output_width, JSAMPIMAGE input_buf,
364
             JDIMENSION in_row_group_ctr, JSAMPARRAY output_buf));
365
EXTERN(void) jsimd_h2v2_extxrgb_merged_upsample_sse2
366
        JPP((JDIMENSION output_width, JSAMPIMAGE input_buf,
367
             JDIMENSION in_row_group_ctr, JSAMPARRAY output_buf));
368
EXTERN(void) jsimd_h2v1_merged_upsample_sse2
369
        JPP((JDIMENSION output_width, JSAMPIMAGE input_buf,
370
             JDIMENSION in_row_group_ctr, JSAMPARRAY output_buf));
371
EXTERN(void) jsimd_h2v1_extrgb_merged_upsample_sse2
372
        JPP((JDIMENSION output_width, JSAMPIMAGE input_buf,
373
             JDIMENSION in_row_group_ctr, JSAMPARRAY output_buf));
374
EXTERN(void) jsimd_h2v1_extrgbx_merged_upsample_sse2
375
        JPP((JDIMENSION output_width, JSAMPIMAGE input_buf,
376
             JDIMENSION in_row_group_ctr, JSAMPARRAY output_buf));
377
EXTERN(void) jsimd_h2v1_extbgr_merged_upsample_sse2
378
        JPP((JDIMENSION output_width, JSAMPIMAGE input_buf,
379
             JDIMENSION in_row_group_ctr, JSAMPARRAY output_buf));
380
EXTERN(void) jsimd_h2v1_extbgrx_merged_upsample_sse2
381
        JPP((JDIMENSION output_width, JSAMPIMAGE input_buf,
382
             JDIMENSION in_row_group_ctr, JSAMPARRAY output_buf));
383
EXTERN(void) jsimd_h2v1_extxbgr_merged_upsample_sse2
384
        JPP((JDIMENSION output_width, JSAMPIMAGE input_buf,
385
             JDIMENSION in_row_group_ctr, JSAMPARRAY output_buf));
386
EXTERN(void) jsimd_h2v1_extxrgb_merged_upsample_sse2
387
        JPP((JDIMENSION output_width, JSAMPIMAGE input_buf,
388
             JDIMENSION in_row_group_ctr, JSAMPARRAY output_buf));
389
390
/* SIMD Sample Conversion */
391
EXTERN(void) jsimd_convsamp_mmx JPP((JSAMPARRAY sample_data,
392
                                     JDIMENSION start_col,
393
                                     DCTELEM * workspace));
394
395
EXTERN(void) jsimd_convsamp_sse2 JPP((JSAMPARRAY sample_data,
396
                                      JDIMENSION start_col,
397
                                      DCTELEM * workspace));
398
399
EXTERN(void) jsimd_convsamp_float_3dnow JPP((JSAMPARRAY sample_data,
400
                                             JDIMENSION start_col,
401
                                             FAST_FLOAT * workspace));
402
403
EXTERN(void) jsimd_convsamp_float_sse JPP((JSAMPARRAY sample_data,
404
                                           JDIMENSION start_col,
405
                                           FAST_FLOAT * workspace));
406
407
EXTERN(void) jsimd_convsamp_float_sse2 JPP((JSAMPARRAY sample_data,
408
                                            JDIMENSION start_col,
409
                                            FAST_FLOAT * workspace));
410
411
/* SIMD Forward DCT */
412
EXTERN(void) jsimd_fdct_islow_mmx JPP((DCTELEM * data));
413
EXTERN(void) jsimd_fdct_ifast_mmx JPP((DCTELEM * data));
414
415
extern const int jconst_fdct_ifast_sse2[];
416
EXTERN(void) jsimd_fdct_islow_sse2 JPP((DCTELEM * data));
417
extern const int jconst_fdct_islow_sse2[];
418
EXTERN(void) jsimd_fdct_ifast_sse2 JPP((DCTELEM * data));
419
420
EXTERN(void) jsimd_fdct_float_3dnow JPP((FAST_FLOAT * data));
421
422
extern const int jconst_fdct_float_sse[];
423
EXTERN(void) jsimd_fdct_float_sse JPP((FAST_FLOAT * data));
424
425
/* SIMD Quantization */
426
EXTERN(void) jsimd_quantize_mmx JPP((JCOEFPTR coef_block,
427
                                     DCTELEM * divisors,
428
                                     DCTELEM * workspace));
429
430
EXTERN(void) jsimd_quantize_sse2 JPP((JCOEFPTR coef_block,
431
                                      DCTELEM * divisors,
432
                                      DCTELEM * workspace));
433
434
EXTERN(void) jsimd_quantize_float_3dnow JPP((JCOEFPTR coef_block,
435
                                             FAST_FLOAT * divisors,
436
                                             FAST_FLOAT * workspace));
437
438
EXTERN(void) jsimd_quantize_float_sse JPP((JCOEFPTR coef_block,
439
                                           FAST_FLOAT * divisors,
440
                                           FAST_FLOAT * workspace));
441
442
EXTERN(void) jsimd_quantize_float_sse2 JPP((JCOEFPTR coef_block,
443
                                            FAST_FLOAT * divisors,
444
                                            FAST_FLOAT * workspace));
445
446
/* SIMD Reduced Inverse DCT */
447
EXTERN(void) jsimd_idct_2x2_mmx JPP((void * dct_table,
448
                                     JCOEFPTR coef_block,
449
                                     JSAMPARRAY output_buf,
450
                                     JDIMENSION output_col));
451
EXTERN(void) jsimd_idct_4x4_mmx JPP((void * dct_table,
452
                                     JCOEFPTR coef_block,
453
                                     JSAMPARRAY output_buf,
454
                                     JDIMENSION output_col));
455
456
extern const int jconst_idct_red_sse2[];
457
EXTERN(void) jsimd_idct_2x2_sse2 JPP((void * dct_table,
458
                                      JCOEFPTR coef_block,
459
                                      JSAMPARRAY output_buf,
460
                                      JDIMENSION output_col));
461
EXTERN(void) jsimd_idct_4x4_sse2 JPP((void * dct_table,
462
                                      JCOEFPTR coef_block,
463
                                      JSAMPARRAY output_buf,
464
                                      JDIMENSION output_col));
465
466
/* SIMD Inverse DCT */
467
EXTERN(void) jsimd_idct_islow_mmx JPP((void * dct_table,
468
                                       JCOEFPTR coef_block,
469
                                       JSAMPARRAY output_buf,
470
                                       JDIMENSION output_col));
471
EXTERN(void) jsimd_idct_ifast_mmx JPP((void * dct_table,
472
                                       JCOEFPTR coef_block,
473
                                       JSAMPARRAY output_buf,
474
                                       JDIMENSION output_col));
475
476
extern const int jconst_idct_islow_sse2[];
477
EXTERN(void) jsimd_idct_islow_sse2 JPP((void * dct_table,
478
                                        JCOEFPTR coef_block,
479
                                        JSAMPARRAY output_buf,
480
                                        JDIMENSION output_col));
481
extern const int jconst_idct_ifast_sse2[];
482
EXTERN(void) jsimd_idct_ifast_sse2 JPP((void * dct_table,
483
                                        JCOEFPTR coef_block,
484
                                        JSAMPARRAY output_buf,
485
                                        JDIMENSION output_col));
486
487
EXTERN(void) jsimd_idct_float_3dnow JPP((void * dct_table,
488
                                         JCOEFPTR coef_block,
489
                                         JSAMPARRAY output_buf,
490
                                         JDIMENSION output_col));
491
492
extern const int jconst_idct_float_sse[];
493
EXTERN(void) jsimd_idct_float_sse JPP((void * dct_table,
494
                                       JCOEFPTR coef_block,
495
                                       JSAMPARRAY output_buf,
496
                                       JDIMENSION output_col));
497
498
extern const int jconst_idct_float_sse2[];
499
EXTERN(void) jsimd_idct_float_sse2 JPP((void * dct_table,
500
                                        JCOEFPTR coef_block,
501
                                        JSAMPARRAY output_buf,
502
                                        JDIMENSION output_col));
503
(-)a/jpeg/simd/jsimd_i386.c (+956 lines)
Line     Link Here 
Line 0    Link Here 
1
/*
2
 * jsimd_i386.c
3
 *
4
 * Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
5
 * Copyright 2009 D. R. Commander
6
 * 
7
 * Based on the x86 SIMD extension for IJG JPEG library,
8
 * Copyright (C) 1999-2006, MIYASAKA Masaru.
9
 *
10
 * This file contains the interface between the "normal" portions
11
 * of the library and the SIMD implementations when running on a
12
 * 32-bit x86 architecture.
13
 */
14
15
#define JPEG_INTERNALS
16
#include "../jinclude.h"
17
#include "../jpeglib.h"
18
#include "../jsimd.h"
19
#include "../jdct.h"
20
#include "../jsimddct.h"
21
#include "jsimd.h"
22
23
/*
24
 * In the PIC cases, we have no guarantee that constants will keep
25
 * their alignment. This macro allows us to verify it at runtime.
26
 */
27
#define IS_ALIGNED(ptr, order) (((unsigned)ptr & ((1 << order) - 1)) == 0)
28
29
#define IS_ALIGNED_SSE(ptr) (IS_ALIGNED(ptr, 4)) /* 16 byte alignment */
30
31
static unsigned int simd_support = ~0;
32
33
/*
34
 * Check what SIMD accelerations are supported.
35
 *
36
 * FIXME: This code is racy under a multi-threaded environment.
37
 */
38
LOCAL(void)
39
init_simd (void)
40
{
41
  char *env = NULL;
42
43
  if (simd_support != ~0)
44
    return;
45
46
  simd_support = jpeg_simd_cpu_support();
47
48
  /* Force different settings through environment variables */
49
  env = getenv("JSIMD_FORCEMMX");
50
  if ((env != NULL) && (strcmp(env, "1") == 0))
51
    simd_support &= JSIMD_MMX;
52
  env = getenv("JSIMD_FORCE3DNOW");
53
  if ((env != NULL) && (strcmp(env, "1") == 0))
54
    simd_support &= JSIMD_3DNOW|JSIMD_MMX;
55
  env = getenv("JSIMD_FORCESSE");
56
  if ((env != NULL) && (strcmp(env, "1") == 0))
57
    simd_support &= JSIMD_SSE|JSIMD_MMX;
58
  env = getenv("JSIMD_FORCESSE2");
59
  if ((env != NULL) && (strcmp(env, "1") == 0))
60
    simd_support &= JSIMD_SSE2;
61
}
62
63
GLOBAL(int)
64
jsimd_can_rgb_ycc (void)
65
{
66
  init_simd();
67
68
  /* The code is optimised for these values only */
69
  if (BITS_IN_JSAMPLE != 8)
70
    return 0;
71
  if (sizeof(JDIMENSION) != 4)
72
    return 0;
73
  if ((RGB_PIXELSIZE != 3) && (RGB_PIXELSIZE != 4))
74
    return 0;
75
76
  if ((simd_support & JSIMD_SSE2) &&
77
      IS_ALIGNED_SSE(jconst_rgb_ycc_convert_sse2))
78
    return 1;
79
  if (simd_support & JSIMD_MMX)
80
    return 1;
81
82
  return 0;
83
}
84
85
GLOBAL(int)
86
jsimd_can_ycc_rgb (void)
87
{
88
  init_simd();
89
90
  /* The code is optimised for these values only */
91
  if (BITS_IN_JSAMPLE != 8)
92
    return 0;
93
  if (sizeof(JDIMENSION) != 4)
94
    return 0;
95
  if ((RGB_PIXELSIZE != 3) && (RGB_PIXELSIZE != 4))
96
    return 0;
97
98
  if ((simd_support & JSIMD_SSE2) &&
99
      IS_ALIGNED_SSE(jconst_ycc_rgb_convert_sse2))
100
    return 1;
101
  if (simd_support & JSIMD_MMX)
102
    return 1;
103
104
  return 0;
105
}
106
107
GLOBAL(void)
108
jsimd_rgb_ycc_convert (j_compress_ptr cinfo,
109
                       JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
110
                       JDIMENSION output_row, int num_rows)
111
{
112
  void (*sse2fct)(JDIMENSION, JSAMPARRAY, JSAMPIMAGE, JDIMENSION, int);
113
  void (*mmxfct)(JDIMENSION, JSAMPARRAY, JSAMPIMAGE, JDIMENSION, int);
114
115
  switch(cinfo->in_color_space)
116
  {
117
    case JCS_EXT_RGB:
118
      sse2fct=jsimd_extrgb_ycc_convert_sse2;
119
      mmxfct=jsimd_extrgb_ycc_convert_mmx;
120
      break;
121
    case JCS_EXT_RGBX:
122
      sse2fct=jsimd_extrgbx_ycc_convert_sse2;
123
      mmxfct=jsimd_extrgbx_ycc_convert_mmx;
124
      break;
125
    case JCS_EXT_BGR:
126
      sse2fct=jsimd_extbgr_ycc_convert_sse2;
127
      mmxfct=jsimd_extbgr_ycc_convert_mmx;
128
      break;
129
    case JCS_EXT_BGRX:
130
      sse2fct=jsimd_extbgrx_ycc_convert_sse2;
131
      mmxfct=jsimd_extbgrx_ycc_convert_mmx;
132
      break;
133
    case JCS_EXT_XBGR:
134
      sse2fct=jsimd_extxbgr_ycc_convert_sse2;
135
      mmxfct=jsimd_extxbgr_ycc_convert_mmx;
136
      break;
137
    case JCS_EXT_XRGB:
138
      sse2fct=jsimd_extxrgb_ycc_convert_sse2;
139
      mmxfct=jsimd_extxrgb_ycc_convert_mmx;
140
      break;
141
    default:
142
      sse2fct=jsimd_rgb_ycc_convert_sse2;
143
      mmxfct=jsimd_rgb_ycc_convert_mmx;
144
      break;
145
  }
146
147
  if ((simd_support & JSIMD_SSE2) &&
148
      IS_ALIGNED_SSE(jconst_rgb_ycc_convert_sse2))
149
    sse2fct(cinfo->image_width, input_buf,
150
        output_buf, output_row, num_rows);
151
  else if (simd_support & JSIMD_MMX)
152
    mmxfct(cinfo->image_width, input_buf,
153
        output_buf, output_row, num_rows);
154
}
155
156
GLOBAL(void)
157
jsimd_ycc_rgb_convert (j_decompress_ptr cinfo,
158
                       JSAMPIMAGE input_buf, JDIMENSION input_row,
159
                       JSAMPARRAY output_buf, int num_rows)
160
{
161
  void (*sse2fct)(JDIMENSION, JSAMPIMAGE, JDIMENSION, JSAMPARRAY, int);
162
  void (*mmxfct)(JDIMENSION, JSAMPIMAGE, JDIMENSION, JSAMPARRAY, int);
163
164
  switch(cinfo->out_color_space)
165
  {
166
    case JCS_EXT_RGB:
167
      sse2fct=jsimd_ycc_extrgb_convert_sse2;
168
      mmxfct=jsimd_ycc_extrgb_convert_mmx;
169
      break;
170
    case JCS_EXT_RGBX:
171
      sse2fct=jsimd_ycc_extrgbx_convert_sse2;
172
      mmxfct=jsimd_ycc_extrgbx_convert_mmx;
173
      break;
174
    case JCS_EXT_BGR:
175
      sse2fct=jsimd_ycc_extbgr_convert_sse2;
176
      mmxfct=jsimd_ycc_extbgr_convert_mmx;
177
      break;
178
    case JCS_EXT_BGRX:
179
      sse2fct=jsimd_ycc_extbgrx_convert_sse2;
180
      mmxfct=jsimd_ycc_extbgrx_convert_mmx;
181
      break;
182
    case JCS_EXT_XBGR:
183
      sse2fct=jsimd_ycc_extxbgr_convert_sse2;
184
      mmxfct=jsimd_ycc_extxbgr_convert_mmx;
185
      break;
186
    case JCS_EXT_XRGB:
187
      sse2fct=jsimd_ycc_extxrgb_convert_sse2;
188
      mmxfct=jsimd_ycc_extxrgb_convert_mmx;
189
      break;
190
    default:
191
      sse2fct=jsimd_ycc_rgb_convert_sse2;
192
      mmxfct=jsimd_ycc_rgb_convert_mmx;
193
      break;
194
  }
195
196
  if ((simd_support & JSIMD_SSE2) &&
197
      IS_ALIGNED_SSE(jconst_ycc_rgb_convert_sse2))
198
    sse2fct(cinfo->output_width, input_buf,
199
        input_row, output_buf, num_rows);
200
  else if (simd_support & JSIMD_MMX)
201
    mmxfct(cinfo->output_width, input_buf,
202
        input_row, output_buf, num_rows);
203
}
204
205
GLOBAL(int)
206
jsimd_can_h2v2_downsample (void)
207
{
208
  init_simd();
209
210
  /* The code is optimised for these values only */
211
  if (BITS_IN_JSAMPLE != 8)
212
    return 0;
213
  if (sizeof(JDIMENSION) != 4)
214
    return 0;
215
216
  if (simd_support & JSIMD_SSE2)
217
    return 1;
218
  if (simd_support & JSIMD_MMX)
219
    return 1;
220
221
  return 0;
222
}
223
224
GLOBAL(int)
225
jsimd_can_h2v1_downsample (void)
226
{
227
  init_simd();
228
229
  /* The code is optimised for these values only */
230
  if (BITS_IN_JSAMPLE != 8)
231
    return 0;
232
  if (sizeof(JDIMENSION) != 4)
233
    return 0;
234
235
  if (simd_support & JSIMD_SSE2)
236
    return 1;
237
  if (simd_support & JSIMD_MMX)
238
    return 1;
239
240
  return 0;
241
}
242
243
GLOBAL(void)
244
jsimd_h2v2_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr,
245
                       JSAMPARRAY input_data, JSAMPARRAY output_data)
246
{
247
  if (simd_support & JSIMD_SSE2)
248
    jsimd_h2v2_downsample_sse2(cinfo->image_width, cinfo->max_v_samp_factor,
249
        compptr->v_samp_factor, compptr->width_in_blocks,
250
        input_data, output_data);
251
  else if (simd_support & JSIMD_MMX)
252
    jsimd_h2v2_downsample_mmx(cinfo->image_width, cinfo->max_v_samp_factor,
253
        compptr->v_samp_factor, compptr->width_in_blocks,
254
        input_data, output_data);
255
}
256
257
GLOBAL(void)
258
jsimd_h2v1_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr,
259
                       JSAMPARRAY input_data, JSAMPARRAY output_data)
260
{
261
  if (simd_support & JSIMD_SSE2)
262
    jsimd_h2v1_downsample_sse2(cinfo->image_width, cinfo->max_v_samp_factor,
263
        compptr->v_samp_factor, compptr->width_in_blocks,
264
        input_data, output_data);
265
  else if (simd_support & JSIMD_MMX)
266
    jsimd_h2v1_downsample_mmx(cinfo->image_width, cinfo->max_v_samp_factor,
267
        compptr->v_samp_factor, compptr->width_in_blocks,
268
        input_data, output_data);
269
}
270
271
GLOBAL(int)
272
jsimd_can_h2v2_upsample (void)
273
{
274
  init_simd();
275
276
  /* The code is optimised for these values only */
277
  if (BITS_IN_JSAMPLE != 8)
278
    return 0;
279
  if (sizeof(JDIMENSION) != 4)
280
    return 0;
281
282
  if (simd_support & JSIMD_SSE2)
283
    return 1;
284
  if (simd_support & JSIMD_MMX)
285
    return 1;
286
287
  return 0;
288
}
289
290
GLOBAL(int)
291
jsimd_can_h2v1_upsample (void)
292
{
293
  init_simd();
294
295
  /* The code is optimised for these values only */
296
  if (BITS_IN_JSAMPLE != 8)
297
    return 0;
298
  if (sizeof(JDIMENSION) != 4)
299
    return 0;
300
301
  if (simd_support & JSIMD_SSE2)
302
    return 1;
303
  if (simd_support & JSIMD_MMX)
304
    return 1;
305
306
  return 0;
307
}
308
309
GLOBAL(void)
310
jsimd_h2v2_upsample (j_decompress_ptr cinfo,
311
                     jpeg_component_info * compptr, 
312
                     JSAMPARRAY input_data,
313
                     JSAMPARRAY * output_data_ptr)
314
{
315
  if (simd_support & JSIMD_SSE2)
316
    jsimd_h2v2_upsample_sse2(cinfo->max_v_samp_factor,
317
        cinfo->output_width, input_data, output_data_ptr);
318
  else if (simd_support & JSIMD_MMX)
319
    jsimd_h2v2_upsample_mmx(cinfo->max_v_samp_factor,
320
        cinfo->output_width, input_data, output_data_ptr);
321
}
322
323
GLOBAL(void)
324
jsimd_h2v1_upsample (j_decompress_ptr cinfo,
325
                     jpeg_component_info * compptr, 
326
                     JSAMPARRAY input_data,
327
                     JSAMPARRAY * output_data_ptr)
328
{
329
  if (simd_support & JSIMD_SSE2)
330
    jsimd_h2v1_upsample_sse2(cinfo->max_v_samp_factor,
331
        cinfo->output_width, input_data, output_data_ptr);
332
  else if (simd_support & JSIMD_MMX)
333
    jsimd_h2v1_upsample_mmx(cinfo->max_v_samp_factor,
334
        cinfo->output_width, input_data, output_data_ptr);
335
}
336
337
GLOBAL(int)
338
jsimd_can_h2v2_fancy_upsample (void)
339
{
340
  init_simd();
341
342
  /* The code is optimised for these values only */
343
  if (BITS_IN_JSAMPLE != 8)
344
    return 0;
345
  if (sizeof(JDIMENSION) != 4)
346
    return 0;
347
348
  if ((simd_support & JSIMD_SSE2) &&
349
      IS_ALIGNED_SSE(jconst_fancy_upsample_sse2))
350
    return 1;
351
  if (simd_support & JSIMD_MMX)
352
    return 1;
353
354
  return 0;
355
}
356
357
GLOBAL(int)
358
jsimd_can_h2v1_fancy_upsample (void)
359
{
360
  init_simd();
361
362
  /* The code is optimised for these values only */
363
  if (BITS_IN_JSAMPLE != 8)
364
    return 0;
365
  if (sizeof(JDIMENSION) != 4)
366
    return 0;
367
368
  if ((simd_support & JSIMD_SSE2) &&
369
      IS_ALIGNED_SSE(jconst_fancy_upsample_sse2))
370
    return 1;
371
  if (simd_support & JSIMD_MMX)
372
    return 1;
373
374
  return 0;
375
}
376
377
GLOBAL(void)
378
jsimd_h2v2_fancy_upsample (j_decompress_ptr cinfo,
379
                           jpeg_component_info * compptr, 
380
                           JSAMPARRAY input_data,
381
                           JSAMPARRAY * output_data_ptr)
382
{
383
  if ((simd_support & JSIMD_SSE2) &&
384
      IS_ALIGNED_SSE(jconst_fancy_upsample_sse2))
385
    jsimd_h2v1_fancy_upsample_sse2(cinfo->max_v_samp_factor,
386
        compptr->downsampled_width, input_data, output_data_ptr);
387
  else if (simd_support & JSIMD_MMX)
388
    jsimd_h2v2_fancy_upsample_mmx(cinfo->max_v_samp_factor,
389
        compptr->downsampled_width, input_data, output_data_ptr);
390
}
391
392
GLOBAL(void)
393
jsimd_h2v1_fancy_upsample (j_decompress_ptr cinfo,
394
                           jpeg_component_info * compptr, 
395
                           JSAMPARRAY input_data,
396
                           JSAMPARRAY * output_data_ptr)
397
{
398
  if ((simd_support & JSIMD_SSE2) &&
399
      IS_ALIGNED_SSE(jconst_fancy_upsample_sse2))
400
    jsimd_h2v1_fancy_upsample_sse2(cinfo->max_v_samp_factor,
401
        compptr->downsampled_width, input_data, output_data_ptr);
402
  else if (simd_support & JSIMD_MMX)
403
    jsimd_h2v1_fancy_upsample_mmx(cinfo->max_v_samp_factor,
404
        compptr->downsampled_width, input_data, output_data_ptr);
405
}
406
407
GLOBAL(int)
408
jsimd_can_h2v2_merged_upsample (void)
409
{
410
  init_simd();
411
412
  /* The code is optimised for these values only */
413
  if (BITS_IN_JSAMPLE != 8)
414
    return 0;
415
  if (sizeof(JDIMENSION) != 4)
416
    return 0;
417
418
  if ((simd_support & JSIMD_SSE2) &&
419
      IS_ALIGNED_SSE(jconst_merged_upsample_sse2))
420
    return 1;
421
  if (simd_support & JSIMD_MMX)
422
    return 1;
423
424
  return 0;
425
}
426
427
GLOBAL(int)
428
jsimd_can_h2v1_merged_upsample (void)
429
{
430
  init_simd();
431
432
  /* The code is optimised for these values only */
433
  if (BITS_IN_JSAMPLE != 8)
434
    return 0;
435
  if (sizeof(JDIMENSION) != 4)
436
    return 0;
437
438
  if ((simd_support & JSIMD_SSE2) &&
439
      IS_ALIGNED_SSE(jconst_merged_upsample_sse2))
440
    return 1;
441
  if (simd_support & JSIMD_MMX)
442
    return 1;
443
444
  return 0;
445
}
446
447
GLOBAL(void)
448
jsimd_h2v2_merged_upsample (j_decompress_ptr cinfo,
449
                            JSAMPIMAGE input_buf,
450
                            JDIMENSION in_row_group_ctr,
451
                            JSAMPARRAY output_buf)
452
{
453
  void (*sse2fct)(JDIMENSION, JSAMPIMAGE, JDIMENSION, JSAMPARRAY);
454
  void (*mmxfct)(JDIMENSION, JSAMPIMAGE, JDIMENSION, JSAMPARRAY);
455
456
  switch(cinfo->out_color_space)
457
  {
458
    case JCS_EXT_RGB:
459
      sse2fct=jsimd_h2v2_extrgb_merged_upsample_sse2;
460
      mmxfct=jsimd_h2v2_extrgb_merged_upsample_mmx;
461
      break;
462
    case JCS_EXT_RGBX:
463
      sse2fct=jsimd_h2v2_extrgbx_merged_upsample_sse2;
464
      mmxfct=jsimd_h2v2_extrgbx_merged_upsample_mmx;
465
      break;
466
    case JCS_EXT_BGR:
467
      sse2fct=jsimd_h2v2_extbgr_merged_upsample_sse2;
468
      mmxfct=jsimd_h2v2_extbgr_merged_upsample_mmx;
469
      break;
470
    case JCS_EXT_BGRX:
471
      sse2fct=jsimd_h2v2_extbgrx_merged_upsample_sse2;
472
      mmxfct=jsimd_h2v2_extbgrx_merged_upsample_mmx;
473
      break;
474
    case JCS_EXT_XBGR:
475
      sse2fct=jsimd_h2v2_extxbgr_merged_upsample_sse2;
476
      mmxfct=jsimd_h2v2_extxbgr_merged_upsample_mmx;
477
      break;
478
    case JCS_EXT_XRGB:
479
      sse2fct=jsimd_h2v2_extxrgb_merged_upsample_sse2;
480
      mmxfct=jsimd_h2v2_extxrgb_merged_upsample_mmx;
481
      break;
482
    default:
483
      sse2fct=jsimd_h2v2_merged_upsample_sse2;
484
      mmxfct=jsimd_h2v2_merged_upsample_mmx;
485
      break;
486
  }
487
488
  if ((simd_support & JSIMD_SSE2) &&
489
      IS_ALIGNED_SSE(jconst_merged_upsample_sse2))
490
    sse2fct(cinfo->output_width, input_buf,
491
        in_row_group_ctr, output_buf);
492
  else if (simd_support & JSIMD_MMX)
493
    mmxfct(cinfo->output_width, input_buf,
494
        in_row_group_ctr, output_buf);
495
}
496
497
GLOBAL(void)
498
jsimd_h2v1_merged_upsample (j_decompress_ptr cinfo,
499
                            JSAMPIMAGE input_buf,
500
                            JDIMENSION in_row_group_ctr,
501
                            JSAMPARRAY output_buf)
502
{
503
  void (*sse2fct)(JDIMENSION, JSAMPIMAGE, JDIMENSION, JSAMPARRAY);
504
  void (*mmxfct)(JDIMENSION, JSAMPIMAGE, JDIMENSION, JSAMPARRAY);
505
506
  switch(cinfo->out_color_space)
507
  {
508
    case JCS_EXT_RGB:
509
      sse2fct=jsimd_h2v1_extrgb_merged_upsample_sse2;
510
      mmxfct=jsimd_h2v1_extrgb_merged_upsample_mmx;
511
      break;
512
    case JCS_EXT_RGBX:
513
      sse2fct=jsimd_h2v1_extrgbx_merged_upsample_sse2;
514
      mmxfct=jsimd_h2v1_extrgbx_merged_upsample_mmx;
515
      break;
516
    case JCS_EXT_BGR:
517
      sse2fct=jsimd_h2v1_extbgr_merged_upsample_sse2;
518
      mmxfct=jsimd_h2v1_extbgr_merged_upsample_mmx;
519
      break;
520
    case JCS_EXT_BGRX:
521
      sse2fct=jsimd_h2v1_extbgrx_merged_upsample_sse2;
522
      mmxfct=jsimd_h2v1_extbgrx_merged_upsample_mmx;
523
      break;
524
    case JCS_EXT_XBGR:
525
      sse2fct=jsimd_h2v1_extxbgr_merged_upsample_sse2;
526
      mmxfct=jsimd_h2v1_extxbgr_merged_upsample_mmx;
527
      break;
528
    case JCS_EXT_XRGB:
529
      sse2fct=jsimd_h2v1_extxrgb_merged_upsample_sse2;
530
      mmxfct=jsimd_h2v1_extxrgb_merged_upsample_mmx;
531
      break;
532
    default:
533
      sse2fct=jsimd_h2v1_merged_upsample_sse2;
534
      mmxfct=jsimd_h2v1_merged_upsample_mmx;
535
      break;
536
  }
537
538
  if ((simd_support & JSIMD_SSE2) &&
539
      IS_ALIGNED_SSE(jconst_merged_upsample_sse2))
540
    sse2fct(cinfo->output_width, input_buf,
541
        in_row_group_ctr, output_buf);
542
  else if (simd_support & JSIMD_MMX)
543
    mmxfct(cinfo->output_width, input_buf,
544
        in_row_group_ctr, output_buf);
545
}
546
547
GLOBAL(int)
548
jsimd_can_convsamp (void)
549
{
550
  init_simd();
551
552
  /* The code is optimised for these values only */
553
  if (DCTSIZE != 8)
554
    return 0;
555
  if (BITS_IN_JSAMPLE != 8)
556
    return 0;
557
  if (sizeof(JDIMENSION) != 4)
558
    return 0;
559
  if (sizeof(DCTELEM) != 2)
560
    return 0;
561
562
  if (simd_support & JSIMD_SSE2)
563
    return 1;
564
  if (simd_support & JSIMD_MMX)
565
    return 1;
566
567
  return 0;
568
}
569
570
GLOBAL(int)
571
jsimd_can_convsamp_float (void)
572
{
573
  init_simd();
574
575
  /* The code is optimised for these values only */
576
  if (DCTSIZE != 8)
577
    return 0;
578
  if (BITS_IN_JSAMPLE != 8)
579
    return 0;
580
  if (sizeof(JDIMENSION) != 4)
581
    return 0;
582
  if (sizeof(FAST_FLOAT) != 4)
583
    return 0;
584
585
  if (simd_support & JSIMD_SSE2)
586
    return 1;
587
  if (simd_support & JSIMD_SSE)
588
    return 1;
589
  if (simd_support & JSIMD_3DNOW)
590
    return 1;
591
592
  return 0;
593
}
594
595
GLOBAL(void)
596
jsimd_convsamp (JSAMPARRAY sample_data, JDIMENSION start_col,
597
                DCTELEM * workspace)
598
{
599
  if (simd_support & JSIMD_SSE2)
600
    jsimd_convsamp_sse2(sample_data, start_col, workspace);
601
  else if (simd_support & JSIMD_MMX)
602
    jsimd_convsamp_mmx(sample_data, start_col, workspace);
603
}
604
605
GLOBAL(void)
606
jsimd_convsamp_float (JSAMPARRAY sample_data, JDIMENSION start_col,
607
                      FAST_FLOAT * workspace)
608
{
609
  if (simd_support & JSIMD_SSE2)
610
    jsimd_convsamp_float_sse2(sample_data, start_col, workspace);
611
  else if (simd_support & JSIMD_SSE)
612
    jsimd_convsamp_float_sse(sample_data, start_col, workspace);
613
  else if (simd_support & JSIMD_3DNOW)
614
    jsimd_convsamp_float_3dnow(sample_data, start_col, workspace);
615
}
616
617
GLOBAL(int)
618
jsimd_can_fdct_islow (void)
619
{
620
  init_simd();
621
622
  /* The code is optimised for these values only */
623
  if (DCTSIZE != 8)
624
    return 0;
625
  if (sizeof(DCTELEM) != 2)
626
    return 0;
627
628
  if ((simd_support & JSIMD_SSE2) && IS_ALIGNED_SSE(jconst_fdct_islow_sse2))
629
    return 1;
630
  if (simd_support & JSIMD_MMX)
631
    return 1;
632
633
  return 0;
634
}
635
636
GLOBAL(int)
637
jsimd_can_fdct_ifast (void)
638
{
639
  init_simd();
640
641
  /* The code is optimised for these values only */
642
  if (DCTSIZE != 8)
643
    return 0;
644
  if (sizeof(DCTELEM) != 2)
645
    return 0;
646
647
  if ((simd_support & JSIMD_SSE2) && IS_ALIGNED_SSE(jconst_fdct_ifast_sse2))
648
    return 1;
649
  if (simd_support & JSIMD_MMX)
650
    return 1;
651
652
  return 0;
653
}
654
655
GLOBAL(int)
656
jsimd_can_fdct_float (void)
657
{
658
  init_simd();
659
660
  /* The code is optimised for these values only */
661
  if (DCTSIZE != 8)
662
    return 0;
663
  if (sizeof(FAST_FLOAT) != 4)
664
    return 0;
665
666
  if ((simd_support & JSIMD_SSE) && IS_ALIGNED_SSE(jconst_fdct_float_sse))
667
    return 1;
668
  if (simd_support & JSIMD_3DNOW)
669
    return 1;
670
671
  return 0;
672
}
673
674
GLOBAL(void)
675
jsimd_fdct_islow (DCTELEM * data)
676
{
677
  if ((simd_support & JSIMD_SSE2) && IS_ALIGNED_SSE(jconst_fdct_islow_sse2))
678
    jsimd_fdct_islow_sse2(data);
679
  else if (simd_support & JSIMD_MMX)
680
    jsimd_fdct_islow_mmx(data);
681
}
682
683
GLOBAL(void)
684
jsimd_fdct_ifast (DCTELEM * data)
685
{
686
  if ((simd_support & JSIMD_SSE2) && IS_ALIGNED_SSE(jconst_fdct_islow_sse2))
687
    jsimd_fdct_ifast_sse2(data);
688
  else if (simd_support & JSIMD_MMX)
689
    jsimd_fdct_ifast_mmx(data);
690
}
691
692
GLOBAL(void)
693
jsimd_fdct_float (FAST_FLOAT * data)
694
{
695
  if ((simd_support & JSIMD_SSE) && IS_ALIGNED_SSE(jconst_fdct_float_sse))
696
    jsimd_fdct_float_sse(data);
697
  else if (simd_support & JSIMD_3DNOW)
698
    jsimd_fdct_float_3dnow(data);
699
}
700
701
GLOBAL(int)
702
jsimd_can_quantize (void)
703
{
704
  init_simd();
705
706
  /* The code is optimised for these values only */
707
  if (DCTSIZE != 8)
708
    return 0;
709
  if (sizeof(JCOEF) != 2)
710
    return 0;
711
  if (sizeof(DCTELEM) != 2)
712
    return 0;
713
714
  if (simd_support & JSIMD_SSE2)
715
    return 1;
716
  if (simd_support & JSIMD_MMX)
717
    return 1;
718
719
  return 0;
720
}
721
722
GLOBAL(int)
723
jsimd_can_quantize_float (void)
724
{
725
  init_simd();
726
727
  /* The code is optimised for these values only */
728
  if (DCTSIZE != 8)
729
    return 0;
730
  if (sizeof(JCOEF) != 2)
731
    return 0;
732
  if (sizeof(FAST_FLOAT) != 4)
733
    return 0;
734
735
  if (simd_support & JSIMD_SSE2)
736
    return 1;
737
  if (simd_support & JSIMD_SSE)
738
    return 1;
739
  if (simd_support & JSIMD_3DNOW)
740
    return 1;
741
742
  return 0;
743
}
744
745
GLOBAL(void)
746
jsimd_quantize (JCOEFPTR coef_block, DCTELEM * divisors,
747
                DCTELEM * workspace)
748
{
749
  if (simd_support & JSIMD_SSE2)
750
    jsimd_quantize_sse2(coef_block, divisors, workspace);
751
  else if (simd_support & JSIMD_MMX)
752
    jsimd_quantize_mmx(coef_block, divisors, workspace);
753
}
754
755
GLOBAL(void)
756
jsimd_quantize_float (JCOEFPTR coef_block, FAST_FLOAT * divisors,
757
                      FAST_FLOAT * workspace)
758
{
759
  if (simd_support & JSIMD_SSE2)
760
    jsimd_quantize_float_sse2(coef_block, divisors, workspace);
761
  else if (simd_support & JSIMD_SSE)
762
    jsimd_quantize_float_sse(coef_block, divisors, workspace);
763
  else if (simd_support & JSIMD_3DNOW)
764
    jsimd_quantize_float_3dnow(coef_block, divisors, workspace);
765
}
766
767
GLOBAL(int)
768
jsimd_can_idct_2x2 (void)
769
{
770
  init_simd();
771
772
  /* The code is optimised for these values only */
773
  if (DCTSIZE != 8)
774
    return 0;
775
  if (sizeof(JCOEF) != 2)
776
    return 0;
777
  if (BITS_IN_JSAMPLE != 8)
778
    return 0;
779
  if (sizeof(JDIMENSION) != 4)
780
    return 0;
781
  if (sizeof(ISLOW_MULT_TYPE) != 2)
782
    return 0;
783
784
  if ((simd_support & JSIMD_SSE2) && IS_ALIGNED_SSE(jconst_idct_red_sse2))
785
    return 1;
786
  if (simd_support & JSIMD_MMX)
787
    return 1;
788
789
  return 0;
790
}
791
792
GLOBAL(int)
793
jsimd_can_idct_4x4 (void)
794
{
795
  init_simd();
796
797
  /* The code is optimised for these values only */
798
  if (DCTSIZE != 8)
799
    return 0;
800
  if (sizeof(JCOEF) != 2)
801
    return 0;
802
  if (BITS_IN_JSAMPLE != 8)
803
    return 0;
804
  if (sizeof(JDIMENSION) != 4)
805
    return 0;
806
  if (sizeof(ISLOW_MULT_TYPE) != 2)
807
    return 0;
808
809
  if ((simd_support & JSIMD_SSE2) && IS_ALIGNED_SSE(jconst_idct_red_sse2))
810
    return 1;
811
  if (simd_support & JSIMD_MMX)
812
    return 1;
813
814
  return 0;
815
}
816
817
GLOBAL(void)
818
jsimd_idct_2x2 (j_decompress_ptr cinfo, jpeg_component_info * compptr,
819
                JCOEFPTR coef_block, JSAMPARRAY output_buf,
820
                JDIMENSION output_col)
821
{
822
  if ((simd_support & JSIMD_SSE2) && IS_ALIGNED_SSE(jconst_idct_red_sse2))
823
    jsimd_idct_2x2_sse2(compptr->dct_table, coef_block, output_buf, output_col);
824
  else if (simd_support & JSIMD_MMX)
825
    jsimd_idct_2x2_mmx(compptr->dct_table, coef_block, output_buf, output_col);
826
}
827
828
GLOBAL(void)
829
jsimd_idct_4x4 (j_decompress_ptr cinfo, jpeg_component_info * compptr,
830
                JCOEFPTR coef_block, JSAMPARRAY output_buf,
831
                JDIMENSION output_col)
832
{
833
  if ((simd_support & JSIMD_SSE2) && IS_ALIGNED_SSE(jconst_idct_red_sse2))
834
    jsimd_idct_4x4_sse2(compptr->dct_table, coef_block, output_buf, output_col);
835
  else if (simd_support & JSIMD_MMX)
836
    jsimd_idct_4x4_mmx(compptr->dct_table, coef_block, output_buf, output_col);
837
}
838
839
GLOBAL(int)
840
jsimd_can_idct_islow (void)
841
{
842
  init_simd();
843
844
  /* The code is optimised for these values only */
845
  if (DCTSIZE != 8)
846
    return 0;
847
  if (sizeof(JCOEF) != 2)
848
    return 0;
849
  if (BITS_IN_JSAMPLE != 8)
850
    return 0;
851
  if (sizeof(JDIMENSION) != 4)
852
    return 0;
853
  if (sizeof(ISLOW_MULT_TYPE) != 2)
854
    return 0;
855
856
  if ((simd_support & JSIMD_SSE2) && IS_ALIGNED_SSE(jconst_idct_islow_sse2))
857
    return 1;
858
  if (simd_support & JSIMD_MMX)
859
    return 1;
860
861
  return 0;
862
}
863
864
GLOBAL(int)
865
jsimd_can_idct_ifast (void)
866
{
867
  init_simd();
868
869
  /* The code is optimised for these values only */
870
  if (DCTSIZE != 8)
871
    return 0;
872
  if (sizeof(JCOEF) != 2)
873
    return 0;
874
  if (BITS_IN_JSAMPLE != 8)
875
    return 0;
876
  if (sizeof(JDIMENSION) != 4)
877
    return 0;
878
  if (sizeof(IFAST_MULT_TYPE) != 2)
879
    return 0;
880
  if (IFAST_SCALE_BITS != 2)
881
    return 0;
882
883
  if ((simd_support & JSIMD_SSE2) && IS_ALIGNED_SSE(jconst_idct_ifast_sse2))
884
    return 1;
885
  if (simd_support & JSIMD_MMX)
886
    return 1;
887
888
  return 0;
889
}
890
891
GLOBAL(int)
892
jsimd_can_idct_float (void)
893
{
894
  init_simd();
895
896
  if (DCTSIZE != 8)
897
    return 0;
898
  if (sizeof(JCOEF) != 2)
899
    return 0;
900
  if (BITS_IN_JSAMPLE != 8)
901
    return 0;
902
  if (sizeof(JDIMENSION) != 4)
903
    return 0;
904
  if (sizeof(FAST_FLOAT) != 4)
905
    return 0;
906
  if (sizeof(FLOAT_MULT_TYPE) != 4)
907
    return 0;
908
909
  if ((simd_support & JSIMD_SSE2) && IS_ALIGNED_SSE(jconst_idct_float_sse2))
910
    return 1;
911
  if ((simd_support & JSIMD_SSE) && IS_ALIGNED_SSE(jconst_idct_float_sse))
912
    return 1;
913
  if (simd_support & JSIMD_3DNOW)
914
    return 1;
915
916
  return 0;
917
}
918
919
GLOBAL(void)
920
jsimd_idct_islow (j_decompress_ptr cinfo, jpeg_component_info * compptr,
921
                JCOEFPTR coef_block, JSAMPARRAY output_buf,
922
                JDIMENSION output_col)
923
{
924
  if ((simd_support & JSIMD_SSE2) && IS_ALIGNED_SSE(jconst_idct_islow_sse2))
925
    jsimd_idct_islow_sse2(compptr->dct_table, coef_block, output_buf, output_col);
926
  else if (simd_support & JSIMD_MMX)
927
    jsimd_idct_islow_mmx(compptr->dct_table, coef_block, output_buf, output_col);
928
}
929
930
GLOBAL(void)
931
jsimd_idct_ifast (j_decompress_ptr cinfo, jpeg_component_info * compptr,
932
                JCOEFPTR coef_block, JSAMPARRAY output_buf,
933
                JDIMENSION output_col)
934
{
935
  if ((simd_support & JSIMD_SSE2) && IS_ALIGNED_SSE(jconst_idct_ifast_sse2))
936
    jsimd_idct_ifast_sse2(compptr->dct_table, coef_block, output_buf, output_col);
937
  else if (simd_support & JSIMD_MMX)
938
    jsimd_idct_ifast_mmx(compptr->dct_table, coef_block, output_buf, output_col);
939
}
940
941
GLOBAL(void)
942
jsimd_idct_float (j_decompress_ptr cinfo, jpeg_component_info * compptr,
943
                JCOEFPTR coef_block, JSAMPARRAY output_buf,
944
                JDIMENSION output_col)
945
{
946
  if ((simd_support & JSIMD_SSE2) && IS_ALIGNED_SSE(jconst_idct_float_sse2))
947
    jsimd_idct_float_sse2(compptr->dct_table, coef_block,
948
        output_buf, output_col);
949
  else if ((simd_support & JSIMD_SSE) && IS_ALIGNED_SSE(jconst_idct_float_sse))
950
    jsimd_idct_float_sse(compptr->dct_table, coef_block,
951
        output_buf, output_col);
952
  else if (simd_support & JSIMD_3DNOW)
953
    jsimd_idct_float_3dnow(compptr->dct_table, coef_block,
954
        output_buf, output_col);
955
}
956
(-)a/jpeg/simd/jsimd_x86_64.c (+680 lines)
Line     Link Here 
Line 0    Link Here 
1
/*
2
 * jsimd_x86_64.c
3
 *
4
 * Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
5
 * Copyright 2009 D. R. Commander
6
 * 
7
 * Based on the x86 SIMD extension for IJG JPEG library,
8
 * Copyright (C) 1999-2006, MIYASAKA Masaru.
9
 *
10
 * This file contains the interface between the "normal" portions
11
 * of the library and the SIMD implementations when running on a
12
 * x86_64 architecture.
13
 */
14
15
#define JPEG_INTERNALS
16
#include "../jinclude.h"
17
#include "../jpeglib.h"
18
#include "../jsimd.h"
19
#include "../jdct.h"
20
#include "../jsimddct.h"
21
#include "simd/jsimd.h"
22
23
/*
24
 * In the PIC cases, we have no guarantee that constants will keep
25
 * their alignment. This macro allows us to verify it at runtime.
26
 */
27
#define IS_ALIGNED(ptr, order) (((size_t)ptr & ((1 << order) - 1)) == 0)
28
29
#define IS_ALIGNED_SSE(ptr) (IS_ALIGNED(ptr, 4)) /* 16 byte alignment */
30
31
GLOBAL(int)
32
jsimd_can_rgb_ycc (void)
33
{
34
  /* The code is optimised for these values only */
35
  if (BITS_IN_JSAMPLE != 8)
36
    return 0;
37
  if (sizeof(JDIMENSION) != 4)
38
    return 0;
39
  if ((RGB_PIXELSIZE != 3) && (RGB_PIXELSIZE != 4))
40
    return 0;
41
42
  if (!IS_ALIGNED_SSE(jconst_rgb_ycc_convert_sse2))
43
    return 0;
44
45
  return 1;
46
}
47
48
GLOBAL(int)
49
jsimd_can_ycc_rgb (void)
50
{
51
  /* The code is optimised for these values only */
52
  if (BITS_IN_JSAMPLE != 8)
53
    return 0;
54
  if (sizeof(JDIMENSION) != 4)
55
    return 0;
56
  if ((RGB_PIXELSIZE != 3) && (RGB_PIXELSIZE != 4))
57
    return 0;
58
59
  if (!IS_ALIGNED_SSE(jconst_ycc_rgb_convert_sse2))
60
    return 0;
61
62
  return 1;
63
}
64
65
GLOBAL(void)
66
jsimd_rgb_ycc_convert (j_compress_ptr cinfo,
67
                       JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
68
                       JDIMENSION output_row, int num_rows)
69
{
70
  void (*sse2fct)(JDIMENSION, JSAMPARRAY, JSAMPIMAGE, JDIMENSION, int);
71
72
  switch(cinfo->in_color_space)
73
  {
74
    case JCS_EXT_RGB:
75
      sse2fct=jsimd_extrgb_ycc_convert_sse2;
76
      break;
77
    case JCS_EXT_RGBX:
78
      sse2fct=jsimd_extrgbx_ycc_convert_sse2;
79
      break;
80
    case JCS_EXT_BGR:
81
      sse2fct=jsimd_extbgr_ycc_convert_sse2;
82
      break;
83
    case JCS_EXT_BGRX:
84
      sse2fct=jsimd_extbgrx_ycc_convert_sse2;
85
      break;
86
    case JCS_EXT_XBGR:
87
      sse2fct=jsimd_extxbgr_ycc_convert_sse2;
88
      break;
89
    case JCS_EXT_XRGB:
90
      sse2fct=jsimd_extxrgb_ycc_convert_sse2;
91
      break;
92
    default:
93
      sse2fct=jsimd_rgb_ycc_convert_sse2;
94
      break;
95
  }
96
97
  sse2fct(cinfo->image_width, input_buf, output_buf, output_row, num_rows);
98
}
99
100
GLOBAL(void)
101
jsimd_ycc_rgb_convert (j_decompress_ptr cinfo,
102
                       JSAMPIMAGE input_buf, JDIMENSION input_row,
103
                       JSAMPARRAY output_buf, int num_rows)
104
{
105
  void (*sse2fct)(JDIMENSION, JSAMPIMAGE, JDIMENSION, JSAMPARRAY, int);
106
107
  switch(cinfo->out_color_space)
108
  {
109
    case JCS_EXT_RGB:
110
      sse2fct=jsimd_ycc_extrgb_convert_sse2;
111
      break;
112
    case JCS_EXT_RGBX:
113
      sse2fct=jsimd_ycc_extrgbx_convert_sse2;
114
      break;
115
    case JCS_EXT_BGR:
116
      sse2fct=jsimd_ycc_extbgr_convert_sse2;
117
      break;
118
    case JCS_EXT_BGRX:
119
      sse2fct=jsimd_ycc_extbgrx_convert_sse2;
120
      break;
121
    case JCS_EXT_XBGR:
122
      sse2fct=jsimd_ycc_extxbgr_convert_sse2;
123
      break;
124
    case JCS_EXT_XRGB:
125
      sse2fct=jsimd_ycc_extxrgb_convert_sse2;
126
      break;
127
    default:
128
      sse2fct=jsimd_ycc_rgb_convert_sse2;
129
      break;
130
  }
131
132
  sse2fct(cinfo->output_width, input_buf, input_row, output_buf, num_rows);
133
}
134
135
GLOBAL(int)
136
jsimd_can_h2v2_downsample (void)
137
{
138
  /* The code is optimised for these values only */
139
  if (BITS_IN_JSAMPLE != 8)
140
    return 0;
141
  if (sizeof(JDIMENSION) != 4)
142
    return 0;
143
144
  return 1;
145
}
146
147
GLOBAL(int)
148
jsimd_can_h2v1_downsample (void)
149
{
150
  /* The code is optimised for these values only */
151
  if (BITS_IN_JSAMPLE != 8)
152
    return 0;
153
  if (sizeof(JDIMENSION) != 4)
154
    return 0;
155
156
  return 1;
157
}
158
159
GLOBAL(void)
160
jsimd_h2v2_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr,
161
                       JSAMPARRAY input_data, JSAMPARRAY output_data)
162
{
163
  jsimd_h2v2_downsample_sse2(cinfo->image_width,
164
                             cinfo->max_v_samp_factor,
165
                             compptr->v_samp_factor,
166
                             compptr->width_in_blocks,
167
                             input_data, output_data);
168
}
169
170
GLOBAL(void)
171
jsimd_h2v1_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr,
172
                       JSAMPARRAY input_data, JSAMPARRAY output_data)
173
{
174
  jsimd_h2v1_downsample_sse2(cinfo->image_width,
175
                             cinfo->max_v_samp_factor,
176
                             compptr->v_samp_factor,
177
                             compptr->width_in_blocks,
178
                             input_data, output_data);
179
}
180
181
GLOBAL(int)
182
jsimd_can_h2v2_upsample (void)
183
{
184
  /* The code is optimised for these values only */
185
  if (BITS_IN_JSAMPLE != 8)
186
    return 0;
187
  if (sizeof(JDIMENSION) != 4)
188
    return 0;
189
190
  return 1;
191
}
192
193
GLOBAL(int)
194
jsimd_can_h2v1_upsample (void)
195
{
196
  /* The code is optimised for these values only */
197
  if (BITS_IN_JSAMPLE != 8)
198
    return 0;
199
  if (sizeof(JDIMENSION) != 4)
200
    return 0;
201
202
  return 1;
203
}
204
205
GLOBAL(void)
206
jsimd_h2v2_upsample (j_decompress_ptr cinfo,
207
                     jpeg_component_info * compptr, 
208
                     JSAMPARRAY input_data,
209
                     JSAMPARRAY * output_data_ptr)
210
{
211
  jsimd_h2v2_upsample_sse2(cinfo->max_v_samp_factor,
212
                           cinfo->output_width,
213
                           input_data, output_data_ptr);
214
}
215
216
GLOBAL(void)
217
jsimd_h2v1_upsample (j_decompress_ptr cinfo,
218
                     jpeg_component_info * compptr, 
219
                     JSAMPARRAY input_data,
220
                     JSAMPARRAY * output_data_ptr)
221
{
222
  jsimd_h2v1_upsample_sse2(cinfo->max_v_samp_factor,
223
                           cinfo->output_width,
224
                           input_data, output_data_ptr);
225
}
226
227
GLOBAL(int)
228
jsimd_can_h2v2_fancy_upsample (void)
229
{
230
  /* The code is optimised for these values only */
231
  if (BITS_IN_JSAMPLE != 8)
232
    return 0;
233
  if (sizeof(JDIMENSION) != 4)
234
    return 0;
235
236
  if (!IS_ALIGNED_SSE(jconst_fancy_upsample_sse2))
237
    return 0;
238
239
  return 1;
240
}
241
242
GLOBAL(int)
243
jsimd_can_h2v1_fancy_upsample (void)
244
{
245
  /* The code is optimised for these values only */
246
  if (BITS_IN_JSAMPLE != 8)
247
    return 0;
248
  if (sizeof(JDIMENSION) != 4)
249
    return 0;
250
251
  if (!IS_ALIGNED_SSE(jconst_fancy_upsample_sse2))
252
    return 0;
253
254
  return 1;
255
}
256
257
GLOBAL(void)
258
jsimd_h2v2_fancy_upsample (j_decompress_ptr cinfo,
259
                           jpeg_component_info * compptr, 
260
                           JSAMPARRAY input_data,
261
                           JSAMPARRAY * output_data_ptr)
262
{
263
  jsimd_h2v1_fancy_upsample_sse2(cinfo->max_v_samp_factor,
264
                                 compptr->downsampled_width,
265
                                 input_data, output_data_ptr);
266
}
267
268
GLOBAL(void)
269
jsimd_h2v1_fancy_upsample (j_decompress_ptr cinfo,
270
                           jpeg_component_info * compptr, 
271
                           JSAMPARRAY input_data,
272
                           JSAMPARRAY * output_data_ptr)
273
{
274
  jsimd_h2v1_fancy_upsample_sse2(cinfo->max_v_samp_factor,
275
                                 compptr->downsampled_width,
276
                                 input_data, output_data_ptr);
277
}
278
279
GLOBAL(int)
280
jsimd_can_h2v2_merged_upsample (void)
281
{
282
  /* The code is optimised for these values only */
283
  if (BITS_IN_JSAMPLE != 8)
284
    return 0;
285
  if (sizeof(JDIMENSION) != 4)
286
    return 0;
287
288
  if (!IS_ALIGNED_SSE(jconst_merged_upsample_sse2))
289
    return 0;
290
291
  return 1;
292
}
293
294
GLOBAL(int)
295
jsimd_can_h2v1_merged_upsample (void)
296
{
297
  /* The code is optimised for these values only */
298
  if (BITS_IN_JSAMPLE != 8)
299
    return 0;
300
  if (sizeof(JDIMENSION) != 4)
301
    return 0;
302
303
  if (!IS_ALIGNED_SSE(jconst_merged_upsample_sse2))
304
    return 0;
305
306
  return 1;
307
}
308
309
GLOBAL(void)
310
jsimd_h2v2_merged_upsample (j_decompress_ptr cinfo,
311
                            JSAMPIMAGE input_buf,
312
                            JDIMENSION in_row_group_ctr,
313
                            JSAMPARRAY output_buf)
314
{
315
  void (*sse2fct)(JDIMENSION, JSAMPIMAGE, JDIMENSION, JSAMPARRAY);
316
317
  switch(cinfo->out_color_space)
318
  {
319
    case JCS_EXT_RGB:
320
      sse2fct=jsimd_h2v2_extrgb_merged_upsample_sse2;
321
      break;
322
    case JCS_EXT_RGBX:
323
      sse2fct=jsimd_h2v2_extrgbx_merged_upsample_sse2;
324
      break;
325
    case JCS_EXT_BGR:
326
      sse2fct=jsimd_h2v2_extbgr_merged_upsample_sse2;
327
      break;
328
    case JCS_EXT_BGRX:
329
      sse2fct=jsimd_h2v2_extbgrx_merged_upsample_sse2;
330
      break;
331
    case JCS_EXT_XBGR:
332
      sse2fct=jsimd_h2v2_extxbgr_merged_upsample_sse2;
333
      break;
334
    case JCS_EXT_XRGB:
335
      sse2fct=jsimd_h2v2_extxrgb_merged_upsample_sse2;
336
      break;
337
    default:
338
      sse2fct=jsimd_h2v2_merged_upsample_sse2;
339
      break;
340
  }
341
342
  sse2fct(cinfo->output_width, input_buf, in_row_group_ctr, output_buf);
343
}
344
345
GLOBAL(void)
346
jsimd_h2v1_merged_upsample (j_decompress_ptr cinfo,
347
                            JSAMPIMAGE input_buf,
348
                            JDIMENSION in_row_group_ctr,
349
                            JSAMPARRAY output_buf)
350
{
351
  void (*sse2fct)(JDIMENSION, JSAMPIMAGE, JDIMENSION, JSAMPARRAY);
352
353
  switch(cinfo->out_color_space)
354
  {
355
    case JCS_EXT_RGB:
356
      sse2fct=jsimd_h2v1_extrgb_merged_upsample_sse2;
357
      break;
358
    case JCS_EXT_RGBX:
359
      sse2fct=jsimd_h2v1_extrgbx_merged_upsample_sse2;
360
      break;
361
    case JCS_EXT_BGR:
362
      sse2fct=jsimd_h2v1_extbgr_merged_upsample_sse2;
363
      break;
364
    case JCS_EXT_BGRX:
365
      sse2fct=jsimd_h2v1_extbgrx_merged_upsample_sse2;
366
      break;
367
    case JCS_EXT_XBGR:
368
      sse2fct=jsimd_h2v1_extxbgr_merged_upsample_sse2;
369
      break;
370
    case JCS_EXT_XRGB:
371
      sse2fct=jsimd_h2v1_extxrgb_merged_upsample_sse2;
372
      break;
373
    default:
374
      sse2fct=jsimd_h2v1_merged_upsample_sse2;
375
      break;
376
  }
377
378
  sse2fct(cinfo->output_width, input_buf, in_row_group_ctr, output_buf);
379
}
380
381
GLOBAL(int)
382
jsimd_can_convsamp (void)
383
{
384
  /* The code is optimised for these values only */
385
  if (DCTSIZE != 8)
386
    return 0;
387
  if (BITS_IN_JSAMPLE != 8)
388
    return 0;
389
  if (sizeof(JDIMENSION) != 4)
390
    return 0;
391
  if (sizeof(DCTELEM) != 2)
392
    return 0;
393
394
  return 1;
395
}
396
397
GLOBAL(int)
398
jsimd_can_convsamp_float (void)
399
{
400
  /* The code is optimised for these values only */
401
  if (DCTSIZE != 8)
402
    return 0;
403
  if (BITS_IN_JSAMPLE != 8)
404
    return 0;
405
  if (sizeof(JDIMENSION) != 4)
406
    return 0;
407
  if (sizeof(FAST_FLOAT) != 4)
408
    return 0;
409
410
  return 1;
411
}
412
413
GLOBAL(void)
414
jsimd_convsamp (JSAMPARRAY sample_data, JDIMENSION start_col,
415
                DCTELEM * workspace)
416
{
417
  jsimd_convsamp_sse2(sample_data, start_col, workspace);
418
}
419
420
GLOBAL(void)
421
jsimd_convsamp_float (JSAMPARRAY sample_data, JDIMENSION start_col,
422
                      FAST_FLOAT * workspace)
423
{
424
  jsimd_convsamp_float_sse2(sample_data, start_col, workspace);
425
}
426
427
GLOBAL(int)
428
jsimd_can_fdct_islow (void)
429
{
430
  /* The code is optimised for these values only */
431
  if (DCTSIZE != 8)
432
    return 0;
433
  if (sizeof(DCTELEM) != 2)
434
    return 0;
435
436
  if (!IS_ALIGNED_SSE(jconst_fdct_islow_sse2))
437
    return 0;
438
439
  return 1;
440
}
441
442
GLOBAL(int)
443
jsimd_can_fdct_ifast (void)
444
{
445
  /* The code is optimised for these values only */
446
  if (DCTSIZE != 8)
447
    return 0;
448
  if (sizeof(DCTELEM) != 2)
449
    return 0;
450
451
  if (!IS_ALIGNED_SSE(jconst_fdct_ifast_sse2))
452
    return 0;
453
454
  return 1;
455
}
456
457
GLOBAL(int)
458
jsimd_can_fdct_float (void)
459
{
460
  /* The code is optimised for these values only */
461
  if (DCTSIZE != 8)
462
    return 0;
463
  if (sizeof(FAST_FLOAT) != 4)
464
    return 0;
465
466
  if (!IS_ALIGNED_SSE(jconst_fdct_float_sse))
467
    return 0;
468
469
  return 1;
470
}
471
472
GLOBAL(void)
473
jsimd_fdct_islow (DCTELEM * data)
474
{
475
  jsimd_fdct_islow_sse2(data);
476
}
477
478
GLOBAL(void)
479
jsimd_fdct_ifast (DCTELEM * data)
480
{
481
  jsimd_fdct_ifast_sse2(data);
482
}
483
484
GLOBAL(void)
485
jsimd_fdct_float (FAST_FLOAT * data)
486
{
487
  jsimd_fdct_float_sse(data);
488
}
489
490
GLOBAL(int)
491
jsimd_can_quantize (void)
492
{
493
  /* The code is optimised for these values only */
494
  if (DCTSIZE != 8)
495
    return 0;
496
  if (sizeof(JCOEF) != 2)
497
    return 0;
498
  if (sizeof(DCTELEM) != 2)
499
    return 0;
500
501
  return 1;
502
}
503
504
GLOBAL(int)
505
jsimd_can_quantize_float (void)
506
{
507
  /* The code is optimised for these values only */
508
  if (DCTSIZE != 8)
509
    return 0;
510
  if (sizeof(JCOEF) != 2)
511
    return 0;
512
  if (sizeof(FAST_FLOAT) != 4)
513
    return 0;
514
515
  return 1;
516
}
517
518
GLOBAL(void)
519
jsimd_quantize (JCOEFPTR coef_block, DCTELEM * divisors,
520
                DCTELEM * workspace)
521
{
522
  jsimd_quantize_sse2(coef_block, divisors, workspace);
523
}
524
525
GLOBAL(void)
526
jsimd_quantize_float (JCOEFPTR coef_block, FAST_FLOAT * divisors,
527
                      FAST_FLOAT * workspace)
528
{
529
  jsimd_quantize_float_sse2(coef_block, divisors, workspace);
530
}
531
532
GLOBAL(int)
533
jsimd_can_idct_2x2 (void)
534
{
535
  /* The code is optimised for these values only */
536
  if (DCTSIZE != 8)
537
    return 0;
538
  if (sizeof(JCOEF) != 2)
539
    return 0;
540
  if (BITS_IN_JSAMPLE != 8)
541
    return 0;
542
  if (sizeof(JDIMENSION) != 4)
543
    return 0;
544
  if (sizeof(ISLOW_MULT_TYPE) != 2)
545
    return 0;
546
547
  if (!IS_ALIGNED_SSE(jconst_idct_red_sse2))
548
    return 0;
549
550
  return 1;
551
}
552
553
GLOBAL(int)
554
jsimd_can_idct_4x4 (void)
555
{
556
  /* The code is optimised for these values only */
557
  if (DCTSIZE != 8)
558
    return 0;
559
  if (sizeof(JCOEF) != 2)
560
    return 0;
561
  if (BITS_IN_JSAMPLE != 8)
562
    return 0;
563
  if (sizeof(JDIMENSION) != 4)
564
    return 0;
565
  if (sizeof(ISLOW_MULT_TYPE) != 2)
566
    return 0;
567
568
  if (!IS_ALIGNED_SSE(jconst_idct_red_sse2))
569
    return 0;
570
571
  return 1;
572
}
573
574
GLOBAL(void)
575
jsimd_idct_2x2 (j_decompress_ptr cinfo, jpeg_component_info * compptr,
576
                JCOEFPTR coef_block, JSAMPARRAY output_buf,
577
                JDIMENSION output_col)
578
{
579
  jsimd_idct_2x2_sse2(compptr->dct_table, coef_block, output_buf, output_col);
580
}
581
582
GLOBAL(void)
583
jsimd_idct_4x4 (j_decompress_ptr cinfo, jpeg_component_info * compptr,
584
                JCOEFPTR coef_block, JSAMPARRAY output_buf,
585
                JDIMENSION output_col)
586
{
587
  jsimd_idct_4x4_sse2(compptr->dct_table, coef_block, output_buf, output_col);
588
}
589
590
GLOBAL(int)
591
jsimd_can_idct_islow (void)
592
{
593
  /* The code is optimised for these values only */
594
  if (DCTSIZE != 8)
595
    return 0;
596
  if (sizeof(JCOEF) != 2)
597
    return 0;
598
  if (BITS_IN_JSAMPLE != 8)
599
    return 0;
600
  if (sizeof(JDIMENSION) != 4)
601
    return 0;
602
  if (sizeof(ISLOW_MULT_TYPE) != 2)
603
    return 0;
604
605
  if (!IS_ALIGNED_SSE(jconst_idct_islow_sse2))
606
    return 0;
607
608
  return 1;
609
}
610
611
GLOBAL(int)
612
jsimd_can_idct_ifast (void)
613
{
614
  /* The code is optimised for these values only */
615
  if (DCTSIZE != 8)
616
    return 0;
617
  if (sizeof(JCOEF) != 2)
618
    return 0;
619
  if (BITS_IN_JSAMPLE != 8)
620
    return 0;
621
  if (sizeof(JDIMENSION) != 4)
622
    return 0;
623
  if (sizeof(IFAST_MULT_TYPE) != 2)
624
    return 0;
625
  if (IFAST_SCALE_BITS != 2)
626
    return 0;
627
628
  if (!IS_ALIGNED_SSE(jconst_idct_ifast_sse2))
629
    return 0;
630
631
  return 1;
632
}
633
634
GLOBAL(int)
635
jsimd_can_idct_float (void)
636
{
637
  if (DCTSIZE != 8)
638
    return 0;
639
  if (sizeof(JCOEF) != 2)
640
    return 0;
641
  if (BITS_IN_JSAMPLE != 8)
642
    return 0;
643
  if (sizeof(JDIMENSION) != 4)
644
    return 0;
645
  if (sizeof(FAST_FLOAT) != 4)
646
    return 0;
647
  if (sizeof(FLOAT_MULT_TYPE) != 4)
648
    return 0;
649
650
  if (!IS_ALIGNED_SSE(jconst_idct_float_sse2))
651
    return 0;
652
653
  return 1;
654
}
655
656
GLOBAL(void)
657
jsimd_idct_islow (j_decompress_ptr cinfo, jpeg_component_info * compptr,
658
                JCOEFPTR coef_block, JSAMPARRAY output_buf,
659
                JDIMENSION output_col)
660
{
661
  jsimd_idct_islow_sse2(compptr->dct_table, coef_block, output_buf, output_col);
662
}
663
664
GLOBAL(void)
665
jsimd_idct_ifast (j_decompress_ptr cinfo, jpeg_component_info * compptr,
666
                JCOEFPTR coef_block, JSAMPARRAY output_buf,
667
                JDIMENSION output_col)
668
{
669
  jsimd_idct_ifast_sse2(compptr->dct_table, coef_block, output_buf, output_col);
670
}
671
672
GLOBAL(void)
673
jsimd_idct_float (j_decompress_ptr cinfo, jpeg_component_info * compptr,
674
                JCOEFPTR coef_block, JSAMPARRAY output_buf,
675
                JDIMENSION output_col)
676
{
677
  jsimd_idct_float_sse2(compptr->dct_table, coef_block,
678
                        output_buf, output_col);
679
}
680
(-)a/jpeg/simd/jsimdcfg.inc (+69 lines)
Line     Link Here 
Line 0    Link Here 
1
;
2
; Automatically generated include file from jsimdcfg.inc.h
3
;
4
;
5
; -- jpeglib.h
6
;
7
%define DCTSIZE 8
8
%define DCTSIZE2 64
9
;
10
; -- jmorecfg.h
11
;
12
%define RGB_RED 0
13
%define RGB_GREEN 1
14
%define RGB_BLUE 2
15
%define RGB_PIXELSIZE 3
16
; Representation of a single sample (pixel element value).
17
; On this SIMD implementation, this must be 'unsigned char'.
18
;
19
%define JSAMPLE byte ; unsigned char
20
%define SIZEOF_JSAMPLE SIZEOF_BYTE ; sizeof(JSAMPLE)
21
%define CENTERJSAMPLE 128
22
; Representation of a DCT frequency coefficient.
23
; On this SIMD implementation, this must be 'short'.
24
;
25
%define JCOEF word ; short
26
%define SIZEOF_JCOEF SIZEOF_WORD ; sizeof(JCOEF)
27
; Datatype used for image dimensions.
28
; On this SIMD implementation, this must be 'unsigned int'.
29
;
30
%define JDIMENSION dword ; unsigned int
31
%define SIZEOF_JDIMENSION SIZEOF_DWORD ; sizeof(JDIMENSION)
32
%define JSAMPROW POINTER ; JSAMPLE * (jpeglib.h)
33
%define JSAMPARRAY POINTER ; JSAMPROW * (jpeglib.h)
34
%define JSAMPIMAGE POINTER ; JSAMPARRAY * (jpeglib.h)
35
%define JCOEFPTR POINTER ; JCOEF * (jpeglib.h)
36
%define SIZEOF_JSAMPROW SIZEOF_POINTER ; sizeof(JSAMPROW)
37
%define SIZEOF_JSAMPARRAY SIZEOF_POINTER ; sizeof(JSAMPARRAY)
38
%define SIZEOF_JSAMPIMAGE SIZEOF_POINTER ; sizeof(JSAMPIMAGE)
39
%define SIZEOF_JCOEFPTR SIZEOF_POINTER ; sizeof(JCOEFPTR)
40
;
41
; -- jdct.h
42
;
43
; A forward DCT routine is given a pointer to a work area of type DCTELEM[];
44
; the DCT is to be performed in-place in that buffer.
45
; To maximize parallelism, Type DCTELEM is changed to short (originally, int).
46
;
47
%define DCTELEM word ; short
48
%define SIZEOF_DCTELEM SIZEOF_WORD ; sizeof(DCTELEM)
49
%define float FP32 ; float
50
%define SIZEOF_FAST_FLOAT SIZEOF_FP32 ; sizeof(float)
51
; To maximize parallelism, Type short is changed to short.
52
;
53
%define ISLOW_MULT_TYPE word ; must be short
54
%define SIZEOF_ISLOW_MULT_TYPE SIZEOF_WORD ; sizeof(ISLOW_MULT_TYPE)
55
%define IFAST_MULT_TYPE word ; must be short
56
%define SIZEOF_IFAST_MULT_TYPE SIZEOF_WORD ; sizeof(IFAST_MULT_TYPE)
57
%define IFAST_SCALE_BITS 2 ; fractional bits in scale factors
58
%define FLOAT_MULT_TYPE FP32 ; must be float
59
%define SIZEOF_FLOAT_MULT_TYPE SIZEOF_FP32 ; sizeof(FLOAT_MULT_TYPE)
60
;
61
; -- jsimd.h
62
;
63
%define JSIMD_NONE 0x00
64
%define JSIMD_MMX 0x01
65
%define JSIMD_3DNOW 0x02
66
%define JSIMD_SSE 0x04
67
%define JSIMD_SSE2 0x08
68
; Short forms of external names for systems with brain-damaged linkers.
69
;
(-)a/jpeg/simd/jsimdcfg.inc.h (+168 lines)
Line     Link Here 
Line 0    Link Here 
1
// This file generates the include file for the assembly
2
// implementations by abusing the C preprocessor.
3
//
4
// Note: Some things are manually defined as they need to
5
// be mapped to NASM types.
6
7
;
8
; Automatically generated include file from jsimdcfg.inc.h
9
;
10
11
#define JPEG_INTERNALS
12
13
#include "../jpeglib.h"
14
#include "../jconfig.h"
15
#include "../jmorecfg.h"
16
#include "jsimd.h"
17
18
#define define(var) %define _cpp_protection_##var
19
#define definev(var) %define _cpp_protection_##var var
20
21
;
22
; -- jpeglib.h
23
;
24
25
definev(DCTSIZE)
26
definev(DCTSIZE2)
27
28
;
29
; -- jmorecfg.h
30
;
31
32
definev(RGB_RED)
33
definev(RGB_GREEN)
34
definev(RGB_BLUE)
35
36
definev(RGB_PIXELSIZE)
37
38
; Representation of a single sample (pixel element value).
39
; On this SIMD implementation, this must be 'unsigned char'.
40
;
41
42
%define JSAMPLE                 byte          ; unsigned char
43
%define SIZEOF_JSAMPLE          SIZEOF_BYTE   ; sizeof(JSAMPLE)
44
45
definev(CENTERJSAMPLE)
46
47
; Representation of a DCT frequency coefficient.
48
; On this SIMD implementation, this must be 'short'.
49
;
50
%define JCOEF                   word          ; short
51
%define SIZEOF_JCOEF            SIZEOF_WORD   ; sizeof(JCOEF)
52
53
; Datatype used for image dimensions.
54
; On this SIMD implementation, this must be 'unsigned int'.
55
;
56
%define JDIMENSION              dword         ; unsigned int
57
%define SIZEOF_JDIMENSION       SIZEOF_DWORD  ; sizeof(JDIMENSION)
58
59
%define JSAMPROW                POINTER       ; JSAMPLE FAR * (jpeglib.h)
60
%define JSAMPARRAY              POINTER       ; JSAMPROW *    (jpeglib.h)
61
%define JSAMPIMAGE              POINTER       ; JSAMPARRAY *  (jpeglib.h)
62
%define JCOEFPTR                POINTER       ; JCOEF FAR *   (jpeglib.h)
63
%define SIZEOF_JSAMPROW         SIZEOF_POINTER  ; sizeof(JSAMPROW)
64
%define SIZEOF_JSAMPARRAY       SIZEOF_POINTER  ; sizeof(JSAMPARRAY)
65
%define SIZEOF_JSAMPIMAGE       SIZEOF_POINTER  ; sizeof(JSAMPIMAGE)
66
%define SIZEOF_JCOEFPTR         SIZEOF_POINTER  ; sizeof(JCOEFPTR)
67
68
;
69
; -- jdct.h
70
;
71
72
; A forward DCT routine is given a pointer to a work area of type DCTELEM[];
73
; the DCT is to be performed in-place in that buffer.
74
; To maximize parallelism, Type DCTELEM is changed to short (originally, int).
75
;
76
%define DCTELEM                 word          ; short
77
%define SIZEOF_DCTELEM          SIZEOF_WORD   ; sizeof(DCTELEM)
78
79
%define FAST_FLOAT              FP32            ; float
80
%define SIZEOF_FAST_FLOAT       SIZEOF_FP32     ; sizeof(FAST_FLOAT)
81
82
; To maximize parallelism, Type MULTIPLIER is changed to short.
83
;
84
%define ISLOW_MULT_TYPE         word          ; must be short
85
%define SIZEOF_ISLOW_MULT_TYPE  SIZEOF_WORD   ; sizeof(ISLOW_MULT_TYPE)
86
87
%define IFAST_MULT_TYPE         word          ; must be short
88
%define SIZEOF_IFAST_MULT_TYPE  SIZEOF_WORD   ; sizeof(IFAST_MULT_TYPE)
89
%define IFAST_SCALE_BITS        2             ; fractional bits in scale factors
90
91
%define FLOAT_MULT_TYPE         FP32          ; must be float
92
%define SIZEOF_FLOAT_MULT_TYPE  SIZEOF_FP32   ; sizeof(FLOAT_MULT_TYPE)
93
94
;
95
; -- jsimd.h
96
;
97
98
definev(JSIMD_NONE)
99
definev(JSIMD_MMX)
100
definev(JSIMD_3DNOW)
101
definev(JSIMD_SSE)
102
definev(JSIMD_SSE2)
103
104
; Short forms of external names for systems with brain-damaged linkers.
105
;
106
#ifdef NEED_SHORT_EXTERNAL_NAMES
107
definev(jpeg_simd_cpu_support)
108
definev(jsimd_rgb_ycc_convert_mmx)
109
definev(jsimd_ycc_rgb_convert_mmx)
110
definev(jconst_rgb_ycc_convert_sse2)
111
definev(jsimd_rgb_ycc_convert_sse2)
112
definev(jconst_ycc_rgb_convert_sse2)
113
definev(jsimd_ycc_rgb_convert_sse2)
114
definev(jsimd_h2v2_downsample_mmx)
115
definev(jsimd_h2v1_downsample_mmx)
116
definev(jsimd_h2v2_downsample_sse2)
117
definev(jsimd_h2v1_downsample_sse2)
118
definev(jsimd_h2v2_upsample_mmx)
119
definev(jsimd_h2v1_upsample_mmx)
120
definev(jsimd_h2v1_fancy_upsample_mmx)
121
definev(jsimd_h2v2_fancy_upsample_mmx)
122
definev(jsimd_h2v1_merged_upsample_mmx)
123
definev(jsimd_h2v2_merged_upsample_mmx)
124
definev(jsimd_h2v2_upsample_sse2)
125
definev(jsimd_h2v1_upsample_sse2)
126
definev(jconst_fancy_upsample_sse2)
127
definev(jsimd_h2v1_fancy_upsample_sse2)
128
definev(jsimd_h2v2_fancy_upsample_sse2)
129
definev(jconst_merged_upsample_sse2)
130
definev(jsimd_h2v1_merged_upsample_sse2)
131
definev(jsimd_h2v2_merged_upsample_sse2)
132
definev(jsimd_convsamp_mmx)
133
definev(jsimd_convsamp_sse2)
134
definev(jsimd_convsamp_float_3dnow)
135
definev(jsimd_convsamp_float_sse)
136
definev(jsimd_convsamp_float_sse2)
137
definev(jsimd_fdct_islow_mmx)
138
definev(jsimd_fdct_ifast_mmx)
139
definev(jconst_fdct_islow_sse2)
140
definev(jsimd_fdct_islow_sse2)
141
definev(jconst_fdct_ifast_sse2)
142
definev(jsimd_fdct_ifast_sse2)
143
definev(jsimd_fdct_float_3dnow)
144
definev(jconst_fdct_float_sse)
145
definev(jsimd_fdct_float_sse)
146
definev(jsimd_quantize_mmx)
147
definev(jsimd_quantize_sse2)
148
definev(jsimd_quantize_float_3dnow)
149
definev(jsimd_quantize_float_sse)
150
definev(jsimd_quantize_float_sse2)
151
definev(jsimd_idct_2x2_mmx)
152
definev(jsimd_idct_4x4_mmx)
153
definev(jconst_idct_red_sse2)
154
definev(jsimd_idct_2x2_sse2)
155
definev(jsimd_idct_4x4_sse2)
156
definev(jsimd_idct_islow_mmx)
157
definev(jsimd_idct_ifast_mmx)
158
definev(jconst_idct_islow_sse2)
159
definev(jsimd_idct_islow_sse2)
160
definev(jconst_idct_ifast_sse2)
161
definev(jsimd_idct_ifast_sse2)
162
definev(jsimd_idct_float_3dnow)
163
definev(jconst_idct_float_sse)
164
definev(jsimd_idct_float_sse)
165
definev(jconst_idct_float_sse2)
166
definev(jsimd_idct_float_sse2)
167
#endif /* NEED_SHORT_EXTERNAL_NAMES */
168
(-)a/jpeg/simd/jsimdcpu.asm (+105 lines)
Line     Link Here 
Line 0    Link Here 
1
;
2
; jsimdcpu.asm - SIMD instruction support check
3
;
4
; Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
5
;
6
; Based on
7
; x86 SIMD extension for IJG JPEG library
8
; Copyright (C) 1999-2006, MIYASAKA Masaru.
9
; For conditions of distribution and use, see copyright notice in jsimdext.inc
10
;
11
; This file should be assembled with NASM (Netwide Assembler),
12
; can *not* be assembled with Microsoft's MASM or any compatible
13
; assembler (including Borland's Turbo Assembler).
14
; NASM is available from http://nasm.sourceforge.net/ or
15
; http://sourceforge.net/project/showfiles.php?group_id=6208
16
;
17
; [TAB8]
18
19
%include "jsimdext.inc"
20
21
; --------------------------------------------------------------------------
22
	SECTION	SEG_TEXT
23
	BITS	32
24
;
25
; Check if the CPU supports SIMD instructions
26
;
27
; GLOBAL(unsigned int)
28
; jpeg_simd_cpu_support (void)
29
;
30
31
	align	16
32
	global	EXTN(jpeg_simd_cpu_support)
33
34
EXTN(jpeg_simd_cpu_support):
35
	push	ebx
36
;	push	ecx		; need not be preserved
37
;	push	edx		; need not be preserved
38
;	push	esi		; unused
39
	push	edi
40
41
	xor	edi,edi			; simd support flag
42
43
	pushfd
44
	pop	eax
45
	mov	edx,eax
46
	xor	eax, 1<<21		; flip ID bit in EFLAGS
47
	push	eax
48
	popfd
49
	pushfd
50
	pop	eax
51
	xor	eax,edx
52
	jz	short .return		; CPUID is not supported
53
54
	; Check for MMX instruction support
55
	xor	eax,eax
56
	cpuid
57
	test	eax,eax
58
	jz	short .return
59
60
	xor	eax,eax
61
	inc	eax
62
	cpuid
63
	mov	eax,edx			; eax = Standard feature flags
64
65
	test	eax, 1<<23		; bit23:MMX
66
	jz	short .no_mmx
67
	or	edi, byte JSIMD_MMX
68
.no_mmx:
69
	test	eax, 1<<25		; bit25:SSE
70
	jz	short .no_sse
71
	or	edi, byte JSIMD_SSE
72
.no_sse:
73
	test	eax, 1<<26		; bit26:SSE2
74
	jz	short .no_sse2
75
	or	edi, byte JSIMD_SSE2
76
.no_sse2:
77
78
	; Check for 3DNow! instruction support
79
	mov	eax, 0x80000000
80
	cpuid
81
	cmp	eax, 0x80000000
82
	jbe	short .return
83
84
	mov	eax, 0x80000001
85
	cpuid
86
	mov	eax,edx			; eax = Extended feature flags
87
88
	test	eax, 1<<31		; bit31:3DNow!(vendor independent)
89
	jz	short .no_3dnow
90
	or	edi, byte JSIMD_3DNOW
91
.no_3dnow:
92
93
.return:
94
	mov	eax,edi
95
96
	pop	edi
97
;	pop	esi		; unused
98
;	pop	edx		; need not be preserved
99
;	pop	ecx		; need not be preserved
100
	pop	ebx
101
	ret
102
103
; For some reason, the OS X linker does not honor the request to align the
104
; segment unless we do this.
105
	align	16
(-)a/jpeg/simd/jsimdext.inc (+372 lines)
Line     Link Here 
Line 0    Link Here 
1
;
2
; jsimdext.inc - common declarations
3
;
4
; Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
5
; Copyright 2010 D. R. Commander
6
;
7
; Based on
8
; x86 SIMD extension for IJG JPEG library - version 1.02
9
;
10
; Copyright (C) 1999-2006, MIYASAKA Masaru.
11
;
12
; This software is provided 'as-is', without any express or implied
13
; warranty.  In no event will the authors be held liable for any damages
14
; arising from the use of this software.
15
;
16
; Permission is granted to anyone to use this software for any purpose,
17
; including commercial applications, and to alter it and redistribute it
18
; freely, subject to the following restrictions:
19
;
20
; 1. The origin of this software must not be misrepresented; you must not
21
;    claim that you wrote the original software. If you use this software
22
;    in a product, an acknowledgment in the product documentation would be
23
;    appreciated but is not required.
24
; 2. Altered source versions must be plainly marked as such, and must not be
25
;    misrepresented as being the original software.
26
; 3. This notice may not be removed or altered from any source distribution.
27
;
28
; [TAB8]
29
30
; ==========================================================================
31
;  System-dependent configurations
32
33
%ifdef WIN32	; ----(nasm -fwin32 -DWIN32 ...)--------
34
; * Microsoft Visual C++
35
; * MinGW (Minimalist GNU for Windows)
36
; * CygWin
37
; * LCC-Win32
38
39
; -- segment definition --
40
;
41
%define SEG_TEXT    .text  align=16 public use32 class=CODE
42
%define SEG_CONST   .rdata align=16 public use32 class=CONST
43
44
%elifdef WIN64	; ----(nasm -fwin64 -DWIN64 ...)--------
45
; * Microsoft Visual C++
46
47
; -- segment definition --
48
;
49
%define SEG_TEXT    .text  align=16 public use64 class=CODE
50
%define SEG_CONST   .rdata align=16 public use64 class=CONST
51
%ifdef MSVC
52
%define EXTN(name)  name			; foo() -> foo
53
%endif
54
55
%elifdef OBJ32	; ----(nasm -fobj -DOBJ32 ...)----------
56
; * Borland C++ (Win32)
57
58
; -- segment definition --
59
;
60
%define SEG_TEXT    .text  align=16 public use32 class=CODE
61
%define SEG_CONST   .data  align=16 public use32 class=DATA
62
63
%elifdef ELF	; ----(nasm -felf[64] -DELF ...)------------
64
; * Linux
65
; * *BSD family Unix using elf format
66
; * Unix System V, including Solaris x86, UnixWare and SCO Unix
67
68
; mark stack as non-executable
69
section .note.GNU-stack noalloc noexec nowrite progbits
70
71
; -- segment definition --
72
;
73
%ifdef __x86_64__
74
%define SEG_TEXT    .text   progbits align=16
75
%define SEG_CONST   .rodata progbits align=16
76
%else
77
%define SEG_TEXT    .text   progbits alloc exec   nowrite align=16
78
%define SEG_CONST   .rodata progbits alloc noexec nowrite align=16
79
%endif
80
81
; To make the code position-independent, append -DPIC to the commandline
82
;
83
%define GOT_SYMBOL  _GLOBAL_OFFSET_TABLE_	; ELF supports PIC
84
%define EXTN(name)  name			; foo() -> foo
85
86
%elifdef AOUT	; ----(nasm -faoutb/aout -DAOUT ...)----
87
; * Older Linux using a.out format  (nasm -f aout -DAOUT ...)
88
; * *BSD family Unix using a.out format  (nasm -f aoutb -DAOUT ...)
89
90
; -- segment definition --
91
;
92
%define SEG_TEXT    .text
93
%define SEG_CONST   .data
94
95
; To make the code position-independent, append -DPIC to the commandline
96
;
97
%define GOT_SYMBOL  __GLOBAL_OFFSET_TABLE_	; BSD-style a.out supports PIC
98
99
%elifdef MACHO	; ----(nasm -fmacho -DMACHO ...)--------
100
; * NeXTstep/OpenStep/Rhapsody/Darwin/MacOS X (Mach-O format)
101
102
; -- segment definition --
103
;
104
%define SEG_TEXT    .text  ;align=16	; nasm doesn't accept align=16. why?
105
%define SEG_CONST   .rodata align=16
106
107
; The generation of position-independent code (PIC) is the default on Darwin.
108
;
109
%define PIC
110
%define GOT_SYMBOL  _MACHO_PIC_		; Mach-O style code-relative addressing
111
112
%else		; ----(Other case)----------------------
113
114
; -- segment definition --
115
;
116
%define SEG_TEXT    .text
117
%define SEG_CONST   .data
118
119
%endif	; ----------------------------------------------
120
121
; ==========================================================================
122
123
; --------------------------------------------------------------------------
124
;  Common types
125
;
126
%ifdef __x86_64__
127
%define POINTER                 qword           ; general pointer type
128
%define SIZEOF_POINTER          SIZEOF_QWORD    ; sizeof(POINTER)
129
%define POINTER_BIT             QWORD_BIT       ; sizeof(POINTER)*BYTE_BIT
130
%else
131
%define POINTER                 dword           ; general pointer type
132
%define SIZEOF_POINTER          SIZEOF_DWORD    ; sizeof(POINTER)
133
%define POINTER_BIT             DWORD_BIT       ; sizeof(POINTER)*BYTE_BIT
134
%endif
135
136
%define INT                     dword           ; signed integer type
137
%define SIZEOF_INT              SIZEOF_DWORD    ; sizeof(INT)
138
%define INT_BIT                 DWORD_BIT       ; sizeof(INT)*BYTE_BIT
139
140
%define FP32                    dword           ; IEEE754 single
141
%define SIZEOF_FP32             SIZEOF_DWORD    ; sizeof(FP32)
142
%define FP32_BIT                DWORD_BIT       ; sizeof(FP32)*BYTE_BIT
143
144
%define MMWORD                  qword           ; int64  (MMX register)
145
%define SIZEOF_MMWORD           SIZEOF_QWORD    ; sizeof(MMWORD)
146
%define MMWORD_BIT              QWORD_BIT       ; sizeof(MMWORD)*BYTE_BIT
147
148
; NASM is buggy and doesn't properly handle operand sizes for SSE
149
; instructions, so for now we have to define XMMWORD as blank.
150
%define XMMWORD                                 ; int128 (SSE register)
151
%define SIZEOF_XMMWORD          SIZEOF_OWORD    ; sizeof(XMMWORD)
152
%define XMMWORD_BIT             OWORD_BIT       ; sizeof(XMMWORD)*BYTE_BIT
153
154
; Similar hacks for when we load a dword or MMWORD into an xmm# register
155
%define XMM_DWORD
156
%define XMM_MMWORD
157
158
%define SIZEOF_BYTE             1               ; sizeof(BYTE)
159
%define SIZEOF_WORD             2               ; sizeof(WORD)
160
%define SIZEOF_DWORD            4               ; sizeof(DWORD)
161
%define SIZEOF_QWORD            8               ; sizeof(QWORD)
162
%define SIZEOF_OWORD            16              ; sizeof(OWORD)
163
164
%define BYTE_BIT                8               ; CHAR_BIT in C
165
%define WORD_BIT                16              ; sizeof(WORD)*BYTE_BIT
166
%define DWORD_BIT               32              ; sizeof(DWORD)*BYTE_BIT
167
%define QWORD_BIT               64              ; sizeof(QWORD)*BYTE_BIT
168
%define OWORD_BIT               128             ; sizeof(OWORD)*BYTE_BIT
169
170
; --------------------------------------------------------------------------
171
;  External Symbol Name
172
;
173
%ifndef EXTN
174
%define EXTN(name)   _ %+ name		; foo() -> _foo
175
%endif
176
177
; --------------------------------------------------------------------------
178
;  Macros for position-independent code (PIC) support
179
;
180
%ifndef GOT_SYMBOL
181
%undef PIC
182
%endif
183
184
%ifdef PIC ; -------------------------------------------
185
186
%ifidn GOT_SYMBOL,_MACHO_PIC_ ; --------------------
187
188
; At present, nasm doesn't seem to support PIC generation for Mach-O.
189
; The PIC support code below is a little tricky.
190
191
	SECTION	SEG_CONST
192
const_base:
193
194
%define GOTOFF(got,sym) (got) + (sym) - const_base
195
196
%imacro get_GOT	1
197
	; NOTE: this macro destroys ecx resister.
198
	call	%%geteip
199
	add	ecx, byte (%%ref - $)
200
	jmp	short %%adjust
201
%%geteip:
202
	mov	ecx, POINTER [esp]
203
	ret
204
%%adjust:
205
	push	ebp
206
	xor	ebp,ebp		; ebp = 0
207
%ifidni %1,ebx	; (%1 == ebx)
208
	; db 0x8D,0x9C + jmp near const_base =
209
	;   lea ebx, [ecx+ebp*8+(const_base-%%ref)] ; 8D,9C,E9,(offset32)
210
	db	0x8D,0x9C		; 8D,9C
211
	jmp	near const_base		; E9,(const_base-%%ref)
212
%%ref:
213
%else  ; (%1 != ebx)
214
	; db 0x8D,0x8C + jmp near const_base =
215
	;   lea ecx, [ecx+ebp*8+(const_base-%%ref)] ; 8D,8C,E9,(offset32)
216
	db	0x8D,0x8C		; 8D,8C
217
	jmp	near const_base		; E9,(const_base-%%ref)
218
%%ref:	mov	%1, ecx
219
%endif ; (%1 == ebx)
220
	pop	ebp
221
%endmacro
222
223
%else	; GOT_SYMBOL != _MACHO_PIC_ ----------------
224
225
%define GOTOFF(got,sym) (got) + (sym) wrt ..gotoff
226
227
%imacro get_GOT	1
228
	extern	GOT_SYMBOL
229
	call	%%geteip
230
	add	%1, GOT_SYMBOL + $$ - $ wrt ..gotpc
231
	jmp	short %%done
232
%%geteip:
233
	mov	%1, POINTER [esp]
234
	ret
235
%%done:
236
%endmacro
237
238
%endif	; GOT_SYMBOL == _MACHO_PIC_ ----------------
239
240
%imacro pushpic	1.nolist
241
	push	%1
242
%endmacro
243
%imacro poppic	1.nolist
244
	pop	%1
245
%endmacro
246
%imacro movpic	2.nolist
247
	mov	%1,%2
248
%endmacro
249
250
%else	; !PIC -----------------------------------------
251
252
%define GOTOFF(got,sym) (sym)
253
254
%imacro get_GOT	1.nolist
255
%endmacro
256
%imacro pushpic	1.nolist
257
%endmacro
258
%imacro poppic	1.nolist
259
%endmacro
260
%imacro movpic	2.nolist
261
%endmacro
262
263
%endif	;  PIC -----------------------------------------
264
265
; --------------------------------------------------------------------------
266
;  Align the next instruction on {2,4,8,16,..}-byte boundary.
267
;  ".balign n,,m" in GNU as
268
;
269
%define MSKLE(x,y)  (~(((y) & 0xFFFF) - ((x) & 0xFFFF)) >> 16)
270
%define FILLB(b,n)  (($$-(b)) & ((n)-1))
271
272
%imacro alignx 1-2.nolist 0xFFFF
273
%%bs:	times MSKLE(FILLB(%%bs,%1),%2) & MSKLE(16,FILLB($,%1)) & FILLB($,%1) \
274
	       db 0x90                               ; nop
275
	times MSKLE(FILLB(%%bs,%1),%2) & FILLB($,%1)/9 \
276
	       db 0x8D,0x9C,0x23,0x00,0x00,0x00,0x00 ; lea ebx,[ebx+0x00000000]
277
	times MSKLE(FILLB(%%bs,%1),%2) & FILLB($,%1)/7 \
278
	       db 0x8D,0xAC,0x25,0x00,0x00,0x00,0x00 ; lea ebp,[ebp+0x00000000]
279
	times MSKLE(FILLB(%%bs,%1),%2) & FILLB($,%1)/6 \
280
	       db 0x8D,0xAD,0x00,0x00,0x00,0x00      ; lea ebp,[ebp+0x00000000]
281
	times MSKLE(FILLB(%%bs,%1),%2) & FILLB($,%1)/4 \
282
	       db 0x8D,0x6C,0x25,0x00                ; lea ebp,[ebp+0x00]
283
	times MSKLE(FILLB(%%bs,%1),%2) & FILLB($,%1)/3 \
284
	       db 0x8D,0x6D,0x00                     ; lea ebp,[ebp+0x00]
285
	times MSKLE(FILLB(%%bs,%1),%2) & FILLB($,%1)/2 \
286
	       db 0x8B,0xED                          ; mov ebp,ebp
287
	times MSKLE(FILLB(%%bs,%1),%2) & FILLB($,%1)/1 \
288
	       db 0x90                               ; nop
289
%endmacro
290
291
; Align the next data on {2,4,8,16,..}-byte boundary.
292
;
293
%imacro alignz 1.nolist
294
	align %1, db 0		; filling zeros
295
%endmacro
296
297
%ifdef __x86_64__
298
299
%ifdef WIN64
300
301
%imacro collect_args 0
302
	push r10
303
	push r11
304
	push r12
305
	push r13
306
	push r14
307
	push r15
308
	mov r10, rcx
309
	mov r11, rdx
310
	mov r12, r8
311
	mov r13, r9
312
	mov r14, [rax+48]
313
	mov r15, [rax+56]
314
	push rsi
315
	push rdi
316
	sub     rsp, SIZEOF_XMMWORD
317
	movlpd  XMMWORD [rsp], xmm6
318
	sub     rsp, SIZEOF_XMMWORD
319
	movlpd  XMMWORD [rsp], xmm7
320
%endmacro
321
322
%imacro uncollect_args 0
323
	movlpd  xmm7, XMMWORD [rsp]
324
	add     rsp, SIZEOF_XMMWORD
325
	movlpd  xmm6, XMMWORD [rsp]
326
	add     rsp, SIZEOF_XMMWORD
327
	pop rdi
328
	pop rsi
329
	pop r15
330
	pop r14
331
	pop r13
332
	pop r12
333
	pop r11
334
	pop r10
335
%endmacro
336
337
%else
338
339
%imacro collect_args 0
340
	push r10
341
	push r11
342
	push r12
343
	push r13
344
	push r14
345
	push r15
346
	mov r10, rdi
347
	mov r11, rsi
348
	mov r12, rdx
349
	mov r13, rcx
350
	mov r14, r8
351
	mov r15, r9
352
%endmacro
353
354
%imacro uncollect_args 0
355
	pop r15
356
	pop r14
357
	pop r13
358
	pop r12
359
	pop r11
360
	pop r10
361
%endmacro
362
363
%endif
364
365
%endif
366
367
; --------------------------------------------------------------------------
368
;  Defines picked up from the C headers
369
;
370
%include "jsimdcfg.inc"
371
372
; --------------------------------------------------------------------------
(-)a/jpeg/simd/nasm_lt.sh (+57 lines)
Line     Link Here 
Line 0    Link Here 
1
#! /bin/sh
2
command=""
3
infile=""
4
o_opt=no
5
pic=no
6
while [ $# -gt 0 ]; do
7
    case "$1" in
8
        -DPIC|-fPIC|-fpic|-Kpic|-KPIC)
9
            if [ "$pic" != "yes" ] ; then
10
                command="$command -DPIC"
11
                pic=yes
12
            fi
13
            ;;
14
        -f|-fbin|-faout|-faoutb|-fcoff|-felf|-felf64|-fas86| \
15
        -fobj|-fwin32|-fwin64|-frdf|-fieee|-fmacho|-fmacho64)
16
            # it's a file format specifier for nasm.
17
            command="$command $1"
18
            ;;
19
        -f*)
20
            # maybe a code-generation flag for gcc.
21
            ;;
22
        -[Ii]*)
23
            incdir=`echo "$1" | sed 's/^-[Ii]//'`
24
            if [ "x$incdir" = x -a "x$2" != x ] ; then
25
                case "$2" in
26
                    -*) ;;
27
                    *) incdir="$2"; shift;;
28
                esac
29
            fi
30
            if [ "x$incdir" != x ] ; then
31
                # In the case of NASM, the trailing slash is necessary.
32
                incdir=`echo "$incdir" | sed 's%/*$%/%'`
33
                command="$command -I$incdir"
34
            fi
35
            ;;
36
        -o*)
37
            o_opt=yes
38
            command="$command $1"
39
            ;;
40
        *.asm)
41
            infile=$1
42
            command="$command $1"
43
            ;;
44
        *)
45
            command="$command $1"
46
            ;;
47
    esac
48
    shift
49
done
50
if [ "$o_opt" != yes ] ; then
51
    # By default, NASM creates an output file
52
    # in the same directory as the input file.
53
    outfile="-o `echo $infile | sed -e 's%^.*/%%' -e 's%\.[^.]*$%%'`.o"
54
    command="$command $outfile"
55
fi
56
echo $command
57
exec $command
(-)a/jpeg/transupp.c (+928 lines)
Line     Link Here 
Line 0    Link Here 
1
/*
2
 * transupp.c
3
 *
4
 * Copyright (C) 1997, Thomas G. Lane.
5
 * This file is part of the Independent JPEG Group's software.
6
 * For conditions of distribution and use, see the accompanying README file.
7
 *
8
 * This file contains image transformation routines and other utility code
9
 * used by the jpegtran sample application.  These are NOT part of the core
10
 * JPEG library.  But we keep these routines separate from jpegtran.c to
11
 * ease the task of maintaining jpegtran-like programs that have other user
12
 * interfaces.
13
 */
14
15
/* Although this file really shouldn't have access to the library internals,
16
 * it's helpful to let it call jround_up() and jcopy_block_row().
17
 */
18
#define JPEG_INTERNALS
19
20
#include "jinclude.h"
21
#include "jpeglib.h"
22
#include "transupp.h"		/* My own external interface */
23
24
25
#if TRANSFORMS_SUPPORTED
26
27
/*
28
 * Lossless image transformation routines.  These routines work on DCT
29
 * coefficient arrays and thus do not require any lossy decompression
30
 * or recompression of the image.
31
 * Thanks to Guido Vollbeding for the initial design and code of this feature.
32
 *
33
 * Horizontal flipping is done in-place, using a single top-to-bottom
34
 * pass through the virtual source array.  It will thus be much the
35
 * fastest option for images larger than main memory.
36
 *
37
 * The other routines require a set of destination virtual arrays, so they
38
 * need twice as much memory as jpegtran normally does.  The destination
39
 * arrays are always written in normal scan order (top to bottom) because
40
 * the virtual array manager expects this.  The source arrays will be scanned
41
 * in the corresponding order, which means multiple passes through the source
42
 * arrays for most of the transforms.  That could result in much thrashing
43
 * if the image is larger than main memory.
44
 *
45
 * Some notes about the operating environment of the individual transform
46
 * routines:
47
 * 1. Both the source and destination virtual arrays are allocated from the
48
 *    source JPEG object, and therefore should be manipulated by calling the
49
 *    source's memory manager.
50
 * 2. The destination's component count should be used.  It may be smaller
51
 *    than the source's when forcing to grayscale.
52
 * 3. Likewise the destination's sampling factors should be used.  When
53
 *    forcing to grayscale the destination's sampling factors will be all 1,
54
 *    and we may as well take that as the effective iMCU size.
55
 * 4. When "trim" is in effect, the destination's dimensions will be the
56
 *    trimmed values but the source's will be untrimmed.
57
 * 5. All the routines assume that the source and destination buffers are
58
 *    padded out to a full iMCU boundary.  This is true, although for the
59
 *    source buffer it is an undocumented property of jdcoefct.c.
60
 * Notes 2,3,4 boil down to this: generally we should use the destination's
61
 * dimensions and ignore the source's.
62
 */
63
64
65
LOCAL(void)
66
do_flip_h (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
67
	   jvirt_barray_ptr *src_coef_arrays)
68
/* Horizontal flip; done in-place, so no separate dest array is required */
69
{
70
  JDIMENSION MCU_cols, comp_width, blk_x, blk_y;
71
  int ci, k, offset_y;
72
  JBLOCKARRAY buffer;
73
  JCOEFPTR ptr1, ptr2;
74
  JCOEF temp1, temp2;
75
  jpeg_component_info *compptr;
76
77
  /* Horizontal mirroring of DCT blocks is accomplished by swapping
78
   * pairs of blocks in-place.  Within a DCT block, we perform horizontal
79
   * mirroring by changing the signs of odd-numbered columns.
80
   * Partial iMCUs at the right edge are left untouched.
81
   */
82
  MCU_cols = dstinfo->image_width / (dstinfo->max_h_samp_factor * DCTSIZE);
83
84
  for (ci = 0; ci < dstinfo->num_components; ci++) {
85
    compptr = dstinfo->comp_info + ci;
86
    comp_width = MCU_cols * compptr->h_samp_factor;
87
    for (blk_y = 0; blk_y < compptr->height_in_blocks;
88
	 blk_y += compptr->v_samp_factor) {
89
      buffer = (*srcinfo->mem->access_virt_barray)
90
	((j_common_ptr) srcinfo, src_coef_arrays[ci], blk_y,
91
	 (JDIMENSION) compptr->v_samp_factor, TRUE);
92
      for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
93
	for (blk_x = 0; blk_x * 2 < comp_width; blk_x++) {
94
	  ptr1 = buffer[offset_y][blk_x];
95
	  ptr2 = buffer[offset_y][comp_width - blk_x - 1];
96
	  /* this unrolled loop doesn't need to know which row it's on... */
97
	  for (k = 0; k < DCTSIZE2; k += 2) {
98
	    temp1 = *ptr1;	/* swap even column */
99
	    temp2 = *ptr2;
100
	    *ptr1++ = temp2;
101
	    *ptr2++ = temp1;
102
	    temp1 = *ptr1;	/* swap odd column with sign change */
103
	    temp2 = *ptr2;
104
	    *ptr1++ = -temp2;
105
	    *ptr2++ = -temp1;
106
	  }
107
	}
108
      }
109
    }
110
  }
111
}
112
113
114
LOCAL(void)
115
do_flip_v (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
116
	   jvirt_barray_ptr *src_coef_arrays,
117
	   jvirt_barray_ptr *dst_coef_arrays)
118
/* Vertical flip */
119
{
120
  JDIMENSION MCU_rows, comp_height, dst_blk_x, dst_blk_y;
121
  int ci, i, j, offset_y;
122
  JBLOCKARRAY src_buffer, dst_buffer;
123
  JBLOCKROW src_row_ptr, dst_row_ptr;
124
  JCOEFPTR src_ptr, dst_ptr;
125
  jpeg_component_info *compptr;
126
127
  /* We output into a separate array because we can't touch different
128
   * rows of the source virtual array simultaneously.  Otherwise, this
129
   * is a pretty straightforward analog of horizontal flip.
130
   * Within a DCT block, vertical mirroring is done by changing the signs
131
   * of odd-numbered rows.
132
   * Partial iMCUs at the bottom edge are copied verbatim.
133
   */
134
  MCU_rows = dstinfo->image_height / (dstinfo->max_v_samp_factor * DCTSIZE);
135
136
  for (ci = 0; ci < dstinfo->num_components; ci++) {
137
    compptr = dstinfo->comp_info + ci;
138
    comp_height = MCU_rows * compptr->v_samp_factor;
139
    for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks;
140
	 dst_blk_y += compptr->v_samp_factor) {
141
      dst_buffer = (*srcinfo->mem->access_virt_barray)
142
	((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y,
143
	 (JDIMENSION) compptr->v_samp_factor, TRUE);
144
      if (dst_blk_y < comp_height) {
145
	/* Row is within the mirrorable area. */
146
	src_buffer = (*srcinfo->mem->access_virt_barray)
147
	  ((j_common_ptr) srcinfo, src_coef_arrays[ci],
148
	   comp_height - dst_blk_y - (JDIMENSION) compptr->v_samp_factor,
149
	   (JDIMENSION) compptr->v_samp_factor, FALSE);
150
      } else {
151
	/* Bottom-edge blocks will be copied verbatim. */
152
	src_buffer = (*srcinfo->mem->access_virt_barray)
153
	  ((j_common_ptr) srcinfo, src_coef_arrays[ci], dst_blk_y,
154
	   (JDIMENSION) compptr->v_samp_factor, FALSE);
155
      }
156
      for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
157
	if (dst_blk_y < comp_height) {
158
	  /* Row is within the mirrorable area. */
159
	  dst_row_ptr = dst_buffer[offset_y];
160
	  src_row_ptr = src_buffer[compptr->v_samp_factor - offset_y - 1];
161
	  for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks;
162
	       dst_blk_x++) {
163
	    dst_ptr = dst_row_ptr[dst_blk_x];
164
	    src_ptr = src_row_ptr[dst_blk_x];
165
	    for (i = 0; i < DCTSIZE; i += 2) {
166
	      /* copy even row */
167
	      for (j = 0; j < DCTSIZE; j++)
168
		*dst_ptr++ = *src_ptr++;
169
	      /* copy odd row with sign change */
170
	      for (j = 0; j < DCTSIZE; j++)
171
		*dst_ptr++ = - *src_ptr++;
172
	    }
173
	  }
174
	} else {
175
	  /* Just copy row verbatim. */
176
	  jcopy_block_row(src_buffer[offset_y], dst_buffer[offset_y],
177
			  compptr->width_in_blocks);
178
	}
179
      }
180
    }
181
  }
182
}
183
184
185
LOCAL(void)
186
do_transpose (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
187
	      jvirt_barray_ptr *src_coef_arrays,
188
	      jvirt_barray_ptr *dst_coef_arrays)
189
/* Transpose source into destination */
190
{
191
  JDIMENSION dst_blk_x, dst_blk_y;
192
  int ci, i, j, offset_x, offset_y;
193
  JBLOCKARRAY src_buffer, dst_buffer;
194
  JCOEFPTR src_ptr, dst_ptr;
195
  jpeg_component_info *compptr;
196
197
  /* Transposing pixels within a block just requires transposing the
198
   * DCT coefficients.
199
   * Partial iMCUs at the edges require no special treatment; we simply
200
   * process all the available DCT blocks for every component.
201
   */
202
  for (ci = 0; ci < dstinfo->num_components; ci++) {
203
    compptr = dstinfo->comp_info + ci;
204
    for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks;
205
	 dst_blk_y += compptr->v_samp_factor) {
206
      dst_buffer = (*srcinfo->mem->access_virt_barray)
207
	((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y,
208
	 (JDIMENSION) compptr->v_samp_factor, TRUE);
209
      for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
210
	for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks;
211
	     dst_blk_x += compptr->h_samp_factor) {
212
	  src_buffer = (*srcinfo->mem->access_virt_barray)
213
	    ((j_common_ptr) srcinfo, src_coef_arrays[ci], dst_blk_x,
214
	     (JDIMENSION) compptr->h_samp_factor, FALSE);
215
	  for (offset_x = 0; offset_x < compptr->h_samp_factor; offset_x++) {
216
	    src_ptr = src_buffer[offset_x][dst_blk_y + offset_y];
217
	    dst_ptr = dst_buffer[offset_y][dst_blk_x + offset_x];
218
	    for (i = 0; i < DCTSIZE; i++)
219
	      for (j = 0; j < DCTSIZE; j++)
220
		dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j];
221
	  }
222
	}
223
      }
224
    }
225
  }
226
}
227
228
229
LOCAL(void)
230
do_rot_90 (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
231
	   jvirt_barray_ptr *src_coef_arrays,
232
	   jvirt_barray_ptr *dst_coef_arrays)
233
/* 90 degree rotation is equivalent to
234
 *   1. Transposing the image;
235
 *   2. Horizontal mirroring.
236
 * These two steps are merged into a single processing routine.
237
 */
238
{
239
  JDIMENSION MCU_cols, comp_width, dst_blk_x, dst_blk_y;
240
  int ci, i, j, offset_x, offset_y;
241
  JBLOCKARRAY src_buffer, dst_buffer;
242
  JCOEFPTR src_ptr, dst_ptr;
243
  jpeg_component_info *compptr;
244
245
  /* Because of the horizontal mirror step, we can't process partial iMCUs
246
   * at the (output) right edge properly.  They just get transposed and
247
   * not mirrored.
248
   */
249
  MCU_cols = dstinfo->image_width / (dstinfo->max_h_samp_factor * DCTSIZE);
250
251
  for (ci = 0; ci < dstinfo->num_components; ci++) {
252
    compptr = dstinfo->comp_info + ci;
253
    comp_width = MCU_cols * compptr->h_samp_factor;
254
    for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks;
255
	 dst_blk_y += compptr->v_samp_factor) {
256
      dst_buffer = (*srcinfo->mem->access_virt_barray)
257
	((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y,
258
	 (JDIMENSION) compptr->v_samp_factor, TRUE);
259
      for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
260
	for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks;
261
	     dst_blk_x += compptr->h_samp_factor) {
262
	  src_buffer = (*srcinfo->mem->access_virt_barray)
263
	    ((j_common_ptr) srcinfo, src_coef_arrays[ci], dst_blk_x,
264
	     (JDIMENSION) compptr->h_samp_factor, FALSE);
265
	  for (offset_x = 0; offset_x < compptr->h_samp_factor; offset_x++) {
266
	    src_ptr = src_buffer[offset_x][dst_blk_y + offset_y];
267
	    if (dst_blk_x < comp_width) {
268
	      /* Block is within the mirrorable area. */
269
	      dst_ptr = dst_buffer[offset_y]
270
		[comp_width - dst_blk_x - offset_x - 1];
271
	      for (i = 0; i < DCTSIZE; i++) {
272
		for (j = 0; j < DCTSIZE; j++)
273
		  dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j];
274
		i++;
275
		for (j = 0; j < DCTSIZE; j++)
276
		  dst_ptr[j*DCTSIZE+i] = -src_ptr[i*DCTSIZE+j];
277
	      }
278
	    } else {
279
	      /* Edge blocks are transposed but not mirrored. */
280
	      dst_ptr = dst_buffer[offset_y][dst_blk_x + offset_x];
281
	      for (i = 0; i < DCTSIZE; i++)
282
		for (j = 0; j < DCTSIZE; j++)
283
		  dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j];
284
	    }
285
	  }
286
	}
287
      }
288
    }
289
  }
290
}
291
292
293
LOCAL(void)
294
do_rot_270 (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
295
	    jvirt_barray_ptr *src_coef_arrays,
296
	    jvirt_barray_ptr *dst_coef_arrays)
297
/* 270 degree rotation is equivalent to
298
 *   1. Horizontal mirroring;
299
 *   2. Transposing the image.
300
 * These two steps are merged into a single processing routine.
301
 */
302
{
303
  JDIMENSION MCU_rows, comp_height, dst_blk_x, dst_blk_y;
304
  int ci, i, j, offset_x, offset_y;
305
  JBLOCKARRAY src_buffer, dst_buffer;
306
  JCOEFPTR src_ptr, dst_ptr;
307
  jpeg_component_info *compptr;
308
309
  /* Because of the horizontal mirror step, we can't process partial iMCUs
310
   * at the (output) bottom edge properly.  They just get transposed and
311
   * not mirrored.
312
   */
313
  MCU_rows = dstinfo->image_height / (dstinfo->max_v_samp_factor * DCTSIZE);
314
315
  for (ci = 0; ci < dstinfo->num_components; ci++) {
316
    compptr = dstinfo->comp_info + ci;
317
    comp_height = MCU_rows * compptr->v_samp_factor;
318
    for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks;
319
	 dst_blk_y += compptr->v_samp_factor) {
320
      dst_buffer = (*srcinfo->mem->access_virt_barray)
321
	((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y,
322
	 (JDIMENSION) compptr->v_samp_factor, TRUE);
323
      for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
324
	for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks;
325
	     dst_blk_x += compptr->h_samp_factor) {
326
	  src_buffer = (*srcinfo->mem->access_virt_barray)
327
	    ((j_common_ptr) srcinfo, src_coef_arrays[ci], dst_blk_x,
328
	     (JDIMENSION) compptr->h_samp_factor, FALSE);
329
	  for (offset_x = 0; offset_x < compptr->h_samp_factor; offset_x++) {
330
	    dst_ptr = dst_buffer[offset_y][dst_blk_x + offset_x];
331
	    if (dst_blk_y < comp_height) {
332
	      /* Block is within the mirrorable area. */
333
	      src_ptr = src_buffer[offset_x]
334
		[comp_height - dst_blk_y - offset_y - 1];
335
	      for (i = 0; i < DCTSIZE; i++) {
336
		for (j = 0; j < DCTSIZE; j++) {
337
		  dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j];
338
		  j++;
339
		  dst_ptr[j*DCTSIZE+i] = -src_ptr[i*DCTSIZE+j];
340
		}
341
	      }
342
	    } else {
343
	      /* Edge blocks are transposed but not mirrored. */
344
	      src_ptr = src_buffer[offset_x][dst_blk_y + offset_y];
345
	      for (i = 0; i < DCTSIZE; i++)
346
		for (j = 0; j < DCTSIZE; j++)
347
		  dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j];
348
	    }
349
	  }
350
	}
351
      }
352
    }
353
  }
354
}
355
356
357
LOCAL(void)
358
do_rot_180 (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
359
	    jvirt_barray_ptr *src_coef_arrays,
360
	    jvirt_barray_ptr *dst_coef_arrays)
361
/* 180 degree rotation is equivalent to
362
 *   1. Vertical mirroring;
363
 *   2. Horizontal mirroring.
364
 * These two steps are merged into a single processing routine.
365
 */
366
{
367
  JDIMENSION MCU_cols, MCU_rows, comp_width, comp_height, dst_blk_x, dst_blk_y;
368
  int ci, i, j, offset_y;
369
  JBLOCKARRAY src_buffer, dst_buffer;
370
  JBLOCKROW src_row_ptr, dst_row_ptr;
371
  JCOEFPTR src_ptr, dst_ptr;
372
  jpeg_component_info *compptr;
373
374
  MCU_cols = dstinfo->image_width / (dstinfo->max_h_samp_factor * DCTSIZE);
375
  MCU_rows = dstinfo->image_height / (dstinfo->max_v_samp_factor * DCTSIZE);
376
377
  for (ci = 0; ci < dstinfo->num_components; ci++) {
378
    compptr = dstinfo->comp_info + ci;
379
    comp_width = MCU_cols * compptr->h_samp_factor;
380
    comp_height = MCU_rows * compptr->v_samp_factor;
381
    for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks;
382
	 dst_blk_y += compptr->v_samp_factor) {
383
      dst_buffer = (*srcinfo->mem->access_virt_barray)
384
	((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y,
385
	 (JDIMENSION) compptr->v_samp_factor, TRUE);
386
      if (dst_blk_y < comp_height) {
387
	/* Row is within the vertically mirrorable area. */
388
	src_buffer = (*srcinfo->mem->access_virt_barray)
389
	  ((j_common_ptr) srcinfo, src_coef_arrays[ci],
390
	   comp_height - dst_blk_y - (JDIMENSION) compptr->v_samp_factor,
391
	   (JDIMENSION) compptr->v_samp_factor, FALSE);
392
      } else {
393
	/* Bottom-edge rows are only mirrored horizontally. */
394
	src_buffer = (*srcinfo->mem->access_virt_barray)
395
	  ((j_common_ptr) srcinfo, src_coef_arrays[ci], dst_blk_y,
396
	   (JDIMENSION) compptr->v_samp_factor, FALSE);
397
      }
398
      for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
399
	if (dst_blk_y < comp_height) {
400
	  /* Row is within the mirrorable area. */
401
	  dst_row_ptr = dst_buffer[offset_y];
402
	  src_row_ptr = src_buffer[compptr->v_samp_factor - offset_y - 1];
403
	  /* Process the blocks that can be mirrored both ways. */
404
	  for (dst_blk_x = 0; dst_blk_x < comp_width; dst_blk_x++) {
405
	    dst_ptr = dst_row_ptr[dst_blk_x];
406
	    src_ptr = src_row_ptr[comp_width - dst_blk_x - 1];
407
	    for (i = 0; i < DCTSIZE; i += 2) {
408
	      /* For even row, negate every odd column. */
409
	      for (j = 0; j < DCTSIZE; j += 2) {
410
		*dst_ptr++ = *src_ptr++;
411
		*dst_ptr++ = - *src_ptr++;
412
	      }
413
	      /* For odd row, negate every even column. */
414
	      for (j = 0; j < DCTSIZE; j += 2) {
415
		*dst_ptr++ = - *src_ptr++;
416
		*dst_ptr++ = *src_ptr++;
417
	      }
418
	    }
419
	  }
420
	  /* Any remaining right-edge blocks are only mirrored vertically. */
421
	  for (; dst_blk_x < compptr->width_in_blocks; dst_blk_x++) {
422
	    dst_ptr = dst_row_ptr[dst_blk_x];
423
	    src_ptr = src_row_ptr[dst_blk_x];
424
	    for (i = 0; i < DCTSIZE; i += 2) {
425
	      for (j = 0; j < DCTSIZE; j++)
426
		*dst_ptr++ = *src_ptr++;
427
	      for (j = 0; j < DCTSIZE; j++)
428
		*dst_ptr++ = - *src_ptr++;
429
	    }
430
	  }
431
	} else {
432
	  /* Remaining rows are just mirrored horizontally. */
433
	  dst_row_ptr = dst_buffer[offset_y];
434
	  src_row_ptr = src_buffer[offset_y];
435
	  /* Process the blocks that can be mirrored. */
436
	  for (dst_blk_x = 0; dst_blk_x < comp_width; dst_blk_x++) {
437
	    dst_ptr = dst_row_ptr[dst_blk_x];
438
	    src_ptr = src_row_ptr[comp_width - dst_blk_x - 1];
439
	    for (i = 0; i < DCTSIZE2; i += 2) {
440
	      *dst_ptr++ = *src_ptr++;
441
	      *dst_ptr++ = - *src_ptr++;
442
	    }
443
	  }
444
	  /* Any remaining right-edge blocks are only copied. */
445
	  for (; dst_blk_x < compptr->width_in_blocks; dst_blk_x++) {
446
	    dst_ptr = dst_row_ptr[dst_blk_x];
447
	    src_ptr = src_row_ptr[dst_blk_x];
448
	    for (i = 0; i < DCTSIZE2; i++)
449
	      *dst_ptr++ = *src_ptr++;
450
	  }
451
	}
452
      }
453
    }
454
  }
455
}
456
457
458
LOCAL(void)
459
do_transverse (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
460
	       jvirt_barray_ptr *src_coef_arrays,
461
	       jvirt_barray_ptr *dst_coef_arrays)
462
/* Transverse transpose is equivalent to
463
 *   1. 180 degree rotation;
464
 *   2. Transposition;
465
 * or
466
 *   1. Horizontal mirroring;
467
 *   2. Transposition;
468
 *   3. Horizontal mirroring.
469
 * These steps are merged into a single processing routine.
470
 */
471
{
472
  JDIMENSION MCU_cols, MCU_rows, comp_width, comp_height, dst_blk_x, dst_blk_y;
473
  int ci, i, j, offset_x, offset_y;
474
  JBLOCKARRAY src_buffer, dst_buffer;
475
  JCOEFPTR src_ptr, dst_ptr;
476
  jpeg_component_info *compptr;
477
478
  MCU_cols = dstinfo->image_width / (dstinfo->max_h_samp_factor * DCTSIZE);
479
  MCU_rows = dstinfo->image_height / (dstinfo->max_v_samp_factor * DCTSIZE);
480
481
  for (ci = 0; ci < dstinfo->num_components; ci++) {
482
    compptr = dstinfo->comp_info + ci;
483
    comp_width = MCU_cols * compptr->h_samp_factor;
484
    comp_height = MCU_rows * compptr->v_samp_factor;
485
    for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks;
486
	 dst_blk_y += compptr->v_samp_factor) {
487
      dst_buffer = (*srcinfo->mem->access_virt_barray)
488
	((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y,
489
	 (JDIMENSION) compptr->v_samp_factor, TRUE);
490
      for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
491
	for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks;
492
	     dst_blk_x += compptr->h_samp_factor) {
493
	  src_buffer = (*srcinfo->mem->access_virt_barray)
494
	    ((j_common_ptr) srcinfo, src_coef_arrays[ci], dst_blk_x,
495
	     (JDIMENSION) compptr->h_samp_factor, FALSE);
496
	  for (offset_x = 0; offset_x < compptr->h_samp_factor; offset_x++) {
497
	    if (dst_blk_y < comp_height) {
498
	      src_ptr = src_buffer[offset_x]
499
		[comp_height - dst_blk_y - offset_y - 1];
500
	      if (dst_blk_x < comp_width) {
501
		/* Block is within the mirrorable area. */
502
		dst_ptr = dst_buffer[offset_y]
503
		  [comp_width - dst_blk_x - offset_x - 1];
504
		for (i = 0; i < DCTSIZE; i++) {
505
		  for (j = 0; j < DCTSIZE; j++) {
506
		    dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j];
507
		    j++;
508
		    dst_ptr[j*DCTSIZE+i] = -src_ptr[i*DCTSIZE+j];
509
		  }
510
		  i++;
511
		  for (j = 0; j < DCTSIZE; j++) {
512
		    dst_ptr[j*DCTSIZE+i] = -src_ptr[i*DCTSIZE+j];
513
		    j++;
514
		    dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j];
515
		  }
516
		}
517
	      } else {
518
		/* Right-edge blocks are mirrored in y only */
519
		dst_ptr = dst_buffer[offset_y][dst_blk_x + offset_x];
520
		for (i = 0; i < DCTSIZE; i++) {
521
		  for (j = 0; j < DCTSIZE; j++) {
522
		    dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j];
523
		    j++;
524
		    dst_ptr[j*DCTSIZE+i] = -src_ptr[i*DCTSIZE+j];
525
		  }
526
		}
527
	      }
528
	    } else {
529
	      src_ptr = src_buffer[offset_x][dst_blk_y + offset_y];
530
	      if (dst_blk_x < comp_width) {
531
		/* Bottom-edge blocks are mirrored in x only */
532
		dst_ptr = dst_buffer[offset_y]
533
		  [comp_width - dst_blk_x - offset_x - 1];
534
		for (i = 0; i < DCTSIZE; i++) {
535
		  for (j = 0; j < DCTSIZE; j++)
536
		    dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j];
537
		  i++;
538
		  for (j = 0; j < DCTSIZE; j++)
539
		    dst_ptr[j*DCTSIZE+i] = -src_ptr[i*DCTSIZE+j];
540
		}
541
	      } else {
542
		/* At lower right corner, just transpose, no mirroring */
543
		dst_ptr = dst_buffer[offset_y][dst_blk_x + offset_x];
544
		for (i = 0; i < DCTSIZE; i++)
545
		  for (j = 0; j < DCTSIZE; j++)
546
		    dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j];
547
	      }
548
	    }
549
	  }
550
	}
551
      }
552
    }
553
  }
554
}
555
556
557
/* Request any required workspace.
558
 *
559
 * We allocate the workspace virtual arrays from the source decompression
560
 * object, so that all the arrays (both the original data and the workspace)
561
 * will be taken into account while making memory management decisions.
562
 * Hence, this routine must be called after jpeg_read_header (which reads
563
 * the image dimensions) and before jpeg_read_coefficients (which realizes
564
 * the source's virtual arrays).
565
 */
566
567
GLOBAL(void)
568
jtransform_request_workspace (j_decompress_ptr srcinfo,
569
			      jpeg_transform_info *info)
570
{
571
  jvirt_barray_ptr *coef_arrays = NULL;
572
  jpeg_component_info *compptr;
573
  int ci;
574
575
  if (info->force_grayscale &&
576
      srcinfo->jpeg_color_space == JCS_YCbCr &&
577
      srcinfo->num_components == 3) {
578
    /* We'll only process the first component */
579
    info->num_components = 1;
580
  } else {
581
    /* Process all the components */
582
    info->num_components = srcinfo->num_components;
583
  }
584
585
  switch (info->transform) {
586
  case JXFORM_NONE:
587
  case JXFORM_FLIP_H:
588
    /* Don't need a workspace array */
589
    break;
590
  case JXFORM_FLIP_V:
591
  case JXFORM_ROT_180:
592
    /* Need workspace arrays having same dimensions as source image.
593
     * Note that we allocate arrays padded out to the next iMCU boundary,
594
     * so that transform routines need not worry about missing edge blocks.
595
     */
596
    coef_arrays = (jvirt_barray_ptr *)
597
      (*srcinfo->mem->alloc_small) ((j_common_ptr) srcinfo, JPOOL_IMAGE,
598
	SIZEOF(jvirt_barray_ptr) * info->num_components);
599
    for (ci = 0; ci < info->num_components; ci++) {
600
      compptr = srcinfo->comp_info + ci;
601
      coef_arrays[ci] = (*srcinfo->mem->request_virt_barray)
602
	((j_common_ptr) srcinfo, JPOOL_IMAGE, FALSE,
603
	 (JDIMENSION) jround_up((long) compptr->width_in_blocks,
604
				(long) compptr->h_samp_factor),
605
	 (JDIMENSION) jround_up((long) compptr->height_in_blocks,
606
				(long) compptr->v_samp_factor),
607
	 (JDIMENSION) compptr->v_samp_factor);
608
    }
609
    break;
610
  case JXFORM_TRANSPOSE:
611
  case JXFORM_TRANSVERSE:
612
  case JXFORM_ROT_90:
613
  case JXFORM_ROT_270:
614
    /* Need workspace arrays having transposed dimensions.
615
     * Note that we allocate arrays padded out to the next iMCU boundary,
616
     * so that transform routines need not worry about missing edge blocks.
617
     */
618
    coef_arrays = (jvirt_barray_ptr *)
619
      (*srcinfo->mem->alloc_small) ((j_common_ptr) srcinfo, JPOOL_IMAGE,
620
	SIZEOF(jvirt_barray_ptr) * info->num_components);
621
    for (ci = 0; ci < info->num_components; ci++) {
622
      compptr = srcinfo->comp_info + ci;
623
      coef_arrays[ci] = (*srcinfo->mem->request_virt_barray)
624
	((j_common_ptr) srcinfo, JPOOL_IMAGE, FALSE,
625
	 (JDIMENSION) jround_up((long) compptr->height_in_blocks,
626
				(long) compptr->v_samp_factor),
627
	 (JDIMENSION) jround_up((long) compptr->width_in_blocks,
628
				(long) compptr->h_samp_factor),
629
	 (JDIMENSION) compptr->h_samp_factor);
630
    }
631
    break;
632
  }
633
  info->workspace_coef_arrays = coef_arrays;
634
}
635
636
637
/* Transpose destination image parameters */
638
639
LOCAL(void)
640
transpose_critical_parameters (j_compress_ptr dstinfo)
641
{
642
  int tblno, i, j, ci, itemp;
643
  jpeg_component_info *compptr;
644
  JQUANT_TBL *qtblptr;
645
  JDIMENSION dtemp;
646
  UINT16 qtemp;
647
648
  /* Transpose basic image dimensions */
649
  dtemp = dstinfo->image_width;
650
  dstinfo->image_width = dstinfo->image_height;
651
  dstinfo->image_height = dtemp;
652
653
  /* Transpose sampling factors */
654
  for (ci = 0; ci < dstinfo->num_components; ci++) {
655
    compptr = dstinfo->comp_info + ci;
656
    itemp = compptr->h_samp_factor;
657
    compptr->h_samp_factor = compptr->v_samp_factor;
658
    compptr->v_samp_factor = itemp;
659
  }
660
661
  /* Transpose quantization tables */
662
  for (tblno = 0; tblno < NUM_QUANT_TBLS; tblno++) {
663
    qtblptr = dstinfo->quant_tbl_ptrs[tblno];
664
    if (qtblptr != NULL) {
665
      for (i = 0; i < DCTSIZE; i++) {
666
	for (j = 0; j < i; j++) {
667
	  qtemp = qtblptr->quantval[i*DCTSIZE+j];
668
	  qtblptr->quantval[i*DCTSIZE+j] = qtblptr->quantval[j*DCTSIZE+i];
669
	  qtblptr->quantval[j*DCTSIZE+i] = qtemp;
670
	}
671
      }
672
    }
673
  }
674
}
675
676
677
/* Trim off any partial iMCUs on the indicated destination edge */
678
679
LOCAL(void)
680
trim_right_edge (j_compress_ptr dstinfo)
681
{
682
  int ci, max_h_samp_factor;
683
  JDIMENSION MCU_cols;
684
685
  /* We have to compute max_h_samp_factor ourselves,
686
   * because it hasn't been set yet in the destination
687
   * (and we don't want to use the source's value).
688
   */
689
  max_h_samp_factor = 1;
690
  for (ci = 0; ci < dstinfo->num_components; ci++) {
691
    int h_samp_factor = dstinfo->comp_info[ci].h_samp_factor;
692
    max_h_samp_factor = MAX(max_h_samp_factor, h_samp_factor);
693
  }
694
  MCU_cols = dstinfo->image_width / (max_h_samp_factor * DCTSIZE);
695
  if (MCU_cols > 0)		/* can't trim to 0 pixels */
696
    dstinfo->image_width = MCU_cols * (max_h_samp_factor * DCTSIZE);
697
}
698
699
LOCAL(void)
700
trim_bottom_edge (j_compress_ptr dstinfo)
701
{
702
  int ci, max_v_samp_factor;
703
  JDIMENSION MCU_rows;
704
705
  /* We have to compute max_v_samp_factor ourselves,
706
   * because it hasn't been set yet in the destination
707
   * (and we don't want to use the source's value).
708
   */
709
  max_v_samp_factor = 1;
710
  for (ci = 0; ci < dstinfo->num_components; ci++) {
711
    int v_samp_factor = dstinfo->comp_info[ci].v_samp_factor;
712
    max_v_samp_factor = MAX(max_v_samp_factor, v_samp_factor);
713
  }
714
  MCU_rows = dstinfo->image_height / (max_v_samp_factor * DCTSIZE);
715
  if (MCU_rows > 0)		/* can't trim to 0 pixels */
716
    dstinfo->image_height = MCU_rows * (max_v_samp_factor * DCTSIZE);
717
}
718
719
720
/* Adjust output image parameters as needed.
721
 *
722
 * This must be called after jpeg_copy_critical_parameters()
723
 * and before jpeg_write_coefficients().
724
 *
725
 * The return value is the set of virtual coefficient arrays to be written
726
 * (either the ones allocated by jtransform_request_workspace, or the
727
 * original source data arrays).  The caller will need to pass this value
728
 * to jpeg_write_coefficients().
729
 */
730
731
GLOBAL(jvirt_barray_ptr *)
732
jtransform_adjust_parameters (j_decompress_ptr srcinfo,
733
			      j_compress_ptr dstinfo,
734
			      jvirt_barray_ptr *src_coef_arrays,
735
			      jpeg_transform_info *info)
736
{
737
  /* If force-to-grayscale is requested, adjust destination parameters */
738
  if (info->force_grayscale) {
739
    /* We use jpeg_set_colorspace to make sure subsidiary settings get fixed
740
     * properly.  Among other things, the target h_samp_factor & v_samp_factor
741
     * will get set to 1, which typically won't match the source.
742
     * In fact we do this even if the source is already grayscale; that
743
     * provides an easy way of coercing a grayscale JPEG with funny sampling
744
     * factors to the customary 1,1.  (Some decoders fail on other factors.)
745
     */
746
    if ((dstinfo->jpeg_color_space == JCS_YCbCr &&
747
	 dstinfo->num_components == 3) ||
748
	(dstinfo->jpeg_color_space == JCS_GRAYSCALE &&
749
	 dstinfo->num_components == 1)) {
750
      /* We have to preserve the source's quantization table number. */
751
      int sv_quant_tbl_no = dstinfo->comp_info[0].quant_tbl_no;
752
      jpeg_set_colorspace(dstinfo, JCS_GRAYSCALE);
753
      dstinfo->comp_info[0].quant_tbl_no = sv_quant_tbl_no;
754
    } else {
755
      /* Sorry, can't do it */
756
      ERREXIT(dstinfo, JERR_CONVERSION_NOTIMPL);
757
    }
758
  }
759
760
  /* Correct the destination's image dimensions etc if necessary */
761
  switch (info->transform) {
762
  case JXFORM_NONE:
763
    /* Nothing to do */
764
    break;
765
  case JXFORM_FLIP_H:
766
    if (info->trim)
767
      trim_right_edge(dstinfo);
768
    break;
769
  case JXFORM_FLIP_V:
770
    if (info->trim)
771
      trim_bottom_edge(dstinfo);
772
    break;
773
  case JXFORM_TRANSPOSE:
774
    transpose_critical_parameters(dstinfo);
775
    /* transpose does NOT have to trim anything */
776
    break;
777
  case JXFORM_TRANSVERSE:
778
    transpose_critical_parameters(dstinfo);
779
    if (info->trim) {
780
      trim_right_edge(dstinfo);
781
      trim_bottom_edge(dstinfo);
782
    }
783
    break;
784
  case JXFORM_ROT_90:
785
    transpose_critical_parameters(dstinfo);
786
    if (info->trim)
787
      trim_right_edge(dstinfo);
788
    break;
789
  case JXFORM_ROT_180:
790
    if (info->trim) {
791
      trim_right_edge(dstinfo);
792
      trim_bottom_edge(dstinfo);
793
    }
794
    break;
795
  case JXFORM_ROT_270:
796
    transpose_critical_parameters(dstinfo);
797
    if (info->trim)
798
      trim_bottom_edge(dstinfo);
799
    break;
800
  }
801
802
  /* Return the appropriate output data set */
803
  if (info->workspace_coef_arrays != NULL)
804
    return info->workspace_coef_arrays;
805
  return src_coef_arrays;
806
}
807
808
809
/* Execute the actual transformation, if any.
810
 *
811
 * This must be called *after* jpeg_write_coefficients, because it depends
812
 * on jpeg_write_coefficients to have computed subsidiary values such as
813
 * the per-component width and height fields in the destination object.
814
 *
815
 * Note that some transformations will modify the source data arrays!
816
 */
817
818
GLOBAL(void)
819
jtransform_execute_transformation (j_decompress_ptr srcinfo,
820
				   j_compress_ptr dstinfo,
821
				   jvirt_barray_ptr *src_coef_arrays,
822
				   jpeg_transform_info *info)
823
{
824
  jvirt_barray_ptr *dst_coef_arrays = info->workspace_coef_arrays;
825
826
  switch (info->transform) {
827
  case JXFORM_NONE:
828
    break;
829
  case JXFORM_FLIP_H:
830
    do_flip_h(srcinfo, dstinfo, src_coef_arrays);
831
    break;
832
  case JXFORM_FLIP_V:
833
    do_flip_v(srcinfo, dstinfo, src_coef_arrays, dst_coef_arrays);
834
    break;
835
  case JXFORM_TRANSPOSE:
836
    do_transpose(srcinfo, dstinfo, src_coef_arrays, dst_coef_arrays);
837
    break;
838
  case JXFORM_TRANSVERSE:
839
    do_transverse(srcinfo, dstinfo, src_coef_arrays, dst_coef_arrays);
840
    break;
841
  case JXFORM_ROT_90:
842
    do_rot_90(srcinfo, dstinfo, src_coef_arrays, dst_coef_arrays);
843
    break;
844
  case JXFORM_ROT_180:
845
    do_rot_180(srcinfo, dstinfo, src_coef_arrays, dst_coef_arrays);
846
    break;
847
  case JXFORM_ROT_270:
848
    do_rot_270(srcinfo, dstinfo, src_coef_arrays, dst_coef_arrays);
849
    break;
850
  }
851
}
852
853
#endif /* TRANSFORMS_SUPPORTED */
854
855
856
/* Setup decompression object to save desired markers in memory.
857
 * This must be called before jpeg_read_header() to have the desired effect.
858
 */
859
860
GLOBAL(void)
861
jcopy_markers_setup (j_decompress_ptr srcinfo, JCOPY_OPTION option)
862
{
863
#ifdef SAVE_MARKERS_SUPPORTED
864
  int m;
865
866
  /* Save comments except under NONE option */
867
  if (option != JCOPYOPT_NONE) {
868
    jpeg_save_markers(srcinfo, JPEG_COM, 0xFFFF);
869
  }
870
  /* Save all types of APPn markers iff ALL option */
871
  if (option == JCOPYOPT_ALL) {
872
    for (m = 0; m < 16; m++)
873
      jpeg_save_markers(srcinfo, JPEG_APP0 + m, 0xFFFF);
874
  }
875
#endif /* SAVE_MARKERS_SUPPORTED */
876
}
877
878
/* Copy markers saved in the given source object to the destination object.
879
 * This should be called just after jpeg_start_compress() or
880
 * jpeg_write_coefficients().
881
 * Note that those routines will have written the SOI, and also the
882
 * JFIF APP0 or Adobe APP14 markers if selected.
883
 */
884
885
GLOBAL(void)
886
jcopy_markers_execute (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
887
		       JCOPY_OPTION option)
888
{
889
  jpeg_saved_marker_ptr marker;
890
891
  /* In the current implementation, we don't actually need to examine the
892
   * option flag here; we just copy everything that got saved.
893
   * But to avoid confusion, we do not output JFIF and Adobe APP14 markers
894
   * if the encoder library already wrote one.
895
   */
896
  for (marker = srcinfo->marker_list; marker != NULL; marker = marker->next) {
897
    if (dstinfo->write_JFIF_header &&
898
	marker->marker == JPEG_APP0 &&
899
	marker->data_length >= 5 &&
900
	GETJOCTET(marker->data[0]) == 0x4A &&
901
	GETJOCTET(marker->data[1]) == 0x46 &&
902
	GETJOCTET(marker->data[2]) == 0x49 &&
903
	GETJOCTET(marker->data[3]) == 0x46 &&
904
	GETJOCTET(marker->data[4]) == 0)
905
      continue;			/* reject duplicate JFIF */
906
    if (dstinfo->write_Adobe_marker &&
907
	marker->marker == JPEG_APP0+14 &&
908
	marker->data_length >= 5 &&
909
	GETJOCTET(marker->data[0]) == 0x41 &&
910
	GETJOCTET(marker->data[1]) == 0x64 &&
911
	GETJOCTET(marker->data[2]) == 0x6F &&
912
	GETJOCTET(marker->data[3]) == 0x62 &&
913
	GETJOCTET(marker->data[4]) == 0x65)
914
      continue;			/* reject duplicate Adobe */
915
#ifdef NEED_FAR_POINTERS
916
    /* We could use jpeg_write_marker if the data weren't FAR... */
917
    {
918
      unsigned int i;
919
      jpeg_write_m_header(dstinfo, marker->marker, marker->data_length);
920
      for (i = 0; i < marker->data_length; i++)
921
	jpeg_write_m_byte(dstinfo, marker->data[i]);
922
    }
923
#else
924
    jpeg_write_marker(dstinfo, marker->marker,
925
		      marker->data, marker->data_length);
926
#endif
927
  }
928
}
(-)a/jpeg/transupp.h (+135 lines)
Line     Link Here 
Line 0    Link Here 
1
/*
2
 * transupp.h
3
 *
4
 * Copyright (C) 1997, Thomas G. Lane.
5
 * This file is part of the Independent JPEG Group's software.
6
 * For conditions of distribution and use, see the accompanying README file.
7
 *
8
 * This file contains declarations for image transformation routines and
9
 * other utility code used by the jpegtran sample application.  These are
10
 * NOT part of the core JPEG library.  But we keep these routines separate
11
 * from jpegtran.c to ease the task of maintaining jpegtran-like programs
12
 * that have other user interfaces.
13
 *
14
 * NOTE: all the routines declared here have very specific requirements
15
 * about when they are to be executed during the reading and writing of the
16
 * source and destination files.  See the comments in transupp.c, or see
17
 * jpegtran.c for an example of correct usage.
18
 */
19
20
/* If you happen not to want the image transform support, disable it here */
21
#ifndef TRANSFORMS_SUPPORTED
22
#define TRANSFORMS_SUPPORTED 1		/* 0 disables transform code */
23
#endif
24
25
/* Short forms of external names for systems with brain-damaged linkers. */
26
27
#ifdef NEED_SHORT_EXTERNAL_NAMES
28
#define jtransform_request_workspace		jTrRequest
29
#define jtransform_adjust_parameters		jTrAdjust
30
#define jtransform_execute_transformation	jTrExec
31
#define jcopy_markers_setup			jCMrkSetup
32
#define jcopy_markers_execute			jCMrkExec
33
#endif /* NEED_SHORT_EXTERNAL_NAMES */
34
35
36
/*
37
 * Codes for supported types of image transformations.
38
 */
39
40
typedef enum {
41
	JXFORM_NONE,		/* no transformation */
42
	JXFORM_FLIP_H,		/* horizontal flip */
43
	JXFORM_FLIP_V,		/* vertical flip */
44
	JXFORM_TRANSPOSE,	/* transpose across UL-to-LR axis */
45
	JXFORM_TRANSVERSE,	/* transpose across UR-to-LL axis */
46
	JXFORM_ROT_90,		/* 90-degree clockwise rotation */
47
	JXFORM_ROT_180,		/* 180-degree rotation */
48
	JXFORM_ROT_270		/* 270-degree clockwise (or 90 ccw) */
49
} JXFORM_CODE;
50
51
/*
52
 * Although rotating and flipping data expressed as DCT coefficients is not
53
 * hard, there is an asymmetry in the JPEG format specification for images
54
 * whose dimensions aren't multiples of the iMCU size.  The right and bottom
55
 * image edges are padded out to the next iMCU boundary with junk data; but
56
 * no padding is possible at the top and left edges.  If we were to flip
57
 * the whole image including the pad data, then pad garbage would become
58
 * visible at the top and/or left, and real pixels would disappear into the
59
 * pad margins --- perhaps permanently, since encoders & decoders may not
60
 * bother to preserve DCT blocks that appear to be completely outside the
61
 * nominal image area.  So, we have to exclude any partial iMCUs from the
62
 * basic transformation.
63
 *
64
 * Transpose is the only transformation that can handle partial iMCUs at the
65
 * right and bottom edges completely cleanly.  flip_h can flip partial iMCUs
66
 * at the bottom, but leaves any partial iMCUs at the right edge untouched.
67
 * Similarly flip_v leaves any partial iMCUs at the bottom edge untouched.
68
 * The other transforms are defined as combinations of these basic transforms
69
 * and process edge blocks in a way that preserves the equivalence.
70
 *
71
 * The "trim" option causes untransformable partial iMCUs to be dropped;
72
 * this is not strictly lossless, but it usually gives the best-looking
73
 * result for odd-size images.  Note that when this option is active,
74
 * the expected mathematical equivalences between the transforms may not hold.
75
 * (For example, -rot 270 -trim trims only the bottom edge, but -rot 90 -trim
76
 * followed by -rot 180 -trim trims both edges.)
77
 *
78
 * We also offer a "force to grayscale" option, which simply discards the
79
 * chrominance channels of a YCbCr image.  This is lossless in the sense that
80
 * the luminance channel is preserved exactly.  It's not the same kind of
81
 * thing as the rotate/flip transformations, but it's convenient to handle it
82
 * as part of this package, mainly because the transformation routines have to
83
 * be aware of the option to know how many components to work on.
84
 */
85
86
typedef struct {
87
  /* Options: set by caller */
88
  JXFORM_CODE transform;	/* image transform operator */
89
  boolean trim;			/* if TRUE, trim partial MCUs as needed */
90
  boolean force_grayscale;	/* if TRUE, convert color image to grayscale */
91
92
  /* Internal workspace: caller should not touch these */
93
  int num_components;		/* # of components in workspace */
94
  jvirt_barray_ptr * workspace_coef_arrays; /* workspace for transformations */
95
} jpeg_transform_info;
96
97
98
#if TRANSFORMS_SUPPORTED
99
100
/* Request any required workspace */
101
EXTERN(void) jtransform_request_workspace
102
	JPP((j_decompress_ptr srcinfo, jpeg_transform_info *info));
103
/* Adjust output image parameters */
104
EXTERN(jvirt_barray_ptr *) jtransform_adjust_parameters
105
	JPP((j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
106
	     jvirt_barray_ptr *src_coef_arrays,
107
	     jpeg_transform_info *info));
108
/* Execute the actual transformation, if any */
109
EXTERN(void) jtransform_execute_transformation
110
	JPP((j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
111
	     jvirt_barray_ptr *src_coef_arrays,
112
	     jpeg_transform_info *info));
113
114
#endif /* TRANSFORMS_SUPPORTED */
115
116
117
/*
118
 * Support for copying optional markers from source to destination file.
119
 */
120
121
typedef enum {
122
	JCOPYOPT_NONE,		/* copy no optional markers */
123
	JCOPYOPT_COMMENTS,	/* copy only comment (COM) markers */
124
	JCOPYOPT_ALL		/* copy all optional markers */
125
} JCOPY_OPTION;
126
127
#define JCOPYOPT_DEFAULT  JCOPYOPT_COMMENTS	/* recommended default */
128
129
/* Setup decompression object to save desired markers in memory */
130
EXTERN(void) jcopy_markers_setup
131
	JPP((j_decompress_ptr srcinfo, JCOPY_OPTION option));
132
/* Copy markers saved in the given source object to the destination object */
133
EXTERN(void) jcopy_markers_execute
134
	JPP((j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
135
	     JCOPY_OPTION option));
(-)a/jpeg/turbojpeg-mapfile (+13 lines)
Line     Link Here 
Line 0    Link Here 
1
{
2
	global:
3
		tjInitCompress;
4
		tjCompress;
5
		TJBUFSIZE;
6
		tjInitDecompress;
7
		tjDecompressHeader;
8
		tjDecompress;
9
		tjDestroy;
10
		tjGetErrorStr;
11
	local:
12
		*;
13
};
(-)a/jpeg/wrbmp.c (+442 lines)
Line     Link Here 
Line 0    Link Here 
1
/*
2
 * wrbmp.c
3
 *
4
 * Copyright (C) 1994-1996, Thomas G. Lane.
5
 * This file is part of the Independent JPEG Group's software.
6
 * For conditions of distribution and use, see the accompanying README file.
7
 *
8
 * This file contains routines to write output images in Microsoft "BMP"
9
 * format (MS Windows 3.x and OS/2 1.x flavors).
10
 * Either 8-bit colormapped or 24-bit full-color format can be written.
11
 * No compression is supported.
12
 *
13
 * These routines may need modification for non-Unix environments or
14
 * specialized applications.  As they stand, they assume output to
15
 * an ordinary stdio stream.
16
 *
17
 * This code contributed by James Arthur Boucher.
18
 */
19
20
#include "cdjpeg.h"		/* Common decls for cjpeg/djpeg applications */
21
22
#ifdef BMP_SUPPORTED
23
24
25
/*
26
 * To support 12-bit JPEG data, we'd have to scale output down to 8 bits.
27
 * This is not yet implemented.
28
 */
29
30
#if BITS_IN_JSAMPLE != 8
31
  Sorry, this code only copes with 8-bit JSAMPLEs. /* deliberate syntax err */
32
#endif
33
34
/*
35
 * Since BMP stores scanlines bottom-to-top, we have to invert the image
36
 * from JPEG's top-to-bottom order.  To do this, we save the outgoing data
37
 * in a virtual array during put_pixel_row calls, then actually emit the
38
 * BMP file during finish_output.  The virtual array contains one JSAMPLE per
39
 * pixel if the output is grayscale or colormapped, three if it is full color.
40
 */
41
42
/* Private version of data destination object */
43
44
typedef struct {
45
  struct djpeg_dest_struct pub;	/* public fields */
46
47
  boolean is_os2;		/* saves the OS2 format request flag */
48
49
  jvirt_sarray_ptr whole_image;	/* needed to reverse row order */
50
  JDIMENSION data_width;	/* JSAMPLEs per row */
51
  JDIMENSION row_width;		/* physical width of one row in the BMP file */
52
  int pad_bytes;		/* number of padding bytes needed per row */
53
  JDIMENSION cur_output_row;	/* next row# to write to virtual array */
54
} bmp_dest_struct;
55
56
typedef bmp_dest_struct * bmp_dest_ptr;
57
58
59
/* Forward declarations */
60
LOCAL(void) write_colormap
61
	JPP((j_decompress_ptr cinfo, bmp_dest_ptr dest,
62
	     int map_colors, int map_entry_size));
63
64
65
/*
66
 * Write some pixel data.
67
 * In this module rows_supplied will always be 1.
68
 */
69
70
METHODDEF(void)
71
put_pixel_rows (j_decompress_ptr cinfo, djpeg_dest_ptr dinfo,
72
		JDIMENSION rows_supplied)
73
/* This version is for writing 24-bit pixels */
74
{
75
  bmp_dest_ptr dest = (bmp_dest_ptr) dinfo;
76
  JSAMPARRAY image_ptr;
77
  register JSAMPROW inptr, outptr;
78
  register JDIMENSION col;
79
  int pad;
80
81
  /* Access next row in virtual array */
82
  image_ptr = (*cinfo->mem->access_virt_sarray)
83
    ((j_common_ptr) cinfo, dest->whole_image,
84
     dest->cur_output_row, (JDIMENSION) 1, TRUE);
85
  dest->cur_output_row++;
86
87
  /* Transfer data.  Note destination values must be in BGR order
88
   * (even though Microsoft's own documents say the opposite).
89
   */
90
  inptr = dest->pub.buffer[0];
91
  outptr = image_ptr[0];
92
  for (col = cinfo->output_width; col > 0; col--) {
93
    outptr[2] = *inptr++;	/* can omit GETJSAMPLE() safely */
94
    outptr[1] = *inptr++;
95
    outptr[0] = *inptr++;
96
    outptr += 3;
97
  }
98
99
  /* Zero out the pad bytes. */
100
  pad = dest->pad_bytes;
101
  while (--pad >= 0)
102
    *outptr++ = 0;
103
}
104
105
METHODDEF(void)
106
put_gray_rows (j_decompress_ptr cinfo, djpeg_dest_ptr dinfo,
107
	       JDIMENSION rows_supplied)
108
/* This version is for grayscale OR quantized color output */
109
{
110
  bmp_dest_ptr dest = (bmp_dest_ptr) dinfo;
111
  JSAMPARRAY image_ptr;
112
  register JSAMPROW inptr, outptr;
113
  register JDIMENSION col;
114
  int pad;
115
116
  /* Access next row in virtual array */
117
  image_ptr = (*cinfo->mem->access_virt_sarray)
118
    ((j_common_ptr) cinfo, dest->whole_image,
119
     dest->cur_output_row, (JDIMENSION) 1, TRUE);
120
  dest->cur_output_row++;
121
122
  /* Transfer data. */
123
  inptr = dest->pub.buffer[0];
124
  outptr = image_ptr[0];
125
  for (col = cinfo->output_width; col > 0; col--) {
126
    *outptr++ = *inptr++;	/* can omit GETJSAMPLE() safely */
127
  }
128
129
  /* Zero out the pad bytes. */
130
  pad = dest->pad_bytes;
131
  while (--pad >= 0)
132
    *outptr++ = 0;
133
}
134
135
136
/*
137
 * Startup: normally writes the file header.
138
 * In this module we may as well postpone everything until finish_output.
139
 */
140
141
METHODDEF(void)
142
start_output_bmp (j_decompress_ptr cinfo, djpeg_dest_ptr dinfo)
143
{
144
  /* no work here */
145
}
146
147
148
/*
149
 * Finish up at the end of the file.
150
 *
151
 * Here is where we really output the BMP file.
152
 *
153
 * First, routines to write the Windows and OS/2 variants of the file header.
154
 */
155
156
LOCAL(void)
157
write_bmp_header (j_decompress_ptr cinfo, bmp_dest_ptr dest)
158
/* Write a Windows-style BMP file header, including colormap if needed */
159
{
160
  char bmpfileheader[14];
161
  char bmpinfoheader[40];
162
#define PUT_2B(array,offset,value)  \
163
	(array[offset] = (char) ((value) & 0xFF), \
164
	 array[offset+1] = (char) (((value) >> 8) & 0xFF))
165
#define PUT_4B(array,offset,value)  \
166
	(array[offset] = (char) ((value) & 0xFF), \
167
	 array[offset+1] = (char) (((value) >> 8) & 0xFF), \
168
	 array[offset+2] = (char) (((value) >> 16) & 0xFF), \
169
	 array[offset+3] = (char) (((value) >> 24) & 0xFF))
170
  INT32 headersize, bfSize;
171
  int bits_per_pixel, cmap_entries;
172
173
  /* Compute colormap size and total file size */
174
  if (cinfo->out_color_space == JCS_RGB) {
175
    if (cinfo->quantize_colors) {
176
      /* Colormapped RGB */
177
      bits_per_pixel = 8;
178
      cmap_entries = 256;
179
    } else {
180
      /* Unquantized, full color RGB */
181
      bits_per_pixel = 24;
182
      cmap_entries = 0;
183
    }
184
  } else {
185
    /* Grayscale output.  We need to fake a 256-entry colormap. */
186
    bits_per_pixel = 8;
187
    cmap_entries = 256;
188
  }
189
  /* File size */
190
  headersize = 14 + 40 + cmap_entries * 4; /* Header and colormap */
191
  bfSize = headersize + (INT32) dest->row_width * (INT32) cinfo->output_height;
192
  
193
  /* Set unused fields of header to 0 */
194
  MEMZERO(bmpfileheader, SIZEOF(bmpfileheader));
195
  MEMZERO(bmpinfoheader, SIZEOF(bmpinfoheader));
196
197
  /* Fill the file header */
198
  bmpfileheader[0] = 0x42;	/* first 2 bytes are ASCII 'B', 'M' */
199
  bmpfileheader[1] = 0x4D;
200
  PUT_4B(bmpfileheader, 2, bfSize); /* bfSize */
201
  /* we leave bfReserved1 & bfReserved2 = 0 */
202
  PUT_4B(bmpfileheader, 10, headersize); /* bfOffBits */
203
204
  /* Fill the info header (Microsoft calls this a BITMAPINFOHEADER) */
205
  PUT_2B(bmpinfoheader, 0, 40);	/* biSize */
206
  PUT_4B(bmpinfoheader, 4, cinfo->output_width); /* biWidth */
207
  PUT_4B(bmpinfoheader, 8, cinfo->output_height); /* biHeight */
208
  PUT_2B(bmpinfoheader, 12, 1);	/* biPlanes - must be 1 */
209
  PUT_2B(bmpinfoheader, 14, bits_per_pixel); /* biBitCount */
210
  /* we leave biCompression = 0, for none */
211
  /* we leave biSizeImage = 0; this is correct for uncompressed data */
212
  if (cinfo->density_unit == 2) { /* if have density in dots/cm, then */
213
    PUT_4B(bmpinfoheader, 24, (INT32) (cinfo->X_density*100)); /* XPels/M */
214
    PUT_4B(bmpinfoheader, 28, (INT32) (cinfo->Y_density*100)); /* XPels/M */
215
  }
216
  PUT_2B(bmpinfoheader, 32, cmap_entries); /* biClrUsed */
217
  /* we leave biClrImportant = 0 */
218
219
  if (JFWRITE(dest->pub.output_file, bmpfileheader, 14) != (size_t) 14)
220
    ERREXIT(cinfo, JERR_FILE_WRITE);
221
  if (JFWRITE(dest->pub.output_file, bmpinfoheader, 40) != (size_t) 40)
222
    ERREXIT(cinfo, JERR_FILE_WRITE);
223
224
  if (cmap_entries > 0)
225
    write_colormap(cinfo, dest, cmap_entries, 4);
226
}
227
228
229
LOCAL(void)
230
write_os2_header (j_decompress_ptr cinfo, bmp_dest_ptr dest)
231
/* Write an OS2-style BMP file header, including colormap if needed */
232
{
233
  char bmpfileheader[14];
234
  char bmpcoreheader[12];
235
  INT32 headersize, bfSize;
236
  int bits_per_pixel, cmap_entries;
237
238
  /* Compute colormap size and total file size */
239
  if (cinfo->out_color_space == JCS_RGB) {
240
    if (cinfo->quantize_colors) {
241
      /* Colormapped RGB */
242
      bits_per_pixel = 8;
243
      cmap_entries = 256;
244
    } else {
245
      /* Unquantized, full color RGB */
246
      bits_per_pixel = 24;
247
      cmap_entries = 0;
248
    }
249
  } else {
250
    /* Grayscale output.  We need to fake a 256-entry colormap. */
251
    bits_per_pixel = 8;
252
    cmap_entries = 256;
253
  }
254
  /* File size */
255
  headersize = 14 + 12 + cmap_entries * 3; /* Header and colormap */
256
  bfSize = headersize + (INT32) dest->row_width * (INT32) cinfo->output_height;
257
  
258
  /* Set unused fields of header to 0 */
259
  MEMZERO(bmpfileheader, SIZEOF(bmpfileheader));
260
  MEMZERO(bmpcoreheader, SIZEOF(bmpcoreheader));
261
262
  /* Fill the file header */
263
  bmpfileheader[0] = 0x42;	/* first 2 bytes are ASCII 'B', 'M' */
264
  bmpfileheader[1] = 0x4D;
265
  PUT_4B(bmpfileheader, 2, bfSize); /* bfSize */
266
  /* we leave bfReserved1 & bfReserved2 = 0 */
267
  PUT_4B(bmpfileheader, 10, headersize); /* bfOffBits */
268
269
  /* Fill the info header (Microsoft calls this a BITMAPCOREHEADER) */
270
  PUT_2B(bmpcoreheader, 0, 12);	/* bcSize */
271
  PUT_2B(bmpcoreheader, 4, cinfo->output_width); /* bcWidth */
272
  PUT_2B(bmpcoreheader, 6, cinfo->output_height); /* bcHeight */
273
  PUT_2B(bmpcoreheader, 8, 1);	/* bcPlanes - must be 1 */
274
  PUT_2B(bmpcoreheader, 10, bits_per_pixel); /* bcBitCount */
275
276
  if (JFWRITE(dest->pub.output_file, bmpfileheader, 14) != (size_t) 14)
277
    ERREXIT(cinfo, JERR_FILE_WRITE);
278
  if (JFWRITE(dest->pub.output_file, bmpcoreheader, 12) != (size_t) 12)
279
    ERREXIT(cinfo, JERR_FILE_WRITE);
280
281
  if (cmap_entries > 0)
282
    write_colormap(cinfo, dest, cmap_entries, 3);
283
}
284
285
286
/*
287
 * Write the colormap.
288
 * Windows uses BGR0 map entries; OS/2 uses BGR entries.
289
 */
290
291
LOCAL(void)
292
write_colormap (j_decompress_ptr cinfo, bmp_dest_ptr dest,
293
		int map_colors, int map_entry_size)
294
{
295
  JSAMPARRAY colormap = cinfo->colormap;
296
  int num_colors = cinfo->actual_number_of_colors;
297
  FILE * outfile = dest->pub.output_file;
298
  int i;
299
300
  if (colormap != NULL) {
301
    if (cinfo->out_color_components == 3) {
302
      /* Normal case with RGB colormap */
303
      for (i = 0; i < num_colors; i++) {
304
	putc(GETJSAMPLE(colormap[2][i]), outfile);
305
	putc(GETJSAMPLE(colormap[1][i]), outfile);
306
	putc(GETJSAMPLE(colormap[0][i]), outfile);
307
	if (map_entry_size == 4)
308
	  putc(0, outfile);
309
      }
310
    } else {
311
      /* Grayscale colormap (only happens with grayscale quantization) */
312
      for (i = 0; i < num_colors; i++) {
313
	putc(GETJSAMPLE(colormap[0][i]), outfile);
314
	putc(GETJSAMPLE(colormap[0][i]), outfile);
315
	putc(GETJSAMPLE(colormap[0][i]), outfile);
316
	if (map_entry_size == 4)
317
	  putc(0, outfile);
318
      }
319
    }
320
  } else {
321
    /* If no colormap, must be grayscale data.  Generate a linear "map". */
322
    for (i = 0; i < 256; i++) {
323
      putc(i, outfile);
324
      putc(i, outfile);
325
      putc(i, outfile);
326
      if (map_entry_size == 4)
327
	putc(0, outfile);
328
    }
329
  }
330
  /* Pad colormap with zeros to ensure specified number of colormap entries */ 
331
  if (i > map_colors)
332
    ERREXIT1(cinfo, JERR_TOO_MANY_COLORS, i);
333
  for (; i < map_colors; i++) {
334
    putc(0, outfile);
335
    putc(0, outfile);
336
    putc(0, outfile);
337
    if (map_entry_size == 4)
338
      putc(0, outfile);
339
  }
340
}
341
342
343
METHODDEF(void)
344
finish_output_bmp (j_decompress_ptr cinfo, djpeg_dest_ptr dinfo)
345
{
346
  bmp_dest_ptr dest = (bmp_dest_ptr) dinfo;
347
  register FILE * outfile = dest->pub.output_file;
348
  JSAMPARRAY image_ptr;
349
  register JSAMPROW data_ptr;
350
  JDIMENSION row;
351
  register JDIMENSION col;
352
  cd_progress_ptr progress = (cd_progress_ptr) cinfo->progress;
353
354
  /* Write the header and colormap */
355
  if (dest->is_os2)
356
    write_os2_header(cinfo, dest);
357
  else
358
    write_bmp_header(cinfo, dest);
359
360
  /* Write the file body from our virtual array */
361
  for (row = cinfo->output_height; row > 0; row--) {
362
    if (progress != NULL) {
363
      progress->pub.pass_counter = (long) (cinfo->output_height - row);
364
      progress->pub.pass_limit = (long) cinfo->output_height;
365
      (*progress->pub.progress_monitor) ((j_common_ptr) cinfo);
366
    }
367
    image_ptr = (*cinfo->mem->access_virt_sarray)
368
      ((j_common_ptr) cinfo, dest->whole_image, row-1, (JDIMENSION) 1, FALSE);
369
    data_ptr = image_ptr[0];
370
    for (col = dest->row_width; col > 0; col--) {
371
      putc(GETJSAMPLE(*data_ptr), outfile);
372
      data_ptr++;
373
    }
374
  }
375
  if (progress != NULL)
376
    progress->completed_extra_passes++;
377
378
  /* Make sure we wrote the output file OK */
379
  fflush(outfile);
380
  if (ferror(outfile))
381
    ERREXIT(cinfo, JERR_FILE_WRITE);
382
}
383
384
385
/*
386
 * The module selection routine for BMP format output.
387
 */
388
389
GLOBAL(djpeg_dest_ptr)
390
jinit_write_bmp (j_decompress_ptr cinfo, boolean is_os2)
391
{
392
  bmp_dest_ptr dest;
393
  JDIMENSION row_width;
394
395
  /* Create module interface object, fill in method pointers */
396
  dest = (bmp_dest_ptr)
397
      (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
398
				  SIZEOF(bmp_dest_struct));
399
  dest->pub.start_output = start_output_bmp;
400
  dest->pub.finish_output = finish_output_bmp;
401
  dest->is_os2 = is_os2;
402
403
  if (cinfo->out_color_space == JCS_GRAYSCALE) {
404
    dest->pub.put_pixel_rows = put_gray_rows;
405
  } else if (cinfo->out_color_space == JCS_RGB) {
406
    if (cinfo->quantize_colors)
407
      dest->pub.put_pixel_rows = put_gray_rows;
408
    else
409
      dest->pub.put_pixel_rows = put_pixel_rows;
410
  } else {
411
    ERREXIT(cinfo, JERR_BMP_COLORSPACE);
412
  }
413
414
  /* Calculate output image dimensions so we can allocate space */
415
  jpeg_calc_output_dimensions(cinfo);
416
417
  /* Determine width of rows in the BMP file (padded to 4-byte boundary). */
418
  row_width = cinfo->output_width * cinfo->output_components;
419
  dest->data_width = row_width;
420
  while ((row_width & 3) != 0) row_width++;
421
  dest->row_width = row_width;
422
  dest->pad_bytes = (int) (row_width - dest->data_width);
423
424
  /* Allocate space for inversion array, prepare for write pass */
425
  dest->whole_image = (*cinfo->mem->request_virt_sarray)
426
    ((j_common_ptr) cinfo, JPOOL_IMAGE, FALSE,
427
     row_width, cinfo->output_height, (JDIMENSION) 1);
428
  dest->cur_output_row = 0;
429
  if (cinfo->progress != NULL) {
430
    cd_progress_ptr progress = (cd_progress_ptr) cinfo->progress;
431
    progress->total_extra_passes++; /* count file input as separate pass */
432
  }
433
434
  /* Create decompressor output buffer. */
435
  dest->pub.buffer = (*cinfo->mem->alloc_sarray)
436
    ((j_common_ptr) cinfo, JPOOL_IMAGE, row_width, (JDIMENSION) 1);
437
  dest->pub.buffer_height = 1;
438
439
  return (djpeg_dest_ptr) dest;
440
}
441
442
#endif /* BMP_SUPPORTED */
(-)a/jpeg/wrgif.c (+399 lines)
Line     Link Here 
Line 0    Link Here 
1
/*
2
 * wrgif.c
3
 *
4
 * Copyright (C) 1991-1997, Thomas G. Lane.
5
 * This file is part of the Independent JPEG Group's software.
6
 * For conditions of distribution and use, see the accompanying README file.
7
 *
8
 * This file contains routines to write output images in GIF format.
9
 *
10
 **************************************************************************
11
 * NOTE: to avoid entanglements with Unisys' patent on LZW compression,   *
12
 * this code has been modified to output "uncompressed GIF" files.        *
13
 * There is no trace of the LZW algorithm in this file.                   *
14
 **************************************************************************
15
 *
16
 * These routines may need modification for non-Unix environments or
17
 * specialized applications.  As they stand, they assume output to
18
 * an ordinary stdio stream.
19
 */
20
21
/*
22
 * This code is loosely based on ppmtogif from the PBMPLUS distribution
23
 * of Feb. 1991.  That file contains the following copyright notice:
24
 *    Based on GIFENCODE by David Rowley <mgardi@watdscu.waterloo.edu>.
25
 *    Lempel-Ziv compression based on "compress" by Spencer W. Thomas et al.
26
 *    Copyright (C) 1989 by Jef Poskanzer.
27
 *    Permission to use, copy, modify, and distribute this software and its
28
 *    documentation for any purpose and without fee is hereby granted, provided
29
 *    that the above copyright notice appear in all copies and that both that
30
 *    copyright notice and this permission notice appear in supporting
31
 *    documentation.  This software is provided "as is" without express or
32
 *    implied warranty.
33
 *
34
 * We are also required to state that
35
 *    "The Graphics Interchange Format(c) is the Copyright property of
36
 *    CompuServe Incorporated. GIF(sm) is a Service Mark property of
37
 *    CompuServe Incorporated."
38
 */
39
40
#include "cdjpeg.h"		/* Common decls for cjpeg/djpeg applications */
41
42
#ifdef GIF_SUPPORTED
43
44
45
/* Private version of data destination object */
46
47
typedef struct {
48
  struct djpeg_dest_struct pub;	/* public fields */
49
50
  j_decompress_ptr cinfo;	/* back link saves passing separate parm */
51
52
  /* State for packing variable-width codes into a bitstream */
53
  int n_bits;			/* current number of bits/code */
54
  int maxcode;			/* maximum code, given n_bits */
55
  INT32 cur_accum;		/* holds bits not yet output */
56
  int cur_bits;			/* # of bits in cur_accum */
57
58
  /* State for GIF code assignment */
59
  int ClearCode;		/* clear code (doesn't change) */
60
  int EOFCode;			/* EOF code (ditto) */
61
  int code_counter;		/* counts output symbols */
62
63
  /* GIF data packet construction buffer */
64
  int bytesinpkt;		/* # of bytes in current packet */
65
  char packetbuf[256];		/* workspace for accumulating packet */
66
67
} gif_dest_struct;
68
69
typedef gif_dest_struct * gif_dest_ptr;
70
71
/* Largest value that will fit in N bits */
72
#define MAXCODE(n_bits)	((1 << (n_bits)) - 1)
73
74
75
/*
76
 * Routines to package finished data bytes into GIF data blocks.
77
 * A data block consists of a count byte (1..255) and that many data bytes.
78
 */
79
80
LOCAL(void)
81
flush_packet (gif_dest_ptr dinfo)
82
/* flush any accumulated data */
83
{
84
  if (dinfo->bytesinpkt > 0) {	/* never write zero-length packet */
85
    dinfo->packetbuf[0] = (char) dinfo->bytesinpkt++;
86
    if (JFWRITE(dinfo->pub.output_file, dinfo->packetbuf, dinfo->bytesinpkt)
87
	!= (size_t) dinfo->bytesinpkt)
88
      ERREXIT(dinfo->cinfo, JERR_FILE_WRITE);
89
    dinfo->bytesinpkt = 0;
90
  }
91
}
92
93
94
/* Add a character to current packet; flush to disk if necessary */
95
#define CHAR_OUT(dinfo,c)  \
96
	{ (dinfo)->packetbuf[++(dinfo)->bytesinpkt] = (char) (c);  \
97
	    if ((dinfo)->bytesinpkt >= 255)  \
98
	      flush_packet(dinfo);  \
99
	}
100
101
102
/* Routine to convert variable-width codes into a byte stream */
103
104
LOCAL(void)
105
output (gif_dest_ptr dinfo, int code)
106
/* Emit a code of n_bits bits */
107
/* Uses cur_accum and cur_bits to reblock into 8-bit bytes */
108
{
109
  dinfo->cur_accum |= ((INT32) code) << dinfo->cur_bits;
110
  dinfo->cur_bits += dinfo->n_bits;
111
112
  while (dinfo->cur_bits >= 8) {
113
    CHAR_OUT(dinfo, dinfo->cur_accum & 0xFF);
114
    dinfo->cur_accum >>= 8;
115
    dinfo->cur_bits -= 8;
116
  }
117
}
118
119
120
/* The pseudo-compression algorithm.
121
 *
122
 * In this module we simply output each pixel value as a separate symbol;
123
 * thus, no compression occurs.  In fact, there is expansion of one bit per
124
 * pixel, because we use a symbol width one bit wider than the pixel width.
125
 *
126
 * GIF ordinarily uses variable-width symbols, and the decoder will expect
127
 * to ratchet up the symbol width after a fixed number of symbols.
128
 * To simplify the logic and keep the expansion penalty down, we emit a
129
 * GIF Clear code to reset the decoder just before the width would ratchet up.
130
 * Thus, all the symbols in the output file will have the same bit width.
131
 * Note that emitting the Clear codes at the right times is a mere matter of
132
 * counting output symbols and is in no way dependent on the LZW patent.
133
 *
134
 * With a small basic pixel width (low color count), Clear codes will be
135
 * needed very frequently, causing the file to expand even more.  So this
136
 * simplistic approach wouldn't work too well on bilevel images, for example.
137
 * But for output of JPEG conversions the pixel width will usually be 8 bits
138
 * (129 to 256 colors), so the overhead added by Clear symbols is only about
139
 * one symbol in every 256.
140
 */
141
142
LOCAL(void)
143
compress_init (gif_dest_ptr dinfo, int i_bits)
144
/* Initialize pseudo-compressor */
145
{
146
  /* init all the state variables */
147
  dinfo->n_bits = i_bits;
148
  dinfo->maxcode = MAXCODE(dinfo->n_bits);
149
  dinfo->ClearCode = (1 << (i_bits - 1));
150
  dinfo->EOFCode = dinfo->ClearCode + 1;
151
  dinfo->code_counter = dinfo->ClearCode + 2;
152
  /* init output buffering vars */
153
  dinfo->bytesinpkt = 0;
154
  dinfo->cur_accum = 0;
155
  dinfo->cur_bits = 0;
156
  /* GIF specifies an initial Clear code */
157
  output(dinfo, dinfo->ClearCode);
158
}
159
160
161
LOCAL(void)
162
compress_pixel (gif_dest_ptr dinfo, int c)
163
/* Accept and "compress" one pixel value.
164
 * The given value must be less than n_bits wide.
165
 */
166
{
167
  /* Output the given pixel value as a symbol. */
168
  output(dinfo, c);
169
  /* Issue Clear codes often enough to keep the reader from ratcheting up
170
   * its symbol size.
171
   */
172
  if (dinfo->code_counter < dinfo->maxcode) {
173
    dinfo->code_counter++;
174
  } else {
175
    output(dinfo, dinfo->ClearCode);
176
    dinfo->code_counter = dinfo->ClearCode + 2;	/* reset the counter */
177
  }
178
}
179
180
181
LOCAL(void)
182
compress_term (gif_dest_ptr dinfo)
183
/* Clean up at end */
184
{
185
  /* Send an EOF code */
186
  output(dinfo, dinfo->EOFCode);
187
  /* Flush the bit-packing buffer */
188
  if (dinfo->cur_bits > 0) {
189
    CHAR_OUT(dinfo, dinfo->cur_accum & 0xFF);
190
  }
191
  /* Flush the packet buffer */
192
  flush_packet(dinfo);
193
}
194
195
196
/* GIF header construction */
197
198
199
LOCAL(void)
200
put_word (gif_dest_ptr dinfo, unsigned int w)
201
/* Emit a 16-bit word, LSB first */
202
{
203
  putc(w & 0xFF, dinfo->pub.output_file);
204
  putc((w >> 8) & 0xFF, dinfo->pub.output_file);
205
}
206
207
208
LOCAL(void)
209
put_3bytes (gif_dest_ptr dinfo, int val)
210
/* Emit 3 copies of same byte value --- handy subr for colormap construction */
211
{
212
  putc(val, dinfo->pub.output_file);
213
  putc(val, dinfo->pub.output_file);
214
  putc(val, dinfo->pub.output_file);
215
}
216
217
218
LOCAL(void)
219
emit_header (gif_dest_ptr dinfo, int num_colors, JSAMPARRAY colormap)
220
/* Output the GIF file header, including color map */
221
/* If colormap==NULL, synthesize a gray-scale colormap */
222
{
223
  int BitsPerPixel, ColorMapSize, InitCodeSize, FlagByte;
224
  int cshift = dinfo->cinfo->data_precision - 8;
225
  int i;
226
227
  if (num_colors > 256)
228
    ERREXIT1(dinfo->cinfo, JERR_TOO_MANY_COLORS, num_colors);
229
  /* Compute bits/pixel and related values */
230
  BitsPerPixel = 1;
231
  while (num_colors > (1 << BitsPerPixel))
232
    BitsPerPixel++;
233
  ColorMapSize = 1 << BitsPerPixel;
234
  if (BitsPerPixel <= 1)
235
    InitCodeSize = 2;
236
  else
237
    InitCodeSize = BitsPerPixel;
238
  /*
239
   * Write the GIF header.
240
   * Note that we generate a plain GIF87 header for maximum compatibility.
241
   */
242
  putc('G', dinfo->pub.output_file);
243
  putc('I', dinfo->pub.output_file);
244
  putc('F', dinfo->pub.output_file);
245
  putc('8', dinfo->pub.output_file);
246
  putc('7', dinfo->pub.output_file);
247
  putc('a', dinfo->pub.output_file);
248
  /* Write the Logical Screen Descriptor */
249
  put_word(dinfo, (unsigned int) dinfo->cinfo->output_width);
250
  put_word(dinfo, (unsigned int) dinfo->cinfo->output_height);
251
  FlagByte = 0x80;		/* Yes, there is a global color table */
252
  FlagByte |= (BitsPerPixel-1) << 4; /* color resolution */
253
  FlagByte |= (BitsPerPixel-1);	/* size of global color table */
254
  putc(FlagByte, dinfo->pub.output_file);
255
  putc(0, dinfo->pub.output_file); /* Background color index */
256
  putc(0, dinfo->pub.output_file); /* Reserved (aspect ratio in GIF89) */
257
  /* Write the Global Color Map */
258
  /* If the color map is more than 8 bits precision, */
259
  /* we reduce it to 8 bits by shifting */
260
  for (i=0; i < ColorMapSize; i++) {
261
    if (i < num_colors) {
262
      if (colormap != NULL) {
263
	if (dinfo->cinfo->out_color_space == JCS_RGB) {
264
	  /* Normal case: RGB color map */
265
	  putc(GETJSAMPLE(colormap[0][i]) >> cshift, dinfo->pub.output_file);
266
	  putc(GETJSAMPLE(colormap[1][i]) >> cshift, dinfo->pub.output_file);
267
	  putc(GETJSAMPLE(colormap[2][i]) >> cshift, dinfo->pub.output_file);
268
	} else {
269
	  /* Grayscale "color map": possible if quantizing grayscale image */
270
	  put_3bytes(dinfo, GETJSAMPLE(colormap[0][i]) >> cshift);
271
	}
272
      } else {
273
	/* Create a gray-scale map of num_colors values, range 0..255 */
274
	put_3bytes(dinfo, (i * 255 + (num_colors-1)/2) / (num_colors-1));
275
      }
276
    } else {
277
      /* fill out the map to a power of 2 */
278
      put_3bytes(dinfo, 0);
279
    }
280
  }
281
  /* Write image separator and Image Descriptor */
282
  putc(',', dinfo->pub.output_file); /* separator */
283
  put_word(dinfo, 0);		/* left/top offset */
284
  put_word(dinfo, 0);
285
  put_word(dinfo, (unsigned int) dinfo->cinfo->output_width); /* image size */
286
  put_word(dinfo, (unsigned int) dinfo->cinfo->output_height);
287
  /* flag byte: not interlaced, no local color map */
288
  putc(0x00, dinfo->pub.output_file);
289
  /* Write Initial Code Size byte */
290
  putc(InitCodeSize, dinfo->pub.output_file);
291
292
  /* Initialize for "compression" of image data */
293
  compress_init(dinfo, InitCodeSize+1);
294
}
295
296
297
/*
298
 * Startup: write the file header.
299
 */
300
301
METHODDEF(void)
302
start_output_gif (j_decompress_ptr cinfo, djpeg_dest_ptr dinfo)
303
{
304
  gif_dest_ptr dest = (gif_dest_ptr) dinfo;
305
306
  if (cinfo->quantize_colors)
307
    emit_header(dest, cinfo->actual_number_of_colors, cinfo->colormap);
308
  else
309
    emit_header(dest, 256, (JSAMPARRAY) NULL);
310
}
311
312
313
/*
314
 * Write some pixel data.
315
 * In this module rows_supplied will always be 1.
316
 */
317
318
METHODDEF(void)
319
put_pixel_rows (j_decompress_ptr cinfo, djpeg_dest_ptr dinfo,
320
		JDIMENSION rows_supplied)
321
{
322
  gif_dest_ptr dest = (gif_dest_ptr) dinfo;
323
  register JSAMPROW ptr;
324
  register JDIMENSION col;
325
326
  ptr = dest->pub.buffer[0];
327
  for (col = cinfo->output_width; col > 0; col--) {
328
    compress_pixel(dest, GETJSAMPLE(*ptr++));
329
  }
330
}
331
332
333
/*
334
 * Finish up at the end of the file.
335
 */
336
337
METHODDEF(void)
338
finish_output_gif (j_decompress_ptr cinfo, djpeg_dest_ptr dinfo)
339
{
340
  gif_dest_ptr dest = (gif_dest_ptr) dinfo;
341
342
  /* Flush "compression" mechanism */
343
  compress_term(dest);
344
  /* Write a zero-length data block to end the series */
345
  putc(0, dest->pub.output_file);
346
  /* Write the GIF terminator mark */
347
  putc(';', dest->pub.output_file);
348
  /* Make sure we wrote the output file OK */
349
  fflush(dest->pub.output_file);
350
  if (ferror(dest->pub.output_file))
351
    ERREXIT(cinfo, JERR_FILE_WRITE);
352
}
353
354
355
/*
356
 * The module selection routine for GIF format output.
357
 */
358
359
GLOBAL(djpeg_dest_ptr)
360
jinit_write_gif (j_decompress_ptr cinfo)
361
{
362
  gif_dest_ptr dest;
363
364
  /* Create module interface object, fill in method pointers */
365
  dest = (gif_dest_ptr)
366
      (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
367
				  SIZEOF(gif_dest_struct));
368
  dest->cinfo = cinfo;		/* make back link for subroutines */
369
  dest->pub.start_output = start_output_gif;
370
  dest->pub.put_pixel_rows = put_pixel_rows;
371
  dest->pub.finish_output = finish_output_gif;
372
373
  if (cinfo->out_color_space != JCS_GRAYSCALE &&
374
      cinfo->out_color_space != JCS_RGB)
375
    ERREXIT(cinfo, JERR_GIF_COLORSPACE);
376
377
  /* Force quantization if color or if > 8 bits input */
378
  if (cinfo->out_color_space != JCS_GRAYSCALE || cinfo->data_precision > 8) {
379
    /* Force quantization to at most 256 colors */
380
    cinfo->quantize_colors = TRUE;
381
    if (cinfo->desired_number_of_colors > 256)
382
      cinfo->desired_number_of_colors = 256;
383
  }
384
385
  /* Calculate output image dimensions so we can allocate space */
386
  jpeg_calc_output_dimensions(cinfo);
387
388
  if (cinfo->output_components != 1) /* safety check: just one component? */
389
    ERREXIT(cinfo, JERR_GIF_BUG);
390
391
  /* Create decompressor output buffer. */
392
  dest->pub.buffer = (*cinfo->mem->alloc_sarray)
393
    ((j_common_ptr) cinfo, JPOOL_IMAGE, cinfo->output_width, (JDIMENSION) 1);
394
  dest->pub.buffer_height = 1;
395
396
  return (djpeg_dest_ptr) dest;
397
}
398
399
#endif /* GIF_SUPPORTED */
(-)a/jpeg/wrjpgcom.1 (+103 lines)
Line     Link Here 
Line 0    Link Here 
1
.TH WRJPGCOM 1 "15 June 1995"
2
.SH NAME
3
wrjpgcom \- insert text comments into a JPEG file
4
.SH SYNOPSIS
5
.B wrjpgcom
6
[
7
.B \-replace
8
]
9
[
10
.BI \-comment " text"
11
]
12
[
13
.BI \-cfile " name"
14
]
15
[
16
.I filename
17
]
18
.LP
19
.SH DESCRIPTION
20
.LP
21
.B wrjpgcom
22
reads the named JPEG/JFIF file, or the standard input if no file is named,
23
and generates a new JPEG/JFIF file on standard output.  A comment block is
24
added to the file.
25
.PP
26
The JPEG standard allows "comment" (COM) blocks to occur within a JPEG file.
27
Although the standard doesn't actually define what COM blocks are for, they
28
are widely used to hold user-supplied text strings.  This lets you add
29
annotations, titles, index terms, etc to your JPEG files, and later retrieve
30
them as text.  COM blocks do not interfere with the image stored in the JPEG
31
file.  The maximum size of a COM block is 64K, but you can have as many of
32
them as you like in one JPEG file.
33
.PP
34
.B wrjpgcom
35
adds a COM block, containing text you provide, to a JPEG file.
36
Ordinarily, the COM block is added after any existing COM blocks; but you
37
can delete the old COM blocks if you wish.
38
.SH OPTIONS
39
Switch names may be abbreviated, and are not case sensitive.
40
.TP
41
.B \-replace
42
Delete any existing COM blocks from the file.
43
.TP
44
.BI \-comment " text"
45
Supply text for new COM block on command line.
46
.TP
47
.BI \-cfile " name"
48
Read text for new COM block from named file.
49
.PP
50
If you have only one line of comment text to add, you can provide it on the
51
command line with
52
.BR \-comment .
53
The comment text must be surrounded with quotes so that it is treated as a
54
single argument.  Longer comments can be read from a text file.
55
.PP
56
If you give neither
57
.B \-comment
58
nor
59
.BR \-cfile ,
60
then
61
.B wrjpgcom
62
will read the comment text from standard input.  (In this case an input image
63
file name MUST be supplied, so that the source JPEG file comes from somewhere
64
else.)  You can enter multiple lines, up to 64KB worth.  Type an end-of-file
65
indicator (usually control-D) to terminate the comment text entry.
66
.PP
67
.B wrjpgcom
68
will not add a COM block if the provided comment string is empty.  Therefore
69
\fB\-replace \-comment ""\fR can be used to delete all COM blocks from a file.
70
.SH EXAMPLES
71
.LP
72
Add a short comment to in.jpg, producing out.jpg:
73
.IP
74
.B wrjpgcom \-c
75
\fI"View of my back yard" in.jpg
76
.B >
77
.I out.jpg
78
.PP
79
Attach a long comment previously stored in comment.txt:
80
.IP
81
.B wrjpgcom
82
.I in.jpg
83
.B <
84
.I comment.txt
85
.B >
86
.I out.jpg
87
.PP
88
or equivalently
89
.IP
90
.B wrjpgcom
91
.B -cfile
92
.I comment.txt
93
.B <
94
.I in.jpg
95
.B >
96
.I out.jpg
97
.SH SEE ALSO
98
.BR cjpeg (1),
99
.BR djpeg (1),
100
.BR jpegtran (1),
101
.BR rdjpgcom (1)
102
.SH AUTHOR
103
Independent JPEG Group
(-)a/jpeg/wrjpgcom.c (+583 lines)
Line     Link Here 
Line 0    Link Here 
1
/*
2
 * wrjpgcom.c
3
 *
4
 * Copyright (C) 1994-1997, Thomas G. Lane.
5
 * This file is part of the Independent JPEG Group's software.
6
 * For conditions of distribution and use, see the accompanying README file.
7
 *
8
 * This file contains a very simple stand-alone application that inserts
9
 * user-supplied text as a COM (comment) marker in a JFIF file.
10
 * This may be useful as an example of the minimum logic needed to parse
11
 * JPEG markers.
12
 */
13
14
#define JPEG_CJPEG_DJPEG	/* to get the command-line config symbols */
15
#include "jinclude.h"		/* get auto-config symbols, <stdio.h> */
16
17
#ifndef HAVE_STDLIB_H		/* <stdlib.h> should declare malloc() */
18
extern void * malloc ();
19
#endif
20
#include <ctype.h>		/* to declare isupper(), tolower() */
21
#ifdef USE_SETMODE
22
#include <fcntl.h>		/* to declare setmode()'s parameter macros */
23
/* If you have setmode() but not <io.h>, just delete this line: */
24
#include <io.h>			/* to declare setmode() */
25
#endif
26
27
#ifdef USE_CCOMMAND		/* command-line reader for Macintosh */
28
#ifdef __MWERKS__
29
#include <SIOUX.h>              /* Metrowerks needs this */
30
#include <console.h>		/* ... and this */
31
#endif
32
#ifdef THINK_C
33
#include <console.h>		/* Think declares it here */
34
#endif
35
#endif
36
37
#ifdef DONT_USE_B_MODE		/* define mode parameters for fopen() */
38
#define READ_BINARY	"r"
39
#define WRITE_BINARY	"w"
40
#else
41
#ifdef VMS			/* VMS is very nonstandard */
42
#define READ_BINARY	"rb", "ctx=stm"
43
#define WRITE_BINARY	"wb", "ctx=stm"
44
#else				/* standard ANSI-compliant case */
45
#define READ_BINARY	"rb"
46
#define WRITE_BINARY	"wb"
47
#endif
48
#endif
49
50
#ifndef EXIT_FAILURE		/* define exit() codes if not provided */
51
#define EXIT_FAILURE  1
52
#endif
53
#ifndef EXIT_SUCCESS
54
#ifdef VMS
55
#define EXIT_SUCCESS  1		/* VMS is very nonstandard */
56
#else
57
#define EXIT_SUCCESS  0
58
#endif
59
#endif
60
61
/* Reduce this value if your malloc() can't allocate blocks up to 64K.
62
 * On DOS, compiling in large model is usually a better solution.
63
 */
64
65
#ifndef MAX_COM_LENGTH
66
#define MAX_COM_LENGTH 65000L	/* must be <= 65533 in any case */
67
#endif
68
69
70
/*
71
 * These macros are used to read the input file and write the output file.
72
 * To reuse this code in another application, you might need to change these.
73
 */
74
75
static FILE * infile;		/* input JPEG file */
76
77
/* Return next input byte, or EOF if no more */
78
#define NEXTBYTE()  getc(infile)
79
80
static FILE * outfile;		/* output JPEG file */
81
82
/* Emit an output byte */
83
#define PUTBYTE(x)  putc((x), outfile)
84
85
86
/* Error exit handler */
87
#define ERREXIT(msg)  (fprintf(stderr, "%s\n", msg), exit(EXIT_FAILURE))
88
89
90
/* Read one byte, testing for EOF */
91
static int
92
read_1_byte (void)
93
{
94
  int c;
95
96
  c = NEXTBYTE();
97
  if (c == EOF)
98
    ERREXIT("Premature EOF in JPEG file");
99
  return c;
100
}
101
102
/* Read 2 bytes, convert to unsigned int */
103
/* All 2-byte quantities in JPEG markers are MSB first */
104
static unsigned int
105
read_2_bytes (void)
106
{
107
  int c1, c2;
108
109
  c1 = NEXTBYTE();
110
  if (c1 == EOF)
111
    ERREXIT("Premature EOF in JPEG file");
112
  c2 = NEXTBYTE();
113
  if (c2 == EOF)
114
    ERREXIT("Premature EOF in JPEG file");
115
  return (((unsigned int) c1) << 8) + ((unsigned int) c2);
116
}
117
118
119
/* Routines to write data to output file */
120
121
static void
122
write_1_byte (int c)
123
{
124
  PUTBYTE(c);
125
}
126
127
static void
128
write_2_bytes (unsigned int val)
129
{
130
  PUTBYTE((val >> 8) & 0xFF);
131
  PUTBYTE(val & 0xFF);
132
}
133
134
static void
135
write_marker (int marker)
136
{
137
  PUTBYTE(0xFF);
138
  PUTBYTE(marker);
139
}
140
141
static void
142
copy_rest_of_file (void)
143
{
144
  int c;
145
146
  while ((c = NEXTBYTE()) != EOF)
147
    PUTBYTE(c);
148
}
149
150
151
/*
152
 * JPEG markers consist of one or more 0xFF bytes, followed by a marker
153
 * code byte (which is not an FF).  Here are the marker codes of interest
154
 * in this program.  (See jdmarker.c for a more complete list.)
155
 */
156
157
#define M_SOF0  0xC0		/* Start Of Frame N */
158
#define M_SOF1  0xC1		/* N indicates which compression process */
159
#define M_SOF2  0xC2		/* Only SOF0-SOF2 are now in common use */
160
#define M_SOF3  0xC3
161
#define M_SOF5  0xC5		/* NB: codes C4 and CC are NOT SOF markers */
162
#define M_SOF6  0xC6
163
#define M_SOF7  0xC7
164
#define M_SOF9  0xC9
165
#define M_SOF10 0xCA
166
#define M_SOF11 0xCB
167
#define M_SOF13 0xCD
168
#define M_SOF14 0xCE
169
#define M_SOF15 0xCF
170
#define M_SOI   0xD8		/* Start Of Image (beginning of datastream) */
171
#define M_EOI   0xD9		/* End Of Image (end of datastream) */
172
#define M_SOS   0xDA		/* Start Of Scan (begins compressed data) */
173
#define M_COM   0xFE		/* COMment */
174
175
176
/*
177
 * Find the next JPEG marker and return its marker code.
178
 * We expect at least one FF byte, possibly more if the compressor used FFs
179
 * to pad the file.  (Padding FFs will NOT be replicated in the output file.)
180
 * There could also be non-FF garbage between markers.  The treatment of such
181
 * garbage is unspecified; we choose to skip over it but emit a warning msg.
182
 * NB: this routine must not be used after seeing SOS marker, since it will
183
 * not deal correctly with FF/00 sequences in the compressed image data...
184
 */
185
186
static int
187
next_marker (void)
188
{
189
  int c;
190
  int discarded_bytes = 0;
191
192
  /* Find 0xFF byte; count and skip any non-FFs. */
193
  c = read_1_byte();
194
  while (c != 0xFF) {
195
    discarded_bytes++;
196
    c = read_1_byte();
197
  }
198
  /* Get marker code byte, swallowing any duplicate FF bytes.  Extra FFs
199
   * are legal as pad bytes, so don't count them in discarded_bytes.
200
   */
201
  do {
202
    c = read_1_byte();
203
  } while (c == 0xFF);
204
205
  if (discarded_bytes != 0) {
206
    fprintf(stderr, "Warning: garbage data found in JPEG file\n");
207
  }
208
209
  return c;
210
}
211
212
213
/*
214
 * Read the initial marker, which should be SOI.
215
 * For a JFIF file, the first two bytes of the file should be literally
216
 * 0xFF M_SOI.  To be more general, we could use next_marker, but if the
217
 * input file weren't actually JPEG at all, next_marker might read the whole
218
 * file and then return a misleading error message...
219
 */
220
221
static int
222
first_marker (void)
223
{
224
  int c1, c2;
225
226
  c1 = NEXTBYTE();
227
  c2 = NEXTBYTE();
228
  if (c1 != 0xFF || c2 != M_SOI)
229
    ERREXIT("Not a JPEG file");
230
  return c2;
231
}
232
233
234
/*
235
 * Most types of marker are followed by a variable-length parameter segment.
236
 * This routine skips over the parameters for any marker we don't otherwise
237
 * want to process.
238
 * Note that we MUST skip the parameter segment explicitly in order not to
239
 * be fooled by 0xFF bytes that might appear within the parameter segment;
240
 * such bytes do NOT introduce new markers.
241
 */
242
243
static void
244
copy_variable (void)
245
/* Copy an unknown or uninteresting variable-length marker */
246
{
247
  unsigned int length;
248
249
  /* Get the marker parameter length count */
250
  length = read_2_bytes();
251
  write_2_bytes(length);
252
  /* Length includes itself, so must be at least 2 */
253
  if (length < 2)
254
    ERREXIT("Erroneous JPEG marker length");
255
  length -= 2;
256
  /* Skip over the remaining bytes */
257
  while (length > 0) {
258
    write_1_byte(read_1_byte());
259
    length--;
260
  }
261
}
262
263
static void
264
skip_variable (void)
265
/* Skip over an unknown or uninteresting variable-length marker */
266
{
267
  unsigned int length;
268
269
  /* Get the marker parameter length count */
270
  length = read_2_bytes();
271
  /* Length includes itself, so must be at least 2 */
272
  if (length < 2)
273
    ERREXIT("Erroneous JPEG marker length");
274
  length -= 2;
275
  /* Skip over the remaining bytes */
276
  while (length > 0) {
277
    (void) read_1_byte();
278
    length--;
279
  }
280
}
281
282
283
/*
284
 * Parse the marker stream until SOFn or EOI is seen;
285
 * copy data to output, but discard COM markers unless keep_COM is true.
286
 */
287
288
static int
289
scan_JPEG_header (int keep_COM)
290
{
291
  int marker;
292
293
  /* Expect SOI at start of file */
294
  if (first_marker() != M_SOI)
295
    ERREXIT("Expected SOI marker first");
296
  write_marker(M_SOI);
297
298
  /* Scan miscellaneous markers until we reach SOFn. */
299
  for (;;) {
300
    marker = next_marker();
301
    switch (marker) {
302
      /* Note that marker codes 0xC4, 0xC8, 0xCC are not, and must not be,
303
       * treated as SOFn.  C4 in particular is actually DHT.
304
       */
305
    case M_SOF0:		/* Baseline */
306
    case M_SOF1:		/* Extended sequential, Huffman */
307
    case M_SOF2:		/* Progressive, Huffman */
308
    case M_SOF3:		/* Lossless, Huffman */
309
    case M_SOF5:		/* Differential sequential, Huffman */
310
    case M_SOF6:		/* Differential progressive, Huffman */
311
    case M_SOF7:		/* Differential lossless, Huffman */
312
    case M_SOF9:		/* Extended sequential, arithmetic */
313
    case M_SOF10:		/* Progressive, arithmetic */
314
    case M_SOF11:		/* Lossless, arithmetic */
315
    case M_SOF13:		/* Differential sequential, arithmetic */
316
    case M_SOF14:		/* Differential progressive, arithmetic */
317
    case M_SOF15:		/* Differential lossless, arithmetic */
318
      return marker;
319
320
    case M_SOS:			/* should not see compressed data before SOF */
321
      ERREXIT("SOS without prior SOFn");
322
      break;
323
324
    case M_EOI:			/* in case it's a tables-only JPEG stream */
325
      return marker;
326
327
    case M_COM:			/* Existing COM: conditionally discard */
328
      if (keep_COM) {
329
	write_marker(marker);
330
	copy_variable();
331
      } else {
332
	skip_variable();
333
      }
334
      break;
335
336
    default:			/* Anything else just gets copied */
337
      write_marker(marker);
338
      copy_variable();		/* we assume it has a parameter count... */
339
      break;
340
    }
341
  } /* end loop */
342
}
343
344
345
/* Command line parsing code */
346
347
static const char * progname;	/* program name for error messages */
348
349
350
static void
351
usage (void)
352
/* complain about bad command line */
353
{
354
  fprintf(stderr, "wrjpgcom inserts a textual comment in a JPEG file.\n");
355
  fprintf(stderr, "You can add to or replace any existing comment(s).\n");
356
357
  fprintf(stderr, "Usage: %s [switches] ", progname);
358
#ifdef TWO_FILE_COMMANDLINE
359
  fprintf(stderr, "inputfile outputfile\n");
360
#else
361
  fprintf(stderr, "[inputfile]\n");
362
#endif
363
364
  fprintf(stderr, "Switches (names may be abbreviated):\n");
365
  fprintf(stderr, "  -replace         Delete any existing comments\n");
366
  fprintf(stderr, "  -comment \"text\"  Insert comment with given text\n");
367
  fprintf(stderr, "  -cfile name      Read comment from named file\n");
368
  fprintf(stderr, "Notice that you must put quotes around the comment text\n");
369
  fprintf(stderr, "when you use -comment.\n");
370
  fprintf(stderr, "If you do not give either -comment or -cfile on the command line,\n");
371
  fprintf(stderr, "then the comment text is read from standard input.\n");
372
  fprintf(stderr, "It can be multiple lines, up to %u characters total.\n",
373
	  (unsigned int) MAX_COM_LENGTH);
374
#ifndef TWO_FILE_COMMANDLINE
375
  fprintf(stderr, "You must specify an input JPEG file name when supplying\n");
376
  fprintf(stderr, "comment text from standard input.\n");
377
#endif
378
379
  exit(EXIT_FAILURE);
380
}
381
382
383
static int
384
keymatch (char * arg, const char * keyword, int minchars)
385
/* Case-insensitive matching of (possibly abbreviated) keyword switches. */
386
/* keyword is the constant keyword (must be lower case already), */
387
/* minchars is length of minimum legal abbreviation. */
388
{
389
  register int ca, ck;
390
  register int nmatched = 0;
391
392
  while ((ca = *arg++) != '\0') {
393
    if ((ck = *keyword++) == '\0')
394
      return 0;			/* arg longer than keyword, no good */
395
    if (isupper(ca))		/* force arg to lcase (assume ck is already) */
396
      ca = tolower(ca);
397
    if (ca != ck)
398
      return 0;			/* no good */
399
    nmatched++;			/* count matched characters */
400
  }
401
  /* reached end of argument; fail if it's too short for unique abbrev */
402
  if (nmatched < minchars)
403
    return 0;
404
  return 1;			/* A-OK */
405
}
406
407
408
/*
409
 * The main program.
410
 */
411
412
int
413
main (int argc, char **argv)
414
{
415
  int argn;
416
  char * arg;
417
  int keep_COM = 1;
418
  char * comment_arg = NULL;
419
  FILE * comment_file = NULL;
420
  unsigned int comment_length = 0;
421
  int marker;
422
423
  /* On Mac, fetch a command line. */
424
#ifdef USE_CCOMMAND
425
  argc = ccommand(&argv);
426
#endif
427
428
  progname = argv[0];
429
  if (progname == NULL || progname[0] == 0)
430
    progname = "wrjpgcom";	/* in case C library doesn't provide it */
431
432
  /* Parse switches, if any */
433
  for (argn = 1; argn < argc; argn++) {
434
    arg = argv[argn];
435
    if (arg[0] != '-')
436
      break;			/* not switch, must be file name */
437
    arg++;			/* advance over '-' */
438
    if (keymatch(arg, "replace", 1)) {
439
      keep_COM = 0;
440
    } else if (keymatch(arg, "cfile", 2)) {
441
      if (++argn >= argc) usage();
442
      if ((comment_file = fopen(argv[argn], "r")) == NULL) {
443
	fprintf(stderr, "%s: can't open %s\n", progname, argv[argn]);
444
	exit(EXIT_FAILURE);
445
      }
446
    } else if (keymatch(arg, "comment", 1)) {
447
      if (++argn >= argc) usage();
448
      comment_arg = argv[argn];
449
      /* If the comment text starts with '"', then we are probably running
450
       * under MS-DOG and must parse out the quoted string ourselves.  Sigh.
451
       */
452
      if (comment_arg[0] == '"') {
453
	comment_arg = (char *) malloc((size_t) MAX_COM_LENGTH);
454
	if (comment_arg == NULL)
455
	  ERREXIT("Insufficient memory");
456
	strcpy(comment_arg, argv[argn]+1);
457
	for (;;) {
458
	  comment_length = (unsigned int) strlen(comment_arg);
459
	  if (comment_length > 0 && comment_arg[comment_length-1] == '"') {
460
	    comment_arg[comment_length-1] = '\0'; /* zap terminating quote */
461
	    break;
462
	  }
463
	  if (++argn >= argc)
464
	    ERREXIT("Missing ending quote mark");
465
	  strcat(comment_arg, " ");
466
	  strcat(comment_arg, argv[argn]);
467
	}
468
      }
469
      comment_length = (unsigned int) strlen(comment_arg);
470
    } else
471
      usage();
472
  }
473
474
  /* Cannot use both -comment and -cfile. */
475
  if (comment_arg != NULL && comment_file != NULL)
476
    usage();
477
  /* If there is neither -comment nor -cfile, we will read the comment text
478
   * from stdin; in this case there MUST be an input JPEG file name.
479
   */
480
  if (comment_arg == NULL && comment_file == NULL && argn >= argc)
481
    usage();
482
483
  /* Open the input file. */
484
  if (argn < argc) {
485
    if ((infile = fopen(argv[argn], READ_BINARY)) == NULL) {
486
      fprintf(stderr, "%s: can't open %s\n", progname, argv[argn]);
487
      exit(EXIT_FAILURE);
488
    }
489
  } else {
490
    /* default input file is stdin */
491
#ifdef USE_SETMODE		/* need to hack file mode? */
492
    setmode(fileno(stdin), O_BINARY);
493
#endif
494
#ifdef USE_FDOPEN		/* need to re-open in binary mode? */
495
    if ((infile = fdopen(fileno(stdin), READ_BINARY)) == NULL) {
496
      fprintf(stderr, "%s: can't open stdin\n", progname);
497
      exit(EXIT_FAILURE);
498
    }
499
#else
500
    infile = stdin;
501
#endif
502
  }
503
504
  /* Open the output file. */
505
#ifdef TWO_FILE_COMMANDLINE
506
  /* Must have explicit output file name */
507
  if (argn != argc-2) {
508
    fprintf(stderr, "%s: must name one input and one output file\n",
509
	    progname);
510
    usage();
511
  }
512
  if ((outfile = fopen(argv[argn+1], WRITE_BINARY)) == NULL) {
513
    fprintf(stderr, "%s: can't open %s\n", progname, argv[argn+1]);
514
    exit(EXIT_FAILURE);
515
  }
516
#else
517
  /* Unix style: expect zero or one file name */
518
  if (argn < argc-1) {
519
    fprintf(stderr, "%s: only one input file\n", progname);
520
    usage();
521
  }
522
  /* default output file is stdout */
523
#ifdef USE_SETMODE		/* need to hack file mode? */
524
  setmode(fileno(stdout), O_BINARY);
525
#endif
526
#ifdef USE_FDOPEN		/* need to re-open in binary mode? */
527
  if ((outfile = fdopen(fileno(stdout), WRITE_BINARY)) == NULL) {
528
    fprintf(stderr, "%s: can't open stdout\n", progname);
529
    exit(EXIT_FAILURE);
530
  }
531
#else
532
  outfile = stdout;
533
#endif
534
#endif /* TWO_FILE_COMMANDLINE */
535
536
  /* Collect comment text from comment_file or stdin, if necessary */
537
  if (comment_arg == NULL) {
538
    FILE * src_file;
539
    int c;
540
541
    comment_arg = (char *) malloc((size_t) MAX_COM_LENGTH);
542
    if (comment_arg == NULL)
543
      ERREXIT("Insufficient memory");
544
    comment_length = 0;
545
    src_file = (comment_file != NULL ? comment_file : stdin);
546
    while ((c = getc(src_file)) != EOF) {
547
      if (comment_length >= (unsigned int) MAX_COM_LENGTH) {
548
	fprintf(stderr, "Comment text may not exceed %u bytes\n",
549
		(unsigned int) MAX_COM_LENGTH);
550
	exit(EXIT_FAILURE);
551
      }
552
      comment_arg[comment_length++] = (char) c;
553
    }
554
    if (comment_file != NULL)
555
      fclose(comment_file);
556
  }
557
558
  /* Copy JPEG headers until SOFn marker;
559
   * we will insert the new comment marker just before SOFn.
560
   * This (a) causes the new comment to appear after, rather than before,
561
   * existing comments; and (b) ensures that comments come after any JFIF
562
   * or JFXX markers, as required by the JFIF specification.
563
   */
564
  marker = scan_JPEG_header(keep_COM);
565
  /* Insert the new COM marker, but only if nonempty text has been supplied */
566
  if (comment_length > 0) {
567
    write_marker(M_COM);
568
    write_2_bytes(comment_length + 2);
569
    while (comment_length > 0) {
570
      write_1_byte(*comment_arg++);
571
      comment_length--;
572
    }
573
  }
574
  /* Duplicate the remainder of the source file.
575
   * Note that any COM markers occuring after SOF will not be touched.
576
   */
577
  write_marker(marker);
578
  copy_rest_of_file();
579
580
  /* All done. */
581
  exit(EXIT_SUCCESS);
582
  return 0;			/* suppress no-return-value warnings */
583
}
(-)a/jpeg/wrppm.c (+268 lines)
Line     Link Here 
Line 0    Link Here 
1
/*
2
 * wrppm.c
3
 *
4
 * Copyright (C) 1991-1996, Thomas G. Lane.
5
 * This file is part of the Independent JPEG Group's software.
6
 * For conditions of distribution and use, see the accompanying README file.
7
 *
8
 * This file contains routines to write output images in PPM/PGM format.
9
 * The extended 2-byte-per-sample raw PPM/PGM formats are supported.
10
 * The PBMPLUS library is NOT required to compile this software
11
 * (but it is highly useful as a set of PPM image manipulation programs).
12
 *
13
 * These routines may need modification for non-Unix environments or
14
 * specialized applications.  As they stand, they assume output to
15
 * an ordinary stdio stream.
16
 */
17
18
#include "cdjpeg.h"		/* Common decls for cjpeg/djpeg applications */
19
20
#ifdef PPM_SUPPORTED
21
22
23
/*
24
 * For 12-bit JPEG data, we either downscale the values to 8 bits
25
 * (to write standard byte-per-sample PPM/PGM files), or output
26
 * nonstandard word-per-sample PPM/PGM files.  Downscaling is done
27
 * if PPM_NORAWWORD is defined (this can be done in the Makefile
28
 * or in jconfig.h).
29
 * (When the core library supports data precision reduction, a cleaner
30
 * implementation will be to ask for that instead.)
31
 */
32
33
#if BITS_IN_JSAMPLE == 8
34
#define PUTPPMSAMPLE(ptr,v)  *ptr++ = (char) (v)
35
#define BYTESPERSAMPLE 1
36
#define PPM_MAXVAL 255
37
#else
38
#ifdef PPM_NORAWWORD
39
#define PUTPPMSAMPLE(ptr,v)  *ptr++ = (char) ((v) >> (BITS_IN_JSAMPLE-8))
40
#define BYTESPERSAMPLE 1
41
#define PPM_MAXVAL 255
42
#else
43
/* The word-per-sample format always puts the LSB first. */
44
#define PUTPPMSAMPLE(ptr,v)			\
45
	{ register int val_ = v;		\
46
	  *ptr++ = (char) (val_ & 0xFF);	\
47
	  *ptr++ = (char) ((val_ >> 8) & 0xFF);	\
48
	}
49
#define BYTESPERSAMPLE 2
50
#define PPM_MAXVAL ((1<<BITS_IN_JSAMPLE)-1)
51
#endif
52
#endif
53
54
55
/*
56
 * When JSAMPLE is the same size as char, we can just fwrite() the
57
 * decompressed data to the PPM or PGM file.  On PCs, in order to make this
58
 * work the output buffer must be allocated in near data space, because we are
59
 * assuming small-data memory model wherein fwrite() can't reach far memory.
60
 * If you need to process very wide images on a PC, you might have to compile
61
 * in large-memory model, or else replace fwrite() with a putc() loop ---
62
 * which will be much slower.
63
 */
64
65
66
/* Private version of data destination object */
67
68
typedef struct {
69
  struct djpeg_dest_struct pub;	/* public fields */
70
71
  /* Usually these two pointers point to the same place: */
72
  char *iobuffer;		/* fwrite's I/O buffer */
73
  JSAMPROW pixrow;		/* decompressor output buffer */
74
  size_t buffer_width;		/* width of I/O buffer */
75
  JDIMENSION samples_per_row;	/* JSAMPLEs per output row */
76
} ppm_dest_struct;
77
78
typedef ppm_dest_struct * ppm_dest_ptr;
79
80
81
/*
82
 * Write some pixel data.
83
 * In this module rows_supplied will always be 1.
84
 *
85
 * put_pixel_rows handles the "normal" 8-bit case where the decompressor
86
 * output buffer is physically the same as the fwrite buffer.
87
 */
88
89
METHODDEF(void)
90
put_pixel_rows (j_decompress_ptr cinfo, djpeg_dest_ptr dinfo,
91
		JDIMENSION rows_supplied)
92
{
93
  ppm_dest_ptr dest = (ppm_dest_ptr) dinfo;
94
95
  (void) JFWRITE(dest->pub.output_file, dest->iobuffer, dest->buffer_width);
96
}
97
98
99
/*
100
 * This code is used when we have to copy the data and apply a pixel
101
 * format translation.  Typically this only happens in 12-bit mode.
102
 */
103
104
METHODDEF(void)
105
copy_pixel_rows (j_decompress_ptr cinfo, djpeg_dest_ptr dinfo,
106
		 JDIMENSION rows_supplied)
107
{
108
  ppm_dest_ptr dest = (ppm_dest_ptr) dinfo;
109
  register char * bufferptr;
110
  register JSAMPROW ptr;
111
  register JDIMENSION col;
112
113
  ptr = dest->pub.buffer[0];
114
  bufferptr = dest->iobuffer;
115
  for (col = dest->samples_per_row; col > 0; col--) {
116
    PUTPPMSAMPLE(bufferptr, GETJSAMPLE(*ptr++));
117
  }
118
  (void) JFWRITE(dest->pub.output_file, dest->iobuffer, dest->buffer_width);
119
}
120
121
122
/*
123
 * Write some pixel data when color quantization is in effect.
124
 * We have to demap the color index values to straight data.
125
 */
126
127
METHODDEF(void)
128
put_demapped_rgb (j_decompress_ptr cinfo, djpeg_dest_ptr dinfo,
129
		  JDIMENSION rows_supplied)
130
{
131
  ppm_dest_ptr dest = (ppm_dest_ptr) dinfo;
132
  register char * bufferptr;
133
  register int pixval;
134
  register JSAMPROW ptr;
135
  register JSAMPROW color_map0 = cinfo->colormap[0];
136
  register JSAMPROW color_map1 = cinfo->colormap[1];
137
  register JSAMPROW color_map2 = cinfo->colormap[2];
138
  register JDIMENSION col;
139
140
  ptr = dest->pub.buffer[0];
141
  bufferptr = dest->iobuffer;
142
  for (col = cinfo->output_width; col > 0; col--) {
143
    pixval = GETJSAMPLE(*ptr++);
144
    PUTPPMSAMPLE(bufferptr, GETJSAMPLE(color_map0[pixval]));
145
    PUTPPMSAMPLE(bufferptr, GETJSAMPLE(color_map1[pixval]));
146
    PUTPPMSAMPLE(bufferptr, GETJSAMPLE(color_map2[pixval]));
147
  }
148
  (void) JFWRITE(dest->pub.output_file, dest->iobuffer, dest->buffer_width);
149
}
150
151
152
METHODDEF(void)
153
put_demapped_gray (j_decompress_ptr cinfo, djpeg_dest_ptr dinfo,
154
		   JDIMENSION rows_supplied)
155
{
156
  ppm_dest_ptr dest = (ppm_dest_ptr) dinfo;
157
  register char * bufferptr;
158
  register JSAMPROW ptr;
159
  register JSAMPROW color_map = cinfo->colormap[0];
160
  register JDIMENSION col;
161
162
  ptr = dest->pub.buffer[0];
163
  bufferptr = dest->iobuffer;
164
  for (col = cinfo->output_width; col > 0; col--) {
165
    PUTPPMSAMPLE(bufferptr, GETJSAMPLE(color_map[GETJSAMPLE(*ptr++)]));
166
  }
167
  (void) JFWRITE(dest->pub.output_file, dest->iobuffer, dest->buffer_width);
168
}
169
170
171
/*
172
 * Startup: write the file header.
173
 */
174
175
METHODDEF(void)
176
start_output_ppm (j_decompress_ptr cinfo, djpeg_dest_ptr dinfo)
177
{
178
  ppm_dest_ptr dest = (ppm_dest_ptr) dinfo;
179
180
  /* Emit file header */
181
  switch (cinfo->out_color_space) {
182
  case JCS_GRAYSCALE:
183
    /* emit header for raw PGM format */
184
    fprintf(dest->pub.output_file, "P5\n%ld %ld\n%d\n",
185
	    (long) cinfo->output_width, (long) cinfo->output_height,
186
	    PPM_MAXVAL);
187
    break;
188
  case JCS_RGB:
189
    /* emit header for raw PPM format */
190
    fprintf(dest->pub.output_file, "P6\n%ld %ld\n%d\n",
191
	    (long) cinfo->output_width, (long) cinfo->output_height,
192
	    PPM_MAXVAL);
193
    break;
194
  default:
195
    ERREXIT(cinfo, JERR_PPM_COLORSPACE);
196
  }
197
}
198
199
200
/*
201
 * Finish up at the end of the file.
202
 */
203
204
METHODDEF(void)
205
finish_output_ppm (j_decompress_ptr cinfo, djpeg_dest_ptr dinfo)
206
{
207
  /* Make sure we wrote the output file OK */
208
  fflush(dinfo->output_file);
209
  if (ferror(dinfo->output_file))
210
    ERREXIT(cinfo, JERR_FILE_WRITE);
211
}
212
213
214
/*
215
 * The module selection routine for PPM format output.
216
 */
217
218
GLOBAL(djpeg_dest_ptr)
219
jinit_write_ppm (j_decompress_ptr cinfo)
220
{
221
  ppm_dest_ptr dest;
222
223
  /* Create module interface object, fill in method pointers */
224
  dest = (ppm_dest_ptr)
225
      (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
226
				  SIZEOF(ppm_dest_struct));
227
  dest->pub.start_output = start_output_ppm;
228
  dest->pub.finish_output = finish_output_ppm;
229
230
  /* Calculate output image dimensions so we can allocate space */
231
  jpeg_calc_output_dimensions(cinfo);
232
233
  /* Create physical I/O buffer.  Note we make this near on a PC. */
234
  dest->samples_per_row = cinfo->output_width * cinfo->out_color_components;
235
  dest->buffer_width = dest->samples_per_row * (BYTESPERSAMPLE * SIZEOF(char));
236
  dest->iobuffer = (char *) (*cinfo->mem->alloc_small)
237
    ((j_common_ptr) cinfo, JPOOL_IMAGE, dest->buffer_width);
238
239
  if (cinfo->quantize_colors || BITS_IN_JSAMPLE != 8 ||
240
      SIZEOF(JSAMPLE) != SIZEOF(char)) {
241
    /* When quantizing, we need an output buffer for colormap indexes
242
     * that's separate from the physical I/O buffer.  We also need a
243
     * separate buffer if pixel format translation must take place.
244
     */
245
    dest->pub.buffer = (*cinfo->mem->alloc_sarray)
246
      ((j_common_ptr) cinfo, JPOOL_IMAGE,
247
       cinfo->output_width * cinfo->output_components, (JDIMENSION) 1);
248
    dest->pub.buffer_height = 1;
249
    if (! cinfo->quantize_colors)
250
      dest->pub.put_pixel_rows = copy_pixel_rows;
251
    else if (cinfo->out_color_space == JCS_GRAYSCALE)
252
      dest->pub.put_pixel_rows = put_demapped_gray;
253
    else
254
      dest->pub.put_pixel_rows = put_demapped_rgb;
255
  } else {
256
    /* We will fwrite() directly from decompressor output buffer. */
257
    /* Synthesize a JSAMPARRAY pointer structure */
258
    /* Cast here implies near->far pointer conversion on PCs */
259
    dest->pixrow = (JSAMPROW) dest->iobuffer;
260
    dest->pub.buffer = & dest->pixrow;
261
    dest->pub.buffer_height = 1;
262
    dest->pub.put_pixel_rows = put_pixel_rows;
263
  }
264
265
  return (djpeg_dest_ptr) dest;
266
}
267
268
#endif /* PPM_SUPPORTED */
(-)a/jpeg/wrrle.c (+305 lines)
Line     Link Here 
Line 0    Link Here 
1
/*
2
 * wrrle.c
3
 *
4
 * Copyright (C) 1991-1996, Thomas G. Lane.
5
 * This file is part of the Independent JPEG Group's software.
6
 * For conditions of distribution and use, see the accompanying README file.
7
 *
8
 * This file contains routines to write output images in RLE format.
9
 * The Utah Raster Toolkit library is required (version 3.1 or later).
10
 *
11
 * These routines may need modification for non-Unix environments or
12
 * specialized applications.  As they stand, they assume output to
13
 * an ordinary stdio stream.
14
 *
15
 * Based on code contributed by Mike Lijewski,
16
 * with updates from Robert Hutchinson.
17
 */
18
19
#include "cdjpeg.h"		/* Common decls for cjpeg/djpeg applications */
20
21
#ifdef RLE_SUPPORTED
22
23
/* rle.h is provided by the Utah Raster Toolkit. */
24
25
#include <rle.h>
26
27
/*
28
 * We assume that JSAMPLE has the same representation as rle_pixel,
29
 * to wit, "unsigned char".  Hence we can't cope with 12- or 16-bit samples.
30
 */
31
32
#if BITS_IN_JSAMPLE != 8
33
  Sorry, this code only copes with 8-bit JSAMPLEs. /* deliberate syntax err */
34
#endif
35
36
37
/*
38
 * Since RLE stores scanlines bottom-to-top, we have to invert the image
39
 * from JPEG's top-to-bottom order.  To do this, we save the outgoing data
40
 * in a virtual array during put_pixel_row calls, then actually emit the
41
 * RLE file during finish_output.
42
 */
43
44
45
/*
46
 * For now, if we emit an RLE color map then it is always 256 entries long,
47
 * though not all of the entries need be used.
48
 */
49
50
#define CMAPBITS	8
51
#define CMAPLENGTH	(1<<(CMAPBITS))
52
53
typedef struct {
54
  struct djpeg_dest_struct pub; /* public fields */
55
56
  jvirt_sarray_ptr image;	/* virtual array to store the output image */
57
  rle_map *colormap;	 	/* RLE-style color map, or NULL if none */
58
  rle_pixel **rle_row;		/* To pass rows to rle_putrow() */
59
60
} rle_dest_struct;
61
62
typedef rle_dest_struct * rle_dest_ptr;
63
64
/* Forward declarations */
65
METHODDEF(void) rle_put_pixel_rows
66
    JPP((j_decompress_ptr cinfo, djpeg_dest_ptr dinfo,
67
	 JDIMENSION rows_supplied));
68
69
70
/*
71
 * Write the file header.
72
 *
73
 * In this module it's easier to wait till finish_output to write anything.
74
 */
75
76
METHODDEF(void)
77
start_output_rle (j_decompress_ptr cinfo, djpeg_dest_ptr dinfo)
78
{
79
  rle_dest_ptr dest = (rle_dest_ptr) dinfo;
80
  size_t cmapsize;
81
  int i, ci;
82
#ifdef PROGRESS_REPORT
83
  cd_progress_ptr progress = (cd_progress_ptr) cinfo->progress;
84
#endif
85
86
  /*
87
   * Make sure the image can be stored in RLE format.
88
   *
89
   * - RLE stores image dimensions as *signed* 16 bit integers.  JPEG
90
   *   uses unsigned, so we have to check the width.
91
   *
92
   * - Colorspace is expected to be grayscale or RGB.
93
   *
94
   * - The number of channels (components) is expected to be 1 (grayscale/
95
   *   pseudocolor) or 3 (truecolor/directcolor).
96
   *   (could be 2 or 4 if using an alpha channel, but we aren't)
97
   */
98
99
  if (cinfo->output_width > 32767 || cinfo->output_height > 32767)
100
    ERREXIT2(cinfo, JERR_RLE_DIMENSIONS, cinfo->output_width, 
101
	     cinfo->output_height);
102
103
  if (cinfo->out_color_space != JCS_GRAYSCALE &&
104
      cinfo->out_color_space != JCS_RGB)
105
    ERREXIT(cinfo, JERR_RLE_COLORSPACE);
106
107
  if (cinfo->output_components != 1 && cinfo->output_components != 3)
108
    ERREXIT1(cinfo, JERR_RLE_TOOMANYCHANNELS, cinfo->num_components);
109
110
  /* Convert colormap, if any, to RLE format. */
111
112
  dest->colormap = NULL;
113
114
  if (cinfo->quantize_colors) {
115
    /* Allocate storage for RLE-style cmap, zero any extra entries */
116
    cmapsize = cinfo->out_color_components * CMAPLENGTH * SIZEOF(rle_map);
117
    dest->colormap = (rle_map *) (*cinfo->mem->alloc_small)
118
      ((j_common_ptr) cinfo, JPOOL_IMAGE, cmapsize);
119
    MEMZERO(dest->colormap, cmapsize);
120
121
    /* Save away data in RLE format --- note 8-bit left shift! */
122
    /* Shifting would need adjustment for JSAMPLEs wider than 8 bits. */
123
    for (ci = 0; ci < cinfo->out_color_components; ci++) {
124
      for (i = 0; i < cinfo->actual_number_of_colors; i++) {
125
        dest->colormap[ci * CMAPLENGTH + i] =
126
          GETJSAMPLE(cinfo->colormap[ci][i]) << 8;
127
      }
128
    }
129
  }
130
131
  /* Set the output buffer to the first row */
132
  dest->pub.buffer = (*cinfo->mem->access_virt_sarray)
133
    ((j_common_ptr) cinfo, dest->image, (JDIMENSION) 0, (JDIMENSION) 1, TRUE);
134
  dest->pub.buffer_height = 1;
135
136
  dest->pub.put_pixel_rows = rle_put_pixel_rows;
137
138
#ifdef PROGRESS_REPORT
139
  if (progress != NULL) {
140
    progress->total_extra_passes++;  /* count file writing as separate pass */
141
  }
142
#endif
143
}
144
145
146
/*
147
 * Write some pixel data.
148
 *
149
 * This routine just saves the data away in a virtual array.
150
 */
151
152
METHODDEF(void)
153
rle_put_pixel_rows (j_decompress_ptr cinfo, djpeg_dest_ptr dinfo,
154
		    JDIMENSION rows_supplied)
155
{
156
  rle_dest_ptr dest = (rle_dest_ptr) dinfo;
157
158
  if (cinfo->output_scanline < cinfo->output_height) {
159
    dest->pub.buffer = (*cinfo->mem->access_virt_sarray)
160
      ((j_common_ptr) cinfo, dest->image,
161
       cinfo->output_scanline, (JDIMENSION) 1, TRUE);
162
  }
163
}
164
165
/*
166
 * Finish up at the end of the file.
167
 *
168
 * Here is where we really output the RLE file.
169
 */
170
171
METHODDEF(void)
172
finish_output_rle (j_decompress_ptr cinfo, djpeg_dest_ptr dinfo)
173
{
174
  rle_dest_ptr dest = (rle_dest_ptr) dinfo;
175
  rle_hdr header;		/* Output file information */
176
  rle_pixel **rle_row, *red, *green, *blue;
177
  JSAMPROW output_row;
178
  char cmapcomment[80];
179
  int row, col;
180
  int ci;
181
#ifdef PROGRESS_REPORT
182
  cd_progress_ptr progress = (cd_progress_ptr) cinfo->progress;
183
#endif
184
185
  /* Initialize the header info */
186
  header = *rle_hdr_init(NULL);
187
  header.rle_file = dest->pub.output_file;
188
  header.xmin     = 0;
189
  header.xmax     = cinfo->output_width  - 1;
190
  header.ymin     = 0;
191
  header.ymax     = cinfo->output_height - 1;
192
  header.alpha    = 0;
193
  header.ncolors  = cinfo->output_components;
194
  for (ci = 0; ci < cinfo->output_components; ci++) {
195
    RLE_SET_BIT(header, ci);
196
  }
197
  if (cinfo->quantize_colors) {
198
    header.ncmap   = cinfo->out_color_components;
199
    header.cmaplen = CMAPBITS;
200
    header.cmap    = dest->colormap;
201
    /* Add a comment to the output image with the true colormap length. */
202
    sprintf(cmapcomment, "color_map_length=%d", cinfo->actual_number_of_colors);
203
    rle_putcom(cmapcomment, &header);
204
  }
205
206
  /* Emit the RLE header and color map (if any) */
207
  rle_put_setup(&header);
208
209
  /* Now output the RLE data from our virtual array.
210
   * We assume here that (a) rle_pixel is represented the same as JSAMPLE,
211
   * and (b) we are not on a machine where FAR pointers differ from regular.
212
   */
213
214
#ifdef PROGRESS_REPORT
215
  if (progress != NULL) {
216
    progress->pub.pass_limit = cinfo->output_height;
217
    progress->pub.pass_counter = 0;
218
    (*progress->pub.progress_monitor) ((j_common_ptr) cinfo);
219
  }
220
#endif
221
222
  if (cinfo->output_components == 1) {
223
    for (row = cinfo->output_height-1; row >= 0; row--) {
224
      rle_row = (rle_pixel **) (*cinfo->mem->access_virt_sarray)
225
        ((j_common_ptr) cinfo, dest->image,
226
	 (JDIMENSION) row, (JDIMENSION) 1, FALSE);
227
      rle_putrow(rle_row, (int) cinfo->output_width, &header);
228
#ifdef PROGRESS_REPORT
229
      if (progress != NULL) {
230
        progress->pub.pass_counter++;
231
        (*progress->pub.progress_monitor) ((j_common_ptr) cinfo);
232
      }
233
#endif
234
    }
235
  } else {
236
    for (row = cinfo->output_height-1; row >= 0; row--) {
237
      rle_row = (rle_pixel **) dest->rle_row;
238
      output_row = * (*cinfo->mem->access_virt_sarray)
239
        ((j_common_ptr) cinfo, dest->image,
240
	 (JDIMENSION) row, (JDIMENSION) 1, FALSE);
241
      red = rle_row[0];
242
      green = rle_row[1];
243
      blue = rle_row[2];
244
      for (col = cinfo->output_width; col > 0; col--) {
245
        *red++ = GETJSAMPLE(*output_row++);
246
        *green++ = GETJSAMPLE(*output_row++);
247
        *blue++ = GETJSAMPLE(*output_row++);
248
      }
249
      rle_putrow(rle_row, (int) cinfo->output_width, &header);
250
#ifdef PROGRESS_REPORT
251
      if (progress != NULL) {
252
        progress->pub.pass_counter++;
253
        (*progress->pub.progress_monitor) ((j_common_ptr) cinfo);
254
      }
255
#endif
256
    }
257
  }
258
259
#ifdef PROGRESS_REPORT
260
  if (progress != NULL)
261
    progress->completed_extra_passes++;
262
#endif
263
264
  /* Emit file trailer */
265
  rle_puteof(&header);
266
  fflush(dest->pub.output_file);
267
  if (ferror(dest->pub.output_file))
268
    ERREXIT(cinfo, JERR_FILE_WRITE);
269
}
270
271
272
/*
273
 * The module selection routine for RLE format output.
274
 */
275
276
GLOBAL(djpeg_dest_ptr)
277
jinit_write_rle (j_decompress_ptr cinfo)
278
{
279
  rle_dest_ptr dest;
280
281
  /* Create module interface object, fill in method pointers */
282
  dest = (rle_dest_ptr)
283
      (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
284
                                  SIZEOF(rle_dest_struct));
285
  dest->pub.start_output = start_output_rle;
286
  dest->pub.finish_output = finish_output_rle;
287
288
  /* Calculate output image dimensions so we can allocate space */
289
  jpeg_calc_output_dimensions(cinfo);
290
291
  /* Allocate a work array for output to the RLE library. */
292
  dest->rle_row = (*cinfo->mem->alloc_sarray)
293
    ((j_common_ptr) cinfo, JPOOL_IMAGE,
294
     cinfo->output_width, (JDIMENSION) cinfo->output_components);
295
296
  /* Allocate a virtual array to hold the image. */
297
  dest->image = (*cinfo->mem->request_virt_sarray)
298
    ((j_common_ptr) cinfo, JPOOL_IMAGE, FALSE,
299
     (JDIMENSION) (cinfo->output_width * cinfo->output_components),
300
     cinfo->output_height, (JDIMENSION) 1);
301
302
  return (djpeg_dest_ptr) dest;
303
}
304
305
#endif /* RLE_SUPPORTED */
(-)a/jpeg/wrtarga.c (+253 lines)
Line     Link Here 
Line 0    Link Here 
1
/*
2
 * wrtarga.c
3
 *
4
 * Copyright (C) 1991-1996, Thomas G. Lane.
5
 * This file is part of the Independent JPEG Group's software.
6
 * For conditions of distribution and use, see the accompanying README file.
7
 *
8
 * This file contains routines to write output images in Targa format.
9
 *
10
 * These routines may need modification for non-Unix environments or
11
 * specialized applications.  As they stand, they assume output to
12
 * an ordinary stdio stream.
13
 *
14
 * Based on code contributed by Lee Daniel Crocker.
15
 */
16
17
#include "cdjpeg.h"		/* Common decls for cjpeg/djpeg applications */
18
19
#ifdef TARGA_SUPPORTED
20
21
22
/*
23
 * To support 12-bit JPEG data, we'd have to scale output down to 8 bits.
24
 * This is not yet implemented.
25
 */
26
27
#if BITS_IN_JSAMPLE != 8
28
  Sorry, this code only copes with 8-bit JSAMPLEs. /* deliberate syntax err */
29
#endif
30
31
/*
32
 * The output buffer needs to be writable by fwrite().  On PCs, we must
33
 * allocate the buffer in near data space, because we are assuming small-data
34
 * memory model, wherein fwrite() can't reach far memory.  If you need to
35
 * process very wide images on a PC, you might have to compile in large-memory
36
 * model, or else replace fwrite() with a putc() loop --- which will be much
37
 * slower.
38
 */
39
40
41
/* Private version of data destination object */
42
43
typedef struct {
44
  struct djpeg_dest_struct pub;	/* public fields */
45
46
  char *iobuffer;		/* physical I/O buffer */
47
  JDIMENSION buffer_width;	/* width of one row */
48
} tga_dest_struct;
49
50
typedef tga_dest_struct * tga_dest_ptr;
51
52
53
LOCAL(void)
54
write_header (j_decompress_ptr cinfo, djpeg_dest_ptr dinfo, int num_colors)
55
/* Create and write a Targa header */
56
{
57
  char targaheader[18];
58
59
  /* Set unused fields of header to 0 */
60
  MEMZERO(targaheader, SIZEOF(targaheader));
61
62
  if (num_colors > 0) {
63
    targaheader[1] = 1;		/* color map type 1 */
64
    targaheader[5] = (char) (num_colors & 0xFF);
65
    targaheader[6] = (char) (num_colors >> 8);
66
    targaheader[7] = 24;	/* 24 bits per cmap entry */
67
  }
68
69
  targaheader[12] = (char) (cinfo->output_width & 0xFF);
70
  targaheader[13] = (char) (cinfo->output_width >> 8);
71
  targaheader[14] = (char) (cinfo->output_height & 0xFF);
72
  targaheader[15] = (char) (cinfo->output_height >> 8);
73
  targaheader[17] = 0x20;	/* Top-down, non-interlaced */
74
75
  if (cinfo->out_color_space == JCS_GRAYSCALE) {
76
    targaheader[2] = 3;		/* image type = uncompressed gray-scale */
77
    targaheader[16] = 8;	/* bits per pixel */
78
  } else {			/* must be RGB */
79
    if (num_colors > 0) {
80
      targaheader[2] = 1;	/* image type = colormapped RGB */
81
      targaheader[16] = 8;
82
    } else {
83
      targaheader[2] = 2;	/* image type = uncompressed RGB */
84
      targaheader[16] = 24;
85
    }
86
  }
87
88
  if (JFWRITE(dinfo->output_file, targaheader, 18) != (size_t) 18)
89
    ERREXIT(cinfo, JERR_FILE_WRITE);
90
}
91
92
93
/*
94
 * Write some pixel data.
95
 * In this module rows_supplied will always be 1.
96
 */
97
98
METHODDEF(void)
99
put_pixel_rows (j_decompress_ptr cinfo, djpeg_dest_ptr dinfo,
100
		JDIMENSION rows_supplied)
101
/* used for unquantized full-color output */
102
{
103
  tga_dest_ptr dest = (tga_dest_ptr) dinfo;
104
  register JSAMPROW inptr;
105
  register char * outptr;
106
  register JDIMENSION col;
107
108
  inptr = dest->pub.buffer[0];
109
  outptr = dest->iobuffer;
110
  for (col = cinfo->output_width; col > 0; col--) {
111
    outptr[0] = (char) GETJSAMPLE(inptr[2]); /* RGB to BGR order */
112
    outptr[1] = (char) GETJSAMPLE(inptr[1]);
113
    outptr[2] = (char) GETJSAMPLE(inptr[0]);
114
    inptr += 3, outptr += 3;
115
  }
116
  (void) JFWRITE(dest->pub.output_file, dest->iobuffer, dest->buffer_width);
117
}
118
119
METHODDEF(void)
120
put_gray_rows (j_decompress_ptr cinfo, djpeg_dest_ptr dinfo,
121
	       JDIMENSION rows_supplied)
122
/* used for grayscale OR quantized color output */
123
{
124
  tga_dest_ptr dest = (tga_dest_ptr) dinfo;
125
  register JSAMPROW inptr;
126
  register char * outptr;
127
  register JDIMENSION col;
128
129
  inptr = dest->pub.buffer[0];
130
  outptr = dest->iobuffer;
131
  for (col = cinfo->output_width; col > 0; col--) {
132
    *outptr++ = (char) GETJSAMPLE(*inptr++);
133
  }
134
  (void) JFWRITE(dest->pub.output_file, dest->iobuffer, dest->buffer_width);
135
}
136
137
138
/*
139
 * Write some demapped pixel data when color quantization is in effect.
140
 * For Targa, this is only applied to grayscale data.
141
 */
142
143
METHODDEF(void)
144
put_demapped_gray (j_decompress_ptr cinfo, djpeg_dest_ptr dinfo,
145
		   JDIMENSION rows_supplied)
146
{
147
  tga_dest_ptr dest = (tga_dest_ptr) dinfo;
148
  register JSAMPROW inptr;
149
  register char * outptr;
150
  register JSAMPROW color_map0 = cinfo->colormap[0];
151
  register JDIMENSION col;
152
153
  inptr = dest->pub.buffer[0];
154
  outptr = dest->iobuffer;
155
  for (col = cinfo->output_width; col > 0; col--) {
156
    *outptr++ = (char) GETJSAMPLE(color_map0[GETJSAMPLE(*inptr++)]);
157
  }
158
  (void) JFWRITE(dest->pub.output_file, dest->iobuffer, dest->buffer_width);
159
}
160
161
162
/*
163
 * Startup: write the file header.
164
 */
165
166
METHODDEF(void)
167
start_output_tga (j_decompress_ptr cinfo, djpeg_dest_ptr dinfo)
168
{
169
  tga_dest_ptr dest = (tga_dest_ptr) dinfo;
170
  int num_colors, i;
171
  FILE *outfile;
172
173
  if (cinfo->out_color_space == JCS_GRAYSCALE) {
174
    /* Targa doesn't have a mapped grayscale format, so we will */
175
    /* demap quantized gray output.  Never emit a colormap. */
176
    write_header(cinfo, dinfo, 0);
177
    if (cinfo->quantize_colors)
178
      dest->pub.put_pixel_rows = put_demapped_gray;
179
    else
180
      dest->pub.put_pixel_rows = put_gray_rows;
181
  } else if (cinfo->out_color_space == JCS_RGB) {
182
    if (cinfo->quantize_colors) {
183
      /* We only support 8-bit colormap indexes, so only 256 colors */
184
      num_colors = cinfo->actual_number_of_colors;
185
      if (num_colors > 256)
186
	ERREXIT1(cinfo, JERR_TOO_MANY_COLORS, num_colors);
187
      write_header(cinfo, dinfo, num_colors);
188
      /* Write the colormap.  Note Targa uses BGR byte order */
189
      outfile = dest->pub.output_file;
190
      for (i = 0; i < num_colors; i++) {
191
	putc(GETJSAMPLE(cinfo->colormap[2][i]), outfile);
192
	putc(GETJSAMPLE(cinfo->colormap[1][i]), outfile);
193
	putc(GETJSAMPLE(cinfo->colormap[0][i]), outfile);
194
      }
195
      dest->pub.put_pixel_rows = put_gray_rows;
196
    } else {
197
      write_header(cinfo, dinfo, 0);
198
      dest->pub.put_pixel_rows = put_pixel_rows;
199
    }
200
  } else {
201
    ERREXIT(cinfo, JERR_TGA_COLORSPACE);
202
  }
203
}
204
205
206
/*
207
 * Finish up at the end of the file.
208
 */
209
210
METHODDEF(void)
211
finish_output_tga (j_decompress_ptr cinfo, djpeg_dest_ptr dinfo)
212
{
213
  /* Make sure we wrote the output file OK */
214
  fflush(dinfo->output_file);
215
  if (ferror(dinfo->output_file))
216
    ERREXIT(cinfo, JERR_FILE_WRITE);
217
}
218
219
220
/*
221
 * The module selection routine for Targa format output.
222
 */
223
224
GLOBAL(djpeg_dest_ptr)
225
jinit_write_targa (j_decompress_ptr cinfo)
226
{
227
  tga_dest_ptr dest;
228
229
  /* Create module interface object, fill in method pointers */
230
  dest = (tga_dest_ptr)
231
      (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
232
				  SIZEOF(tga_dest_struct));
233
  dest->pub.start_output = start_output_tga;
234
  dest->pub.finish_output = finish_output_tga;
235
236
  /* Calculate output image dimensions so we can allocate space */
237
  jpeg_calc_output_dimensions(cinfo);
238
239
  /* Create I/O buffer.  Note we make this near on a PC. */
240
  dest->buffer_width = cinfo->output_width * cinfo->output_components;
241
  dest->iobuffer = (char *)
242
    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
243
				(size_t) (dest->buffer_width * SIZEOF(char)));
244
245
  /* Create decompressor output buffer. */
246
  dest->pub.buffer = (*cinfo->mem->alloc_sarray)
247
    ((j_common_ptr) cinfo, JPOOL_IMAGE, dest->buffer_width, (JDIMENSION) 1);
248
  dest->pub.buffer_height = 1;
249
250
  return (djpeg_dest_ptr) dest;
251
}
252
253
#endif /* TARGA_SUPPORTED */

Return to bug 573948