diff --git a/reactos/dll/3rdparty/3rdparty.rbuild b/reactos/dll/3rdparty/3rdparty.rbuild index 9d01737c327..67c28ac8294 100644 --- a/reactos/dll/3rdparty/3rdparty.rbuild +++ b/reactos/dll/3rdparty/3rdparty.rbuild @@ -7,5 +7,11 @@ + + + + + + \ No newline at end of file diff --git a/reactos/dll/3rdparty/dxtn/Makefile b/reactos/dll/3rdparty/dxtn/Makefile new file mode 100644 index 00000000000..f93271c442d --- /dev/null +++ b/reactos/dll/3rdparty/dxtn/Makefile @@ -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 index 00000000000..7a2527ac5e1 --- /dev/null +++ b/reactos/dll/3rdparty/dxtn/Makefile.DJ @@ -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 index 00000000000..5dc7b52d88a --- /dev/null +++ b/reactos/dll/3rdparty/dxtn/Makefile.mgw @@ -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 index 00000000000..30535608bd4 --- /dev/null +++ b/reactos/dll/3rdparty/dxtn/Makefile.vc @@ -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 index 00000000000..d45ddfe3af2 --- /dev/null +++ b/reactos/dll/3rdparty/dxtn/Makefile.wat @@ -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 index 00000000000..b03b01e0db8 --- /dev/null +++ b/reactos/dll/3rdparty/dxtn/docs/README @@ -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 index 00000000000..234c6c6bebc --- /dev/null +++ b/reactos/dll/3rdparty/dxtn/docs/fxt1license.txt @@ -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 index 00000000000..95425763c84 --- /dev/null +++ b/reactos/dll/3rdparty/dxtn/docs/tc.html @@ -0,0 +1,67 @@ + + + + + + + + + + Texture compression + + + + + +

Texture compression

+
+ +

tc-1.1.tar.gz 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. +
  3. if the graphic driver does not support precompressed textures, + it's still cheap to decode "on-line" application-side
  4. +
  5. the distributed package gets smaller
  6. +
+

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/texture_compression_FXT1.txt b/reactos/dll/3rdparty/dxtn/docs/texture_compression_FXT1.txt new file mode 100644 index 00000000000..034e6a57eca --- /dev/null +++ b/reactos/dll/3rdparty/dxtn/docs/texture_compression_FXT1.txt @@ -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 parameter of TexImage2D, + CopyTexImage2D, TexImage3D, CopyTexImage3D, and by the + and 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 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 is an FXT1 format. + CompressedTexImage2DARB will produce an INVALID_OPERATION error if + 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 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 + is GL_COMPRESSED_RGB_FXT1_3DFX or + GL_COMPRESSED_RGBA_FXT1_3DFX. + + INVALID_OPERATION is generated by CompressedTexImage2DARB or + CompressedTexImage3DARB if is + GL_COMPRESSED_RGB_FXT1_3DFX or GL_COMPRESSED_RGBA_FXT1_3DFX and + is not equal to zero. + + INVALID_ENUM is generated by CompressedTexSubImage1DARB if + 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 index 00000000000..b81085221cc --- /dev/null +++ b/reactos/dll/3rdparty/dxtn/docs/texture_compression_s3tc.txt @@ -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 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 parameter of TexImage2D, CopyTexImage2D, + and CompressedTexImage2DARB and the 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: + + * is not a multiple of four or equal to TEXTURE_WIDTH. + * is not a multiple of four or equal to TEXTURE_HEIGHT. + * or 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 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 is an S3TC format. + CompressedTexImage2DARB will produce an INVALID_OPERATION error if + 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 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: + + * is not a multiple of four or equal to TEXTURE_WIDTH. + * is not a multiple of four or equal to TEXTURE_HEIGHT. + * or 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 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 + is COMPRESSED_RGB_S3TC_DXT1_EXT, + COMPRESSED_RGBA_S3TC_DXT1_EXT, COMPRESSED_RGBA_S3TC_DXT3_EXT, or + COMPRESSED_RGBA_S3TC_DXT5_EXT and is not equal to zero. + + INVALID_ENUM is generated by CompressedTexSubImage1DARB or + CompressedTexSubImage3DARB if 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: is not a multiple of four or equal to + TEXTURE_WIDTH; is not a multiple of four or equal to + TEXTURE_HEIGHT; or 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 , , or 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 , + DELETE: , or is greater than -b, + is + DELETE: less than w+b, + is less than h+b, or + DELETE: + 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 , height of , and block size of + (8 or 16 bytes) is decoded, the corresponding image size (in + bytes) is: + + ceil(/4) * ceil(/4) * blocksize. + + When decoding an S3TC image, the block containing the texel at offset + (, ) begins at an offset (in bytes) relative to the beginning of the + image of: + + blocksize * (ceil(/4) * floor(/4) + floor(/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 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 index 00000000000..c60109c4ea4 --- /dev/null +++ b/reactos/dll/3rdparty/dxtn/docs/vmath.txt @@ -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 index 00000000000..e6e5988c007 --- /dev/null +++ b/reactos/dll/3rdparty/dxtn/dxtn.c @@ -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 +#include + +#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 index 00000000000..a8ca33887d9 --- /dev/null +++ b/reactos/dll/3rdparty/dxtn/dxtn.def @@ -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 index 00000000000..4078fd9f924 --- /dev/null +++ b/reactos/dll/3rdparty/dxtn/dxtn.h @@ -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 index 00000000000..798829f4722 --- /dev/null +++ b/reactos/dll/3rdparty/dxtn/dxtn.rbuild @@ -0,0 +1,12 @@ + + + . + + + msvcrt + + fxt1.c + dxtn.c + wrapper.c + texstore.c + \ 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 index 00000000000..c528ee775fa --- /dev/null +++ b/reactos/dll/3rdparty/dxtn/fxt1.c @@ -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 +#include + +#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 index 00000000000..c2919bbac08 --- /dev/null +++ b/reactos/dll/3rdparty/dxtn/fxt1.h @@ -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 index 00000000000..e5aad300363 --- /dev/null +++ b/reactos/dll/3rdparty/dxtn/internal.h @@ -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 index 00000000000..3a6e6b53d2d --- /dev/null +++ b/reactos/dll/3rdparty/dxtn/test/Makefile @@ -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 index 00000000000..3a315ef637c --- /dev/null +++ b/reactos/dll/3rdparty/dxtn/test/main.c @@ -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 +#include +#include + +#include + +#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 index 00000000000..24ce9ab83d0 --- /dev/null +++ b/reactos/dll/3rdparty/dxtn/test/tga.c @@ -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 +#include +#include +#include + +#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 index 00000000000..93668407a3d --- /dev/null +++ b/reactos/dll/3rdparty/dxtn/test/tga.h @@ -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 index 00000000000..cf6f6dac405 --- /dev/null +++ b/reactos/dll/3rdparty/dxtn/test/util.c @@ -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 +#include +#include + +#include + +#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 index 00000000000..650db518c42 --- /dev/null +++ b/reactos/dll/3rdparty/dxtn/test/util.h @@ -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 + +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 index 00000000000..63496807457 --- /dev/null +++ b/reactos/dll/3rdparty/dxtn/texstore.c @@ -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 + +#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 index 00000000000..40e7153ab32 --- /dev/null +++ b/reactos/dll/3rdparty/dxtn/types.h @@ -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 index 00000000000..7bc8d610add --- /dev/null +++ b/reactos/dll/3rdparty/dxtn/wrapper.c @@ -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 + +#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;*/ +}