dxtn License GPL
authorMagnus Olsen <magnus@greatlord.com>
Sun, 14 Oct 2007 13:03:46 +0000 (13:03 +0000)
committerMagnus Olsen <magnus@greatlord.com>
Sun, 14 Oct 2007 13:03:46 +0000 (13:03 +0000)
Need it by OpenGL / DirectX compress textures, at moment for mesa32
Got Alesky aka Fireball permits to add it, so long it use the patent flag.
Some part in this library can contain patent, thing in USA
This library will not be build directly, you are force to
change the patent flags in the config.rbuild file to 1
But todo so, you need check you country patent.

svn path=/branches/reactx/; revision=29562

28 files changed:
reactos/dll/3rdparty/3rdparty.rbuild
reactos/dll/3rdparty/dxtn/Makefile [new file with mode: 0644]
reactos/dll/3rdparty/dxtn/Makefile.DJ [new file with mode: 0644]
reactos/dll/3rdparty/dxtn/Makefile.mgw [new file with mode: 0644]
reactos/dll/3rdparty/dxtn/Makefile.vc [new file with mode: 0644]
reactos/dll/3rdparty/dxtn/Makefile.wat [new file with mode: 0644]
reactos/dll/3rdparty/dxtn/docs/README [new file with mode: 0644]
reactos/dll/3rdparty/dxtn/docs/fxt1license.txt [new file with mode: 0644]
reactos/dll/3rdparty/dxtn/docs/tc.html [new file with mode: 0644]
reactos/dll/3rdparty/dxtn/docs/texture_compression_FXT1.txt [new file with mode: 0644]
reactos/dll/3rdparty/dxtn/docs/texture_compression_s3tc.txt [new file with mode: 0644]
reactos/dll/3rdparty/dxtn/docs/vmath.txt [new file with mode: 0644]
reactos/dll/3rdparty/dxtn/dxtn.c [new file with mode: 0644]
reactos/dll/3rdparty/dxtn/dxtn.def [new file with mode: 0644]
reactos/dll/3rdparty/dxtn/dxtn.h [new file with mode: 0644]
reactos/dll/3rdparty/dxtn/dxtn.rbuild [new file with mode: 0644]
reactos/dll/3rdparty/dxtn/fxt1.c [new file with mode: 0644]
reactos/dll/3rdparty/dxtn/fxt1.h [new file with mode: 0644]
reactos/dll/3rdparty/dxtn/internal.h [new file with mode: 0644]
reactos/dll/3rdparty/dxtn/test/Makefile [new file with mode: 0644]
reactos/dll/3rdparty/dxtn/test/main.c [new file with mode: 0644]
reactos/dll/3rdparty/dxtn/test/tga.c [new file with mode: 0644]
reactos/dll/3rdparty/dxtn/test/tga.h [new file with mode: 0644]
reactos/dll/3rdparty/dxtn/test/util.c [new file with mode: 0644]
reactos/dll/3rdparty/dxtn/test/util.h [new file with mode: 0644]
reactos/dll/3rdparty/dxtn/texstore.c [new file with mode: 0644]
reactos/dll/3rdparty/dxtn/types.h [new file with mode: 0644]
reactos/dll/3rdparty/dxtn/wrapper.c [new file with mode: 0644]

index 9d01737..67c28ac 100644 (file)
@@ -7,5 +7,11 @@
        <directory name="mesa32">
                <xi:include href="mesa32/mesa32.rbuild" />
        </directory>
+
+       <ifnot property="NSWPAT" value="0">
+               <directory name="dxtn">
+                       <xi:include href="dxtn/dxtn.rbuild" />
+               </directory>
+       </ifnot>
 </group>
        
\ No newline at end of file
diff --git a/reactos/dll/3rdparty/dxtn/Makefile b/reactos/dll/3rdparty/dxtn/Makefile
new file mode 100644 (file)
index 0000000..f93271c
--- /dev/null
@@ -0,0 +1,69 @@
+# Texture compression Linux makefile
+# Version:  1.1
+#
+# Copyright (C) 2004  Daniel Borca   All Rights Reserved.
+#
+# this is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# this is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Make; see the file COPYING.  If not, write to
+# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.        
+
+
+#
+#  Available options:
+#
+#    Environment variables:
+#
+#    Targets:
+#      all:            build dynamic module
+#      clean:          remove object files
+#      realclean:      remove all generated files
+#
+
+
+.PHONY: all clean realclean
+
+DLLNAME = libdxtn.so
+
+CC = gcc
+CFLAGS = -Wall -W -pedantic -ansi
+CFLAGS += -O2 -ffast-math -funroll-loops
+#CFLAGS += -fomit-frame-pointer -fexpensive-optimizations
+CFLAGS += -fPIC -DPIC
+
+LD = gcc
+LDFLAGS = -shared
+LDLIBS =
+
+SOURCES = \
+       fxt1.c \
+       dxtn.c \
+       wrapper.c \
+       texstore.c
+
+OBJECTS = $(SOURCES:.c=.o)
+
+.c.o:
+       $(CC) -o $@ $(CFLAGS) -c $<
+
+all: $(DLLNAME)
+
+$(DLLNAME): $(OBJECTS)
+       $(LD) -o $@ $(LDFLAGS) $^ $(LDLIBS)
+
+clean:
+       -$(RM) $(OBJECTS)
+
+realclean: clean
+       -$(RM) $(DLLNAME)
+
+-include depend
diff --git a/reactos/dll/3rdparty/dxtn/Makefile.DJ b/reactos/dll/3rdparty/dxtn/Makefile.DJ
new file mode 100644 (file)
index 0000000..7a2527a
--- /dev/null
@@ -0,0 +1,69 @@
+# Texture compression DJGPP makefile
+# Version:  1.1
+#
+# Copyright (C) 2004  Daniel Borca   All Rights Reserved.
+#
+# this is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# this is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Make; see the file COPYING.  If not, write to
+# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.        
+
+
+#
+#  Available options:
+#
+#    Environment variables:
+#
+#    Targets:
+#      all:            build dynamic module
+#      clean:          remove object files
+#      realclean:      remove all generated files
+#
+
+
+.PHONY: all clean realclean
+
+DLLNAME = libdxtn.a
+
+CC = gcc
+CFLAGS = -Wall -W -pedantic -ansi
+CFLAGS += -O2 -ffast-math -funroll-loops
+#CFLAGS += -fomit-frame-pointer -fexpensive-optimizations
+
+AR = ar
+ARFLAGS = crus
+
+RM = del
+
+SOURCES = \
+       fxt1.c \
+       dxtn.c \
+       wrapper.c \
+       texstore.c
+
+OBJECTS = $(SOURCES:.c=.o)
+
+.c.o:
+       $(CC) -o $@ $(CFLAGS) -c $<
+
+all: $(DLLNAME)
+
+$(DLLNAME): $(OBJECTS)
+       $(AR) $(ARFLAGS) $@ $^
+
+clean:
+       -$(RM) $(OBJECTS)
+
+realclean: clean
+       -$(RM) $(DLLNAME)
+
+-include depend
diff --git a/reactos/dll/3rdparty/dxtn/Makefile.mgw b/reactos/dll/3rdparty/dxtn/Makefile.mgw
new file mode 100644 (file)
index 0000000..5dc7b52
--- /dev/null
@@ -0,0 +1,70 @@
+# Texture compression MinGW makefile
+# Version:  1.1
+#
+# Copyright (C) 2004  Daniel Borca   All Rights Reserved.
+#
+# this is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# this is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Make; see the file COPYING.  If not, write to
+# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.        
+
+
+#
+#  Available options:
+#
+#    Environment variables:
+#
+#    Targets:
+#      all:            build dynamic module
+#      clean:          remove object files
+#      realclean:      remove all generated files
+#
+
+
+.PHONY: all clean realclean
+
+DLLNAME = dxtn.dll
+
+CC = mingw32-gcc
+CFLAGS = -Wall -W -pedantic -ansi
+CFLAGS += -O2 -ffast-math -funroll-loops
+#CFLAGS += -fomit-frame-pointer -fexpensive-optimizations
+
+LD = mingw32-gcc
+LDFLAGS = -shared
+LDLIBS =
+
+RM = del
+
+SOURCES = \
+       fxt1.c \
+       dxtn.c \
+       wrapper.c \
+       texstore.c
+
+OBJECTS = $(SOURCES:.c=.o)
+
+.c.o:
+       $(CC) -o $@ $(CFLAGS) -c $<
+
+all: $(DLLNAME)
+
+$(DLLNAME): $(OBJECTS)
+       $(LD) -o $@ $(LDFLAGS) $^ $(LDLIBS)
+
+clean:
+       -$(RM) *.o
+
+realclean: clean
+       -$(RM) $(DLLNAME)
+
+-include depend
diff --git a/reactos/dll/3rdparty/dxtn/Makefile.vc b/reactos/dll/3rdparty/dxtn/Makefile.vc
new file mode 100644 (file)
index 0000000..3053560
--- /dev/null
@@ -0,0 +1,69 @@
+# Texture compression VisualC(++) makefile
+# Version:  1.1
+#
+# Copyright (C) 2004  Daniel Borca   All Rights Reserved.
+#
+# this is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# this is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Make; see the file COPYING.  If not, write to
+# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.        
+
+
+#
+#  Available options:
+#
+#    Environment variables:
+#
+#    Targets:
+#      all:            build dynamic module
+#      clean:          remove object files
+#      realclean:      remove all generated files
+#
+
+
+.PHONY: all clean realclean
+
+DLLNAME = dxtn.dll
+
+CC = cl
+CFLAGS = -nologo -W3 -WX -D__MSC__=1 -D__WIN32__
+CFLAGS += -DNDEBUG -G6 -O2
+
+LD = link
+LDFLAGS = -nologo -dll -opt:WIN98 -machine:IX86
+LDLIBS =
+
+RM = del
+
+SOURCES = \
+       fxt1.c \
+       dxtn.c \
+       wrapper.c \
+       texstore.c
+
+OBJECTS = $(SOURCES:.c=.o)
+
+.c.o:
+       $(CC) -Fo$@ $(CFLAGS) -c $<
+
+all: $(DLLNAME)
+
+$(DLLNAME): $(OBJECTS)
+       $(LD) -out:$@ $(LDFLAGS) $^ $(LDLIBS)
+
+clean:
+       -$(RM) *.o
+
+realclean: clean
+       -$(RM) $(DLLNAME)
+
+-include depend
diff --git a/reactos/dll/3rdparty/dxtn/Makefile.wat b/reactos/dll/3rdparty/dxtn/Makefile.wat
new file mode 100644 (file)
index 0000000..d45ddfe
--- /dev/null
@@ -0,0 +1,71 @@
+# Texture compression OpenWatcom makefile
+# Version:  1.1
+#
+# Copyright (C) 2004  Daniel Borca   All Rights Reserved.
+#
+# this is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# this is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Make; see the file COPYING.  If not, write to
+# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.        
+
+
+#
+#  Available options:
+#
+#    Environment variables:
+#
+#    Targets:
+#      all:            build dynamic module
+#      clean:          remove object files
+#      realclean:      remove all generated files
+#
+
+
+.PHONY: all clean realclean
+.SUFFIXES: .c .obj
+
+DLLNAME = dxtn.dll
+
+CC = wcl386
+CFLAGS = -wx -zq
+CFLAGS += -ox -6s
+
+LD = wcl386
+LDFLAGS = -zq -bd
+LDLIBS =
+
+RM = del
+
+SOURCES = \
+       fxt1.c \
+       dxtn.c \
+       wrapper.c \
+       texstore.c
+
+OBJECTS = $(SOURCES:.c=.obj)
+
+.c.obj:
+       $(CC) -fo=$@ $(CFLAGS) -c $<
+
+all: $(DLLNAME)
+
+$(DLLNAME): $(OBJECTS)
+       $(LD) -fe=$@ $(LDFLAGS) $^ $(LDLIBS)
+
+clean:
+       $(RM) *.obj
+       $(RM) *.err
+
+realclean: clean
+       $(RM) $(DLLNAME)
+
+-include depend
diff --git a/reactos/dll/3rdparty/dxtn/docs/README b/reactos/dll/3rdparty/dxtn/docs/README
new file mode 100644 (file)
index 0000000..b03b01e
--- /dev/null
@@ -0,0 +1,49 @@
+This is a working codec for FXT1 and DXTn texture compression.
+It has a balanced speed/quality ratio, and is very tweakable.
+
+Both FXT1 and DXTn use vector quantization for lossy encoding.
+The decoder is rather trivial, at the expense of the encoder
+complexity. This means that applications heavily relying on
+texture compression should provide precompressed textures, for
+several obvious reasons:
+1) the encoding phase can be done "off-line" with hi-quality
+   encoders
+2) if the graphic driver does not support precompressed textures,
+   it's still cheap to decode "on-line" application-side
+3) the distributed package gets smaller
+
+The FXT1 and DXTn codecs were written using documentation freely
+available on the world-wide-web, including, but not limited to:
+3DFX_texture_compression_FXT1 and EXT_texture_compression_s3tc
+from http://oss.sgi.com/projects/ogl-sample/registry/
+I just translated the human readable spec into ANSI C. There are
+NO binaries available, as I am NOT using this code! Therefore,
+THE RESPONSIBILITY OF USING THE CODE IS ENTIRELY WITH YOU!
+
+The implementation per-se is made available under GPL, which
+does not necessarily apply to the abstract content (texture
+compression algorithms):
+FXT1 is subject to "3DFX FXT1 Source Code General Public License"
+
+DXTn is basically the S3TC texture compression, a license to the
+     "S3TC Intellectual Property" may be required prior to any use.
+
+     There is significant IP associated with the S3TC format.
+     Existing users probably have executed licenses directly
+     with S3 or its successors (Sonic Blue, S3 Graphics).
+
+     The current ownership of the S3TC IP is unknown to me. It is
+     known that when S3 exited the graphics hardware business, part of
+     their operations were sold to ATI and part were spun off to a joint
+     Taiwanese venture with Via Technologies, called S3 Graphics.
+
+I, DANIEL BORCA, AM NOT AWARE OF ANY LEGAL ISSUE CAUSED BY RELEASING
+THIS CODE. Prior to commencement of legal action, the Plaintiff should
+make an informal demand to Cease and Desist. In deference to the
+regulations of the Federal Communications Commission, which requires
+notice prior to filing an action, and in the spirit of cooperation,
+all complaints, issues and concerns should first be directed to me
+in an effort to resolve them amicably and promptly. FCC s2250.
+
+Daniel Borca
+dborca 'at' yahoo 'dot' com
diff --git a/reactos/dll/3rdparty/dxtn/docs/fxt1license.txt b/reactos/dll/3rdparty/dxtn/docs/fxt1license.txt
new file mode 100644 (file)
index 0000000..234c6c6
--- /dev/null
@@ -0,0 +1,244 @@
+3DFX FXT1 Source Code General Public License
+
+
+1. PREAMBLE
+
+       This license is for software that provides texture compression and 
+       decompression, particularly in the context of video games. The license
+       is intended to offer terms similar to some standard General Public 
+       Licenses designed to foster open standards and unrestricted 
+       accessibility to source code. Some of these licenses require that, as
+       a condition of the license of the software, any derivative works 
+       (that is, new software which is a work containing the original program
+       or a portion of it) must be available for general use, without
+       restriction other than for a minor transfer fee, and that the source
+       code for such derivative works must likewise be made available. The 
+       only restriction is that such derivative works must be subject to 
+       the same General Public License terms as the original work. 
+
+       This 3dfx FXT1 Source Code General Public License differs from the
+       standard licenses of this type in that it does not require the entire
+       derivative work to be made available under the terms of this license
+       nor is the recipient required to make available the source code for
+       the entire derivative work. Rather, the license is limited to only the
+       identifiable portion of the derivative work that is derived from the
+       licensed software. The precise terms and conditions for copying, 
+       distribution and modification follow.
+
+
+2. DEFINITIONS
+
+       2.1 This License applies to any program (or other "work") which 
+       contains a notice placed by the copyright holder saying it may be 
+       distributed under the terms of this 3dfx FXT1 Source Code General 
+       Public License. 
+
+       2.2 The term "Program" as used in this Agreement refers to 3DFX's 
+       FXT1 source code and object code and any Derivative Work.
+
+       2.3 "Derivative Work" means, for the purpose of the License, that 
+       portion of any work that contains the Program or the identifiable 
+       portion of a work that is derived from the Program, either verbatim or
+       with modifications and/or translated into another language, and that 
+       performs texture compression and decompression. It does not include 
+       any other portions of a work.
+
+       2.4 "Modifications of the Program" means any work, which includes a
+       Derivative Work, and includes the whole of such work.
+
+       2.5 "License" means this 3dfx FXT1 Source Code General Public License.
+
+       2.6 The "Source Code" for a work means the preferred form of the work
+       for making modifications to it. For an executable work, complete source
+       code means all the source code for all modules it contains, any
+       associated interface definition files, and the scripts used to control
+       compilation and installation of the executable work.
+
+       2.7 "3dfx" means 3dfx Interactive, Inc.
+
+
+3. LICENSED ACTIVITIES
+
+       3.1 COPYING - You may copy and distribute verbatim copies of the 
+       Program's Source Code as you receive it, in any medium, subject to the
+       provision of section 3.3 and provided also that:
+
+               (a) you conspicuously and appropriately publish on each copy
+       an appropriate copyright notice (3dfx Interactive, Inc. 1999), a notice
+       that recipients who wish to copy, distribute or modify the Program can
+       only do so subject to this License, and a disclaimer of warranty as
+       set forth in section 5;
+
+               (b) keep intact all the notices that refer to this License and
+       to the absence of any warranty; and
+               (c) give all recipients of the Program a copy of this License
+       along with the Program or instructions on how to easily receive a copy
+       of this License.
+
+
+       3.2 MODIFICATION OF THE PROGRAM/DERIVATIVE WORKS - You may modify your
+       copy or copies of the Program or any portion of it, and copy and
+       distribute such modifications subject to the provisions of section 3.3
+       and provided that you also meet all of the following conditions: 
+
+               (a) you conspicuously and appropriately publish on each copy
+       of a Derivative Work an appropriate copyright notice, a notice that
+       recipients who wish to copy, distribute or modify the Derivative Work
+       can only do so subject to this License, and a disclaimer of warranty
+       as set forth in section 5;
+
+               (b) keep intact all the notices that refer to this License and
+       to the absence of any warranty; and
+               (c) give all recipients of the Derivative Work a copy of this
+       License along with the Derivative Work or instructions on how to easily
+       receive a copy of this License.
+
+               (d) You must cause the modified files of the Derivative Work
+       to carry prominent notices stating that you changed the files and the
+       date of any change. 
+
+               (e) You must cause any Derivative Work that you distribute or
+       publish to be licensed at no charge to all third parties under the
+       terms of this License. 
+
+               (f) If the Derivative Work normally reads commands 
+       interactively when run, you must cause it, when started running for
+       such interactive use, to print or display an announcement as follows:
+
+       "COPYRIGHT 3DFX INTERACTIVE, INC. 1999, ALL RIGHTS RESERVED THIS 
+       SOFTWARE IS FREE AND PROVIDED "AS IS," WITHOUT WARRANTY OF ANY KIND, 
+       EITHER EXPRESSED OR IMPLIED. SEE THE 3DFX FXT1 GENERAL PUBLIC LICENSE
+       FOR A FULL TEXT OF THE DISTRIBUTION AND NON-WARRANTY PROVISIONS 
+       (REQUEST COPY FROM INFO@3DFX.COM)."
+
+               (g) The requirements of this section 3.2 do not apply to the
+       modified work as a whole but only to the Derivative Work. It is not
+       the intent of this License to claim rights or contest your rights to
+       work written entirely by you; rather, the intent is to exercise the
+       right to control the distribution of Derivative Works. 
+
+
+       3.3 DISTRIBUTION 
+
+               (a) All copies of the Program or Derivative Works which are
+       distributed must include in the file headers the following language
+       verbatim:
+
+       "THIS SOFTWARE IS SUBJECT TO COPYRIGHT PROTECTION AND IS OFFERED 
+       ONLY PURSUANT TO THE 3DFX FXT1 GENERAL PUBLIC LICENSE. A COPY OF THIS
+       LICENSE MAY BE OBTAINED FROM THE DISTRIBUTOR OR BY CONTACTING 3DFX
+       INTERACTIVE INC (info@3dfx.com). THIS PROGRAM. IS PROVIDED "AS IS"
+       WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED. SEE THE
+       3DFX FXT1 GENERAL PUBLIC LICENSE FOR A FULL TEXT OF THE NON-WARRANTY
+       PROVISIONS.
+
+       USE, DUPLICATION OR DISCLOSURE BY THE GOVERNMENT IS SUBJECT TO
+       RESTRICTIONS AS SET FORTH IN SUBDIVISION (C)(1)(II) OF THE RIGHTS
+       IN TECHNICAL DATA AND COMPUTER SOFTWARE CLAUSE AT DFARS 252.227-7013,
+       AND/OR IN SIMILAR OR SUCCESSOR CLAUSES IN THE FAR, DOD OR NASA FAR
+       SUPPLEMENT. UNPUBLISHED RIGHTS RESERVED UNDER THE COPYRIGHT LAWS OF
+       THE UNITED STATES.
+
+       COPYRIGHT 3DFX INTERACTIVE, INC. 1999, ALL RIGHTS RESERVED"
+
+               (b) You may distribute the Program or a Derivative Work in
+       object code or executable form under the terms of Sections 3.1 and 3.2
+       provided that you also do one of the following: 
+
+                       (1) Accompany it with the complete corresponding
+       machine-readable source code, which must be distributed under the 
+       terms of Sections 3.1 and 3.2; or,
+                       (2) Accompany it with a written offer, valid for at
+       least three years, to give any third party, for a charge no more than
+       your cost of physically performing source distribution, a complete
+       machine-readable copy of the corresponding source code, to be 
+       distributed under the terms of Sections 3.1 and 3.2 on a medium 
+       customarily used for software interchange; or,
+                       (3) Accompany it with the information you received as
+       to the offer to distribute corresponding source code. (This alternative
+       is allowed only for noncommercial distribution and only if you received
+       the program in object code or executable form with such an offer, in
+       accord with Subsection 3.3(b)(2) above.)
+               (c) The source code distributed need not include anything
+       that is normally distributed (in either source or binary form) with
+       the major components (compiler, kernel, and so on) of the operating
+       system on which the executable runs, unless that component itself
+       accompanies the executable code.
+               (d) If distribution of executable code or object code is made
+       by offering access to copy from a designated place, then offering
+       equivalent access to copy the source code from the same place counts
+       as distribution of the source code, even though third parties are not
+       compelled to copy the source along with the object code. 
+
+               (e) Each time you redistribute the Program or any Derivative
+       Work, the recipient automatically receives a license from 3dfx and
+       successor licensors to copy, distribute or modify the Program and
+       Derivative Works subject to the terms and conditions of the License.
+       You may not impose any further restrictions on the recipients' 
+       exercise of the rights granted herein. You are not responsible for
+       enforcing compliance by third parties to this License.
+               (f) You may not copy, modify, sublicense, or distribute the
+       Program or any Derivative Works except as expressly provided under
+       this License. Any attempt otherwise to copy, modify, sublicense or
+       distribute the Program or any Derivative Works is void, and will
+       automatically terminate your rights under this License. However,
+       parties who have received copies, or rights, from you under this
+       License will not have their licenses terminated so long as such
+       parties remain in full compliance.
+
+4. MISCELLANEOUS
+
+       4.1 Acceptance of this License is voluntary. By using, modifying or
+       distributing the Program or any Derivative Work, you indicate your 
+       acceptance of this License to do so, and all its terms and conditions
+       for copying, distributing or modifying the Program or works based on
+       it. Nothing else grants you permission to modify or distribute the
+       Program or Derivative Works and doing so without acceptance of this
+       License is in violation of the U.S. and international copyright laws.
+
+       4.2 If the distribution and/or use of the Program or Derivative Works
+       is restricted in certain countries either by patents or by copyrighted
+       interfaces, the original copyright holder who places the Program under
+       this License may add an explicit geographical distribution limitation
+       excluding those countries, so that distribution is permitted only in
+       or among countries not thus excluded. In such case, this License
+       incorporates the limitation as if written in the body of this License.
+
+       4.3 This License is to be construed according to the laws of the 
+       State of California and you consent to personal jurisdiction in the
+       State of California in the event it is necessary to enforce the
+       provisions of this License.
+
+
+5. NO WARRANTIES
+
+       5.1 TO THE EXTENT PERMITTED BY APPLICABLE LAW, THERE IS NO WARRANTY
+       FOR THE PROGRAM. OR DERIVATIVE WORKS THE COPYRIGHT HOLDERS AND/OR
+       OTHER PARTIES PROVIDE THE PROGRAM AND ANY DERIVATIVE WORKS"AS IS"
+       WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+       BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+       FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY
+       AND PERFORMANCE OF THE PROGRAM AND ANY DERIVATIVE WORK IS WITH YOU.
+       SHOULD THE PROGRAM OR ANY DERIVATIVE WORK PROVE DEFECTIVE, YOU ASSUME
+       THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+       5.2 IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW WILL 3DFX
+       INTERACTIVE, INC., OR ANY OTHER COPYRIGHT HOLDER, OR ANY OTHER PARTY
+       WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM OR DERIVATIVE WORKS AS
+       PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL,
+       SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR
+       INABILITY TO USE THE PROGRAM OR DERIVATIVE WORKS (INCLUDING BUT NOT
+       LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES
+       SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM OR
+       DERIVATIVE WORKS TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH
+       HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+       DAMAGES.
+
diff --git a/reactos/dll/3rdparty/dxtn/docs/tc.html b/reactos/dll/3rdparty/dxtn/docs/tc.html
new file mode 100644 (file)
index 0000000..9542576
--- /dev/null
@@ -0,0 +1,67 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+
+<head>
+    <meta name="Author" content="Daniel Borca"/>
+    <meta name="Description" content="Texture compression"/>
+    <meta name="KeyWords" content="FXT1, DXTn, S3TC, DXT1, DXT3, DXT5, texture, compression, codec, compressor, decompressor"/>
+
+    <title>Texture compression</title>
+
+    <link rel="STYLESHEET" type="text/css" href="../style.css"/>
+</head>
+
+<body bgcolor="#500000" text="#FFFF00" background="../bg_deepred1.gif">
+    <center><h2>Texture compression</h2></center>
+    <hr/>
+
+    <p><a href="tc-1.1.tar.gz">tc-1.1.tar.gz</a> is a working codec for <b>FXT1</b> and <b>DXTn</b> texture compression.
+    It has a balanced speed/quality ratio, and is very tweakable.</p>
+    <p>Both <b>FXT1</b> and <b>DXTn</b> use vector quantization for lossy encoding.
+    The decoder is rather trivial, at the expense of the encoder
+    complexity. This means that applications heavily relying on
+    texture compression should provide precompressed textures, for
+    several obvious reasons:</p>
+    <ol>
+       <li>the encoding phase can be done "off-line" with hi-quality
+           encoders</li>
+       <li>if the graphic driver does not support precompressed textures,
+           it's still cheap to decode "on-line" application-side</li>
+       <li>the distributed package gets smaller</li>
+    </ol>
+    <p>The <b>FXT1</b> and <b>DXTn</b> codecs were written using documentation freely
+    available on the world-wide-web, including, but not limited to:
+    3DFX_texture_compression_FXT1 and EXT_texture_compression_s3tc
+    from <a href="http://oss.sgi.com/projects/ogl-sample/registry/">http://oss.sgi.com/projects/ogl-sample/registry/</a><BR/>
+    I just translated the human readable spec into ANSI C. There are
+    NO binaries available, as I am <b>NOT</b> using this code! <b>Therefore,
+    <font color="#D8D8D8">THE RESPONSIBILITY OF USING THE CODE IS ENTIRELY WITH YOU!</font></b></p>
+    <p>The implementation <I>per-se</I> is made available under GPL, which
+    does not necessarily apply to the abstract content (texture
+    compression algorithms):</p>
+    <p><b>FXT1</b> is subject to "3DFX FXT1 Source Code General Public License"</p>
+    <p><b>DXTn</b> is basically the S3TC texture compression, a license to the
+     "S3TC Intellectual Property" may be required prior to any use.</p>
+    <dir>
+       <p>There is significant IP associated with the S3TC format.
+       Existing users probably have executed licenses directly
+       with S3 or its successors (Sonic Blue, S3 Graphics).</p>
+
+       <p>The current ownership of the S3TC IP is unknown to me. It is
+       known that when S3 exited the graphics hardware business, part of
+       their operations were sold to ATI and part were spun off to a joint
+       Taiwanese venture with Via Technologies, called S3 Graphics.</p>
+    </dir>
+    <p><b><font color="#D8D8D8">I, DANIEL BORCA, AM NOT AWARE OF ANY LEGAL ISSUE CAUSED BY RELEASING
+    THIS CODE.</font> Prior to commencement of legal action, the Plaintiff should
+    make an informal demand to Cease and Desist. In deference to the
+    regulations of the Federal Communications Commission, which requires
+    notice prior to filing an action, and in the spirit of cooperation,
+    all complaints, issues and concerns should first be directed to me
+    in an effort to resolve them amicably and promptly. FCC s2250.</b></p>
+    <p/>Daniel Borca<br/>
+    <a href="mailto:dborca%20'at'%20yahoo%20'dot'%20com">dborca 'at' yahoo 'dot' com</a>
+</body>
+
+</html>
diff --git a/reactos/dll/3rdparty/dxtn/docs/texture_compression_FXT1.txt b/reactos/dll/3rdparty/dxtn/docs/texture_compression_FXT1.txt
new file mode 100644 (file)
index 0000000..034e6a5
--- /dev/null
@@ -0,0 +1,619 @@
+Name
+
+    3DFX_texture_compression_FXT1
+
+Name Strings
+
+    GL_3DFX_texture_compression_FXT1
+
+Contact
+
+    Don Mullis, 3dfx Interactive (dwm 'at' 3dfx.com)
+
+Status
+
+    CANDIDATE FOR FINAL DRAFT -- NOT YET COMPLETE
+
+Version
+
+    Draft 0.4, 12 Apr 2000
+
+Number
+
+    206
+
+Dependencies
+
+    OpenGL 1.1 is required.
+    GL_ARB_texture_compression is required.
+    This extension is written against the OpenGL 1.2.1 Specification.
+
+Overview
+
+    This extension additional texture compression functionality 's FXT1
+    format, specific to 3dfxsubject to all the requirements and
+    limitations described by the extension GL_ARB_texture_compression.
+    The FXT1 texture format supports only 2D and 3D images without
+    borders.
+
+    Because 3dfx expects to make continual improvement to its FXT1
+    compressor implementation, 3dfx recommends that to achieve best
+    visual quality applications adopt the following procedure with
+    respect to reuse of textures compressed by the GL:
+
+       1) Save the RENDERER and VERSION strings along with images
+          compressed by the GL;
+       2) Before reuse of the textures, compare the stored strings with
+          strings newly returned from the current GL;
+       3) If out-of-date, repeat the compression and storage steps.
+
+IP Status
+
+    A royalty-free license is available from 3dfx Interactive
+    (http://www.3dfx.com/).
+
+Issues
+
+    (1) Two or only one internalformat tokens:
+       GL_COMPRESSED_RGBA_FXT1_3DFX and GL_COMPRESSED_RGB_FXT1_3DFX, or
+       GL_COMPRESSED_RGBA_FXT1_3DFX only. These names are placeholders,
+       the point in question is whether there should be separate tokens
+       reflecting extrinsic knowledge of whether the image contains any
+       non-unity alpha values. This arises because the FXT1 image
+       format distinguishes non-unity alpha only at the level of an
+       individual 8x4 compression block. If there are two distinct
+       tokens, passing GL_COMPRESSED_RGB_FXT1_3DFX to
+       CompressedTexImage with an image that contained non-unity-alpha
+       blocks would be an error.
+
+       RESOLVED. Two distinct tokens specified. This is largely to
+       follow the usual usage by apps of non-compressed tokens.
+
+    (2) Support for borders.
+
+       RESOLVED.  Not supported.
+
+    (3) Support for TexSubImage at a level more general than that
+       guaranteed by ARB_texture_compression.
+
+       RESOLVED. Not supported; See issue (5) of the
+       GL_ARB_texture_compression spec.
+
+New Procedures and Functions
+
+    None
+
+New Tokens
+
+    Accepted by the <internalformat> parameter of TexImage2D,
+    CopyTexImage2D, TexImage3D, CopyTexImage3D, and by the
+    <internalformat> and <format> parameters of
+    CompressedTexImage2D_ARB, CompressedTexSubImage2D_ARB,
+    CompressedTexImage3D_ARB, CompressedTexSubImage3D_ARB:
+
+       COMPRESSED_RGB_FXT1_3DFX                          0x86B0
+       COMPRESSED_RGBA_FXT1_3DFX                         0x86B1
+
+Additions to Chapter 2 of the OpenGL 1.2.1 Specification (OpenGL Operation)
+
+    None.
+
+Additions to Chapter 3 of the OpenGL 1.2.1 Specification (Rasterization)
+
+    Add Table 3.16.1:  Specific Compressed Internal Formats
+
+       Compressed Internal Format         Base Internal Format
+       ==========================         ====================
+       COMPRESSED_RGB_FXT1_3DFX           RGB
+       COMPRESSED_RGBA_FXT1_3DFX          RGBA
+
+    Add to Section 3.8.2, Alternate Image Specification (adding to the
+    end of the CompressedTexImage section introduced by the
+    ARB_texture_compression spec)
+
+    If <internalformat> is COMPRESSED_RGB_FXT1_3DFX,
+    COMPRESSED_RGBA_FXT1_3DFX, the compressed texture is stored using
+    one of several FXT1 compressed texture image formats. FXT1 texture
+    compression supports only 2D images without borders.
+    CompressedTexImage1DARB and CompressedTexImage3DARB produce an
+    INVALID_ENUM error if <internalformat> is an FXT1 format.
+    CompressedTexImage2DARB will produce an INVALID_OPERATION error if
+    <border> is non-zero.
+
+
+    Add to Section 3.8.2, Alternate Image Specification (adding to the
+    end of the CompressedTexSubImage section introduced by the
+    ARB_texture_compression spec)
+
+    If the internal format of the texture image being modified is
+    COMPRESSED_RGB_FXT1_3DFX, COMPRESSED_RGBA_FXT1_3DFX, the texture is
+    stored using one of the several FXT1 compressed texture image
+    formats. Since the FXT1 texture compression algorithm supports only
+    2D images, CompressedTexSubImage1DARB and CompressedTexSubImage3DARB
+    produce an INVALID_ENUM error if <format> is an FXT1 format.
+
+Additions to Chapter 4 of the OpenGL 1.2.1 Specification (Per-Fragment
+Operations and the Frame Buffer)
+
+    None.
+
+Additions to Chapter 5 of the OpenGL 1.2.1 Specification (Special Functions)
+
+    None.
+
+Additions to Chapter 6 of the OpenGL 1.2.1 Specification (State and
+State Requests)
+
+    None.
+
+Additions to Appendix A of the OpenGL 1.2.1 Specification (Invariance)
+
+    None.
+
+Additions to the AGL/GLX/WGL Specifications
+
+    None.
+
+GLX Protocol
+
+    None.
+
+Errors
+
+    INVALID_ENUM is generated by CompressedTexImage1DARB if
+    <internalformat> is GL_COMPRESSED_RGB_FXT1_3DFX or
+    GL_COMPRESSED_RGBA_FXT1_3DFX.
+
+    INVALID_OPERATION is generated by CompressedTexImage2DARB or
+    CompressedTexImage3DARB if <internalformat> is
+    GL_COMPRESSED_RGB_FXT1_3DFX or GL_COMPRESSED_RGBA_FXT1_3DFX and
+    <border> is not equal to zero.
+
+    INVALID_ENUM is generated by CompressedTexSubImage1DARB if <format>
+    is GL_COMPRESSED_RGB_FXT1_3DFX or GL_COMPRESSED_RGBA_FXT1_3DFX.
+
+Appendix
+
+    FXT1 comprises four different compressed texture formats. Each of
+    the formats compress an 8x4 texel blocks into 128 bits. During the
+    compression phase, the encoder selects one of the four formats for
+    each block based on which encoding scheme results in best overall
+    visual quality. Unused pixel locations along the right or bottom
+    edges within a block should contain a repetition of the values in
+    used locations. The total size of an image is ceil(width/8) *
+    ceil(height/4) * 16 bytes.
+
+    In each compression format, the 32 texels of the 8x4 block are
+    partitioned into two 4x4 sub-blocks according to the following
+    diagram:
+
+        t0  t1  t2  t3   t16 t17 t18 t19
+        t4  t5  t6  t7   t20 t21 t22 t23
+        t8  t9 t10 t11   t24 t25 t26 t27
+       t12 t13 t14 t15   t28 t29 t30 t31
+
+    In the following bit-level descriptions, bits of increasing index
+    are stored in bytes at likewise increasing offsets, i.e. the order
+    is "little-endian".
+
+
+    1. FXT1 Compressed Texture Format CC_HI:
+
+    (rgb555) (3-bit/texel)
+    mode[1:0]  color1  color0  texel 31 to 16  texel 15 to 0
+           2      15      15              48             48
+
+
+           [127:126]  mode[1:0]
+           [125:121]  red of color1
+           [120:116]  green of color1
+           [115:111]  blue of color1
+           [110:106]  red of color0
+           [105:101]  green of color0
+            [100:96]  blue of color0
+             [95:93]  texel 31
+               ...
+             [50:48]  texel 16
+             [47:45]  texel 15
+                ...
+               [2:0]  texel 0
+
+    In CC_HI format, mode = 00b, the 15-bit color1 (RGB555 format) and
+    color0 (RGB555 format) colors are converted into 24-bit RGB888
+    colors by duplicating the upper 3 bits for the 3 LSBs. The 24-bit
+    converted color1 and color0 are then used to linearly interpolate 5
+    more levels of color to create seven total levels of colors and 1
+    alpha (transparent) color. The first seven colors always have
+    alpha=ffh (opaque), while the eighth color is defined to be
+    transparent black (r,g,b=00h, alpha=00h).
+
+    These eight 32-bit colors are used as the contents of an 8-entry (3
+    bit index) lookup table. For all 32 texels in the block, each
+    texel's 3-bit index value is used to index the lookup table, the
+    output from the lookup table representing the 32-bit color
+    (ARGB8888) for that texel.
+
+    Generating RGB888 from RGB555:
+
+           Color1 (red) =   {[125:121], [125:123]}
+           Color1 (green) = {[120:116], [120:118]}
+           Color1 (blue) =  {[115:111], [115:113]}
+
+           Color0 (red) =   {[110:106], [110:108]}
+           Color0 (green) = {[105:101], [105:103]}
+           Color0 (blue) =  {[100:96],  [100:98]}
+
+    Creating seven ARGB8888 colors from two RGB888 colors (operations
+    performed individually for each color channel):
+
+           Color[0] = color0[r,g,b], alpha[0] = ffh
+           Color[1] = (5*color0[r,g,b] + color1[r,g,b] +3 )/6 alpha[1] = ffh
+           Color[2] = (4*color0[r,g,b] + 2*color1[r,g,b] +3 )/6 alpha[2] = ffh
+           Color[3] = (3*color0[r,g,b] + 3*color1[r,g,b] +3 )/6 alpha[3] = ffh
+           Color[4] = (2*color0[r,g,b] + 4*color1[r,g,b] +3 )/6 alpha[4] = ffh
+           Color[5] = (color0[r,g,b] + 5*color1[r,g,b] +3 )/6 alpha[5] = ffh
+           Color[6] = color1[r,g,b], alpha[6] = ffh
+           Color[7] = where r,g,b = 00h, alpha[7]=00h
+
+    Table Lookup:
+          3-bit index of   Color for texel 31 to texel 0
+       texel31 to texel0   (ARGB8888)
+
+                       0   color[0] => {a[7:0], r[7:0], g[7:0], b[7:0]}
+                       1   color[1]
+                       2   color[2]
+                       3   color[3]
+                       4   color[4]
+                       5   color[5]
+                       6   color[6]
+                       7   color[7]
+
+
+    2. FXT1 Compressed Texture Format CC_CHROMA:
+
+    (rgb555) (2-bit/texel)
+    Mode[2:0] unused color3 color2 color1 color0  texel 31 to 16  texel 15 to 0
+           3      1     15     15     15     15              32             32
+
+           [127:125]  mode[2:0]
+               [124]  unused
+           [123:119]  color3(r5)
+           [118:114]  color3(g5)
+           [113:109]  color3(b5)
+           [108:104]  color2(r5)
+            [103:99]  color2(g5)
+             [98:94]  color2(b5)
+             [93:89]  color1(r5)
+             [88:84]  color1(g5)
+             [83:79]  color1(b5)
+             [78:74]  color0(r5)
+             [73:69]  color0(g5)
+             [68:64]  color0(b5)
+             [63:62]  texel 31
+                ...
+             [33:32]  texel 16
+             [31:30]  texel 15
+                ...
+               [1:0]  texel 0
+
+    In CC_CHROMA format, mode=010b, the 15-bit colors color[3:0]
+    (RGB555) are converted into 24-bit RGB888 colors exactly the same as
+    in the CC_HI format via bit replication. Color3 to Color0 are used
+    as they are (after conversion to RGB888 format), but without
+    interpolation. The 24-bit converted colors color3, color2, color1,
+    and color0 are used as the contents of a 4-entry (2-bit index)
+    lookup table. The Alpha channel of the output of the lookup table is
+    always opaque(ffh), regardless of the 2-bit index value. The 32-bit
+    (ARGB8888) color value for each texel is obtained by performing
+    table lookup using that texel's 2-bit index.
+
+    Table Lookup:
+
+           2-bit index of   Color for texel 31 to texel 0
+       texel 31 to texel 0   (ARGB8888)
+
+                        0   color0, alpha = ffh
+                        1   color1, alpha = ffh
+                        2   color2, alpha = ffh
+                        3   color3, alpha = ffh
+
+
+    3. FXT1 Compressed Texture Format CC_MIXED:
+
+    (rgb555) (2-bit/texel)
+    mode[0] glsb[1:0] alpha[0] color3 color2 color1 color0  texel 31to16  texel 15to0
+         1         2        1     15     15     15     15            32           32
+
+
+               [127]  mode[0]
+           [126:125]  glsb[1:0] (lsbs of green for color 1 & color 3)
+               [124]  alpha[0]
+           [123:119]  color3(r5)
+           [118:114]  color3(g5)
+           [113:109]  color3(b5)
+           [108:104]  color2(r5)
+            [103:99]  color2(g5)
+             [98:94]  color2(b5)
+             [93:89]  color1(r5)
+             [88:84]  color1(g5)
+             [83:79]  color1(b5)
+             [78:74]  color0(r5)
+             [73:69]  color0(g5)
+             [68:64]  color0(b5)
+             [63:62]  texel 31
+                ...
+             [33:32]  texel 16
+             [31:30]  texel 15
+                ...
+               [1:0]  texel 0
+
+    In CC_MIXED format, mode[0]=1 (only one bit), color2 and color3 are
+    used for texels 31 to 16, and color0 and color1 are used for texels
+    15 to 0. When alpha[0] = 0, the two pairs of colors (colors 0 and 1
+    for texels 15 to 0 and colors 2 and 3 for texels 31 to 16) are
+    interpreted as 16-bit RGB565 colors. For color1 and color3, the LSB
+    (bit 0) of the green channel comes from the glsb bits
+    (color1.green[0] = bit 125, color3.green[0] = bit 126). For color0
+    and color2, the LSB (bit 0) of the green channel comes from the
+    upper select bit for texel 0 and texel 16, respectively
+    (color0.green[0] = bit 1 xor bit 125, color2.green[0] = bit 33 xor
+    bit 126). The two 16-bit colors are then expanded to a 24-bit RGB888
+    format by bit replication (most significant bits replicated in the
+    least significant bits), and are then used to create 2 more levels
+    of color in between the color0/2 and color1/3 values through linear
+    interpolation. A total of 4 colors are therefore available for 2-bit
+    index per texel selection.
+
+    When alpha[0]=1, color0 and color2 are interpreted as 15-bit RGB555
+    colors, and color 1 and color3 are interpreted as RGB565 colors. For
+    color0 and color2, the 15-bit RGB555 colors are expanded to 24-bit
+    RGB888 colors by bit replication. For color1 and color3, the LSB
+    (bit 0) of the green channel comes from the glsb bits
+    (color1.green[0] = bit 125, color3.green[0] = bit 126), and then bit
+    replication is used to convert from the 16-bit RGB565 format to a
+    24-bit RGB888 format. A third color is created by linear
+    interpolation (interpolating between the converted 24-bit RGB888
+    color0 and color1 for texels 15 to 0, and interpolating between the
+    converted 24-bit RGB888 color2 and color3 for texels 31 to 16).
+    Finally, a fourth color (texel index 0x3) is defined to be
+    transparent black (r,g,b=00h, alpha=00h). A total of 4 colors are
+    therefore available for 2-bit index per texel selection. The 32-bit
+    (ARGB8888) color value for all texels is obtained by performing
+    table lookup using each texel's 2-bit index.
+
+    Creating the 24-bit (RGB888) base colors color3 and color2:
+
+           Color3(red) = {[123:119], [123:121]}
+           Color3(green) = {[118:114], [126], [118:117]}
+           Color3(blue) = {[113:109], [113:111]}
+           Color2(red) = {[108:104], [108:106]}
+           Color2(green) = (alpha[0]=1) ? {[103:99],[103:101]}
+                                        : {[103:99],[33]^[126],[103:102]}
+           Color2(blue) = {[98:94], [98:96]}
+
+    Creating the 24-bit (RGB888) base colors color1 and color0:
+
+           Color1(red) = {[93:89], [93:91]}
+           Color1(green) = {[88:84], [125], [88:87]}
+           Color1(blue) = {[83:79], [83:81]}
+           Color0(red) = {[78:74], [78:76]}
+           Color0(green) = (alpha[0]=1) ? {[73:69, [73:71]}
+                                        : {[73:69], [1]^[125], [73:72]}
+           Color0(blue) = {[68:64], [68:66]}
+
+    When alpha[0]=0, because one of the texel select bits is used to
+    determine a bit of color0 and color2, the software encoder must
+    perform some very tricky operations. The method below describes how
+    to generate color0 and color1 and the associated select bits (the
+    same method applies to determining the lsb of green for color2 and
+    color3):
+
+           1. Determine the 16-bit RGB565 color values for color0 & color1.
+
+           2. Determine the select bits for each pixel in the 4x4 sub-block.
+
+           3. If (pixel[0].select[1] != color0.green[0]^color1.green[0]) then
+              swap color0 &color1, and invert all the select bits.
+
+    Below is a snippet of psuedo-C code to generate bits 0-31, bits
+    64-93 & bit 125 based on the initial color0, color1 and pixel
+    indices:
+
+    struct RGB565 {Byte red; Byte green; Byte blue};
+
+    struct CSels {Byte index[16]};
+
+    // cc_mixed_right_half derives bits[93:64] of the 128 bit data word of a
+    // CC_MIXED non-alpha compression block and returns them in 'bits_64_to_31'.
+    // Plus, as a bonus, you will receive bit 125, containing the lsb of
+    // the green channel of color1, and bits_0_to_31, containing all of the pixel indices.
+    void
+    cc_mixed_right_half( RGB565 color0, RGB565 color1,
+                        CSels pix,
+                        Dword &bits_0_to_31,
+                        Dword &bits_64_to_93,
+                        Bit &bit125)
+    {
+       RGB565 o_color0;
+       RGB565 o_color1;
+
+       // Determine if we need to switch color0 & color1
+       if (((pix.index[0] >> 1) & 1) != ((color0.green ^ color1.green) & 1)) {
+           o_color1 = color0;
+           o_color0 = color1;
+
+           for (int i=0; i<16; i++)
+               pix.index[i] = ~pix.index[i] & 3;
+       } else {
+           o_color0 = color0;
+           o_color1 = color1;
+       }
+
+       // Save lsb of color1.green in bit125
+       bit125 = o_color1.green & 1;
+
+       // Convert color0 & color1 to RGB555, and then munge into bits 64 to 93
+       o_color0.green >>= 1;
+       o_color1.green >>= 1;
+
+       bits_64_to_93 = ( (o_color1.red<<25) | (o_color1.green<<20) | (o_color1.blue<<15)
+                       | (o_color0.red<<10) | (o_color0.green<<5) | (o_color0.blue) );
+
+       // Munge the pixel indices into bits 0 to 31
+       bits_0_to_31 = 0;
+
+       for (int i=0; i<16; i++)
+           bits_0_to_31 |= pix.index[i]<<(i*2);
+    }
+
+
+    Generating the 4-entry lookup table for texels 31 to 16:
+
+       If alpha[0]=0,
+           Color[0] = color2[r,g,b] , alpha=ffh
+           Color[1] = (2 * color2[r,g,b] + color3[r,g,b] + 1) / 3, alpha=ffh
+           Color[2] = (color2[r,g,b] + 2 * color3[r,g,b] +1) / 3, alpha=ffh
+           Color[3] = color3[r,g,b], alpha=ffh
+
+       If alpha[0]=1,
+           Color[0] = color2[r,g,b], alpha=ffh
+           Color[1] = (color2[r,g,b] + color3[r,g,b]) / 2, alpha=ffh
+           Color[2] = color3[r,g,b], alpha=ffh
+           Color[3] = [a,r,g,b] = 00h
+
+    Generating the 4-entry lookup table for texels 15 to 0:
+
+       If alpha[0]=0,
+           Color[0] = color0[r,g,b] , alpha=ffh
+           Color[1] = (2 * color0[r,g,b] + color1[r,g,b] + 1) / 3, alpha=ffh
+           Color[2] = (color0[r,g,b] + 2 * color1[r,g,b] + 1) / 3, alpha=ffh
+           Color[3] = color1[r,g,b], alpha=ffh
+
+       If alpha[0]=1,
+           Color[0] = color0[r,g,b], alpha=ffh
+           Color[1] = (color0[r,g,b] + color1[r,g,b]) / 2, alpha=ffh
+           Color[2] = color1[r,g,b], alpha=ffh
+           Color[3] = [a,r,g,b] = 00h
+
+    Table Lookup:
+             2-bit index of   Color for texel 31 to texel 0
+        texel 31 to texel 0   ARGB8888
+
+                          0   color[0], {a[7:0], r[7:0], g[7:0], b[7:0]}
+                          1   color[1]
+                          2   color[2]
+                          3   color[3]
+
+
+    4. FXT1 Compressed Texture format CC_ALPHA:
+
+    (argb5555) (2-bit/texel)
+    mode[2:0] lerp alpha2 alpha1 alpha0 color2 color1 color0  texel 31 to 16  texel 15 to 0
+           3    1      5      5      5     15     15     15              32             32
+
+           [127:125]  mode[2:0]
+               [124]  lerp
+           [123:119]  color2(a5)
+           [118:114]  color1(a5)
+           [113:109]  color0(a5)
+           [108:104]  color2(r5)
+            [103:99]  color2(g5)
+             [98:94]  color2(b5)
+             [93:89]  color1(r5)
+             [88:84]  color1(g5)
+             [83:79]  color1(b5)
+             [78:74]  color0(r5)
+             [73:69]  color0(g5)
+             [68:64]  color0(b5)
+             [63:62]  texel 31
+                ...
+             [33:32]  texel 16
+             [31:30]  texel 15
+                ...
+               [1:0]  texel 0
+
+    In CC_ALPHA format, mode[2:0]=011b, three 20-bit colors color2,
+    color1 and color0 (ARGB5555) are converted to a 32-bit (ARGB8888)
+    format by duplicating the upper 3-bits for the 3 LSBs (all the color
+    channels and the alpha channel are converted from 5-bit formats to
+    8-bit formats using this bit duplication).
+
+    Creating the 32-bit (RGB8888) base colors color2, color1, and color0:
+
+           Color2(alpha) = {[123:119], [123:121]}
+           Color2(red) = {[108:104], [108:106]}
+           Color2(green) = {[103:99], [103:101]}
+           Color2(blue) = {[98:94], [98:96]}
+           Color1(alpha) = {[118:114], [118:116]}
+           Color1(red) = {[93:89], [93:91]}
+           Color1(green) = {[88:84], [88:86]}
+           Color1(blue) = {[83:79], [83:81]}
+           Color0(alpha) = {[113:109], [113:111]}
+           Color0(red) = {[78:74], [78:76]}
+           Color0(green) = {[73:69], [73:71]}
+           Color0(blue) = {[68:64], [68:66]}
+
+    When lerp = 0 (bit 124 = 0), the converted 32-bit colors color2,
+    color1, and color0 are used directly as the first 3 entries in the
+    4-entry lookup table. The last entry in the 4-entry lookup table,
+    accessed with index=3, is defined to be transparent black (rgb=00h,
+    alpha=00h). A total of 4 colors are therefore available for 2-bit
+    index per texel selection, and the 32-bit (ARGB8888) color value for
+    all texels is obtained by performing table lookup using each texel's
+    2-bit index.
+
+    Table Lookup (when lerp = 0):
+
+       Index of texel 31 to 0   Color for texel 31 to texel 0
+                                (ARGB8888)
+
+                            0    Color[0] = color0 alpha = alpha0
+                            1    Color[1] = color1 alpha = alpha1
+                            2    Color[2] = color2 alpha = alpha2
+                            3    Color[3] = 000000h alpha = 00h
+
+    When lerp = 1 (bit 124 = 1), the converted 32-bit colors color2 and
+    color1 are used as the 32-bit base colors for texels 31 to 16, and
+    the converted 32-bit colors color1 and color0 are used as the base
+    colors for texels 15 to 0. The 32-bit base colors are then used to
+    create 2 more levels of color through linear interpolation. A total
+    of 4 colors are therefore available for 2-bit index per texel
+    selection, and the 32-bit (ARGB8888) color value for all texels is
+    obtained by performing table lookup using each texel's 2-bit index.
+
+    Creating the 4 colors used in the 4-entry lookup table from the
+    32-bit base colors (when lerp = 1):
+
+       For texel 31 to texel 16
+           Color[0] = color2[a,r,g,b]
+           Color[1] = (2 * color2[a,r,g,b] + color1[a,r,g,b] + 1) / 3
+           Color[2] = (color2[a,r,g,b] + 2 * color1[a,r,g,b] +1) / 3
+           Color[3] = color1[a,r,g,b]
+
+       For texel 15 to texel 0
+           Color[0] = color0[a,r,g,b]
+           Color[1] = (2 * color0[a,r,g,b] + color1[a,r,g,b] +1) / 3
+           Color[2] = (color0[a,r,g,b] + 2 * color1[a,r,g,b] +1) / 3
+           Color[3] = color1[a,r,g,b]
+
+    Table Lookup (when lerp = 1):
+
+       Index of texel 31 to 0   Color for texel 31 to texel 0
+                                (ARGB8888)
+
+                            0   color[0]
+                            1   color[1]
+                            2   color[2]
+                            3   color[3]
+
+Revision History
+
+    0.1,  01/12/00 dwm: Initial revision.
+    0.2,  02/09/00 dwm: Respond to feedback from Intel.
+    0.3,  02/23/00 dwm: Respond to feedback from Intel.
+    0.4,  04/12/00 dwm: Updated to reflect final version of the
+                       ARB_texture_compression extension.
+
+
+Copyright 1999-2000, 3dfx Interactive, Inc.
+All rights reserved.
diff --git a/reactos/dll/3rdparty/dxtn/docs/texture_compression_s3tc.txt b/reactos/dll/3rdparty/dxtn/docs/texture_compression_s3tc.txt
new file mode 100644 (file)
index 0000000..b810852
--- /dev/null
@@ -0,0 +1,477 @@
+Name
+
+    EXT_texture_compression_s3tc
+
+Name Strings
+
+    GL_EXT_texture_compression_s3tc
+
+Contact
+
+    Pat Brown, Intel Corporation (patrick.r.brown 'at' intel.com)
+
+Status
+
+    CANDIDATE FOR FINAL DRAFT -- NOT YET COMPLETE
+
+Version
+    
+    Draft 0.7, 11 April 2000
+
+Number
+
+    198
+
+Dependencies
+
+    OpenGL 1.1 is required.
+
+    GL_ARB_texture_compression is required.
+
+    This extension is written against the OpenGL 1.2.1 Specification.
+
+Overview
+
+    This extension provides additional texture compression functionality
+    specific to S3's S3TC format (called DXTC in Microsoft's DirectX API),
+    subject to all the requirements and limitations described by the extension
+    GL_ARB_texture_compression.
+
+    This extension supports DXT1, DXT3, and DXT5 texture compression formats.
+    For the DXT1 image format, this specification supports an RGB-only mode
+    and a special RGBA mode with single-bit "transparent" alpha.
+
+IP Status
+
+    Contact S3 Incorporated (http://www.s3.com) regarding any intellectual
+    property issues associated with implementing this extension.
+
+    WARNING:  Vendors able to support S3TC texture compression in Direct3D
+    drivers do not necessarily have the right to use the same functionality in
+    OpenGL.
+
+Issues
+
+    (1) Should DXT2 and DXT4 (premultiplied alpha) formats be supported?
+
+        RESOLVED:  No -- insufficient interest.  Supporting DXT2 and DXT4
+        would require some rework to the TexEnv definition (maybe add a new
+        base internal format RGBA_PREMULTIPLIED_ALPHA) for these formats.
+        Note that the EXT_texture_env_combine extension (which extends normal
+        TexEnv modes) can be used to support textures with premultipled alpha.
+
+    (2) Should generic "RGB_S3TC_EXT" and "RGBA_S3TC_EXT" enums be supported
+        or should we use only the DXT<n> enums?  
+
+        RESOLVED:  No.  A generic RGBA_S3TC_EXT is problematic because DXT3
+        and DXT5 are both nominally RGBA (and DXT1 with the 1-bit alpha is
+        also) yet one format must be chosen up front.
+
+    (3) Should TexSubImage support all block-aligned edits or just the minimal
+        functionality required by the the ARB_texture_compression extension?
+
+        RESOLVED:  Allow all valid block-aligned edits.
+
+    (4) A pre-compressed image with a DXT1 format can be used as either an
+        RGB_S3TC_DXT1 or an RGBA_S3TC_DXT1 image.  If the image has
+        transparent texels, how are they treated in each format?
+
+        RESOLVED:  The renderer has to make sure that an RGB_S3TC_DXT1 format
+        is decoded as RGB (where alpha is effectively one for all texels),
+        while RGBA_S3TC_DXT1 is decoded as RGBA (where alpha is zero for all
+        texels with "transparent" encodings).  Otherwise, the formats are
+        identical.
+
+    (5) Is the encoding of the RGB components for DXT1 formats correct in this
+        spec?  MSDN documentation does not specify an RGB color for the
+        "transparent" encoding.  Is it really black?
+
+        RESOLVED:  Yes.  The specification for the DXT1 format initially
+        required black, but later changed that requirement to a
+        recommendation.  All vendors involved in the definition of this
+        specification support black.  In addition, specifying black has a
+        useful behavior.
+
+        When blending multiple texels (GL_LINEAR filtering), mixing opaque and
+        transparent samples is problematic.  Defining a black color on
+        transparent texels achieves a sensible result that works like a
+        texture with premultiplied alpha.  For example, if three opaque white
+        and one transparent sample is being averaged, the result would be a
+        75% intensity gray (with an alpha of 75%).  This is the same result on
+        the color channels as would be obtained using a white color, 75%
+        alpha, and a SRC_ALPHA blend factor.
+
+    (6) Is the encoding of the RGB components for DXT3 and DXT5 formats
+        correct in this spec?  MSDN documentation suggests that the RGB blocks
+        for DXT3 and DXT5 are decoded as described the the DXT1 format.
+
+        RESOLVED:  Yes -- this appears to be a bug in the MSDN documentation.
+        The specification for the DXT2-DXT5 formats require decoding using the
+        opaque block encoding, regardless of the relative values of "color0"
+        and "color1".
+
+New Procedures and Functions
+
+    None.
+
+New Tokens
+
+    Accepted by the <internalformat> parameter of TexImage2D, CopyTexImage2D,
+    and CompressedTexImage2DARB and the <format> parameter of
+    CompressedTexSubImage2DARB:
+
+        COMPRESSED_RGB_S3TC_DXT1_EXT                   0x83F0
+        COMPRESSED_RGBA_S3TC_DXT1_EXT                  0x83F1
+        COMPRESSED_RGBA_S3TC_DXT3_EXT                  0x83F2
+        COMPRESSED_RGBA_S3TC_DXT5_EXT                  0x83F3
+
+Additions to Chapter 2 of the OpenGL 1.2.1 Specification (OpenGL Operation)
+
+    None.
+
+Additions to Chapter 3 of the OpenGL 1.2.1 Specification (Rasterization)
+
+    Add to Table 3.16.1:  Specific Compressed Internal Formats
+
+        Compressed Internal Format         Base Internal Format
+        ==========================         ====================
+        COMPRESSED_RGB_S3TC_DXT1_EXT       RGB
+        COMPRESSED_RGBA_S3TC_DXT1_EXT      RGBA
+        COMPRESSED_RGBA_S3TC_DXT3_EXT      RGBA
+        COMPRESSED_RGBA_S3TC_DXT5_EXT      RGBA
+
+    
+    Modify Section 3.8.2, Alternate Image Specification
+
+    (add to end of TexSubImage discussion, p.123 -- after edit from the
+    ARB_texture_compression spec)
+
+    If the internal format of the texture image being modified is
+    COMPRESSED_RGB_S3TC_DXT1_EXT, COMPRESSED_RGBA_S3TC_DXT1_EXT,
+    COMPRESSED_RGBA_S3TC_DXT3_EXT, or COMPRESSED_RGBA_S3TC_DXT5_EXT, the
+    texture is stored using one of the several S3TC compressed texture image
+    formats.  Such images are easily edited along 4x4 texel boundaries, so the
+    limitations on TexSubImage2D or CopyTexSubImage2D parameters are relaxed.
+    TexSubImage2D and CopyTexSubImage2D will result in an INVALID_OPERATION
+    error only if one of the following conditions occurs:
+
+        * <width> is not a multiple of four or equal to TEXTURE_WIDTH.
+        * <height> is not a multiple of four or equal to TEXTURE_HEIGHT.
+        * <xoffset> or <yoffset> is not a multiple of four.
+
+
+    Add to Section 3.8.2, Alternate Image Specification (adding to the end of
+    the CompressedTexImage section introduced by the ARB_texture_compression
+    spec)
+
+    If <internalformat> is COMPRESSED_RGB_S3TC_DXT1_EXT,
+    COMPRESSED_RGBA_S3TC_DXT1_EXT, COMPRESSED_RGBA_S3TC_DXT3_EXT, or
+    COMPRESSED_RGBA_S3TC_DXT5_EXT, the compressed texture is stored using one
+    of several S3TC compressed texture image formats.  The S3TC texture
+    compression algorithm supports only 2D images without borders.
+    CompressedTexImage1DARB and CompressedTexImage3DARB produce an
+    INVALID_ENUM error if <internalformat> is an S3TC format.
+    CompressedTexImage2DARB will produce an INVALID_OPERATION error if
+    <border> is non-zero.
+
+
+    Add to Section 3.8.2, Alternate Image Specification (adding to the end of
+    the CompressedTexSubImage section introduced by the
+    ARB_texture_compression spec)
+
+    If the internal format of the texture image being modified is
+    COMPRESSED_RGB_S3TC_DXT1_EXT, COMPRESSED_RGBA_S3TC_DXT1_EXT,
+    COMPRESSED_RGBA_S3TC_DXT3_EXT, or COMPRESSED_RGBA_S3TC_DXT5_EXT, the
+    texture is stored using one of the several S3TC compressed texture image
+    formats.  Since the S3TC texture compression algorithm supports only 2D
+    images, CompressedTexSubImage1DARB and CompressedTexSubImage3DARB produce
+    an INVALID_ENUM error if <format> is an S3TC format.  Since S3TC images
+    are easily edited along 4x4 texel boundaries, the limitations on
+    CompressedTexSubImage2D are relaxed.  CompressedTexSubImage2D will result
+    in an INVALID_OPERATION error only if one of the following conditions
+    occurs:
+
+        * <width> is not a multiple of four or equal to TEXTURE_WIDTH.
+        * <height> is not a multiple of four or equal to TEXTURE_HEIGHT.
+        * <xoffset> or <yoffset> is not a multiple of four.
+
+
+Additions to Chapter 4 of the OpenGL 1.2.1 Specification (Per-Fragment
+Operations and the Frame Buffer)
+
+    None.
+
+Additions to Chapter 5 of the OpenGL 1.2.1 Specification (Special Functions)
+
+    None.
+
+Additions to Chapter 6 of the OpenGL 1.2.1 Specification (State and
+State Requests)
+
+    None.
+
+Additions to Appendix A of the OpenGL 1.2.1 Specification (Invariance)
+
+    None.
+
+Additions to the AGL/GLX/WGL Specifications
+
+    None.
+
+GLX Protocol
+
+    None.
+
+Errors
+
+    INVALID_ENUM is generated by CompressedTexImage1DARB or
+    CompressedTexImage3DARB if <internalformat> is
+    COMPRESSED_RGB_S3TC_DXT1_EXT, COMPRESSED_RGBA_S3TC_DXT1_EXT,
+    COMPRESSED_RGBA_S3TC_DXT3_EXT, or COMPRESSED_RGBA_S3TC_DXT5_EXT.
+
+    INVALID_OPERATION is generated by CompressedTexImage2DARB if if
+    <internalformat> is COMPRESSED_RGB_S3TC_DXT1_EXT,
+    COMPRESSED_RGBA_S3TC_DXT1_EXT, COMPRESSED_RGBA_S3TC_DXT3_EXT, or
+    COMPRESSED_RGBA_S3TC_DXT5_EXT and <border> is not equal to zero.
+
+    INVALID_ENUM is generated by CompressedTexSubImage1DARB or
+    CompressedTexSubImage3DARB if <format> is COMPRESSED_RGB_S3TC_DXT1_EXT,
+    COMPRESSED_RGBA_S3TC_DXT1_EXT, COMPRESSED_RGBA_S3TC_DXT3_EXT, or
+    COMPRESSED_RGBA_S3TC_DXT5_EXT.
+
+    INVALID_OPERATION is generated by TexSubImage2D CopyTexSubImage2D, or
+    CompressedTexSubImage2D if INTERNAL_FORMAT is
+    COMPRESSED_RGB_S3TC_DXT1_EXT, COMPRESSED_RGBA_S3TC_DXT1_EXT,
+    COMPRESSED_RGBA_S3TC_DXT3_EXT, or COMPRESSED_RGBA_S3TC_DXT5_EXT and any of
+    the following apply: <width> is not a multiple of four or equal to
+    TEXTURE_WIDTH; <height> is not a multiple of four or equal to
+    TEXTURE_HEIGHT; <xoffset> or <yoffset> is not a multiple of four.
+
+
+    The following restrictions from the ARB_texture_compression specification
+    do not apply to S3TC texture formats, since subimage modification is
+    straightforward as long as the subimage is properly aligned.
+
+    DELETE: INVALID_OPERATION is generated by TexSubImage1D, TexSubImage2D,
+    DELETE: TexSubImage3D, CopyTexSubImage1D, CopyTexSubImage2D, or
+    DELETE: CopyTexSubImage3D if the internal format of the texture image is
+    DELETE: compressed and <xoffset>, <yoffset>, or <zoffset> does not equal
+    DELETE: -b, where b is value of TEXTURE_BORDER.
+
+    DELETE: INVALID_VALUE is generated by CompressedTexSubImage1DARB,
+    DELETE: CompressedTexSubImage2DARB, or CompressedTexSubImage3DARB if the
+    DELETE: entire texture image is not being edited:  if <xoffset>,
+    DELETE: <yoffset>, or <zoffset> is greater than -b, <xoffset> + <width> is
+    DELETE: less than w+b, <yoffset> + <height> is less than h+b, or <zoffset>
+    DELETE: + <depth> is less than d+b, where b is the value of
+    DELETE: TEXTURE_BORDER, w is the value of TEXTURE_WIDTH, h is the value of
+    DELETE: TEXTURE_HEIGHT, and d is the value of TEXTURE_DEPTH.
+
+    See also errors in the GL_ARB_texture_compression specification.
+
+New State
+
+    None.
+
+Appendix
+
+    S3TC Compressed Texture Image Formats
+
+    Compressed texture images stored using the S3TC compressed image formats
+    are represented as a collection of 4x4 texel blocks, where each block
+    contains 64 or 128 bits of texel data.  The image is encoded as a normal
+    2D raster image in which each 4x4 block is treated as a single pixel.  If
+    an S3TC image has a width or height less than four, the data corresponding
+    to texels outside the image are irrelevant and undefined.
+
+    When an S3TC image with a width of <w>, height of <h>, and block size of
+    <blocksize> (8 or 16 bytes) is decoded, the corresponding image size (in
+    bytes) is:
+    
+        ceil(<w>/4) * ceil(<h>/4) * blocksize.
+
+    When decoding an S3TC image, the block containing the texel at offset
+    (<x>, <y>) begins at an offset (in bytes) relative to the beginning of the
+    image of:
+
+        blocksize * (ceil(<w>/4) * floor(<y>/4) + floor(<x>/4)).
+    
+
+    There are four distinct S3TC image formats:
+
+    COMPRESSED_RGB_S3TC_DXT1_EXT:  Each 4x4 block of texels consists of 64
+    bits of RGB image data.  
+
+    Each RGB image data block is encoded as a sequence of 8 bytes, called (in
+    order of increasing address):
+
+            c0_lo, c0_hi, c1_lo, c1_hi, bits_0, bits_1, bits_2, bits_3
+
+        The 8 bytes of the block are decoded into three quantities:
+
+            color0 = c0_lo + c0_hi * 256
+            color1 = c1_lo + c1_hi * 256
+            bits   = bits_0 + 256 * (bits_1 + 256 * (bits_2 + 256 * bits_3))
+        
+        color0 and color1 are 16-bit unsigned integers that are unpacked to
+        RGB colors RGB0 and RGB1 as though they were 16-bit packed pixels with
+        a <format> of RGB and a type of UNSIGNED_SHORT_5_6_5.
+
+        bits is a 32-bit unsigned integer, from which a two-bit control code
+        is extracted for a texel at location (x,y) in the block using:
+
+            code(x,y) = bits[2*(4*y+x)+1..2*(4*y+x)+0]
+        
+        where bit 31 is the most significant and bit 0 is the least
+        significant bit.
+
+        The RGB color for a texel at location (x,y) in the block is given by:
+
+            RGB0,              if color0 > color1 and code(x,y) == 0
+            RGB1,              if color0 > color1 and code(x,y) == 1
+            (2*RGB0+RGB1)/3,   if color0 > color1 and code(x,y) == 2
+            (RGB0+2*RGB1)/3,   if color0 > color1 and code(x,y) == 3
+
+            RGB0,              if color0 <= color1 and code(x,y) == 0
+            RGB1,              if color0 <= color1 and code(x,y) == 1
+            (RGB0+RGB1)/2,     if color0 <= color1 and code(x,y) == 2
+            BLACK,             if color0 <= color1 and code(x,y) == 3
+
+        Arithmetic operations are done per component, and BLACK refers to an
+        RGB color where red, green, and blue are all zero.
+
+    Since this image has an RGB format, there is no alpha component and the
+    image is considered fully opaque.
+
+
+    COMPRESSED_RGBA_S3TC_DXT1_EXT:  Each 4x4 block of texels consists of 64
+    bits of RGB image data and minimal alpha information.  The RGB components
+    of a texel are extracted in the same way as COMPRESSED_RGB_S3TC_DXT1_EXT.
+        The alpha component for a texel at location (x,y) in the block is
+        given by:
+
+            0.0,               if color0 <= color1 and code(x,y) == 3
+            1.0,               otherwise
+
+        IMPORTANT:  When encoding an RGBA image into a format using 1-bit
+        alpha, any texels with an alpha component less than 0.5 end up with an
+        alpha of 0.0 and any texels with an alpha component greater than or
+        equal to 0.5 end up with an alpha of 1.0.  When encoding an RGBA image
+        into the COMPRESSED_RGBA_S3TC_DXT1_EXT format, the resulting red,
+        green, and blue components of any texels with a final alpha of 0.0
+        will automatically be zero (black).  If this behavior is not desired
+        by an application, it should not use COMPRESSED_RGBA_S3TC_DXT1_EXT.
+        This format will never be used when a generic compressed internal
+        format (Table 3.16.2) is specified, although the nearly identical
+        format COMPRESSED_RGB_S3TC_DXT1_EXT (above) may be.
+
+
+    COMPRESSED_RGBA_S3TC_DXT3_EXT:  Each 4x4 block of texels consists of 64
+    bits of uncompressed alpha image data followed by 64 bits of RGB image
+    data.  
+
+    Each RGB image data block is encoded according to the
+    COMPRESSED_RGB_S3TC_DXT1_EXT format, with the exception that the two code
+    bits always use the non-transparent encodings.  In other words, they are
+    treated as though color0 > color1, regardless of the actual values of
+    color0 and color1.
+
+    Each alpha image data block is encoded as a sequence of 8 bytes, called
+    (in order of increasing address):
+
+            a0, a1, a2, a3, a4, a5, a6, a7
+
+        The 8 bytes of the block are decoded into one 64-bit integer:
+
+            alpha = a0 + 256 * (a1 + 256 * (a2 + 256 * (a3 + 256 * (a4 +
+                         256 * (a5 + 256 * (a6 + 256 * a7))))))
+
+        alpha is a 64-bit unsigned integer, from which a four-bit alpha value
+        is extracted for a texel at location (x,y) in the block using:
+
+            alpha(x,y) = bits[4*(4*y+x)+3..4*(4*y+x)+0]
+
+        where bit 63 is the most significant and bit 0 is the least
+        significant bit.
+
+        The alpha component for a texel at location (x,y) in the block is
+        given by alpha(x,y) / 15.
+
+    COMPRESSED_RGBA_S3TC_DXT5_EXT:  Each 4x4 block of texels consists of 64
+    bits of compressed alpha image data followed by 64 bits of RGB image data.
+
+    Each RGB image data block is encoded according to the
+    COMPRESSED_RGB_S3TC_DXT1_EXT format, with the exception that the two code
+    bits always use the non-transparent encodings.  In other words, they are
+    treated as though color0 > color1, regardless of the actual values of
+    color0 and color1.
+
+    Each alpha image data block is encoded as a sequence of 8 bytes, called
+    (in order of increasing address):
+
+        alpha0, alpha1, bits_0, bits_1, bits_2, bits_3, bits_4, bits_5
+
+        The alpha0 and alpha1 are 8-bit unsigned bytesw converted to alpha
+        components by multiplying by 1/255.
+
+        The 6 "bits" bytes of the block are decoded into one 48-bit integer:
+
+          bits = bits_0 + 256 * (bits_1 + 256 * (bits_2 + 256 * (bits_3 + 
+                          256 * (bits_4 + 256 * bits_5))))
+
+        bits is a 48-bit unsigned integer, from which a three-bit control code
+        is extracted for a texel at location (x,y) in the block using:
+
+            code(x,y) = bits[3*(4*y+x)+1..3*(4*y+x)+0]
+
+        where bit 47 is the most significant and bit 0 is the least
+        significant bit.
+
+        The alpha component for a texel at location (x,y) in the block is
+        given by:
+
+              alpha0,                   code(x,y) == 0
+              alpha1,                   code(x,y) == 1
+
+              (6*alpha0 + 1*alpha1)/7,  alpha0 > alpha1 and code(x,y) == 2
+              (5*alpha0 + 2*alpha1)/7,  alpha0 > alpha1 and code(x,y) == 3
+              (4*alpha0 + 3*alpha1)/7,  alpha0 > alpha1 and code(x,y) == 4
+              (3*alpha0 + 4*alpha1)/7,  alpha0 > alpha1 and code(x,y) == 5
+              (2*alpha0 + 5*alpha1)/7,  alpha0 > alpha1 and code(x,y) == 6
+              (1*alpha0 + 6*alpha1)/7,  alpha0 > alpha1 and code(x,y) == 7
+
+              (4*alpha0 + 1*alpha1)/5,  alpha0 <= alpha1 and code(x,y) == 2
+              (3*alpha0 + 2*alpha1)/5,  alpha0 <= alpha1 and code(x,y) == 3
+              (2*alpha0 + 3*alpha1)/5,  alpha0 <= alpha1 and code(x,y) == 4
+              (1*alpha0 + 4*alpha1)/5,  alpha0 <= alpha1 and code(x,y) == 5
+              0.0,                      alpha0 <= alpha1 and code(x,y) == 6
+              1.0,                      alpha0 <= alpha1 and code(x,y) == 7
+
+
+Revision History
+
+    0.7,  04/11/00 prbrown1:  Added issues on DXT1, DXT3, and DXT5 encodings
+                              where the MSDN documentation doesn't match what
+                              is really done.  Added enum values from the
+                              extension registry.
+
+    0.4,  03/28/00 prbrown1:  Updated to reflect final version of the
+                              ARB_texture_compression extension.  Allowed
+                              block-aligned TexSubImage calls.
+
+    0.3,  03/07/00 prbrown1:  Resolved issues pertaining to the format of RGB
+                              blocks in the DXT3 and DXT5 formats (they don't
+                              ever use the "transparent" encoding).  Fixed
+                              decoding of DXT1 blocks.  Pointed out issue of
+                              "transparent" texels in DXT1 encodings having
+                              different behaviors for RGB and RGBA internal
+                              formats.
+
+    0.2,  02/23/00 prbrown1:  Minor revisions; added several issues.
+
+    0.11, 02/17/00 prbrown1:  Slight modification to error semantics
+      (INVALID_ENUM instead of INVALID_OPERATION).
+
+    0.1,  02/15/00 prbrown1:  Initial revision.
diff --git a/reactos/dll/3rdparty/dxtn/docs/vmath.txt b/reactos/dll/3rdparty/dxtn/docs/vmath.txt
new file mode 100644 (file)
index 0000000..c60109c
--- /dev/null
@@ -0,0 +1,92 @@
+/*
+ * FXT1 codec
+ * Version:  1.0
+ *
+ * Copyright (C) 2004  Daniel Borca   All Rights Reserved.
+ *
+ * this is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * this is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING.  If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.       
+ */
+
+
+Problem:
+~~~~~~~~
+having 3 points P1(x1, y1), P2(x2, y2) and P3(x3, y3), we need to find
+a point P(x, y) on the P1-P2 line, so that distance form P3 to that P is
+minimal.  we shall use the oblong squared distance function:
+       d(P1, P2) = (X*(x2 - x1))^ + (Y*(y2 - y1))^
+
+Solution:
+~~~~~~~~~
+analytical equation of P1-P2 line:
+        x - x1    y - y1
+       ------- = ------- = t
+       x2 - x1   y2 - y1
+
+       or
+
+       x = t * (x2 - x1) + x1
+       y = t * (y2 - y1) + y1
+
+       where
+
+       x1 <= x <= x2  ==>  0 <= t <= 1
+
+thus d(P3, P) will be:
+       d = (X*(x3 - x))^ + (Y*(y3 - y))^
+         = (X*(x3 - (t * (x2 - x1) + x1)))^ + (Y*(y3 - (t * (x2 - x1) + x1)))^
+         = X^*(x3 - x1)^ + Y^*(y3 - y1)^
+         - 2 * t * (X^*(x3 - x1)*dx + Y^*(y3 - y1)*dy)
+         + t^ * (X^*dx^ + Y^*dy^)
+
+       where dx = (x2 - x1) and dy = (y2 - y1)
+
+given the function f = C + Bt + At^, we can find its extrema by using the
+first derivative:
+       (f' = 2At + B) = 0 when t = -B / 2A
+
+having that said, d will have a minimum at:
+              X^*(x3 - x1)*dx + Y^*(y3 - y1)*dy
+       tmin = ---------------------------------
+                       X^*dx^ + Y^*dy^
+
+                        X^*dx                  Y^*dy        x1*X^*dx + y1*Y^*dy
+            = x3 * --------------- + y3 * --------------- - -------------------
+                   X^*dx^ + Y^*dy^        X^*dx^ + Y^*dy^     X^*dx^ + Y^*dy^
+
+we can note:
+                     X^*dx            Y^*dy
+       ivec = ( ---------------, --------------- )
+                X^*dx^ + Y^*dy^  X^*dx^ + Y^*dy^
+
+                x1*X^*dx + y1*Y^*dy
+       base = - -------------------
+                  X^*dx^ + Y^*dy^
+
+       tmin = ivecx * x3 + ivecy * y3 + base
+
+discretizing the line with N equidistant points, we scale:
+                 N * X^*dx        N * Y^*dy
+       iv = ( ---------------, --------------- )
+              X^*dx^ + Y^*dy^  X^*dx^ + Y^*dy^
+
+                 x1*X^*dx + y1*Y^*dy
+       b = - N * -------------------
+                   X^*dx^ + Y^*dy^
+
+       n = (iv . P3) + b
+
+       Note1: this formula stands for n-component vector
+       Note2: (int)n = {0, 1, ... N}, because 0 <= t <= 1
+       Note3: when X=Y=1, d is squared euclidean distance!
diff --git a/reactos/dll/3rdparty/dxtn/dxtn.c b/reactos/dll/3rdparty/dxtn/dxtn.c
new file mode 100644 (file)
index 0000000..e6e5988
--- /dev/null
@@ -0,0 +1,757 @@
+/*
+ * DXTn codec
+ * Version:  1.1
+ *
+ * Copyright (C) 2004  Daniel Borca   All Rights Reserved.
+ *
+ * this is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * this is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING.  If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.       
+ */
+
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "types.h"
+#include "internal.h"
+#include "dxtn.h"
+
+
+/***************************************************************************\
+ * DXTn encoder
+ *
+ * The encoder was built by reversing the decoder,
+ * and is vaguely based on FXT1 codec. Note that this code
+ * is merely a proof of concept, since it is highly UNoptimized!
+\***************************************************************************/
+
+
+#define MAX_COMP 4 /* ever needed maximum number of components in texel */
+#define MAX_VECT 4 /* ever needed maximum number of base vectors to find */
+#define N_TEXELS 16 /* number of texels in a block (always 16) */
+#define COLOR565(v) (word)((((v)[RCOMP] & 0xf8) << 8) | (((v)[GCOMP] & 0xfc) << 3) | ((v)[BCOMP] >> 3))
+
+
+static const int dxtn_color_tlat[2][4] = {
+    { 0, 2, 3, 1 },
+    { 0, 2, 1, 3 }
+};
+
+static const int dxtn_alpha_tlat[2][8] = {
+    { 0, 2, 3, 4, 5, 6, 7, 1 },
+    { 0, 2, 3, 4, 5, 1, 6, 7 }
+};
+
+
+static void
+dxt1_rgb_quantize (dword *cc, const byte *lines[], int comps)
+{
+    float b, iv[MAX_COMP];   /* interpolation vector */
+
+    dword hi; /* high doubleword */
+    int color0, color1;
+    int n_vect;
+    const int n_comp = 3;
+    int black = 0;
+
+    int minSum = 2000; /* big enough */
+    int maxSum = -1; /* small enough */
+    int minCol = 0; /* phoudoin: silent compiler! */
+    int maxCol = 0; /* phoudoin: silent compiler! */
+
+    byte input[N_TEXELS][MAX_COMP];
+    int i, k, l;
+
+    /* make the whole block opaque */
+    /* we will NEVER reference ACOMP of any pixel */
+
+    /* 4 texels each line */
+    for (l = 0; l < 4; l++) {
+       for (k = 0; k < 4; k++) {
+           for (i = 0; i < comps; i++) {
+               input[k + l * 4][i] = *lines[l]++;
+           }
+       }
+    }
+
+    /* Our solution here is to find the darkest and brightest colors in
+     * the 4x4 tile and use those as the two representative colors.
+     * There are probably better algorithms to use (histogram-based).
+     */
+    for (k = 0; k < N_TEXELS; k++) {
+       int sum = 0;
+       for (i = 0; i < n_comp; i++) {
+           sum += input[k][i];
+       }
+       if (minSum > sum) {
+           minSum = sum;
+           minCol = k;
+       }
+       if (maxSum < sum) {
+           maxSum = sum;
+           maxCol = k;
+       }
+       if (sum == 0) {
+           black = 1;
+       }
+    }
+
+    color0 = COLOR565(input[minCol]);
+    color1 = COLOR565(input[maxCol]);
+
+    if (color0 == color1) {
+       /* we'll use 3-vector */
+       cc[0] = color0 | (color1 << 16);
+       hi = black ? -1 : 0;
+    } else {
+       if (black && ((color0 == 0) || (color1 == 0))) {
+           /* we still can use 4-vector */
+           black = 0;
+       }
+
+       if (black ^ (color0 <= color1)) {
+           int aux;
+           aux = color0;
+           color0 = color1;
+           color1 = aux;
+           aux = minCol;
+           minCol = maxCol;
+           maxCol = aux;
+       }
+       n_vect = (color0 <= color1) ? 2 : 3;
+
+       MAKEIVEC(n_vect, n_comp, iv, b, input[minCol], input[maxCol]);
+
+       /* add in texels */
+       cc[0] = color0 | (color1 << 16);
+       hi = 0;
+       for (k = N_TEXELS - 1; k >= 0; k--) {
+           int texel = 3;
+           int sum = 0;
+           if (black) {
+               for (i = 0; i < n_comp; i++) {
+                   sum += input[k][i];
+               }
+           }
+           if (!black || sum) {
+               /* interpolate color */
+               CALCCDOT(texel, n_vect, n_comp, iv, b, input[k]);
+               texel = dxtn_color_tlat[black][texel];
+           }
+           /* add in texel */
+           hi <<= 2;
+           hi |= texel;
+       }
+    }
+    cc[1] = hi;
+}
+
+
+static void
+dxt1_rgba_quantize (dword *cc, const byte *lines[], int comps)
+{
+    float b, iv[MAX_COMP];     /* interpolation vector */
+
+    dword hi;          /* high doubleword */
+    int color0, color1;
+    int n_vect;
+    const int n_comp = 3;
+    int transparent = 0;
+
+    int minSum = 2000;         /* big enough */
+    int maxSum = -1;           /* small enough */
+    int minCol = 0;            /* phoudoin: silent compiler! */
+    int maxCol = 0;            /* phoudoin: silent compiler! */
+
+    byte input[N_TEXELS][MAX_COMP];
+    int i, k, l;
+
+    if (comps == 3) {
+       /* make the whole block opaque */
+       memset(input, -1, sizeof(input));
+    }
+
+    /* 4 texels each line */
+    for (l = 0; l < 4; l++) {
+       for (k = 0; k < 4; k++) {
+           for (i = 0; i < comps; i++) {
+               input[k + l * 4][i] = *lines[l]++;
+           }
+       }
+    }
+
+    /* Our solution here is to find the darkest and brightest colors in
+     * the 4x4 tile and use those as the two representative colors.
+     * There are probably better algorithms to use (histogram-based).
+     */
+    for (k = 0; k < N_TEXELS; k++) {
+       int sum = 0;
+       for (i = 0; i < n_comp; i++) {
+           sum += input[k][i];
+       }
+       if (minSum > sum) {
+           minSum = sum;
+           minCol = k;
+       }
+       if (maxSum < sum) {
+           maxSum = sum;
+           maxCol = k;
+       }
+       if (input[k][ACOMP] < 128) {
+           transparent = 1;
+       }
+    }
+
+    color0 = COLOR565(input[minCol]);
+    color1 = COLOR565(input[maxCol]);
+
+    if (color0 == color1) {
+       /* we'll use 3-vector */
+       cc[0] = color0 | (color1 << 16);
+       hi = transparent ? -1 : 0;
+    } else {
+       if (transparent ^ (color0 <= color1)) {
+           int aux;
+           aux = color0;
+           color0 = color1;
+           color1 = aux;
+           aux = minCol;
+           minCol = maxCol;
+           maxCol = aux;
+       }
+       n_vect = (color0 <= color1) ? 2 : 3;
+
+       MAKEIVEC(n_vect, n_comp, iv, b, input[minCol], input[maxCol]);
+
+       /* add in texels */
+       cc[0] = color0 | (color1 << 16);
+       hi = 0;
+       for (k = N_TEXELS - 1; k >= 0; k--) {
+           int texel = 3;
+           if (input[k][ACOMP] >= 128) {
+               /* interpolate color */
+               CALCCDOT(texel, n_vect, n_comp, iv, b, input[k]);
+               texel = dxtn_color_tlat[transparent][texel];
+           }
+           /* add in texel */
+           hi <<= 2;
+           hi |= texel;
+       }
+    }
+    cc[1] = hi;
+}
+
+
+static void
+dxt3_rgba_quantize (dword *cc, const byte *lines[], int comps)
+{
+    float b, iv[MAX_COMP];     /* interpolation vector */
+
+    dword lolo, lohi;  /* low quadword: lo dword, hi dword */
+    dword hihi;                /* high quadword: high dword */
+    int color0, color1;
+    const int n_vect = 3;
+    const int n_comp = 3;
+
+    int minSum = 2000;         /* big enough */
+    int maxSum = -1;           /* small enough */
+    int minCol = 0;            /* phoudoin: silent compiler! */
+    int maxCol = 0;            /* phoudoin: silent compiler! */
+
+    byte input[N_TEXELS][MAX_COMP];
+    int i, k, l;
+
+    if (comps == 3) {
+       /* make the whole block opaque */
+       memset(input, -1, sizeof(input));
+    }
+
+    /* 4 texels each line */
+    for (l = 0; l < 4; l++) {
+       for (k = 0; k < 4; k++) {
+           for (i = 0; i < comps; i++) {
+               input[k + l * 4][i] = *lines[l]++;
+           }
+       }
+    }
+
+    /* Our solution here is to find the darkest and brightest colors in
+     * the 4x4 tile and use those as the two representative colors.
+     * There are probably better algorithms to use (histogram-based).
+     */
+    for (k = 0; k < N_TEXELS; k++) {
+       int sum = 0;
+       for (i = 0; i < n_comp; i++) {
+           sum += input[k][i];
+       }
+       if (minSum > sum) {
+           minSum = sum;
+           minCol = k;
+       }
+       if (maxSum < sum) {
+           maxSum = sum;
+           maxCol = k;
+       }
+    }
+
+    /* add in alphas */
+    lolo = lohi = 0;
+    for (k = N_TEXELS - 1; k >= N_TEXELS / 2; k--) {
+       /* add in alpha */
+       lohi <<= 4;
+       lohi |= input[k][ACOMP] >> 4;
+    }
+    cc[1] = lohi;
+    for (; k >= 0; k--) {
+       /* add in alpha */
+       lolo <<= 4;
+       lolo |= input[k][ACOMP] >> 4;
+    }
+    cc[0] = lolo;
+
+    color0 = COLOR565(input[minCol]);
+    color1 = COLOR565(input[maxCol]);
+    cc[2] = color0 | (color1 << 16);
+
+    hihi = 0;
+    if (color0 != color1) {
+       MAKEIVEC(n_vect, n_comp, iv, b, input[minCol], input[maxCol]);
+
+       /* add in texels */
+       for (k = N_TEXELS - 1; k >= 0; k--) {
+           int texel;
+           /* interpolate color */
+           CALCCDOT(texel, n_vect, n_comp, iv, b, input[k]);
+           texel = dxtn_color_tlat[0][texel];
+           /* add in texel */
+           hihi <<= 2;
+           hihi |= texel;
+       }
+    }
+    cc[3] = hihi;
+}
+
+
+static void
+dxt5_rgba_quantize (dword *cc, const byte *lines[], int comps)
+{
+    float b, iv[MAX_COMP];     /* interpolation vector */
+
+    qword lo;                  /* low quadword */
+    dword hihi;                /* high quadword: high dword */
+    int color0, color1;
+    const int n_vect = 3;
+    const int n_comp = 3;
+
+    int minSum = 2000;         /* big enough */
+    int maxSum = -1;           /* small enough */
+    int minCol = 0;            /* phoudoin: silent compiler! */
+    int maxCol = 0;            /* phoudoin: silent compiler! */
+    int alpha0 = 2000;         /* big enough */
+    int alpha1 = -1;           /* small enough */
+    int anyZero = 0, anyOne = 0;
+    int a_vect;
+
+    byte input[N_TEXELS][MAX_COMP];
+    int i, k, l;
+
+    if (comps == 3) {
+       /* make the whole block opaque */
+       memset(input, -1, sizeof(input));
+    }
+
+    /* 4 texels each line */
+    for (l = 0; l < 4; l++) {
+       for (k = 0; k < 4; k++) {
+           for (i = 0; i < comps; i++) {
+               input[k + l * 4][i] = *lines[l]++;
+           }
+       }
+    }
+
+    /* Our solution here is to find the darkest and brightest colors in
+     * the 4x4 tile and use those as the two representative colors.
+     * There are probably better algorithms to use (histogram-based).
+     */
+    for (k = 0; k < N_TEXELS; k++) {
+       int sum = 0;
+       for (i = 0; i < n_comp; i++) {
+           sum += input[k][i];
+       }
+       if (minSum > sum) {
+           minSum = sum;
+           minCol = k;
+       }
+       if (maxSum < sum) {
+           maxSum = sum;
+           maxCol = k;
+       }
+       if (alpha0 > input[k][ACOMP]) {
+           alpha0 = input[k][ACOMP];
+       }
+       if (alpha1 < input[k][ACOMP]) {
+           alpha1 = input[k][ACOMP];
+       }
+       if (input[k][ACOMP] == 0) {
+           anyZero = 1;
+       }
+       if (input[k][ACOMP] == 255) {
+           anyOne = 1;
+       }
+    }
+
+    /* add in alphas */
+    if (alpha0 == alpha1) {
+       /* we'll use 6-vector */
+       cc[0] = alpha0 | (alpha1 << 8);
+       cc[1] = 0;
+    } else {
+       if (anyZero && ((alpha0 == 0) || (alpha1 == 0))) {
+           /* we still might use 8-vector */
+           anyZero = 0;
+       }
+       if (anyOne && ((alpha0 == 255) || (alpha1 == 255))) {
+           /* we still might use 8-vector */
+           anyOne = 0;
+       }
+       if ((anyZero | anyOne) ^ (alpha0 <= alpha1)) {
+           int aux;
+           aux = alpha0;
+           alpha0 = alpha1;
+           alpha1 = aux;
+       }
+       a_vect = (alpha0 <= alpha1) ? 5 : 7;
+
+       /* compute interpolation vector */
+       iv[ACOMP] = (float)a_vect / (alpha1 - alpha0);
+       b = -iv[ACOMP] * alpha0 + 0.5F;
+
+       /* add in alphas */
+       Q_MOV32(lo, 0);
+       for (k = N_TEXELS - 1; k >= 0; k--) {
+           int texel = -1;
+           if (anyZero | anyOne) {
+               if (input[k][ACOMP] == 0) {
+                   texel = 6;
+               } else if (input[k][ACOMP] == 255) {
+                   texel = 7;
+               }
+           }
+           /* interpolate alpha */
+           if (texel == -1) {
+               float dot = input[k][ACOMP] * iv[ACOMP];
+               texel = (int)(dot + b);
+#if SAFECDOT
+               if (texel < 0) {
+                   texel = 0;
+               } else if (texel > a_vect) {
+                   texel = a_vect;
+               }
+#endif
+               texel = dxtn_alpha_tlat[anyZero | anyOne][texel];
+           }
+           /* add in texel */
+           Q_SHL(lo, 3);
+           Q_OR32(lo, texel);
+       }
+       Q_SHL(lo, 16);
+       Q_OR32(lo, alpha0 | (alpha1 << 8));
+       ((qword *)cc)[0] = lo;
+    }
+
+    color0 = COLOR565(input[minCol]);
+    color1 = COLOR565(input[maxCol]);
+    cc[2] = color0 | (color1 << 16);
+
+    hihi = 0;
+    if (color0 != color1) {
+       MAKEIVEC(n_vect, n_comp, iv, b, input[minCol], input[maxCol]);
+
+       /* add in texels */
+       for (k = N_TEXELS - 1; k >= 0; k--) {
+           int texel;
+           /* interpolate color */
+           CALCCDOT(texel, n_vect, n_comp, iv, b, input[k]);
+           texel = dxtn_color_tlat[0][texel];
+           /* add in texel */
+           hihi <<= 2;
+           hihi |= texel;
+       }
+    }
+    cc[3] = hihi;
+}
+
+
+#define ENCODER(dxtn, n)                                               \
+int TAPIENTRY                                                          \
+dxtn##_encode (int width, int height, int comps,                       \
+              const void *source, int srcRowStride,                    \
+              void *dest, int destRowStride)                           \
+{                                                                      \
+    int x, y;                                                          \
+    const byte *data;                                                  \
+    dword *encoded = (dword *)dest;                                    \
+    void *newSource = NULL;                                            \
+                                                                       \
+    /* Replicate image if width is not M4 or height is not M4 */       \
+    if ((width & 3) | (height & 3)) {                                  \
+       int newWidth = (width + 3) & ~3;                                \
+       int newHeight = (height + 3) & ~3;                              \
+       newSource = malloc(comps * newWidth * newHeight * sizeof(byte *));\
+       _mesa_upscale_teximage2d(width, height, newWidth, newHeight,    \
+                               comps, (const byte *)source,            \
+                              srcRowStride, (byte *)newSource);        \
+       source = newSource;                                             \
+       width = newWidth;                                               \
+       height = newHeight;                                             \
+       srcRowStride = comps * newWidth;                                \
+    }                                                                  \
+                                                                       \
+    data = (const byte *)source;                                       \
+    destRowStride = (destRowStride - width * n) / 4;                   \
+    for (y = 0; y < height; y += 4) {                                  \
+       unsigned int offs = 0 + (y + 0) * srcRowStride;                 \
+       for (x = 0; x < width; x += 4) {                                \
+           const byte *lines[4];                                       \
+           lines[0] = &data[offs];                                     \
+           lines[1] = lines[0] + srcRowStride;                         \
+           lines[2] = lines[1] + srcRowStride;                         \
+           lines[3] = lines[2] + srcRowStride;                         \
+           offs += 4 * comps;                                          \
+           dxtn##_quantize(encoded, lines, comps);                     \
+           /* 4x4 block */                                             \
+           encoded += n;                                               \
+       }                                                               \
+       encoded += destRowStride;                                       \
+    }                                                                  \
+                                                                       \
+    if (newSource != NULL) {                                           \
+       free(newSource);                                                \
+    }                                                                  \
+                                                                       \
+    return 0;                                                          \
+}
+
+ENCODER(dxt1_rgb,  2)
+ENCODER(dxt1_rgba, 2)
+ENCODER(dxt3_rgba, 4)
+ENCODER(dxt5_rgba, 4)
+
+
+/***************************************************************************\
+ * DXTn decoder
+ *
+ * The decoder is based on GL_EXT_texture_compression_s3tc
+ * specification and serves as a concept for the encoder.
+\***************************************************************************/
+
+
+/* lookup table for scaling 4 bit colors up to 8 bits */
+static const byte _rgb_scale_4[] = {
+    0,   17,  34,  51,  68,  85,  102, 119,
+    136, 153, 170, 187, 204, 221, 238, 255
+};
+
+/* lookup table for scaling 5 bit colors up to 8 bits */
+static const byte _rgb_scale_5[] = {
+    0,   8,   16,  25,  33,  41,  49,  58,
+    66,  74,  82,  90,  99,  107, 115, 123,
+    132, 140, 148, 156, 165, 173, 181, 189,
+    197, 206, 214, 222, 230, 239, 247, 255
+};
+
+/* lookup table for scaling 6 bit colors up to 8 bits */
+static const byte _rgb_scale_6[] = {
+    0,   4,   8,   12,  16,  20,  24,  28,
+    32,  36,  40,  45,  49,  53,  57,  61,
+    65,  69,  73,  77,  81,  85,  89,  93,
+    97,  101, 105, 109, 113, 117, 121, 125,
+    130, 134, 138, 142, 146, 150, 154, 158,
+    162, 166, 170, 174, 178, 182, 186, 190,
+    194, 198, 202, 206, 210, 215, 219, 223,
+    227, 231, 235, 239, 243, 247, 251, 255
+};
+
+
+#define CC_SEL(cc, which) (((dword *)(cc))[(which) / 32] >> ((which) & 31))
+#define UP4(c) _rgb_scale_4[(c) & 15]
+#define UP5(c) _rgb_scale_5[(c) & 31]
+#define UP6(c) _rgb_scale_6[(c) & 63]
+#define ZERO_4UBV(v) *((dword *)(v)) = 0
+
+
+void TAPIENTRY
+dxt1_rgb_decode_1 (const void *texture, int stride,
+                  int i, int j, byte *rgba)
+{
+    const byte *src = (const byte *)texture
+                      + ((j / 4) * ((stride + 3) / 4) + i / 4) * 8;
+    const int code = (src[4 + (j & 3)] >> ((i & 3) * 2)) & 0x3;
+    if (code == 0) {
+       rgba[RCOMP] = UP5(CC_SEL(src, 11));
+       rgba[GCOMP] = UP6(CC_SEL(src,  5));
+       rgba[BCOMP] = UP5(CC_SEL(src,  0));
+    } else if (code == 1) {
+       rgba[RCOMP] = UP5(CC_SEL(src, 27));
+       rgba[GCOMP] = UP6(CC_SEL(src, 21));
+       rgba[BCOMP] = UP5(CC_SEL(src, 16));
+    } else {
+       const word col0 = src[0] | (src[1] << 8);
+       const word col1 = src[2] | (src[3] << 8);
+       if (col0 > col1) {
+           if (code == 2) {
+               rgba[RCOMP] = (UP5(col0 >> 11) * 2 + UP5(col1 >> 11)) / 3;
+               rgba[GCOMP] = (UP6(col0 >>  5) * 2 + UP6(col1 >>  5)) / 3;
+               rgba[BCOMP] = (UP5(col0      ) * 2 + UP5(col1      )) / 3;
+           } else {
+               rgba[RCOMP] = (UP5(col0 >> 11) + 2 * UP5(col1 >> 11)) / 3;
+               rgba[GCOMP] = (UP6(col0 >>  5) + 2 * UP6(col1 >>  5)) / 3;
+               rgba[BCOMP] = (UP5(col0      ) + 2 * UP5(col1      )) / 3;
+           }
+       } else {
+           if (code == 2) {
+               rgba[RCOMP] = (UP5(col0 >> 11) + UP5(col1 >> 11)) / 2;
+               rgba[GCOMP] = (UP6(col0 >>  5) + UP6(col1 >>  5)) / 2;
+               rgba[BCOMP] = (UP5(col0      ) + UP5(col1      )) / 2;
+           } else {
+               ZERO_4UBV(rgba);
+           }
+       }
+    }
+    rgba[ACOMP] = 255;
+}
+
+
+void TAPIENTRY
+dxt1_rgba_decode_1 (const void *texture, int stride,
+                   int i, int j, byte *rgba)
+{
+    /* Same as rgb_dxt1 above, except alpha=0 if col0<=col1 and code=3. */
+    const byte *src = (const byte *)texture
+                      + ((j / 4) * ((stride + 3) / 4) + i / 4) * 8;
+    const int code = (src[4 + (j & 3)] >> ((i & 3) * 2)) & 0x3;
+    if (code == 0) {
+       rgba[RCOMP] = UP5(CC_SEL(src, 11));
+       rgba[GCOMP] = UP6(CC_SEL(src,  5));
+       rgba[BCOMP] = UP5(CC_SEL(src,  0));
+       rgba[ACOMP] = 255;
+    } else if (code == 1) {
+       rgba[RCOMP] = UP5(CC_SEL(src, 27));
+       rgba[GCOMP] = UP6(CC_SEL(src, 21));
+       rgba[BCOMP] = UP5(CC_SEL(src, 16));
+       rgba[ACOMP] = 255;
+    } else {
+       const word col0 = src[0] | (src[1] << 8);
+       const word col1 = src[2] | (src[3] << 8);
+       if (col0 > col1) {
+           if (code == 2) {
+               rgba[RCOMP] = (UP5(col0 >> 11) * 2 + UP5(col1 >> 11)) / 3;
+               rgba[GCOMP] = (UP6(col0 >>  5) * 2 + UP6(col1 >>  5)) / 3;
+               rgba[BCOMP] = (UP5(col0      ) * 2 + UP5(col1      )) / 3;
+           } else {
+               rgba[RCOMP] = (UP5(col0 >> 11) + 2 * UP5(col1 >> 11)) / 3;
+               rgba[GCOMP] = (UP6(col0 >>  5) + 2 * UP6(col1 >>  5)) / 3;
+               rgba[BCOMP] = (UP5(col0      ) + 2 * UP5(col1      )) / 3;
+           }
+           rgba[ACOMP] = 255;
+       } else {
+           if (code == 2) {
+               rgba[RCOMP] = (UP5(col0 >> 11) + UP5(col1 >> 11)) / 2;
+               rgba[GCOMP] = (UP6(col0 >>  5) + UP6(col1 >>  5)) / 2;
+               rgba[BCOMP] = (UP5(col0      ) + UP5(col1      )) / 2;
+               rgba[ACOMP] = 255;
+           } else {
+               ZERO_4UBV(rgba);
+           }
+       }
+    }
+}
+
+
+void TAPIENTRY
+dxt3_rgba_decode_1 (const void *texture, int stride,
+                   int i, int j, byte *rgba)
+{
+    const byte *src = (const byte *)texture
+                      + ((j / 4) * ((stride + 3) / 4) + i / 4) * 16;
+    const int code = (src[12 + (j & 3)] >> ((i & 3) * 2)) & 0x3;
+    const dword *cc = (const dword *)(src + 8);
+    if (code == 0) {
+       rgba[RCOMP] = UP5(CC_SEL(cc, 11));
+       rgba[GCOMP] = UP6(CC_SEL(cc,  5));
+       rgba[BCOMP] = UP5(CC_SEL(cc,  0));
+    } else if (code == 1) {
+       rgba[RCOMP] = UP5(CC_SEL(cc, 27));
+       rgba[GCOMP] = UP6(CC_SEL(cc, 21));
+       rgba[BCOMP] = UP5(CC_SEL(cc, 16));
+    } else if (code == 2) {
+       /* (col0 * (4 - code) + col1 * (code - 1)) / 3 */
+       rgba[RCOMP] = (UP5(CC_SEL(cc, 11)) * 2 + UP5(CC_SEL(cc, 27))) / 3;
+       rgba[GCOMP] = (UP6(CC_SEL(cc,  5)) * 2 + UP6(CC_SEL(cc, 21))) / 3;
+       rgba[BCOMP] = (UP5(CC_SEL(cc,  0)) * 2 + UP5(CC_SEL(cc, 16))) / 3;
+    } else {
+       rgba[RCOMP] = (UP5(CC_SEL(cc, 11)) + 2 * UP5(CC_SEL(cc, 27))) / 3;
+       rgba[GCOMP] = (UP6(CC_SEL(cc,  5)) + 2 * UP6(CC_SEL(cc, 21))) / 3;
+       rgba[BCOMP] = (UP5(CC_SEL(cc,  0)) + 2 * UP5(CC_SEL(cc, 16))) / 3;
+    }
+    rgba[ACOMP] = UP4(src[((j & 3) * 4 + (i & 3)) / 2] >> ((i & 1) * 4));
+}
+
+
+void TAPIENTRY
+dxt5_rgba_decode_1 (const void *texture, int stride,
+                   int i, int j, byte *rgba)
+{
+    const byte *src = (const byte *)texture
+                      + ((j / 4) * ((stride + 3) / 4) + i / 4) * 16;
+    const int code = (src[12 + (j & 3)] >> ((i & 3) * 2)) & 0x3;
+    const dword *cc = (const dword *)(src + 8);
+    const byte alpha0 = src[0];
+    const byte alpha1 = src[1];
+    const int alphaShift = (((j & 3) * 4) + (i & 3)) * 3 + 16;
+    const int acode = ((alphaShift == 31)
+                       ? CC_SEL(src + 2, alphaShift - 16)
+                       : CC_SEL(src, alphaShift)) & 0x7;
+    if (code == 0) {
+       rgba[RCOMP] = UP5(CC_SEL(cc, 11));
+       rgba[GCOMP] = UP6(CC_SEL(cc,  5));
+       rgba[BCOMP] = UP5(CC_SEL(cc,  0));
+    } else if (code == 1) {
+       rgba[RCOMP] = UP5(CC_SEL(cc, 27));
+       rgba[GCOMP] = UP6(CC_SEL(cc, 21));
+       rgba[BCOMP] = UP5(CC_SEL(cc, 16));
+    } else if (code == 2) {
+       /* (col0 * (4 - code) + col1 * (code - 1)) / 3 */
+       rgba[RCOMP] = (UP5(CC_SEL(cc, 11)) * 2 + UP5(CC_SEL(cc, 27))) / 3;
+       rgba[GCOMP] = (UP6(CC_SEL(cc,  5)) * 2 + UP6(CC_SEL(cc, 21))) / 3;
+       rgba[BCOMP] = (UP5(CC_SEL(cc,  0)) * 2 + UP5(CC_SEL(cc, 16))) / 3;
+    } else {
+       rgba[RCOMP] = (UP5(CC_SEL(cc, 11)) + 2 * UP5(CC_SEL(cc, 27))) / 3;
+       rgba[GCOMP] = (UP6(CC_SEL(cc,  5)) + 2 * UP6(CC_SEL(cc, 21))) / 3;
+       rgba[BCOMP] = (UP5(CC_SEL(cc,  0)) + 2 * UP5(CC_SEL(cc, 16))) / 3;
+    }
+    if (acode == 0) {
+       rgba[ACOMP] = alpha0;
+    } else if (acode == 1) {
+       rgba[ACOMP] = alpha1;
+    } else if (alpha0 > alpha1) {
+       rgba[ACOMP] = ((8 - acode) * alpha0 + (acode - 1) * alpha1) / 7;
+    } else if (acode == 6) {
+       rgba[ACOMP] = 0;
+    } else if (acode == 7) {
+       rgba[ACOMP] = 255;
+    } else {
+       rgba[ACOMP] = ((6 - acode) * alpha0 + (acode - 1) * alpha1) / 5;
+    }
+}
diff --git a/reactos/dll/3rdparty/dxtn/dxtn.def b/reactos/dll/3rdparty/dxtn/dxtn.def
new file mode 100644 (file)
index 0000000..a8ca338
--- /dev/null
@@ -0,0 +1,16 @@
+LIBRARY dxtn
+EXPORTS
+dxt1_rgb_encode@28
+dxt1_rgba_encode@28
+dxt3_rgba_encode@28
+dxt5_rgba_encode@28
+dxt1_rgba_decode_1@20
+dxt3_rgba_decode_1@20
+dxt5_rgba_decode_1@20
+fxt1_encode@28
+fxt1_decode_1@20
+fetch_2d_texel_rgb_dxt1@20
+fetch_2d_texel_rgba_dxt1@20
+fetch_2d_texel_rgba_dxt3@20
+fetch_2d_texel_rgba_dxt5@20
+tx_compress_dxtn@28
diff --git a/reactos/dll/3rdparty/dxtn/dxtn.h b/reactos/dll/3rdparty/dxtn/dxtn.h
new file mode 100644 (file)
index 0000000..4078fd9
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * DXTn codec
+ * Version:  1.1
+ *
+ * Copyright (C) 2004  Daniel Borca   All Rights Reserved.
+ *
+ * this is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * this is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING.  If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.       
+ */
+
+
+#ifndef DXTN_H_included
+#define DXTN_H_included
+
+TAPI int TAPIENTRY
+dxt1_rgb_encode (int width, int height, int comps,
+                const void *source, int srcRowStride,
+                void *dest, int destRowStride);
+
+TAPI int TAPIENTRY
+dxt1_rgba_encode (int width, int height, int comps,
+                 const void *source, int srcRowStride,
+                 void *dest, int destRowStride);
+
+TAPI int TAPIENTRY
+dxt3_rgba_encode (int width, int height, int comps,
+                 const void *source, int srcRowStride,
+                 void *dest, int destRowStride);
+
+TAPI int TAPIENTRY
+dxt5_rgba_encode (int width, int height, int comps,
+                 const void *source, int srcRowStride,
+                 void *dest, int destRowStride);
+
+TAPI void TAPIENTRY
+dxt1_rgb_decode_1 (const void *texture, int stride /* in pixels */,
+                  int i, int j, byte *rgba);
+
+TAPI void TAPIENTRY
+dxt1_rgba_decode_1 (const void *texture, int stride /* in pixels */,
+                   int i, int j, byte *rgba);
+
+TAPI void TAPIENTRY
+dxt3_rgba_decode_1 (const void *texture, int stride /* in pixels */,
+                   int i, int j, byte *rgba);
+
+TAPI void TAPIENTRY
+dxt5_rgba_decode_1 (const void *texture, int stride /* in pixels */,
+                   int i, int j, byte *rgba);
+
+#endif
diff --git a/reactos/dll/3rdparty/dxtn/dxtn.rbuild b/reactos/dll/3rdparty/dxtn/dxtn.rbuild
new file mode 100644 (file)
index 0000000..798829f
--- /dev/null
@@ -0,0 +1,12 @@
+<module name="dxtn" type="win32dll" entrypoint="0" installbase="system32" installname="dxnt.dll" allowwarnings="true">
+       <importlibrary definition="dxtn.def" />
+       <include base="dxtn">.</include>
+       <define name="__USE_W32API" />
+
+       <library>msvcrt</library>
+
+       <file>fxt1.c</file>
+       <file>dxtn.c</file>
+       <file>wrapper.c</file>
+       <file>texstore.c</file>
+</module>
\ No newline at end of file
diff --git a/reactos/dll/3rdparty/dxtn/fxt1.c b/reactos/dll/3rdparty/dxtn/fxt1.c
new file mode 100644 (file)
index 0000000..c528ee7
--- /dev/null
@@ -0,0 +1,1369 @@
+/*
+ * FXT1 codec
+ * Version:  1.1
+ *
+ * Copyright (C) 2004  Daniel Borca   All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * DANIEL BORCA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "types.h"
+#include "internal.h"
+#include "fxt1.h"
+
+
+/***************************************************************************\
+ * FXT1 encoder
+ *
+ * The encoder was built by reversing the decoder,
+ * and is vaguely based on Texus2 by 3dfx. Note that this code
+ * is merely a proof of concept, since it is highly UNoptimized;
+ * moreover, it is sub-optimal due to initial conditions passed
+ * to Lloyd's algorithm (the interpolation modes are even worse).
+\***************************************************************************/
+
+
+#define MAX_COMP 4 /* ever needed maximum number of components in texel */
+#define MAX_VECT 4 /* ever needed maximum number of base vectors to find */
+#define N_TEXELS 32 /* number of texels in a block (always 32) */
+#define LL_N_REP 50 /* number of iterations in lloyd's vq */
+#define LL_RMS_D 10 /* fault tolerance (maximum delta) */
+#define LL_RMS_E 255 /* fault tolerance (maximum error) */
+#define ALPHA_TS 2 /* alpha threshold: (255 - ALPHA_TS) deemed opaque */
+#define ISTBLACK(v) (*((dword *)(v)) == 0)
+#define COPY_4UBV(DST, SRC) *((dword *)(DST)) = *((dword *)(SRC))
+
+
+static int
+fxt1_bestcol (float vec[][MAX_COMP], int nv,
+             byte input[MAX_COMP], int nc)
+{
+    int i, j, best = -1;
+    float err = 1e9; /* big enough */
+
+    for (j = 0; j < nv; j++) {
+       float e = 0.0F;
+       for (i = 0; i < nc; i++) {
+           e += (vec[j][i] - input[i]) * (vec[j][i] - input[i]);
+       }
+       if (e < err) {
+           err = e;
+           best = j;
+       }
+    }
+
+    return best;
+}
+
+
+static int
+fxt1_worst (float vec[MAX_COMP],
+           byte input[N_TEXELS][MAX_COMP], int nc, int n)
+{
+    int i, k, worst = -1;
+    float err = -1.0F; /* small enough */
+
+    for (k = 0; k < n; k++) {
+       float e = 0.0F;
+       for (i = 0; i < nc; i++) {
+           e += (vec[i] - input[k][i]) * (vec[i] - input[k][i]);
+       }
+       if (e > err) {
+           err = e;
+           worst = k;
+       }
+    }
+
+    return worst;
+}
+
+
+static int
+fxt1_variance (double variance[MAX_COMP],
+              byte input[N_TEXELS][MAX_COMP], int nc, int n)
+{
+    int i, k, best = 0;
+    dword sx, sx2;
+    double var, maxvar = -1; /* small enough */
+    double teenth = 1.0 / n;
+
+    for (i = 0; i < nc; i++) {
+       sx = sx2 = 0;
+       for (k = 0; k < n; k++) {
+           int t = input[k][i];
+           sx += t;
+           sx2 += t * t;
+       }
+       var = sx2 * teenth - sx * sx * teenth * teenth;
+       if (maxvar < var) {
+           maxvar = var;
+           best = i;
+       }
+       if (variance) {
+           variance[i] = var;
+       }
+    }
+
+    return best;
+}
+
+
+static int
+fxt1_choose (float vec[][MAX_COMP], int nv,
+            byte input[N_TEXELS][MAX_COMP], int nc, int n)
+{
+#if 0
+    /* Choose colors from a grid.
+     */
+    int i, j;
+
+    for (j = 0; j < nv; j++) {
+       int m = j * (n - 1) / (nv - 1);
+       for (i = 0; i < nc; i++) {
+           vec[j][i] = input[m][i];
+       }
+    }
+#else
+    /* Our solution here is to find the darkest and brightest colors in
+     * the 8x4 tile and use those as the two representative colors.
+     * There are probably better algorithms to use (histogram-based).
+     */
+    int i, j, k;
+    int minSum = 2000; /* big enough */
+    int maxSum = -1; /* small enough */
+    int minCol = 0; /* phoudoin: silent compiler! */
+    int maxCol = 0; /* phoudoin: silent compiler! */
+
+    struct {
+       int flag;
+       dword key;
+       int freq;
+       int idx;
+    } hist[N_TEXELS];
+    int lenh = 0;
+
+    memset(hist, 0, sizeof(hist));
+
+    for (k = 0; k < n; k++) {
+       int l;
+       dword key = 0;
+       int sum = 0;
+       for (i = 0; i < nc; i++) {
+           key <<= 8;
+           key |= input[k][i];
+           sum += input[k][i];
+       }
+       for (l = 0; l < n; l++) {
+           if (!hist[l].flag) {
+               /* alloc new slot */
+               hist[l].flag = !0;
+               hist[l].key = key;
+               hist[l].freq = 1;
+               hist[l].idx = k;
+               lenh = l + 1;
+               break;
+           } else if (hist[l].key == key) {
+               hist[l].freq++;
+               break;
+           }
+       }
+       if (minSum > sum) {
+           minSum = sum;
+           minCol = k;
+       }
+       if (maxSum < sum) {
+           maxSum = sum;
+           maxCol = k;
+       }
+    }
+
+    if (lenh <= nv) {
+       for (j = 0; j < lenh; j++) {
+           for (i = 0; i < nc; i++) {
+               vec[j][i] = (float)input[hist[j].idx][i];
+           }
+       }
+       for (; j < nv; j++) {
+           for (i = 0; i < nc; i++) {
+               vec[j][i] = vec[0][i];
+           }
+       }
+       return 0;
+    }
+
+    for (j = 0; j < nv; j++) {
+       for (i = 0; i < nc; i++) {
+           vec[j][i] = ((nv - 1 - j) * input[minCol][i] + j * input[maxCol][i] + (nv - 1) / 2) / (float)(nv - 1);
+       }
+    }
+#endif
+
+    return !0;
+}
+
+
+static int
+fxt1_lloyd (float vec[][MAX_COMP], int nv,
+           byte input[N_TEXELS][MAX_COMP], int nc, int n)
+{
+    /* Use the generalized lloyd's algorithm for VQ:
+     *     find 4 color vectors.
+     *
+     *     for each sample color
+     *         sort to nearest vector.
+     *
+     *     replace each vector with the centroid of it's matching colors.
+     *
+     *     repeat until RMS doesn't improve.
+     *
+     *     if a color vector has no samples, or becomes the same as another
+     *     vector, replace it with the color which is farthest from a sample.
+     *
+     * vec[][MAX_COMP]           initial vectors and resulting colors
+     * nv                        number of resulting colors required
+     * input[N_TEXELS][MAX_COMP] input texels
+     * nc                        number of components in input / vec
+     * n                         number of input samples
+     */
+
+    int sum[MAX_VECT][MAX_COMP]; /* used to accumulate closest texels */
+    int cnt[MAX_VECT]; /* how many times a certain vector was chosen */
+    float error, lasterror = 1e9;
+
+    int i, j, k, rep;
+
+    /* the quantizer */
+    for (rep = 0; rep < LL_N_REP; rep++) {
+       /* reset sums & counters */
+       for (j = 0; j < nv; j++) {
+           for (i = 0; i < nc; i++) {
+               sum[j][i] = 0;
+           }
+           cnt[j] = 0;
+       }
+       error = 0;
+
+       /* scan whole block */
+       for (k = 0; k < n; k++) {
+#if 1
+           int best = -1;
+           float err = 1e9; /* big enough */
+           /* determine best vector */
+           for (j = 0; j < nv; j++) {
+               float e = (vec[j][0] - input[k][0]) * (vec[j][0] - input[k][0]) +
+                         (vec[j][1] - input[k][1]) * (vec[j][1] - input[k][1]) +
+                         (vec[j][2] - input[k][2]) * (vec[j][2] - input[k][2]);
+               if (nc == 4) {
+                   e += (vec[j][3] - input[k][3]) * (vec[j][3] - input[k][3]);
+               }
+               if (e < err) {
+                   err = e;
+                   best = j;
+               }
+           }
+#else
+           int best = fxt1_bestcol(vec, nv, input[k], nc, &err);
+#endif
+           /* add in closest color */
+           for (i = 0; i < nc; i++) {
+               sum[best][i] += input[k][i];
+           }
+           /* mark this vector as used */
+           cnt[best]++;
+           /* accumulate error */
+           error += err;
+       }
+
+       /* check RMS */
+       if ((error < LL_RMS_E) ||
+           ((error < lasterror) && ((lasterror - error) < LL_RMS_D))) {
+           return !0; /* good match */
+       }
+       lasterror = error;
+
+       /* move each vector to the barycenter of its closest colors */
+       for (j = 0; j < nv; j++) {
+           if (cnt[j]) {
+               float div = 1.0F / cnt[j];
+               for (i = 0; i < nc; i++) {
+                   vec[j][i] = div * sum[j][i];
+               }
+           } else {
+               /* this vec has no samples or is identical with a previous vec */
+               int worst = fxt1_worst(vec[j], input, nc, n);
+               for (i = 0; i < nc; i++) {
+                   vec[j][i] = input[worst][i];
+               }
+           }
+       }
+    }
+
+    return 0; /* could not converge fast enough */
+}
+
+
+static void
+fxt1_quantize_CHROMA (dword *cc,
+                     byte input[N_TEXELS][MAX_COMP])
+{
+    const int n_vect = 4; /* 4 base vectors to find */
+    const int n_comp = 3; /* 3 components: R, G, B */
+    float vec[MAX_VECT][MAX_COMP];
+    int i, j, k;
+    qword hi; /* high quadword */
+    dword lohi, lolo; /* low quadword: hi dword, lo dword */
+
+    if (fxt1_choose(vec, n_vect, input, n_comp, N_TEXELS) != 0) {
+       fxt1_lloyd(vec, n_vect, input, n_comp, N_TEXELS);
+    }
+
+    Q_MOV32(hi, 4); /* cc-chroma = "010" + unused bit */
+    for (j = n_vect - 1; j >= 0; j--) {
+       for (i = 0; i < n_comp; i++) {
+           /* add in colors */
+           Q_SHL(hi, 5);
+           Q_OR32(hi, (dword)(vec[j][i] / 8.0F));
+       }
+    }
+    ((qword *)cc)[1] = hi;
+
+    lohi = lolo = 0;
+    /* right microtile */
+    for (k = N_TEXELS - 1; k >= N_TEXELS / 2; k--) {
+       lohi <<= 2;
+       lohi |= fxt1_bestcol(vec, n_vect, input[k], n_comp);
+    }
+    /* left microtile */
+    for (; k >= 0; k--) {
+       lolo <<= 2;
+       lolo |= fxt1_bestcol(vec, n_vect, input[k], n_comp);
+    }
+    cc[1] = lohi;
+    cc[0] = lolo;
+}
+
+
+static void
+fxt1_quantize_ALPHA0 (dword *cc,
+                     byte input[N_TEXELS][MAX_COMP],
+                     byte reord[N_TEXELS][MAX_COMP], int n)
+{
+    const int n_vect = 3; /* 3 base vectors to find */
+    const int n_comp = 4; /* 4 components: R, G, B, A */
+    float vec[MAX_VECT][MAX_COMP];
+    int i, j, k;
+    qword hi; /* high quadword */
+    dword lohi, lolo; /* low quadword: hi dword, lo dword */
+
+    /* the last vector indicates zero */
+    for (i = 0; i < n_comp; i++) {
+       vec[n_vect][i] = 0;
+    }
+
+    /* the first n texels in reord are guaranteed to be non-zero */
+    if (fxt1_choose(vec, n_vect, reord, n_comp, n) != 0) {
+       fxt1_lloyd(vec, n_vect, reord, n_comp, n);
+    }
+
+    Q_MOV32(hi, 6); /* alpha = "011" + lerp = 0 */
+    for (j = n_vect - 1; j >= 0; j--) {
+       /* add in alphas */
+       Q_SHL(hi, 5);
+       Q_OR32(hi, (dword)(vec[j][ACOMP] / 8.0F));
+    }
+    for (j = n_vect - 1; j >= 0; j--) {
+       for (i = 0; i < n_comp - 1; i++) {
+           /* add in colors */
+           Q_SHL(hi, 5);
+           Q_OR32(hi, (dword)(vec[j][i] / 8.0F));
+       }
+    }
+    ((qword *)cc)[1] = hi;
+
+    lohi = lolo = 0;
+    /* right microtile */
+    for (k = N_TEXELS - 1; k >= N_TEXELS / 2; k--) {
+       lohi <<= 2;
+       lohi |= fxt1_bestcol(vec, n_vect + 1, input[k], n_comp);
+    }
+    /* left microtile */
+    for (; k >= 0; k--) {
+       lolo <<= 2;
+       lolo |= fxt1_bestcol(vec, n_vect + 1, input[k], n_comp);
+    }
+    cc[1] = lohi;
+    cc[0] = lolo;
+}
+
+
+static void
+fxt1_quantize_ALPHA1 (dword *cc,
+                     byte input[N_TEXELS][MAX_COMP])
+{
+    const int n_vect = 3; /* highest vector number in each microtile */
+    const int n_comp = 4; /* 4 components: R, G, B, A */
+    float vec[1 + 1 + 1][MAX_COMP]; /* 1.5 extrema for each sub-block */
+    float b, iv[MAX_COMP]; /* interpolation vector */
+    int i, j, k;
+    qword hi; /* high quadword */
+    dword lohi, lolo; /* low quadword: hi dword, lo dword */
+
+    int minSum;
+    int maxSum;
+    int minColL = 0, maxColL = 0;
+    int minColR = 0, maxColR = 0;
+    int sumL = 0, sumR = 0;
+
+    /* Our solution here is to find the darkest and brightest colors in
+     * the 4x4 tile and use those as the two representative colors.
+     * There are probably better algorithms to use (histogram-based).
+     */
+    minSum = 2000; /* big enough */
+    maxSum = -1; /* small enough */
+    for (k = 0; k < N_TEXELS / 2; k++) {
+       int sum = 0;
+       for (i = 0; i < n_comp; i++) {
+           sum += input[k][i];
+       }
+       if (minSum > sum) {
+           minSum = sum;
+           minColL = k;
+       }
+       if (maxSum < sum) {
+           maxSum = sum;
+           maxColL = k;
+       }
+       sumL += sum;
+    }
+    minSum = 2000; /* big enough */
+    maxSum = -1; /* small enough */
+    for (; k < N_TEXELS; k++) {
+       int sum = 0;
+       for (i = 0; i < n_comp; i++) {
+           sum += input[k][i];
+       }
+       if (minSum > sum) {
+           minSum = sum;
+           minColR = k;
+       }
+       if (maxSum < sum) {
+           maxSum = sum;
+           maxColR = k;
+       }
+       sumR += sum;
+    }
+
+    /* choose the common vector (yuck!) */
+    {
+       int j1, j2;
+       int v1 = 0, v2 = 0;
+       float err = 1e9; /* big enough */
+       float tv[2 * 2][MAX_COMP]; /* 2 extrema for each sub-block */
+       for (i = 0; i < n_comp; i++) {
+           tv[0][i] = input[minColL][i];
+           tv[1][i] = input[maxColL][i];
+           tv[2][i] = input[minColR][i];
+           tv[3][i] = input[maxColR][i];
+       }
+       for (j1 = 0; j1 < 2; j1++) {
+           for (j2 = 2; j2 < 4; j2++) {
+               float e = 0.0F;
+               for (i = 0; i < n_comp; i++) {
+                   e += (tv[j1][i] - tv[j2][i]) * (tv[j1][i] - tv[j2][i]);
+               }
+               if (e < err) {
+                   err = e;
+                   v1 = j1;
+                   v2 = j2;
+               }
+           }
+       }
+       for (i = 0; i < n_comp; i++) {
+           vec[0][i] = tv[1 - v1][i];
+           vec[1][i] = (tv[v1][i] * sumL + tv[v2][i] * sumR) / (sumL + sumR);
+           vec[2][i] = tv[5 - v2][i];
+       }
+    }
+
+    /* left microtile */
+    cc[0] = 0;
+    if (minColL != maxColL) {
+       /* compute interpolation vector */
+       MAKEIVEC(n_vect, n_comp, iv, b, vec[0], vec[1]);
+
+       /* add in texels */
+       lolo = 0;
+       for (k = N_TEXELS / 2 - 1; k >= 0; k--) {
+           int texel;
+           /* interpolate color */
+           CALCCDOT(texel, n_vect, n_comp, iv, b, input[k]);
+           /* add in texel */
+           lolo <<= 2;
+           lolo |= texel;
+       }
+
+       cc[0] = lolo;
+    }
+
+    /* right microtile */
+    cc[1] = 0;
+    if (minColR != maxColR) {
+       /* compute interpolation vector */
+       MAKEIVEC(n_vect, n_comp, iv, b, vec[2], vec[1]);
+
+       /* add in texels */
+       lohi = 0;
+       for (k = N_TEXELS - 1; k >= N_TEXELS / 2; k--) {
+           int texel;
+           /* interpolate color */
+           CALCCDOT(texel, n_vect, n_comp, iv, b, input[k]);
+           /* add in texel */
+           lohi <<= 2;
+           lohi |= texel;
+       }
+
+       cc[1] = lohi;
+    }
+
+    Q_MOV32(hi, 7); /* alpha = "011" + lerp = 1 */
+    for (j = n_vect - 1; j >= 0; j--) {
+       /* add in alphas */
+       Q_SHL(hi, 5);
+       Q_OR32(hi, (dword)(vec[j][ACOMP] / 8.0F));
+    }
+    for (j = n_vect - 1; j >= 0; j--) {
+       for (i = 0; i < n_comp - 1; i++) {
+           /* add in colors */
+           Q_SHL(hi, 5);
+           Q_OR32(hi, (dword)(vec[j][i] / 8.0F));
+       }
+    }
+    ((qword *)cc)[1] = hi;
+}
+
+
+static void
+fxt1_quantize_HI (dword *cc,
+                 byte input[N_TEXELS][MAX_COMP],
+                 byte reord[N_TEXELS][MAX_COMP], int n)
+{
+    const int n_vect = 6; /* highest vector number */
+    const int n_comp = 3; /* 3 components: R, G, B */
+    float b = 0.0F;       /* phoudoin: silent compiler! */
+    float iv[MAX_COMP];   /* interpolation vector */
+    int i, k;
+    dword hihi; /* high quadword: hi dword */
+
+    int minSum = 2000; /* big enough */
+    int maxSum = -1; /* small enough */
+    int minCol = 0; /* phoudoin: silent compiler! */
+    int maxCol = 0; /* phoudoin: silent compiler! */
+
+    /* Our solution here is to find the darkest and brightest colors in
+     * the 8x4 tile and use those as the two representative colors.
+     * There are probably better algorithms to use (histogram-based).
+     */
+    for (k = 0; k < n; k++) {
+       int sum = 0;
+       for (i = 0; i < n_comp; i++) {
+           sum += reord[k][i];
+       }
+       if (minSum > sum) {
+           minSum = sum;
+           minCol = k;
+       }
+       if (maxSum < sum) {
+           maxSum = sum;
+           maxCol = k;
+       }
+    }
+
+    hihi = 0; /* cc-hi = "00" */
+    for (i = 0; i < n_comp; i++) {
+       /* add in colors */
+       hihi <<= 5;
+       hihi |= reord[maxCol][i] >> 3;
+    }
+    for (i = 0; i < n_comp; i++) {
+       /* add in colors */
+       hihi <<= 5;
+       hihi |= reord[minCol][i] >> 3;
+    }
+    cc[3] = hihi;
+    cc[0] = cc[1] = cc[2] = 0;
+
+    /* compute interpolation vector */
+    if (minCol != maxCol) {
+       MAKEIVEC(n_vect, n_comp, iv, b, reord[minCol], reord[maxCol]);
+    }
+
+    /* add in texels */
+    for (k = N_TEXELS - 1; k >= 0; k--) {
+       int t = k * 3;
+       dword *kk = (dword *)((byte *)cc + t / 8);
+       int texel = n_vect + 1; /* transparent black */
+
+       if (!ISTBLACK(input[k])) {
+           if (minCol != maxCol) {
+               /* interpolate color */
+               CALCCDOT(texel, n_vect, n_comp, iv, b, input[k]);
+               /* add in texel */
+               kk[0] |= texel << (t & 7);
+           }
+       } else {
+           /* add in texel */
+           kk[0] |= texel << (t & 7);
+       }
+    }
+}
+
+
+static void
+fxt1_quantize_MIXED1 (dword *cc,
+                     byte input[N_TEXELS][MAX_COMP])
+{
+    const int n_vect = 2; /* highest vector number in each microtile */
+    const int n_comp = 3; /* 3 components: R, G, B */
+    byte vec[2 * 2][MAX_COMP]; /* 2 extrema for each sub-block */
+    float b, iv[MAX_COMP]; /* interpolation vector */
+    int i, j, k;
+    qword hi; /* high quadword */
+    dword lohi, lolo; /* low quadword: hi dword, lo dword */
+
+    int minSum;
+    int maxSum;
+    int minColL = 0, maxColL = -1;
+    int minColR = 0, maxColR = -1;
+
+    /* Our solution here is to find the darkest and brightest colors in
+     * the 4x4 tile and use those as the two representative colors.
+     * There are probably better algorithms to use (histogram-based).
+     */
+    minSum = 2000; /* big enough */
+    maxSum = -1; /* small enough */
+    for (k = 0; k < N_TEXELS / 2; k++) {
+       if (!ISTBLACK(input[k])) {
+           int sum = 0;
+           for (i = 0; i < n_comp; i++) {
+               sum += input[k][i];
+           }
+           if (minSum > sum) {
+               minSum = sum;
+               minColL = k;
+           }
+           if (maxSum < sum) {
+               maxSum = sum;
+               maxColL = k;
+           }
+       }
+    }
+    minSum = 2000; /* big enough */
+    maxSum = -1; /* small enough */
+    for (; k < N_TEXELS; k++) {
+       if (!ISTBLACK(input[k])) {
+           int sum = 0;
+           for (i = 0; i < n_comp; i++) {
+               sum += input[k][i];
+           }
+           if (minSum > sum) {
+               minSum = sum;
+               minColR = k;
+           }
+           if (maxSum < sum) {
+               maxSum = sum;
+               maxColR = k;
+           }
+       }
+    }
+
+    /* left microtile */
+    if (maxColL == -1) {
+       /* all transparent black */
+       cc[0] = ~0UL;
+       for (i = 0; i < n_comp; i++) {
+           vec[0][i] = 0;
+           vec[1][i] = 0;
+       }
+    } else {
+       cc[0] = 0;
+       for (i = 0; i < n_comp; i++) {
+           vec[0][i] = input[minColL][i];
+           vec[1][i] = input[maxColL][i];
+       }
+       if (minColL != maxColL) {
+           /* compute interpolation vector */
+           MAKEIVEC(n_vect, n_comp, iv, b, vec[0], vec[1]);
+
+           /* add in texels */
+           lolo = 0;
+           for (k = N_TEXELS / 2 - 1; k >= 0; k--) {
+               int texel = n_vect + 1; /* transparent black */
+               if (!ISTBLACK(input[k])) {
+                   /* interpolate color */
+                   CALCCDOT(texel, n_vect, n_comp, iv, b, input[k]);
+               }
+               /* add in texel */
+               lolo <<= 2;
+               lolo |= texel;
+           }
+           cc[0] = lolo;
+       }
+    }
+
+    /* right microtile */
+    if (maxColR == -1) {
+       /* all transparent black */
+       cc[1] = ~0UL;
+       for (i = 0; i < n_comp; i++) {
+           vec[2][i] = 0;
+           vec[3][i] = 0;
+       }
+    } else {
+       cc[1] = 0;
+       for (i = 0; i < n_comp; i++) {
+           vec[2][i] = input[minColR][i];
+           vec[3][i] = input[maxColR][i];
+       }
+       if (minColR != maxColR) {
+           /* compute interpolation vector */
+           MAKEIVEC(n_vect, n_comp, iv, b, vec[2], vec[3]);
+
+           /* add in texels */
+           lohi = 0;
+           for (k = N_TEXELS - 1; k >= N_TEXELS / 2; k--) {
+               int texel = n_vect + 1; /* transparent black */
+               if (!ISTBLACK(input[k])) {
+                   /* interpolate color */
+                   CALCCDOT(texel, n_vect, n_comp, iv, b, input[k]);
+               }
+               /* add in texel */
+               lohi <<= 2;
+               lohi |= texel;
+           }
+           cc[1] = lohi;
+       }
+    }
+
+    Q_MOV32(hi, 9 | (vec[3][GCOMP] & 4) | ((vec[1][GCOMP] >> 1) & 2)); /* chroma = "1" */
+    for (j = 2 * 2 - 1; j >= 0; j--) {
+       for (i = 0; i < n_comp; i++) {
+           /* add in colors */
+           Q_SHL(hi, 5);
+           Q_OR32(hi, vec[j][i] >> 3);
+       }
+    }
+    ((qword *)cc)[1] = hi;
+}
+
+
+static void
+fxt1_quantize_MIXED0 (dword *cc,
+                     byte input[N_TEXELS][MAX_COMP])
+{
+    const int n_vect = 3; /* highest vector number in each microtile */
+    const int n_comp = 3; /* 3 components: R, G, B */
+    byte vec[2 * 2][MAX_COMP]; /* 2 extrema for each sub-block */
+    float b, iv[MAX_COMP]; /* interpolation vector */
+    int i, j, k;
+    qword hi; /* high quadword */
+    dword lohi, lolo; /* low quadword: hi dword, lo dword */
+
+    int minColL = 0, maxColL = 0;
+    int minColR = 0, maxColR = 0;
+#if 0
+    int minSum;
+    int maxSum;
+
+    /* Our solution here is to find the darkest and brightest colors in
+     * the 4x4 tile and use those as the two representative colors.
+     * There are probably better algorithms to use (histogram-based).
+     */
+    minSum = 2000; /* big enough */
+    maxSum = -1; /* small enough */
+    for (k = 0; k < N_TEXELS / 2; k++) {
+       int sum = 0;
+       for (i = 0; i < n_comp; i++) {
+           sum += input[k][i];
+       }
+       if (minSum > sum) {
+           minSum = sum;
+           minColL = k;
+       }
+       if (maxSum < sum) {
+           maxSum = sum;
+           maxColL = k;
+       }
+    }
+    minSum = 2000; /* big enough */
+    maxSum = -1; /* small enough */
+    for (; k < N_TEXELS; k++) {
+       int sum = 0;
+       for (i = 0; i < n_comp; i++) {
+           sum += input[k][i];
+       }
+       if (minSum > sum) {
+           minSum = sum;
+           minColR = k;
+       }
+       if (maxSum < sum) {
+           maxSum = sum;
+           maxColR = k;
+       }
+    }
+#else
+    int minVal;
+    int maxVal;
+    int maxVarL = fxt1_variance(NULL, input, n_comp, N_TEXELS / 2);
+    int maxVarR = fxt1_variance(NULL, &input[N_TEXELS / 2], n_comp, N_TEXELS / 2);
+
+    /* Scan the channel with max variance for lo & hi
+     * and use those as the two representative colors.
+     */
+    minVal = 2000; /* big enough */
+    maxVal = -1; /* small enough */
+    for (k = 0; k < N_TEXELS / 2; k++) {
+       int t = input[k][maxVarL];
+       if (minVal > t) {
+           minVal = t;
+           minColL = k;
+       }
+       if (maxVal < t) {
+           maxVal = t;
+           maxColL = k;
+       }
+    }
+    minVal = 2000; /* big enough */
+    maxVal = -1; /* small enough */
+    for (; k < N_TEXELS; k++) {
+       int t = input[k][maxVarR];
+       if (minVal > t) {
+           minVal = t;
+           minColR = k;
+       }
+       if (maxVal < t) {
+           maxVal = t;
+           maxColR = k;
+       }
+    }
+#endif
+
+    /* left microtile */
+    cc[0] = 0;
+    for (i = 0; i < n_comp; i++) {
+       vec[0][i] = input[minColL][i];
+       vec[1][i] = input[maxColL][i];
+    }
+    if (minColL != maxColL) {
+       /* compute interpolation vector */
+       MAKEIVEC(n_vect, n_comp, iv, b, vec[0], vec[1]);
+
+       /* add in texels */
+       lolo = 0;
+       for (k = N_TEXELS / 2 - 1; k >= 0; k--) {
+           int texel;
+           /* interpolate color */
+           CALCCDOT(texel, n_vect, n_comp, iv, b, input[k]);
+           /* add in texel */
+           lolo <<= 2;
+           lolo |= texel;
+       }
+
+       /* funky encoding for LSB of green */
+       if ((int)((lolo >> 1) & 1) != (((vec[1][GCOMP] ^ vec[0][GCOMP]) >> 2) & 1)) {
+           for (i = 0; i < n_comp; i++) {
+               vec[1][i] = input[minColL][i];
+               vec[0][i] = input[maxColL][i];
+           }
+           lolo = ~lolo;
+       }
+
+       cc[0] = lolo;
+    }
+
+    /* right microtile */
+    cc[1] = 0;
+    for (i = 0; i < n_comp; i++) {
+       vec[2][i] = input[minColR][i];
+       vec[3][i] = input[maxColR][i];
+    }
+    if (minColR != maxColR) {
+       /* compute interpolation vector */
+       MAKEIVEC(n_vect, n_comp, iv, b, vec[2], vec[3]);
+
+       /* add in texels */
+       lohi = 0;
+       for (k = N_TEXELS - 1; k >= N_TEXELS / 2; k--) {
+           int texel;
+           /* interpolate color */
+           CALCCDOT(texel, n_vect, n_comp, iv, b, input[k]);
+           /* add in texel */
+           lohi <<= 2;
+           lohi |= texel;
+       }
+
+       /* funky encoding for LSB of green */
+       if ((int)((lohi >> 1) & 1) != (((vec[3][GCOMP] ^ vec[2][GCOMP]) >> 2) & 1)) {
+           for (i = 0; i < n_comp; i++) {
+               vec[3][i] = input[minColR][i];
+               vec[2][i] = input[maxColR][i];
+           }
+           lohi = ~lohi;
+       }
+
+       cc[1] = lohi;
+    }
+
+    Q_MOV32(hi, 8 | (vec[3][GCOMP] & 4) | ((vec[1][GCOMP] >> 1) & 2)); /* chroma = "1" */
+    for (j = 2 * 2 - 1; j >= 0; j--) {
+       for (i = 0; i < n_comp; i++) {
+           /* add in colors */
+           Q_SHL(hi, 5);
+           Q_OR32(hi, vec[j][i] >> 3);
+       }
+    }
+    ((qword *)cc)[1] = hi;
+}
+
+
+static void
+fxt1_quantize (dword *cc, const byte *lines[], int comps)
+{
+    int trualpha;
+    byte reord[N_TEXELS][MAX_COMP];
+
+    byte input[N_TEXELS][MAX_COMP];
+    int i, k, l;
+
+    if (comps == 3) {
+       /* make the whole block opaque */
+       memset(input, -1, sizeof(input));
+    }
+
+    /* 8 texels each line */
+    for (l = 0; l < 4; l++) {
+       for (k = 0; k < 4; k++) {
+           for (i = 0; i < comps; i++) {
+               input[k + l * 4][i] = *lines[l]++;
+           }
+       }
+       for (; k < 8; k++) {
+           for (i = 0; i < comps; i++) {
+               input[k + l * 4 + 12][i] = *lines[l]++;
+           }
+       }
+    }
+
+    /* block layout:
+     * 00, 01, 02, 03, 08, 09, 0a, 0b
+     * 10, 11, 12, 13, 18, 19, 1a, 1b
+     * 04, 05, 06, 07, 0c, 0d, 0e, 0f
+     * 14, 15, 16, 17, 1c, 1d, 1e, 1f
+     */
+
+    /* [dBorca]
+     * stupidity flows forth from this
+     */
+    l = N_TEXELS;
+    trualpha = 0;
+    if (comps == 4) {
+       /* skip all transparent black texels */
+       l = 0;
+       for (k = 0; k < N_TEXELS; k++) {
+           /* test all components against 0 */
+           if (!ISTBLACK(input[k])) {
+               /* texel is not transparent black */
+               COPY_4UBV(reord[l], input[k]);
+               if (reord[l][ACOMP] < (255 - ALPHA_TS)) {
+                   /* non-opaque texel */
+                   trualpha = !0;
+               }
+               l++;
+           }
+       }
+    }
+
+#if 0
+    if (trualpha) {
+       fxt1_quantize_ALPHA0(cc, input, reord, l);
+    } else if (l == 0) {
+       cc[0] = cc[1] = cc[2] = -1;
+       cc[3] = 0;
+    } else if (l < N_TEXELS) {
+       fxt1_quantize_HI(cc, input, reord, l);
+    } else {
+       fxt1_quantize_CHROMA(cc, input);
+    }
+    (void)fxt1_quantize_ALPHA1;
+    (void)fxt1_quantize_MIXED1;
+    (void)fxt1_quantize_MIXED0;
+#else
+    if (trualpha) {
+       fxt1_quantize_ALPHA1(cc, input);
+    } else if (l == 0) {
+       cc[0] = cc[1] = cc[2] = ~0UL;
+       cc[3] = 0;
+    } else if (l < N_TEXELS) {
+       fxt1_quantize_MIXED1(cc, input);
+    } else {
+       fxt1_quantize_MIXED0(cc, input);
+    }
+    (void)fxt1_quantize_ALPHA0;
+    (void)fxt1_quantize_HI;
+    (void)fxt1_quantize_CHROMA;
+#endif
+}
+
+
+TAPI int TAPIENTRY
+fxt1_encode (int width, int height, int comps,
+            const void *source, int srcRowStride,
+            void *dest, int destRowStride)
+{
+    int x, y;
+    const byte *data;
+    dword *encoded = (dword *)dest;
+    void *newSource = NULL;
+
+    /* Replicate image if width is not M8 or height is not M4 */
+    if ((width & 7) | (height & 3)) {
+       int newWidth = (width + 7) & ~7;
+       int newHeight = (height + 3) & ~3;
+       newSource = malloc(comps * newWidth * newHeight * sizeof(byte *));
+       _mesa_upscale_teximage2d(width, height, newWidth, newHeight,
+                                comps, (const byte *)source,
+                                srcRowStride, (byte *)newSource);
+       source = newSource;
+       width = newWidth;
+       height = newHeight;
+       srcRowStride = comps * newWidth;
+    }
+
+    data = (const byte *)source;
+    destRowStride = (destRowStride - width * 2) / 4;
+    for (y = 0; y < height; y += 4) {
+       unsigned int offs = 0 + (y + 0) * srcRowStride;
+       for (x = 0; x < width; x += 8) {
+           const byte *lines[4];
+           lines[0] = &data[offs];
+           lines[1] = lines[0] + srcRowStride;
+           lines[2] = lines[1] + srcRowStride;
+           lines[3] = lines[2] + srcRowStride;
+           offs += 8 * comps;
+           fxt1_quantize(encoded, lines, comps);
+           /* 128 bits per 8x4 block */
+           encoded += 4;
+       }
+       encoded += destRowStride;
+    }
+
+    if (newSource != NULL) {
+       free(newSource);
+    }
+
+    return 0;
+}
+
+
+/***************************************************************************\
+ * FXT1 decoder
+ *
+ * The decoder is based on GL_3DFX_texture_compression_FXT1
+ * specification and serves as a concept for the encoder.
+\***************************************************************************/
+
+
+/* lookup table for scaling 5 bit colors up to 8 bits */
+static const byte _rgb_scale_5[] = {
+    0,   8,   16,  25,  33,  41,  49,  58,
+    66,  74,  82,  90,  99,  107, 115, 123,
+    132, 140, 148, 156, 165, 173, 181, 189,
+    197, 206, 214, 222, 230, 239, 247, 255
+};
+
+/* lookup table for scaling 6 bit colors up to 8 bits */
+static const byte _rgb_scale_6[] = {
+    0,   4,   8,   12,  16,  20,  24,  28,
+    32,  36,  40,  45,  49,  53,  57,  61,
+    65,  69,  73,  77,  81,  85,  89,  93,
+    97,  101, 105, 109, 113, 117, 121, 125,
+    130, 134, 138, 142, 146, 150, 154, 158,
+    162, 166, 170, 174, 178, 182, 186, 190,
+    194, 198, 202, 206, 210, 215, 219, 223,
+    227, 231, 235, 239, 243, 247, 251, 255
+};
+
+
+#define CC_SEL(cc, which) (((dword *)(cc))[(which) / 32] >> ((which) & 31))
+#define UP5(c) _rgb_scale_5[(c) & 31]
+#define UP6(c, b) _rgb_scale_6[(((c) & 31) << 1) | ((b) & 1)]
+#define LERP(n, t, c0, c1) (((n) - (t)) * (c0) + (t) * (c1) + (n) / 2) / (n)
+#define ZERO_4UBV(v) *((dword *)(v)) = 0
+
+
+static void
+fxt1_decode_1HI (const byte *code, int t, byte *rgba)
+{
+    const dword *cc;
+
+    t *= 3;
+    cc = (const dword *)(code + t / 8);
+    t = (cc[0] >> (t & 7)) & 7;
+
+    if (t == 7) {
+       ZERO_4UBV(rgba);
+    } else {
+       cc = (const dword *)(code + 12);
+       if (t == 0) {
+           rgba[BCOMP] = UP5(CC_SEL(cc, 0));
+           rgba[GCOMP] = UP5(CC_SEL(cc, 5));
+           rgba[RCOMP] = UP5(CC_SEL(cc, 10));
+       } else if (t == 6) {
+           rgba[BCOMP] = UP5(CC_SEL(cc, 15));
+           rgba[GCOMP] = UP5(CC_SEL(cc, 20));
+           rgba[RCOMP] = UP5(CC_SEL(cc, 25));
+       } else {
+           rgba[BCOMP] = LERP(6, t, UP5(CC_SEL(cc, 0)), UP5(CC_SEL(cc, 15)));
+           rgba[GCOMP] = LERP(6, t, UP5(CC_SEL(cc, 5)), UP5(CC_SEL(cc, 20)));
+           rgba[RCOMP] = LERP(6, t, UP5(CC_SEL(cc, 10)), UP5(CC_SEL(cc, 25)));
+       }
+       rgba[ACOMP] = 255;
+    }
+}
+
+
+static void
+fxt1_decode_1CHROMA (const byte *code, int t, byte *rgba)
+{
+    const dword *cc;
+    dword kk;
+
+    cc = (const dword *)code;
+    if (t & 16) {
+       cc++;
+       t &= 15;
+    }
+    t = (cc[0] >> (t * 2)) & 3;
+
+    t *= 15;
+    cc = (const dword *)(code + 8 + t / 8);
+    kk = cc[0] >> (t & 7);
+    rgba[BCOMP] = UP5(kk);
+    rgba[GCOMP] = UP5(kk >> 5);
+    rgba[RCOMP] = UP5(kk >> 10);
+    rgba[ACOMP] = 255;
+}
+
+
+static void
+fxt1_decode_1MIXED (const byte *code, int t, byte *rgba)
+{
+    const dword *cc;
+    int col[2][3];
+    int glsb, selb;
+
+    cc = (const dword *)code;
+    if (t & 16) {
+       t &= 15;
+       t = (cc[1] >> (t * 2)) & 3;
+       /* col 2 */
+       col[0][BCOMP] = (*(const dword *)(code + 11)) >> 6;
+       col[0][GCOMP] = CC_SEL(cc, 99);
+       col[0][RCOMP] = CC_SEL(cc, 104);
+       /* col 3 */
+       col[1][BCOMP] = CC_SEL(cc, 109);
+       col[1][GCOMP] = CC_SEL(cc, 114);
+       col[1][RCOMP] = CC_SEL(cc, 119);
+       glsb = CC_SEL(cc, 126);
+       selb = CC_SEL(cc, 33);
+    } else {
+       t = (cc[0] >> (t * 2)) & 3;
+       /* col 0 */
+       col[0][BCOMP] = CC_SEL(cc, 64);
+       col[0][GCOMP] = CC_SEL(cc, 69);
+       col[0][RCOMP] = CC_SEL(cc, 74);
+       /* col 1 */
+       col[1][BCOMP] = CC_SEL(cc, 79);
+       col[1][GCOMP] = CC_SEL(cc, 84);
+       col[1][RCOMP] = CC_SEL(cc, 89);
+       glsb = CC_SEL(cc, 125);
+       selb = CC_SEL(cc, 1);
+    }
+
+    if (CC_SEL(cc, 124) & 1) {
+       /* alpha[0] == 1 */
+
+       if (t == 3) {
+           ZERO_4UBV(rgba);
+       } else {
+           if (t == 0) {
+               rgba[BCOMP] = UP5(col[0][BCOMP]);
+               rgba[GCOMP] = UP5(col[0][GCOMP]);
+               rgba[RCOMP] = UP5(col[0][RCOMP]);
+           } else if (t == 2) {
+               rgba[BCOMP] = UP5(col[1][BCOMP]);
+               rgba[GCOMP] = UP6(col[1][GCOMP], glsb);
+               rgba[RCOMP] = UP5(col[1][RCOMP]);
+           } else {
+               rgba[BCOMP] = (UP5(col[0][BCOMP]) + UP5(col[1][BCOMP])) / 2;
+               rgba[GCOMP] = (UP5(col[0][GCOMP]) + UP6(col[1][GCOMP], glsb)) / 2;
+               rgba[RCOMP] = (UP5(col[0][RCOMP]) + UP5(col[1][RCOMP])) / 2;
+           }
+           rgba[ACOMP] = 255;
+       }
+    } else {
+       /* alpha[0] == 0 */
+
+       if (t == 0) {
+           rgba[BCOMP] = UP5(col[0][BCOMP]);
+           rgba[GCOMP] = UP6(col[0][GCOMP], glsb ^ selb);
+           rgba[RCOMP] = UP5(col[0][RCOMP]);
+       } else if (t == 3) {
+           rgba[BCOMP] = UP5(col[1][BCOMP]);
+           rgba[GCOMP] = UP6(col[1][GCOMP], glsb);
+           rgba[RCOMP] = UP5(col[1][RCOMP]);
+       } else {
+           rgba[BCOMP] = LERP(3, t, UP5(col[0][BCOMP]), UP5(col[1][BCOMP]));
+           rgba[GCOMP] = LERP(3, t, UP6(col[0][GCOMP], glsb ^ selb),
+                                    UP6(col[1][GCOMP], glsb));
+           rgba[RCOMP] = LERP(3, t, UP5(col[0][RCOMP]), UP5(col[1][RCOMP]));
+       }
+       rgba[ACOMP] = 255;
+    }
+}
+
+
+static void
+fxt1_decode_1ALPHA (const byte *code, int t, byte *rgba)
+{
+    const dword *cc;
+
+    cc = (const dword *)code;
+    if (CC_SEL(cc, 124) & 1) {
+       /* lerp == 1 */
+       int col0[4];
+
+       if (t & 16) {
+           t &= 15;
+           t = (cc[1] >> (t * 2)) & 3;
+           /* col 2 */
+           col0[BCOMP] = (*(const dword *)(code + 11)) >> 6;
+           col0[GCOMP] = CC_SEL(cc, 99);
+           col0[RCOMP] = CC_SEL(cc, 104);
+           col0[ACOMP] = CC_SEL(cc, 119);
+       } else {
+           t = (cc[0] >> (t * 2)) & 3;
+           /* col 0 */
+           col0[BCOMP] = CC_SEL(cc, 64);
+           col0[GCOMP] = CC_SEL(cc, 69);
+           col0[RCOMP] = CC_SEL(cc, 74);
+           col0[ACOMP] = CC_SEL(cc, 109);
+       }
+
+       if (t == 0) {
+           rgba[BCOMP] = UP5(col0[BCOMP]);
+           rgba[GCOMP] = UP5(col0[GCOMP]);
+           rgba[RCOMP] = UP5(col0[RCOMP]);
+           rgba[ACOMP] = UP5(col0[ACOMP]);
+       } else if (t == 3) {
+           rgba[BCOMP] = UP5(CC_SEL(cc, 79));
+           rgba[GCOMP] = UP5(CC_SEL(cc, 84));
+           rgba[RCOMP] = UP5(CC_SEL(cc, 89));
+           rgba[ACOMP] = UP5(CC_SEL(cc, 114));
+       } else {
+           rgba[BCOMP] = LERP(3, t, UP5(col0[BCOMP]), UP5(CC_SEL(cc, 79)));
+           rgba[GCOMP] = LERP(3, t, UP5(col0[GCOMP]), UP5(CC_SEL(cc, 84)));
+           rgba[RCOMP] = LERP(3, t, UP5(col0[RCOMP]), UP5(CC_SEL(cc, 89)));
+           rgba[ACOMP] = LERP(3, t, UP5(col0[ACOMP]), UP5(CC_SEL(cc, 114)));
+       }
+    } else {
+       /* lerp == 0 */
+
+       if (t & 16) {
+           cc++;
+           t &= 15;
+       }
+       t = (cc[0] >> (t * 2)) & 3;
+
+       if (t == 3) {
+           ZERO_4UBV(rgba);
+       } else {
+           dword kk;
+           cc = (const dword *)code;
+           rgba[ACOMP] = UP5(cc[3] >> (t * 5 + 13));
+           t *= 15;
+           cc = (const dword *)(code + 8 + t / 8);
+           kk = cc[0] >> (t & 7);
+           rgba[BCOMP] = UP5(kk);
+           rgba[GCOMP] = UP5(kk >> 5);
+           rgba[RCOMP] = UP5(kk >> 10);
+       }
+    }
+}
+
+
+TAPI void TAPIENTRY
+fxt1_decode_1 (const void *texture, int stride,
+              int i, int j, byte *rgba)
+{
+    static void (*decode_1[]) (const byte *, int, byte *) = {
+       fxt1_decode_1HI,        /* cc-high   = "00?" */
+       fxt1_decode_1HI,        /* cc-high   = "00?" */
+       fxt1_decode_1CHROMA,    /* cc-chroma = "010" */
+       fxt1_decode_1ALPHA,     /* alpha     = "011" */
+       fxt1_decode_1MIXED,     /* mixed     = "1??" */
+       fxt1_decode_1MIXED,     /* mixed     = "1??" */
+       fxt1_decode_1MIXED,     /* mixed     = "1??" */
+       fxt1_decode_1MIXED      /* mixed     = "1??" */
+    };
+
+    const byte *code = (const byte *)texture +
+                       ((j / 4) * (stride / 8) + (i / 8)) * 16;
+    int mode = CC_SEL(code, 125);
+    int t = i & 7;
+
+    if (t & 4) {
+       t += 12;
+    }
+    t += (j & 3) * 4;
+
+    decode_1[mode](code, t, rgba);
+
+#if VERBOSE
+    {
+       extern int cc_chroma;
+       extern int cc_alpha;
+       extern int cc_high;
+       extern int cc_mixed;
+       static int *cctype[] = {
+           &cc_high,
+           &cc_high,
+           &cc_chroma,
+           &cc_alpha,
+           &cc_mixed,
+           &cc_mixed,
+           &cc_mixed,
+           &cc_mixed
+       };
+       (*cctype[mode])++;
+    }
+#endif
+}
diff --git a/reactos/dll/3rdparty/dxtn/fxt1.h b/reactos/dll/3rdparty/dxtn/fxt1.h
new file mode 100644 (file)
index 0000000..c2919bb
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * FXT1 codec
+ * Version:  1.1
+ *
+ * Copyright (C) 2004  Daniel Borca   All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * DANIEL BORCA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+#ifndef FXT1_H_included
+#define FXT1_H_included
+
+TAPI int TAPIENTRY
+fxt1_encode (int width, int height, int comps,
+             const void *source, int srcRowStride,
+             void *dest, int destRowStride);
+
+TAPI void TAPIENTRY
+fxt1_decode_1 (const void *texture, int stride /* in pixels */,
+              int i, int j, byte *rgba);
+
+#endif
diff --git a/reactos/dll/3rdparty/dxtn/internal.h b/reactos/dll/3rdparty/dxtn/internal.h
new file mode 100644 (file)
index 0000000..e5aad30
--- /dev/null
@@ -0,0 +1,138 @@
+/*
+ * Texture compression
+ * Version:  1.0
+ *
+ * Copyright (C) 2004  Daniel Borca   All Rights Reserved.
+ *
+ * this is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * this is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING.  If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.       
+ */
+
+
+#ifndef INTERNAL_H_included
+#define INTERNAL_H_included
+
+/*****************************************************************************\
+ * DLL stuff
+\*****************************************************************************/
+
+#ifdef __WIN32__
+#define TAPI __declspec(dllexport)
+#define TAPIENTRY /*__stdcall*/
+#else
+#define TAPI
+#define TAPIENTRY
+#endif
+
+
+/*****************************************************************************\
+ * 64bit types on 32bit machine
+\*****************************************************************************/
+
+#if defined(__GNUC__) && !defined(__cplusplus)
+
+typedef unsigned long long qword;
+
+#define Q_MOV32(a, b) a = b
+#define Q_OR32(a, b)  a |= b
+#define Q_SHL(a, c)   a <<= c
+
+#else  /* !__GNUC__ */
+
+typedef struct {
+    dword lo, hi;
+} qword;
+
+#define Q_MOV32(a, b) a.lo = b
+#define Q_OR32(a, b)  a.lo |= b
+#define Q_SHL(a, c)                                    \
+    do {                                               \
+       if ((c) >= 32) {                                \
+           a.hi = a.lo << ((c) - 32);                  \
+           a.lo = 0;                                   \
+       } else {                                        \
+           a.hi = (a.hi << (c)) | (a.lo >> (32 - (c)));\
+           a.lo <<= c;                                 \
+       }                                               \
+    } while (0)
+
+#endif /* !__GNUC__ */
+
+
+/*****************************************************************************\
+ * Config
+\*****************************************************************************/
+
+#define RCOMP 0
+#define GCOMP 1
+#define BCOMP 2
+#define ACOMP 3
+
+
+/*****************************************************************************\
+ * Metric
+\*****************************************************************************/
+
+#define F(i) (float)1 /* can be used to obtain an oblong metric: 0.30 / 0.59 / 0.11 */
+#define SAFECDOT 1 /* for paranoids */
+
+#define MAKEIVEC(NV, NC, IV, B, V0, V1)        \
+    do {                               \
+       /* compute interpolation vector */\
+       float d2 = 0.0F;                \
+       float rd2;                      \
+                                       \
+       for (i = 0; i < NC; i++) {      \
+           IV[i] = (V1[i] - V0[i]) * F(i);\
+           d2 += IV[i] * IV[i];        \
+       }                               \
+       rd2 = (float)NV / d2;           \
+       B = 0;                          \
+       for (i = 0; i < NC; i++) {      \
+           IV[i] *= F(i);              \
+           B -= IV[i] * V0[i];         \
+           IV[i] *= rd2;               \
+       }                               \
+       B = B * rd2 + 0.5F;             \
+    } while (0)
+
+#define CALCCDOT(TEXEL, NV, NC, IV, B, V)\
+    do {                               \
+       float dot = 0.0F;               \
+       for (i = 0; i < NC; i++) {      \
+           dot += V[i] * IV[i];        \
+       }                               \
+       TEXEL = (int)(dot + B);         \
+       if (SAFECDOT) {                 \
+           if (TEXEL < 0) {            \
+               TEXEL = 0;              \
+           } else if (TEXEL > NV) {    \
+               TEXEL = NV;             \
+           }                           \
+       }                               \
+    } while (0)
+
+
+/*****************************************************************************\
+ * Utility functions
+\*****************************************************************************/
+
+void
+_mesa_upscale_teximage2d (unsigned int inWidth, unsigned int inHeight,
+                         unsigned int outWidth, unsigned int outHeight,
+                         unsigned int comps,
+                         const byte *src, int srcRowStride,
+                         unsigned char *dest);
+
+#endif
diff --git a/reactos/dll/3rdparty/dxtn/test/Makefile b/reactos/dll/3rdparty/dxtn/test/Makefile
new file mode 100644 (file)
index 0000000..3a6e6b5
--- /dev/null
@@ -0,0 +1,72 @@
+# Texture compression
+# Version:  1.1
+#
+# Copyright (C) 2004  Daniel Borca   All Rights Reserved.
+#
+# this is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# this is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Make; see the file COPYING.  If not, write to
+# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.        
+
+
+#
+#  Available options:
+#
+#    Environment variables:
+#
+#    Targets:
+#      all:            build codec
+#      clean:          remove object files
+#      realclean:      remove all generated files
+#
+
+
+.PHONY: all clean realclean
+
+EXENAME = codec
+
+CC = gcc
+CFLAGS = -Wall -W -pedantic -ansi
+CFLAGS += -O2 -ffast-math -funroll-loops
+#CFLAGS += -fomit-frame-pointer -fexpensive-optimizations
+CFLAGS += -DVERBOSE=1
+
+LD = gcc
+LDFLAGS = -s
+LDLIBS =
+
+SOURCES = \
+       main.c \
+       tga.c \
+       util.c
+
+SOURCES += \
+       ../fxt1.c \
+       ../dxtn.c \
+       ../wrapper.c \
+       ../texstore.c
+
+OBJECTS = $(SOURCES:.c=.o)
+
+.c.o:
+       $(CC) -o $@ $(CFLAGS) -c $<
+
+all: $(EXENAME)
+
+$(EXENAME): $(OBJECTS)
+       $(LD) -o $@ $(LDFLAGS) $^
+
+clean:
+       -$(RM) $(OBJECTS)
+
+realclean: clean
+       -$(RM) $(EXENAME)
diff --git a/reactos/dll/3rdparty/dxtn/test/main.c b/reactos/dll/3rdparty/dxtn/test/main.c
new file mode 100644 (file)
index 0000000..3a315ef
--- /dev/null
@@ -0,0 +1,356 @@
+/*
+ * Texture compression
+ * Version:  1.1
+ *
+ * Copyright (C) 2004  Daniel Borca   All Rights Reserved.
+ *
+ * this is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * this is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING.  If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.       
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <GL/gl.h>
+
+#include "tga.h"
+#include "util.h"
+#include "../types.h"
+#include "../internal.h"
+#include "../fxt1.h"
+#include "../dxtn.h"
+
+
+#if VERBOSE
+int cc_chroma = 0;
+int cc_alpha = 0;
+int cc_high = 0;
+int cc_mixed = 0;
+#endif
+
+
+typedef int (*encoder) (int width, int height, int comps,
+                       const void *source, int srcRowStride,
+                       void *dest, int destRowStride);
+typedef void (*decoder) (const void *texture, int stride,
+                        int i, int j, unsigned char *rgba);
+
+
+static struct {
+    const char *name;
+    int type;
+    encoder enc;
+    decoder dec;
+    int wround, hround;
+} *q = NULL, tc[] = {
+    { "fxt1rgba", GL_COMPRESSED_RGBA_FXT1_3DFX,     fxt1_encode,      fxt1_decode_1,      7, 3 },
+    { "fxt1rgb",  GL_COMPRESSED_RGB_FXT1_3DFX,      fxt1_encode,      fxt1_decode_1,      7, 3 },
+    { "dxt1rgb",  GL_COMPRESSED_RGB_S3TC_DXT1_EXT,  dxt1_rgb_encode,  dxt1_rgb_decode_1,  3, 3 },
+    { "dxt1rgba", GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, dxt1_rgba_encode, dxt1_rgba_decode_1, 3, 3 },
+    { "dxt3",     GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, dxt3_rgba_encode, dxt3_rgba_decode_1, 3, 3 },
+    { "dxt5",     GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, dxt5_rgba_encode, dxt5_rgba_decode_1, 3, 3 },
+    { NULL,       -1,                               NULL,             NULL,               0, 0 }
+};
+
+
+int
+main (int argc, char **argv)
+{
+    const char *myself = argv[0];
+    const char *inf = NULL, *outf = NULL, *cmpf = NULL, *a0 = NULL, *a1 = NULL;
+
+    int i, j;
+    int width, height;
+    void *input, *output;
+    unsigned char *rgba;
+#if VERBOSE
+    t_type t0;
+#endif
+
+    /* user options */
+    while (--argc) {
+       char *p = *++argv;
+       if (!strcmp(p, "-h") || !strcmp(p, "--help")) {
+           fprintf(stderr, "usage: %s [type] infile [-o outfile] [-k cfile] [-a0 inalpha] [-a1 outalpha]\n", myself);
+           fprintf(stderr, "    infile must be a 24/32bpp TGA\n");
+           fprintf(stderr, "    outfile will be a 32bpp TGA\n");
+           fprintf(stderr, "    cfile will be the compressed file\n");
+           fprintf(stderr, "    inalpha will be original alpha 32bpp TGA\n");
+           fprintf(stderr, "    outalpha will be output alpha 32bpp TGA\n");
+           fprintf(stderr, "    type can be one of the following:\n");
+           for (i = 0; tc[i].name != NULL; i++) {
+               fprintf(stderr, "        -%s%s\n", tc[i].name, (i == 0) ? " (default)" : "");
+           }
+           return 0;
+       } /*else*/ if (!strcmp(p, "-o")) {
+           if (argc > 1) {
+               argc--;
+               outf = *++argv;
+               continue;
+           } else {
+               fprintf(stderr, "%s: argument to `%s' is missing\n", myself, p);
+               return -1;
+           }
+       } else if (!strcmp(p, "-k")) {
+           if (argc > 1) {
+               argc--;
+               cmpf = *++argv;
+               continue;
+           } else {
+               fprintf(stderr, "%s: argument to `%s' is missing\n", myself, p);
+               return -1;
+           }
+       } else if (!strcmp(p, "-a0")) {
+           if (argc > 1) {
+               argc--;
+               a0 = *++argv;
+               continue;
+           } else {
+               fprintf(stderr, "%s: argument to `%s' is missing\n", myself, p);
+               return -1;
+           }
+       } else if (!strcmp(p, "-a1")) {
+           if (argc > 1) {
+               argc--;
+               a1 = *++argv;
+               continue;
+           } else {
+               fprintf(stderr, "%s: argument to `%s' is missing\n", myself, p);
+               return -1;
+           }
+       } else if (*p == '-') {
+           for (q = tc; q->name != NULL; q++) {
+               if (!strcmp(p + 1, q->name)) {
+                   break;
+               }
+           }
+           if (q->name != NULL) {
+               continue;
+           }
+           fprintf(stderr, "%s: bad option `%s'\n", myself, p);
+           return -1;
+       } else if (inf == NULL) {
+           inf = p;
+           continue;
+       }
+       fprintf(stderr, "%s: too many input files\n", myself);
+       return -1;
+    }
+    if (inf == NULL) {
+       fprintf(stderr, "%s: no input files\n", myself);
+       return -1;
+    }
+    if (outf == NULL) {
+       outf = "aout.tga";
+    }
+    if ((q == NULL) || (q->name == NULL)) {
+       q = tc;
+    }
+
+    /* get input data */
+#if 1
+    if (tga_read_32(inf, &width, &height, &input)) {
+       fprintf(stderr, "%s: cannot read `%s'\n", myself, inf);
+       return -1;
+    }
+#elif 0
+    {
+       static char pattern[8 * 32 + 1] = { "\
+                                \
+    MMM    EEEE   SSS    AAA    \
+   M M M  E      S   S  A   A   \
+   M M M  EEEE    SS    A   A   \
+   M M M  E         SS  AAAAA   \
+   M   M  E      S   S  A   A   \
+   M   M   EEEE   SSS   A   A   \
+                                " };
+
+       unsigned char (*texture)[8 * 32][4];
+       width = 32;
+       height = 8;
+       input = malloc(width * height * 4);
+       texture = (unsigned char (*)[8 * 32][4])input;
+       for (i = 0; i < sizeof(pattern) - 1; i++) {
+           switch (pattern[i]) {
+               default:
+               case ' ':
+                   (*texture)[i][0] = 255;
+                   (*texture)[i][1] = 255;
+                   (*texture)[i][2] = 255;
+                   (*texture)[i][3] = 64;
+                   break;
+               case 'M':
+                   (*texture)[i][0] = 255;
+                   (*texture)[i][1] = 0;
+                   (*texture)[i][2] = 0;
+                   (*texture)[i][3] = 255;
+                   break;
+               case 'E':
+                   (*texture)[i][0] = 0;
+                   (*texture)[i][1] = 255;
+                   (*texture)[i][2] = 0;
+                   (*texture)[i][3] = 255;
+                   break;
+               case 'S':
+                   (*texture)[i][0] = 0;
+                   (*texture)[i][1] = 0;
+                   (*texture)[i][2] = 255;
+                   (*texture)[i][3] = 255;
+                   break;
+               case 'A':
+                   (*texture)[i][0] = 255;
+                   (*texture)[i][1] = 255;
+                   (*texture)[i][2] = 0;
+                   (*texture)[i][3] = 255;
+                   break;
+           }
+       }
+    }
+#else
+    {
+       unsigned char (*texture)[4 * 8][4];
+       width = 8;
+       height = 4;
+       input = malloc(width * height * 4);
+       texture = (unsigned char (*)[4 * 8][4])input;
+       for (i = 0; i < 4 * 8; i++) {
+           (*texture)[i][0] =
+           (*texture)[i][1] =
+           (*texture)[i][2] = 255 * i / 31;
+           (*texture)[i][3] = 255;
+       }
+    }
+#endif
+
+    /* make alpha tga (input values) */
+    if (a0 != NULL) {
+       unsigned long *alpha0 = malloc(width * height * 4);
+       if (alpha0) {
+           unsigned long *ap = alpha0;
+           for (j = 0; j < height; j++) {
+               for (i = 0; i < width; i++) {
+                   unsigned char alp = ((unsigned char *)input)[(j * width + i) * 4 + 3];
+                   *ap++ = alp | (alp << 8) | (alp << 16) | (alp << 24);
+               }
+           }
+           if (tga_write(a0, width, height, alpha0, 32) != 0) {
+               fprintf(stderr, "%s: cannot write `%s'\n", myself, a0);
+           }
+           free(alpha0);
+       }
+    }
+
+    /* allocate compressed output storage */
+    output = malloc(tc_size(width, height, q->type));
+    if (output == NULL) {
+       free(input);
+       fprintf(stderr, "%s: out of memory\n", myself);
+       return -1;
+    }
+
+    /* encode */
+#if VERBOSE
+    T_START(t0);
+#endif
+    q->enc(width, height, 4, input, width * 4, output, tc_stride(q->type, width));
+#if VERBOSE
+    T_STOP(t0);
+    fprintf(stderr, "ENC(%s): %lu ticks\n", q->name, T_DELTA(t0));
+#endif
+
+    /* free raw input data, make encoded data as input */
+    free(input);
+    input = output;
+
+    /* allocate uncompressed output storage */
+    width = (width + q->wround) & ~q->wround;
+    height = (height + q->hround) & ~q->hround;
+    output = malloc(width * height * 4);
+    if (output == NULL) {
+       free(input);
+       fprintf(stderr, "%s: out of memory\n", myself);
+       return -1;
+    }
+
+    /* decode */
+    rgba = output;
+#if VERBOSE
+    T_START(t0);
+#endif
+    for (j = 0; j < height; j++) {
+       for (i = 0; i < width; i++) {
+           q->dec(input, width, i, j, rgba);
+           rgba += 4;
+       }
+    }
+#if VERBOSE
+    T_STOP(t0);
+#endif
+
+    /* write encoded block */
+    if (cmpf != NULL) {
+       FILE *eff = fopen(cmpf, "wb");
+       if (eff) {
+           if (!fwrite(input, tc_size(width, height, q->type), 1, eff)) {
+               fprintf(stderr, "%s: cannot write compressed data\n", myself);
+           }
+           fclose(eff);
+       } else {
+           fprintf(stderr, "%s: cannot create `%s'\n", cmpf, myself);
+       }
+    }
+
+    /* free encoded block */
+    free(input);
+
+    /* write decoded block */
+    if (tga_write(outf, width, height, output, 32) != 0) {
+       fprintf(stderr, "%s: cannot write `%s'\n", myself, outf);
+       return -1;
+    }
+
+    /* make alpha tga (output values) */
+    if (a1 != NULL) {
+       unsigned long *alpha1 = malloc(width * height * 4);
+       if (alpha1) {
+           unsigned long *ap = alpha1;
+           for (j = 0; j < height; j++) {
+               for (i = 0; i < width; i++) {
+                   unsigned char alp = ((unsigned char *)output)[(j * width + i) * 4 + 3];
+                   *ap++ = alp | (alp << 8) | (alp << 16) | (alp << 24);
+               }
+           }
+           if (tga_write(a1, width, height, alpha1, 32) != 0) {
+               fprintf(stderr, "%s: cannot write `%s'\n", myself, a1);
+           }
+           free(alpha1);
+       }
+    }
+
+    /* free decoded block */
+    free(output);
+
+    /* final stats */
+#if VERBOSE
+    fprintf(stderr, "CHROMA = %d\n", cc_chroma);
+    fprintf(stderr, "ALPHA  = %d\n", cc_alpha);
+    fprintf(stderr, "HIGH   = %d\n", cc_high);
+    fprintf(stderr, "MIXED  = %d\n", cc_mixed);
+    fprintf(stderr, "DEC(%s): %lu ticks\n", q->name, T_DELTA(t0));
+#endif
+
+    return 0;
+}
diff --git a/reactos/dll/3rdparty/dxtn/test/tga.c b/reactos/dll/3rdparty/dxtn/test/tga.c
new file mode 100644 (file)
index 0000000..24ce9ab
--- /dev/null
@@ -0,0 +1,165 @@
+/*
+ * TGA file handling
+ * Version:  1.1
+ *
+ * Copyright (C) 2004  Daniel Borca   All Rights Reserved.
+ *
+ * this is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * this is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING.  If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.       
+ */
+
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "tga.h"
+
+
+int
+tga_read_32 (const char *filename, int *w, int *h, void **p)
+{
+    FILE *f;
+    void *img;
+    unsigned char header[18];
+    unsigned int skip_cmap_size;
+    unsigned int type, width, height, tga_bpp;
+    unsigned int raw_image_size;
+    unsigned char *raw_image;
+    unsigned int i, j, k;
+
+    if ((f = fopen(filename, "rb")) == NULL) {
+       return TGA_ERR_OPEN;
+    }
+
+    if (!fread(header, 18, 1, f)) {
+       fclose(f);
+       return TGA_ERR_READ;
+    }
+
+    type = header[2];
+    if (type != 2) {
+       fclose(f);
+       return TGA_ERR_FORMAT;
+    }
+    width = ((short *)header)[6];
+    height = ((short *)header)[7];
+    tga_bpp = header[16];
+
+    if (header[1]) {
+       skip_cmap_size = *(short *)&header[5] * header[7] >> 3;
+    } else {
+       skip_cmap_size = 0;
+    }
+    fseek(f, skip_cmap_size + header[0], SEEK_CUR);
+
+    raw_image_size = width * height;
+    switch (tga_bpp) {
+       case 16:
+           raw_image_size *= 2;
+           break;
+       case 24:
+           raw_image_size *= 3;
+           break;
+       case 32:
+           raw_image_size *= 4;
+           break;
+       default:
+           fclose(f);
+           return TGA_ERR_FORMAT;
+    }
+
+    if ((img = malloc(width * height * 4)) == NULL) {
+       fclose(f);
+       return TGA_ERR_MEM;
+    }
+
+    if ((raw_image = malloc(raw_image_size)) == NULL) {
+       free(img);
+       fclose(f);
+       return TGA_ERR_MEM;
+    }
+
+    if (!fread(raw_image, raw_image_size, 1, f)) {
+       free(raw_image);
+       free(img);
+       fclose(f);
+       return TGA_ERR_READ;
+    }
+
+    k = 0;
+    for (i = 0; i < height; i++) {
+       unsigned long decoded;
+       int l = (header[17] & 0x20) ? i : (height - i - 1);
+       unsigned char *bmp_line = (unsigned char *)img + l * width * 4;
+       for (j = 0; j < width; j++) {
+           switch (tga_bpp) {
+               case 16:
+                   assert(0);
+                   k += 2;
+                   break;
+               case 24:
+                   decoded = (*(unsigned long *)&raw_image[k]) | 0xff000000UL;
+                   k += 3;
+                   break;
+               case 32:
+                   decoded = *(unsigned long *)&raw_image[k];
+                   k += 4;
+                   break;
+               default:
+                   decoded = 0;
+           }
+           ((unsigned long *)bmp_line)[j] = decoded;
+       }
+    }
+
+    free(raw_image);
+    fclose(f);
+
+    *p = img;
+    *w = width;
+    *h = height;
+    return TGA_OK;
+}
+
+
+int
+tga_write (const char *filename, int width, int height, void *data, int bpp)
+{
+    int len;
+    char header[18];
+    FILE *f = fopen(filename, "wb");
+
+    if (f == NULL) {
+       return TGA_ERR_CREATE;
+    }
+
+    memset(header, 0, sizeof(header));
+    header[2] = 2;
+    ((unsigned short *)header)[6] = width;
+    ((unsigned short *)header)[7] = height;
+    header[16] = bpp;
+    header[17] |= 0x20;
+
+    len = width * height * ((header[16] + 7) / 8);
+
+    if (!fwrite(header, sizeof(header), 1, f) || !fwrite(data, len, 1, f)) {
+       return TGA_ERR_WRITE;
+    }
+
+    fclose(f);
+
+    return TGA_OK;
+}
diff --git a/reactos/dll/3rdparty/dxtn/test/tga.h b/reactos/dll/3rdparty/dxtn/test/tga.h
new file mode 100644 (file)
index 0000000..9366840
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * TGA file handling
+ * Version:  1.1
+ *
+ * Copyright (C) 2004  Daniel Borca   All Rights Reserved.
+ *
+ * this is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * this is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING.  If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.       
+ */
+
+
+#ifndef TGA_H_included
+#define TGA_H_included
+
+#define TGA_OK          0
+#define TGA_ERR_MEM    -2
+#define TGA_ERR_CREATE -3
+#define TGA_ERR_OPEN   -4
+#define TGA_ERR_READ   -5
+#define TGA_ERR_WRITE  -6
+#define TGA_ERR_FORMAT -7
+
+int tga_read_32 (const char *filename, int *w, int *h, void **p);
+int tga_write (const char *filename, int width, int height, void *data, int bpp);
+
+#endif
diff --git a/reactos/dll/3rdparty/dxtn/test/util.c b/reactos/dll/3rdparty/dxtn/test/util.c
new file mode 100644 (file)
index 0000000..cf6f6da
--- /dev/null
@@ -0,0 +1,175 @@
+/*
+ * Texture compression
+ * Version:  1.1
+ *
+ * Copyright (C) 2004  Daniel Borca   All Rights Reserved.
+ *
+ * this is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * this is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING.  If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.       
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <GL/gl.h>
+
+#include "util.h"
+
+
+#define GL_RGB_S3TC                       0x83A0
+#define GL_RGB4_S3TC                      0x83A1
+#define GL_RGBA_S3TC                      0x83A2
+#define GL_RGBA4_S3TC                     0x83A3
+
+
+int
+tc_stride (int format, unsigned int width)
+{
+    int stride;
+
+    switch (format) {
+       case GL_COMPRESSED_RGB_FXT1_3DFX:
+       case GL_COMPRESSED_RGBA_FXT1_3DFX:
+           stride = ((width + 7) / 8) * 16;    /* 16 bytes per 8x4 tile */
+           break;
+       case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
+       case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
+       case GL_RGB_S3TC:
+       case GL_RGB4_S3TC:
+           stride = ((width + 3) / 4) * 8;     /* 8 bytes per 4x4 tile */
+           break;
+       case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
+       case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
+       case GL_RGBA_S3TC:
+       case GL_RGBA4_S3TC:
+           stride = ((width + 3) / 4) * 16;    /* 16 bytes per 4x4 tile */
+           break;
+       default:
+           return 0;
+    }
+
+    return stride;
+}
+
+
+unsigned int
+tc_size (unsigned int width, unsigned int height, int format)
+{
+    unsigned int size;
+
+    switch (format) {
+       case GL_COMPRESSED_RGB_FXT1_3DFX:
+       case GL_COMPRESSED_RGBA_FXT1_3DFX:
+           /* round up width to next multiple of 8, height to next multiple of 4 */
+           width = (width + 7) & ~7;
+           height = (height + 3) & ~3;
+           /* 16 bytes per 8x4 tile of RGB[A] texels */
+           size = width * height / 2;
+           /* Textures smaller than 8x4 will effectively be made into 8x4 and
+            * take 16 bytes.
+            */
+           if (size < 16)
+               size = 16;
+           return size;
+       case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
+       case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
+       case GL_RGB_S3TC:
+       case GL_RGB4_S3TC:
+           /* round up width, height to next multiple of 4 */
+           width = (width + 3) & ~3;
+           height = (height + 3) & ~3;
+           /* 8 bytes per 4x4 tile of RGB[A] texels */
+           size = width * height / 2;
+           /* Textures smaller than 4x4 will effectively be made into 4x4 and
+            * take 8 bytes.
+            */
+           if (size < 8)
+               size = 8;
+           return size;
+       case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
+       case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
+       case GL_RGBA_S3TC:
+       case GL_RGBA4_S3TC:
+           /* round up width, height to next multiple of 4 */
+           width = (width + 3) & ~3;
+           height = (height + 3) & ~3;
+           /* 16 bytes per 4x4 tile of RGBA texels */
+           size = width * height;      /* simple! */
+           /* Textures smaller than 4x4 will effectively be made into 4x4 and
+            * take 16 bytes.
+            */
+           if (size < 16)
+               size = 16;
+           return size;
+       default:
+           return 0;
+    }
+}
+
+
+void *
+txs_read_fxt1 (const char *filename, int *width, int *height)
+{
+    FILE *f;
+    void *data;
+
+    char cookie[5];
+    float version;
+    int format;
+    int levels;
+    unsigned int offset;
+
+    int rv;
+
+    f = fopen(filename, "rb");
+    if (f == NULL) {
+       fprintf(stderr, "txs_read_fxt1: cannot open `%s'\n", filename);
+       return NULL;
+    }
+
+    if ((fscanf(f, "%4s %f %d %d %d %d %8x", cookie, &version,
+                                            &format, width, height, &levels,
+                                            &offset) != 7) ||
+       strcmp(cookie, "TXSF") ||
+       (version != 1.0) ||
+       (format != 17) ||
+       (*width & 7) ||
+       (*height & 4) ||
+       (levels != 1)) {
+       fclose(f);
+       fprintf(stderr, "txs_read_fxt1: bad TXS file %s\n", filename);
+       return NULL;
+    }
+
+    rv = tc_size(*width, *height, GL_COMPRESSED_RGBA_FXT1_3DFX);
+    data = malloc(rv);
+    if (data == NULL) {
+       fclose(f);
+       fprintf(stderr, "txs_read_fxt1: out of memory\n");
+       return NULL;
+    }
+
+    fseek(f, offset, SEEK_SET);
+    rv = fread(data, rv, 1, f);
+    fclose(f);
+
+    if (!rv) {
+       free(data);
+       data = NULL;
+    }
+
+    return data;
+}
diff --git a/reactos/dll/3rdparty/dxtn/test/util.h b/reactos/dll/3rdparty/dxtn/test/util.h
new file mode 100644 (file)
index 0000000..650db51
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * Texture compression
+ * Version:  1.1
+ *
+ * Copyright (C) 2004  Daniel Borca   All Rights Reserved.
+ *
+ * this is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * this is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING.  If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.       
+ */
+
+
+#ifndef UTIL_H_included
+
+
+/*
+ * timer stuff
+ */
+#ifdef __DJGPP__
+
+typedef unsigned long long t_type;
+extern unsigned long long _rdtsc(void);
+#define T_START(t) do { t = _rdtsc(); } while (0)
+#define T_STOP(t) do { t = _rdtsc() - t; } while (0)
+#define T_DELTA(t) (unsigned long)(t & 0xffffffff)
+
+#elif defined(__linux__)
+
+#include <time.h>
+
+typedef clock_t t_type;
+#define T_START(t) do { t = clock(); } while (0)
+#define T_STOP(t) do { t = clock() - t; } while (0)
+#define T_DELTA(t) t
+
+#else  /* !__linux__ */
+
+typedef int t_type;
+#define T_START(t) do { t = 0; } while (0)
+#define T_STOP(t) do { t = 0 - t; } while (0)
+#define T_DELTA(t) t
+
+#endif /* !__linux__ */
+
+
+/*
+ * compressed texture stuff
+ */
+int tc_stride (int format, unsigned int width);
+unsigned int tc_size (unsigned int width, unsigned int height, int format);
+
+
+/*
+ * specific stuff
+ */
+void *txs_read_fxt1 (const char *filename, int *width, int *height);
+
+
+#endif /* UTIL_H_included */
diff --git a/reactos/dll/3rdparty/dxtn/texstore.c b/reactos/dll/3rdparty/dxtn/texstore.c
new file mode 100644 (file)
index 0000000..6349680
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * Mesa 3-D graphics library
+ * Version:  6.3
+ *
+ * Copyright (C) 1999-2004  Brian Paul   All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+#include <assert.h>
+
+#include "types.h"
+#include "internal.h"
+
+
+void
+_mesa_upscale_teximage2d (unsigned int inWidth, unsigned int inHeight,
+                         unsigned int outWidth, unsigned int outHeight,
+                         unsigned int comps,
+                         const byte *src, int srcRowStride,
+                         byte *dest)
+{
+    unsigned int i, j, k;
+
+    assert(outWidth >= inWidth);
+    assert(outHeight >= inHeight);
+
+    for (i = 0; i < outHeight; i++) {
+       const int ii = i % inHeight;
+       for (j = 0; j < outWidth; j++) {
+           const int jj = j % inWidth;
+           for (k = 0; k < comps; k++) {
+               dest[(i * outWidth + j) * comps + k]
+                   = src[ii * srcRowStride + jj * comps + k];
+           }
+       }
+    }
+}
diff --git a/reactos/dll/3rdparty/dxtn/types.h b/reactos/dll/3rdparty/dxtn/types.h
new file mode 100644 (file)
index 0000000..40e7153
--- /dev/null
@@ -0,0 +1,11 @@
+#ifndef TYPES_H_included
+#define TYPES_H_included
+
+/*****************************************************************************\
+ * 32bit types
+\*****************************************************************************/
+typedef unsigned char byte;    /*  8-bit */
+typedef unsigned short word;   /* 16-bit */
+typedef unsigned int dword;    /* 32-bit */
+
+#endif
diff --git a/reactos/dll/3rdparty/dxtn/wrapper.c b/reactos/dll/3rdparty/dxtn/wrapper.c
new file mode 100644 (file)
index 0000000..7bc8d61
--- /dev/null
@@ -0,0 +1,110 @@
+/*
+ * Texture compression
+ * Version:  1.0
+ *
+ * Copyright (C) 2004  Daniel Borca   All Rights Reserved.
+ *
+ * this is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * this is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING.  If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.       
+ */
+
+
+#include <assert.h>
+
+#include "types.h"
+#include "internal.h"
+#include "dxtn.h"
+
+
+#define GL_COMPRESSED_RGB_S3TC_DXT1_EXT   0x83F0
+#define GL_COMPRESSED_RGBA_S3TC_DXT1_EXT  0x83F1
+#define GL_COMPRESSED_RGBA_S3TC_DXT3_EXT  0x83F2
+#define GL_COMPRESSED_RGBA_S3TC_DXT5_EXT  0x83F3
+
+
+TAPI void TAPIENTRY
+fetch_2d_texel_rgb_dxt1 (int texImage_RowStride,
+                        const byte *texImage_Data,
+                        int i, int j,
+                        byte *texel)
+{
+    dxt1_rgb_decode_1(texImage_Data, texImage_RowStride, i, j, texel);
+}
+
+
+TAPI void TAPIENTRY
+fetch_2d_texel_rgba_dxt1 (int texImage_RowStride,
+                         const byte *texImage_Data,
+                         int i, int j,
+                         byte *texel)
+{
+    dxt1_rgba_decode_1(texImage_Data, texImage_RowStride, i, j, texel);
+}
+
+
+TAPI void TAPIENTRY
+fetch_2d_texel_rgba_dxt3 (int texImage_RowStride,
+                         const byte *texImage_Data,
+                         int i, int j,
+                         byte *texel)
+{
+    dxt3_rgba_decode_1(texImage_Data, texImage_RowStride, i, j, texel);
+}
+
+
+TAPI void TAPIENTRY
+fetch_2d_texel_rgba_dxt5 (int texImage_RowStride,
+                         const byte *texImage_Data,
+                         int i, int j,
+                         byte *texel)
+{
+    dxt5_rgba_decode_1(texImage_Data, texImage_RowStride, i, j, texel);
+}
+
+
+TAPI void TAPIENTRY
+tx_compress_dxtn (int srccomps, int width, int height,
+                 const byte *source, int destformat, byte *dest,
+                 int destRowStride)
+{
+    int srcRowStride = width * srccomps;
+    int rv;
+
+    switch (destformat) {
+       case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
+           rv = dxt1_rgb_encode(width, height, srccomps,
+                                source, srcRowStride,
+                                dest, destRowStride);
+           break;
+       case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
+           rv = dxt1_rgba_encode(width, height, srccomps,
+                                 source, srcRowStride,
+                                 dest, destRowStride);
+           break;
+       case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
+           rv = dxt3_rgba_encode(width, height, srccomps,
+                                 source, srcRowStride,
+                                 dest, destRowStride);
+           break;
+       case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
+           rv = dxt5_rgba_encode(width, height, srccomps,
+                                 source, srcRowStride,
+                                 dest, destRowStride);
+           break;
+       default:
+           assert(0);
+    }
+
+    /*return rv;*/
+}