From b7770f88615d547f3ce081ff0a8b4b15e9663714 Mon Sep 17 00:00:00 2001 From: "imruon@gmail.com" Date: Sun, 10 Jan 2010 18:38:07 +0000 Subject: [PATCH] Splash Image changed, installer now working fine git-svn-id: svn://localhost/Users/andi/Downloads/code/trunk@23 eddbe33b-e435-4246-ac25-f5eb65f9a13c --- CustomizeMiiInstaller/LICENSE.txt | 339 ++ CustomizeMiiInstaller/Makefile | 139 + CustomizeMiiInstaller/README.Orig.es.txt | 43 + CustomizeMiiInstaller/README.Orig.txt | 44 + CustomizeMiiInstaller/README.txt | 3 + CustomizeMiiInstaller/data/background | Bin 0 -> 55434 bytes CustomizeMiiInstaller/installer.pnproj | 1 + CustomizeMiiInstaller/installer.pnps | 1 + CustomizeMiiInstaller/source/fat.c | 57 + CustomizeMiiInstaller/source/fat.h | 41 + CustomizeMiiInstaller/source/gui.c | 62 + CustomizeMiiInstaller/source/gui.h | 8 + CustomizeMiiInstaller/source/install.h | 14 + CustomizeMiiInstaller/source/libpng/png.h | 3569 +++++++++++++++++ CustomizeMiiInstaller/source/libpng/pngconf.h | 1481 +++++++ .../source/libpng/pngu/pngu.c | 1132 ++++++ .../source/libpng/pngu/pngu.h | 171 + CustomizeMiiInstaller/source/menu.c | 36 + CustomizeMiiInstaller/source/menu.h | 8 + CustomizeMiiInstaller/source/restart.c | 33 + CustomizeMiiInstaller/source/restart.h | 8 + CustomizeMiiInstaller/source/sha1.c | 172 + CustomizeMiiInstaller/source/sha1.h | 12 + CustomizeMiiInstaller/source/stub.S | 6 + CustomizeMiiInstaller/source/sys.c | 98 + CustomizeMiiInstaller/source/sys.h | 11 + CustomizeMiiInstaller/source/title.c | 256 ++ CustomizeMiiInstaller/source/title.h | 16 + CustomizeMiiInstaller/source/utils.h | 15 + CustomizeMiiInstaller/source/video.c | 141 + CustomizeMiiInstaller/source/video.h | 19 + CustomizeMiiInstaller/source/wad-manager.c | 72 + CustomizeMiiInstaller/source/wad.c | 374 ++ CustomizeMiiInstaller/source/wad.h | 7 + CustomizeMiiInstaller/source/wpad.c | 81 + CustomizeMiiInstaller/source/wpad.h | 12 + Helpers/Helpers.csproj | 2 +- Helpers/InstallerHelper.cs | 4 +- Helpers/Resources/CustomizeMiiInstaller.dol.z | Bin 0 -> 355239 bytes 39 files changed, 8485 insertions(+), 3 deletions(-) create mode 100644 CustomizeMiiInstaller/LICENSE.txt create mode 100644 CustomizeMiiInstaller/Makefile create mode 100644 CustomizeMiiInstaller/README.Orig.es.txt create mode 100644 CustomizeMiiInstaller/README.Orig.txt create mode 100644 CustomizeMiiInstaller/README.txt create mode 100644 CustomizeMiiInstaller/data/background create mode 100644 CustomizeMiiInstaller/installer.pnproj create mode 100644 CustomizeMiiInstaller/installer.pnps create mode 100644 CustomizeMiiInstaller/source/fat.c create mode 100644 CustomizeMiiInstaller/source/fat.h create mode 100644 CustomizeMiiInstaller/source/gui.c create mode 100644 CustomizeMiiInstaller/source/gui.h create mode 100644 CustomizeMiiInstaller/source/install.h create mode 100644 CustomizeMiiInstaller/source/libpng/png.h create mode 100644 CustomizeMiiInstaller/source/libpng/pngconf.h create mode 100644 CustomizeMiiInstaller/source/libpng/pngu/pngu.c create mode 100644 CustomizeMiiInstaller/source/libpng/pngu/pngu.h create mode 100644 CustomizeMiiInstaller/source/menu.c create mode 100644 CustomizeMiiInstaller/source/menu.h create mode 100644 CustomizeMiiInstaller/source/restart.c create mode 100644 CustomizeMiiInstaller/source/restart.h create mode 100644 CustomizeMiiInstaller/source/sha1.c create mode 100644 CustomizeMiiInstaller/source/sha1.h create mode 100644 CustomizeMiiInstaller/source/stub.S create mode 100644 CustomizeMiiInstaller/source/sys.c create mode 100644 CustomizeMiiInstaller/source/sys.h create mode 100644 CustomizeMiiInstaller/source/title.c create mode 100644 CustomizeMiiInstaller/source/title.h create mode 100644 CustomizeMiiInstaller/source/utils.h create mode 100644 CustomizeMiiInstaller/source/video.c create mode 100644 CustomizeMiiInstaller/source/video.h create mode 100644 CustomizeMiiInstaller/source/wad-manager.c create mode 100644 CustomizeMiiInstaller/source/wad.c create mode 100644 CustomizeMiiInstaller/source/wad.h create mode 100644 CustomizeMiiInstaller/source/wpad.c create mode 100644 CustomizeMiiInstaller/source/wpad.h create mode 100644 Helpers/Resources/CustomizeMiiInstaller.dol.z diff --git a/CustomizeMiiInstaller/LICENSE.txt b/CustomizeMiiInstaller/LICENSE.txt new file mode 100644 index 0000000..7e14f38 --- /dev/null +++ b/CustomizeMiiInstaller/LICENSE.txt @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. 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 General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section 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 or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) 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 1 and 2 above on a medium + customarily used for software interchange; or, + + c) 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 b above.) + +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, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, 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. + +If distribution of executable 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. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program 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. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), 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. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. 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. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program 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. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "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 IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM 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 (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 TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program 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 of the License, or + (at your option) any later version. + + This program 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 this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. \ No newline at end of file diff --git a/CustomizeMiiInstaller/Makefile b/CustomizeMiiInstaller/Makefile new file mode 100644 index 0000000..80096b1 --- /dev/null +++ b/CustomizeMiiInstaller/Makefile @@ -0,0 +1,139 @@ +#--------------------------------------------------------------------------------- +# Clear the implicit built in rules +#--------------------------------------------------------------------------------- +.SUFFIXES: +#--------------------------------------------------------------------------------- +#DEVKITPRO = /opt/devkitPPC +#DEVKITPPC = /opt/devkitPPC + +ifeq ($(strip $(DEVKITPPC)),) +$(error "Please set DEVKITPPC in your environment. export DEVKITPPC=devkitPPC") +endif + +include $(DEVKITPPC)/wii_rules + +#--------------------------------------------------------------------------------- +# TARGET is the name of the output +# BUILD is the directory where object files & intermediate files will be placed +# SOURCES is a list of directories containing source code +# INCLUDES is a list of directories containing extra header files +#--------------------------------------------------------------------------------- +TARGET := $(notdir $(CURDIR)) +BUILD := build +SOURCES := source source/libpng source/libpng/pngu +DATA := data +INCLUDES := + +#--------------------------------------------------------------------------------- +# options for code generation +#--------------------------------------------------------------------------------- + +CFLAGS = -Os -Wall $(MACHDEP) $(INCLUDE) +CXXFLAGS = $(CFLAGS) + +LDFLAGS = $(MACHDEP) -Wl,-Map,$(notdir $@).map + +#--------------------------------------------------------------------------------- +# any extra libraries we wish to link with the project +#--------------------------------------------------------------------------------- +LIBS := -lpng -lfat -lwiiuse -lbte -logc -lm -lz + +#--------------------------------------------------------------------------------- +# list of directories containing libraries, this must be the top level containing +# include and lib +#--------------------------------------------------------------------------------- +LIBDIRS := $(CURDIR) + +#--------------------------------------------------------------------------------- +# no real need to edit anything past this point unless you need to add additional +# rules for different file extensions +#--------------------------------------------------------------------------------- +ifneq ($(BUILD),$(notdir $(CURDIR))) +#--------------------------------------------------------------------------------- + +export OUTPUT := $(CURDIR)/$(TARGET) + +export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \ + $(foreach dir,$(DATA),$(CURDIR)/$(dir)) + +export DEPSDIR := $(CURDIR)/$(BUILD) + +#--------------------------------------------------------------------------------- +# automatically build a list of object files for our project +#--------------------------------------------------------------------------------- +CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c))) +CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp))) +sFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s))) +SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.S))) +BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*))) + +#--------------------------------------------------------------------------------- +# use CXX for linking C++ projects, CC for standard C +#--------------------------------------------------------------------------------- +ifeq ($(strip $(CPPFILES)),) + export LD := $(CC) +else + export LD := $(CXX) +endif + +export OFILES := $(addsuffix .o,$(BINFILES)) \ + $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) \ + $(sFILES:.s=.o) $(SFILES:.S=.o) + +#--------------------------------------------------------------------------------- +# build a list of include paths +#--------------------------------------------------------------------------------- +export INCLUDE := $(foreach dir,$(INCLUDES), -iquote $(CURDIR)/$(dir)) \ + $(foreach dir,$(LIBDIRS),-I$(dir)/include) \ + -I$(CURDIR)/$(BUILD) \ + -I$(LIBOGC_INC) + +#--------------------------------------------------------------------------------- +# build a list of library paths +#--------------------------------------------------------------------------------- +export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib) \ + -L$(LIBOGC_LIB) + +export OUTPUT := $(CURDIR)/$(TARGET) +.PHONY: $(BUILD) clean + +#--------------------------------------------------------------------------------- +$(BUILD): + @[ -d $@ ] || mkdir -p $@ + @make --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile + +#--------------------------------------------------------------------------------- +clean: + @echo clean ... + @rm -fr $(BUILD) $(OUTPUT).elf $(OUTPUT).dol + +#--------------------------------------------------------------------------------- +run: + wiiload $(TARGET).dol + + +#--------------------------------------------------------------------------------- +else + +DEPENDS := $(OFILES:.o=.d) + +#--------------------------------------------------------------------------------- +# main targets +#--------------------------------------------------------------------------------- +$(OUTPUT).dol: $(OUTPUT).elf +$(OUTPUT).elf: $(OFILES) + +#--------------------------------------------------------------------------------- +# This rule links in binary data with the .jpg extension +#--------------------------------------------------------------------------------- +%.jpg.o : %.jpg +#--------------------------------------------------------------------------------- + @echo $(notdir $<) + $(bin2o) + +-include $(DEPENDS) + +#--------------------------------------------------------------------------------- +endif +#--------------------------------------------------------------------------------- + diff --git a/CustomizeMiiInstaller/README.Orig.es.txt b/CustomizeMiiInstaller/README.Orig.es.txt new file mode 100644 index 0000000..d2d0dfe --- /dev/null +++ b/CustomizeMiiInstaller/README.Orig.es.txt @@ -0,0 +1,43 @@ ++----------------------------+ +| WAD Manager v1.4 | +| developed by Waninkoko | ++----------------------------+ +| www.teknoconsolas.es | ++----------------------------+ + + +[ DISCLAIMER ]: + +- ESTA APLICACION VIENE SIN NINGUNA GARANTIA, EXPLICITA NI IMPLICITA. + NO ME HAGO RESPONSABLE POR CUALQUIER DAŅO EN TU CONSOLA WII DEBIDO A + UN USO NO APROPIADO DE ESTE SOFTWARE. + + +[ DESCRIPCION ]: + +- WAD Manager es una aplicacion que te permite (des)instalar paquetes WAD. + + La aplicacion muestra todos los paquetes WAD disponibles en un + dispositivo de almacenamiento para poder elegir cual (des)instalar. + + +[ DISPOSITIVOS SOPORTADOS ]: + +- SDGecko. +- Puerto SD interno (con soporte SDHC). +- Dispositivo USB (1.1 y 2.0). + + +[ COMO USARLO ]: + +1. Crea un directorio llamado "wad" en la raiz del dispositivo de almacenamiento. +2. Copia todos los paquetes WAD en el directorio creado en el paso 1. +3. Ejecuta la aplicacion con cualquier metodo para cargar homebrew. + + +[ KUDOS ]: + +- Team Twiizers/devkitPRO +- svpe +- kwiirk +- Todos mis betatesters. diff --git a/CustomizeMiiInstaller/README.Orig.txt b/CustomizeMiiInstaller/README.Orig.txt new file mode 100644 index 0000000..a01993a --- /dev/null +++ b/CustomizeMiiInstaller/README.Orig.txt @@ -0,0 +1,44 @@ ++----------------------------+ +| WAD Manager v1.4 | +| developed by Waninkoko | ++----------------------------+ +| www.teknoconsolas.es | ++----------------------------+ + + +[ DISCLAIMER ]: + +- THIS APPLICATION COMES WITH NO WARRANTY AT ALL, NEITHER EXPRESS NOR IMPLIED. + I DO NOT TAKE ANY RESPONSIBILITY FOR ANY DAMAGE IN YOUR WII CONSOLE + BECAUSE OF A IMPROPER USAGE OF THIS SOFTWARE. + + +[ DESCRIPTION ]: + +- WAD Manager is an application that allows you to (un)install + WAD packages. + + It lists all the available WAD packages in a storage device + so you can select which one to (un)install. + + +[ SUPPORTED DEVICES ]: + +- SDGecko. +- Internal SD slot (with SDHC support). +- USB device (1.1 and 2.0). + + +[ HOW TO USE ]: + +1. Create a folder called "wad" in the root of the storage device. +2. Copy all the WAD packages in the folder created in the step 1. +3. Run the application with any method to load homebrew. + + +[ KUDOS ]: + +- Team Twiizers/devkitPRO +- svpe +- kwiirk +- All my betatesters. diff --git a/CustomizeMiiInstaller/README.txt b/CustomizeMiiInstaller/README.txt new file mode 100644 index 0000000..5a61b69 --- /dev/null +++ b/CustomizeMiiInstaller/README.txt @@ -0,0 +1,3 @@ +Modified wad manager used to install wads. Make sure you have exactly 4MB +padding file all containing zeroes as install.c. This file is not included +in the source release since it's quite large. \ No newline at end of file diff --git a/CustomizeMiiInstaller/data/background b/CustomizeMiiInstaller/data/background new file mode 100644 index 0000000000000000000000000000000000000000..9128584ea952d00d39fee42490c1c0eeb7613eea GIT binary patch literal 55434 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 w=uv=~>}-DDYs_fm2ui2LE$SX8-^I literal 0 HcmV?d00001 diff --git a/CustomizeMiiInstaller/installer.pnproj b/CustomizeMiiInstaller/installer.pnproj new file mode 100644 index 0000000..66a6acb --- /dev/null +++ b/CustomizeMiiInstaller/installer.pnproj @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/CustomizeMiiInstaller/installer.pnps b/CustomizeMiiInstaller/installer.pnps new file mode 100644 index 0000000..c90d2ed --- /dev/null +++ b/CustomizeMiiInstaller/installer.pnps @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/CustomizeMiiInstaller/source/fat.c b/CustomizeMiiInstaller/source/fat.c new file mode 100644 index 0000000..dfafa13 --- /dev/null +++ b/CustomizeMiiInstaller/source/fat.c @@ -0,0 +1,57 @@ +#include +#include +#include + +#include "fat.h" + + +s32 Fat_Mount(fatDevice *dev) +{ + s32 ret; + + /* Initialize interface */ + ret = dev->interface->startup(); + if (!ret) + return -1; + + /* Mount device */ + ret = fatMountSimple(dev->mount, dev->interface); + if (!ret) + return -1; + + return 0; +} + +void Fat_Unmount(fatDevice *dev) +{ + /* Unmount device */ + fatUnmount(dev->mount); + + /* Shutdown interface */ + dev->interface->shutdown(); +} + +char *Fat_ToFilename(const char *filename) +{ + static char buffer[128]; + + u32 cnt, idx, len; + + /* Clear buffer */ + memset(buffer, 0, sizeof(buffer)); + + /* Get filename length */ + len = strlen(filename); + + for (cnt = idx = 0; idx < len; idx++) { + char c = filename[idx]; + + /* Valid characters */ + if ( (c >= '#' && c <= ')') || (c >= '-' && c <= '.') || + (c >= '0' && c <= '9') || (c >= 'A' && c <= 'z') || + (c >= 'a' && c <= 'z') || (c == '!') ) + buffer[cnt++] = c; + } + + return buffer; +} diff --git a/CustomizeMiiInstaller/source/fat.h b/CustomizeMiiInstaller/source/fat.h new file mode 100644 index 0000000..1e5675e --- /dev/null +++ b/CustomizeMiiInstaller/source/fat.h @@ -0,0 +1,41 @@ +#ifndef _FAT_H_ +#define _FAT_H_ + +/* libfat header */ +#include +#include + +/* SD headers */ +#include +#include + + +/* 'FAT Device' structure */ +typedef struct { + /* Device mount point */ + char *mount; + + /* Device name */ + char *name; + + /* Device interface */ + const DISC_INTERFACE *interface; +} fatDevice; + +/* 'FAT File' structure */ +typedef struct { + /* Filename */ + char filename[128]; + + /* Filestat */ + struct stat filestat; +} fatFile; + + +/* Prototypes */ +s32 Fat_Mount(fatDevice *); +void Fat_Unmount(fatDevice *); +char *Fat_ToFilename(const char *); + +#endif + diff --git a/CustomizeMiiInstaller/source/gui.c b/CustomizeMiiInstaller/source/gui.c new file mode 100644 index 0000000..f2e0631 --- /dev/null +++ b/CustomizeMiiInstaller/source/gui.c @@ -0,0 +1,62 @@ +#include +#include +#include + +#include "video.h" + +/* Constants */ +#define CONSOLE_XCOORD 96 +#define CONSOLE_YCOORD 118 +#define CONSOLE_WIDTH 496 +#define CONSOLE_HEIGHT 236 + + +s32 __Gui_DrawPng(void *img, u32 x, u32 y) +{ + IMGCTX ctx = NULL; + PNGUPROP imgProp; + + s32 ret; + + /* Select PNG data */ + ctx = PNGU_SelectImageFromBuffer(img); + if (!ctx) { + ret = -1; + goto out; + } + + /* Get image properties */ + ret = PNGU_GetImageProperties(ctx, &imgProp); + if (ret != PNGU_OK) { + ret = -1; + goto out; + } + + /* Draw image */ + Video_DrawPng(ctx, imgProp, x, y); + + /* Success */ + ret = 0; + +out: + /* Free memory */ + if (ctx) + PNGU_ReleaseImageContext(ctx); + + return ret; +} + + +void Gui_InitConsole(void) +{ + /* Initialize console */ + Con_Init(CONSOLE_XCOORD, CONSOLE_YCOORD, CONSOLE_WIDTH, CONSOLE_HEIGHT); +} + +void Gui_DrawBackground(void) +{ + extern char bgData[]; + + /* Draw background */ + __Gui_DrawPng(bgData, 0, 0); +} diff --git a/CustomizeMiiInstaller/source/gui.h b/CustomizeMiiInstaller/source/gui.h new file mode 100644 index 0000000..80f174c --- /dev/null +++ b/CustomizeMiiInstaller/source/gui.h @@ -0,0 +1,8 @@ +#ifndef _GUI_H_ +#define _GUI_H_ + +/* Prototypes */ +void Gui_InitConsole(void); +void Gui_DrawBackground(void); + +#endif diff --git a/CustomizeMiiInstaller/source/install.h b/CustomizeMiiInstaller/source/install.h new file mode 100644 index 0000000..3c1be35 --- /dev/null +++ b/CustomizeMiiInstaller/source/install.h @@ -0,0 +1,14 @@ +/* + This file was autogenerated by raw2c. +Visit http://www.devkitpro.org +*/ + +//--------------------------------------------------------------------------------- +#ifndef _install_h_ +#define _install_h_ +//--------------------------------------------------------------------------------- +extern const unsigned char install[]; +extern const int install_size; +//--------------------------------------------------------------------------------- +#endif //_install_h_ +//--------------------------------------------------------------------------------- diff --git a/CustomizeMiiInstaller/source/libpng/png.h b/CustomizeMiiInstaller/source/libpng/png.h new file mode 100644 index 0000000..e0cec0c --- /dev/null +++ b/CustomizeMiiInstaller/source/libpng/png.h @@ -0,0 +1,3569 @@ +/* png.h - header file for PNG reference library + * + * libpng version 1.2.29 - May 8, 2008 + * Copyright (c) 1998-2008 Glenn Randers-Pehrson + * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) + * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) + * + * Authors and maintainers: + * libpng versions 0.71, May 1995, through 0.88, January 1996: Guy Schalnat + * libpng versions 0.89c, June 1996, through 0.96, May 1997: Andreas Dilger + * libpng versions 0.97, January 1998, through 1.2.29 - May 8, 2008: Glenn + * See also "Contributing Authors", below. + * + * Note about libpng version numbers: + * + * Due to various miscommunications, unforeseen code incompatibilities + * and occasional factors outside the authors' control, version numbering + * on the library has not always been consistent and straightforward. + * The following table summarizes matters since version 0.89c, which was + * the first widely used release: + * + * source png.h png.h shared-lib + * version string int version + * ------- ------ ----- ---------- + * 0.89c "1.0 beta 3" 0.89 89 1.0.89 + * 0.90 "1.0 beta 4" 0.90 90 0.90 [should have been 2.0.90] + * 0.95 "1.0 beta 5" 0.95 95 0.95 [should have been 2.0.95] + * 0.96 "1.0 beta 6" 0.96 96 0.96 [should have been 2.0.96] + * 0.97b "1.00.97 beta 7" 1.00.97 97 1.0.1 [should have been 2.0.97] + * 0.97c 0.97 97 2.0.97 + * 0.98 0.98 98 2.0.98 + * 0.99 0.99 98 2.0.99 + * 0.99a-m 0.99 99 2.0.99 + * 1.00 1.00 100 2.1.0 [100 should be 10000] + * 1.0.0 (from here on, the 100 2.1.0 [100 should be 10000] + * 1.0.1 png.h string is 10001 2.1.0 + * 1.0.1a-e identical to the 10002 from here on, the shared library + * 1.0.2 source version) 10002 is 2.V where V is the source code + * 1.0.2a-b 10003 version, except as noted. + * 1.0.3 10003 + * 1.0.3a-d 10004 + * 1.0.4 10004 + * 1.0.4a-f 10005 + * 1.0.5 (+ 2 patches) 10005 + * 1.0.5a-d 10006 + * 1.0.5e-r 10100 (not source compatible) + * 1.0.5s-v 10006 (not binary compatible) + * 1.0.6 (+ 3 patches) 10006 (still binary incompatible) + * 1.0.6d-f 10007 (still binary incompatible) + * 1.0.6g 10007 + * 1.0.6h 10007 10.6h (testing xy.z so-numbering) + * 1.0.6i 10007 10.6i + * 1.0.6j 10007 2.1.0.6j (incompatible with 1.0.0) + * 1.0.7beta11-14 DLLNUM 10007 2.1.0.7beta11-14 (binary compatible) + * 1.0.7beta15-18 1 10007 2.1.0.7beta15-18 (binary compatible) + * 1.0.7rc1-2 1 10007 2.1.0.7rc1-2 (binary compatible) + * 1.0.7 1 10007 (still compatible) + * 1.0.8beta1-4 1 10008 2.1.0.8beta1-4 + * 1.0.8rc1 1 10008 2.1.0.8rc1 + * 1.0.8 1 10008 2.1.0.8 + * 1.0.9beta1-6 1 10009 2.1.0.9beta1-6 + * 1.0.9rc1 1 10009 2.1.0.9rc1 + * 1.0.9beta7-10 1 10009 2.1.0.9beta7-10 + * 1.0.9rc2 1 10009 2.1.0.9rc2 + * 1.0.9 1 10009 2.1.0.9 + * 1.0.10beta1 1 10010 2.1.0.10beta1 + * 1.0.10rc1 1 10010 2.1.0.10rc1 + * 1.0.10 1 10010 2.1.0.10 + * 1.0.11beta1-3 1 10011 2.1.0.11beta1-3 + * 1.0.11rc1 1 10011 2.1.0.11rc1 + * 1.0.11 1 10011 2.1.0.11 + * 1.0.12beta1-2 2 10012 2.1.0.12beta1-2 + * 1.0.12rc1 2 10012 2.1.0.12rc1 + * 1.0.12 2 10012 2.1.0.12 + * 1.1.0a-f - 10100 2.1.1.0a-f (branch abandoned) + * 1.2.0beta1-2 2 10200 2.1.2.0beta1-2 + * 1.2.0beta3-5 3 10200 3.1.2.0beta3-5 + * 1.2.0rc1 3 10200 3.1.2.0rc1 + * 1.2.0 3 10200 3.1.2.0 + * 1.2.1beta1-4 3 10201 3.1.2.1beta1-4 + * 1.2.1rc1-2 3 10201 3.1.2.1rc1-2 + * 1.2.1 3 10201 3.1.2.1 + * 1.2.2beta1-6 12 10202 12.so.0.1.2.2beta1-6 + * 1.0.13beta1 10 10013 10.so.0.1.0.13beta1 + * 1.0.13rc1 10 10013 10.so.0.1.0.13rc1 + * 1.2.2rc1 12 10202 12.so.0.1.2.2rc1 + * 1.0.13 10 10013 10.so.0.1.0.13 + * 1.2.2 12 10202 12.so.0.1.2.2 + * 1.2.3rc1-6 12 10203 12.so.0.1.2.3rc1-6 + * 1.2.3 12 10203 12.so.0.1.2.3 + * 1.2.4beta1-3 13 10204 12.so.0.1.2.4beta1-3 + * 1.0.14rc1 13 10014 10.so.0.1.0.14rc1 + * 1.2.4rc1 13 10204 12.so.0.1.2.4rc1 + * 1.0.14 10 10014 10.so.0.1.0.14 + * 1.2.4 13 10204 12.so.0.1.2.4 + * 1.2.5beta1-2 13 10205 12.so.0.1.2.5beta1-2 + * 1.0.15rc1-3 10 10015 10.so.0.1.0.15rc1-3 + * 1.2.5rc1-3 13 10205 12.so.0.1.2.5rc1-3 + * 1.0.15 10 10015 10.so.0.1.0.15 + * 1.2.5 13 10205 12.so.0.1.2.5 + * 1.2.6beta1-4 13 10206 12.so.0.1.2.6beta1-4 + * 1.0.16 10 10016 10.so.0.1.0.16 + * 1.2.6 13 10206 12.so.0.1.2.6 + * 1.2.7beta1-2 13 10207 12.so.0.1.2.7beta1-2 + * 1.0.17rc1 10 10017 10.so.0.1.0.17rc1 + * 1.2.7rc1 13 10207 12.so.0.1.2.7rc1 + * 1.0.17 10 10017 10.so.0.1.0.17 + * 1.2.7 13 10207 12.so.0.1.2.7 + * 1.2.8beta1-5 13 10208 12.so.0.1.2.8beta1-5 + * 1.0.18rc1-5 10 10018 10.so.0.1.0.18rc1-5 + * 1.2.8rc1-5 13 10208 12.so.0.1.2.8rc1-5 + * 1.0.18 10 10018 10.so.0.1.0.18 + * 1.2.8 13 10208 12.so.0.1.2.8 + * 1.2.9beta1-3 13 10209 12.so.0.1.2.9beta1-3 + * 1.2.9beta4-11 13 10209 12.so.0.9[.0] + * 1.2.9rc1 13 10209 12.so.0.9[.0] + * 1.2.9 13 10209 12.so.0.9[.0] + * 1.2.10beta1-8 13 10210 12.so.0.10[.0] + * 1.2.10rc1-3 13 10210 12.so.0.10[.0] + * 1.2.10 13 10210 12.so.0.10[.0] + * 1.2.11beta1-4 13 10211 12.so.0.11[.0] + * 1.0.19rc1-5 10 10019 10.so.0.19[.0] + * 1.2.11rc1-5 13 10211 12.so.0.11[.0] + * 1.0.19 10 10019 10.so.0.19[.0] + * 1.2.11 13 10211 12.so.0.11[.0] + * 1.0.20 10 10020 10.so.0.20[.0] + * 1.2.12 13 10212 12.so.0.12[.0] + * 1.2.13beta1 13 10213 12.so.0.13[.0] + * 1.0.21 10 10021 10.so.0.21[.0] + * 1.2.13 13 10213 12.so.0.13[.0] + * 1.2.14beta1-2 13 10214 12.so.0.14[.0] + * 1.0.22rc1 10 10022 10.so.0.22[.0] + * 1.2.14rc1 13 10214 12.so.0.14[.0] + * 1.0.22 10 10022 10.so.0.22[.0] + * 1.2.14 13 10214 12.so.0.14[.0] + * 1.2.15beta1-6 13 10215 12.so.0.15[.0] + * 1.0.23rc1-5 10 10023 10.so.0.23[.0] + * 1.2.15rc1-5 13 10215 12.so.0.15[.0] + * 1.0.23 10 10023 10.so.0.23[.0] + * 1.2.15 13 10215 12.so.0.15[.0] + * 1.2.16beta1-2 13 10216 12.so.0.16[.0] + * 1.2.16rc1 13 10216 12.so.0.16[.0] + * 1.0.24 10 10024 10.so.0.24[.0] + * 1.2.16 13 10216 12.so.0.16[.0] + * 1.2.17beta1-2 13 10217 12.so.0.17[.0] + * 1.0.25rc1 10 10025 10.so.0.25[.0] + * 1.2.17rc1-3 13 10217 12.so.0.17[.0] + * 1.0.25 10 10025 10.so.0.25[.0] + * 1.2.17 13 10217 12.so.0.17[.0] + * 1.0.26 10 10026 10.so.0.26[.0] + * 1.2.18 13 10218 12.so.0.18[.0] + * 1.2.19beta1-31 13 10219 12.so.0.19[.0] + * 1.0.27rc1-6 10 10027 10.so.0.27[.0] + * 1.2.19rc1-6 13 10219 12.so.0.19[.0] + * 1.0.27 10 10027 10.so.0.27[.0] + * 1.2.19 13 10219 12.so.0.19[.0] + * 1.2.20beta01-04 13 10220 12.so.0.20[.0] + * 1.0.28rc1-6 10 10028 10.so.0.28[.0] + * 1.2.20rc1-6 13 10220 12.so.0.20[.0] + * 1.0.28 10 10028 10.so.0.28[.0] + * 1.2.20 13 10220 12.so.0.20[.0] + * 1.2.21beta1-2 13 10221 12.so.0.21[.0] + * 1.2.21rc1-3 13 10221 12.so.0.21[.0] + * 1.0.29 10 10029 10.so.0.29[.0] + * 1.2.21 13 10221 12.so.0.21[.0] + * 1.2.22beta1-4 13 10222 12.so.0.22[.0] + * 1.0.30rc1 10 10030 10.so.0.30[.0] + * 1.2.22rc1 13 10222 12.so.0.22[.0] + * 1.0.30 10 10030 10.so.0.30[.0] + * 1.2.22 13 10222 12.so.0.22[.0] + * 1.2.23beta01-05 13 10223 12.so.0.23[.0] + * 1.2.23rc01 13 10223 12.so.0.23[.0] + * 1.2.23 13 10223 12.so.0.23[.0] + * 1.2.24beta01-02 13 10224 12.so.0.24[.0] + * 1.2.24rc01 13 10224 12.so.0.24[.0] + * 1.2.24 13 10224 12.so.0.24[.0] + * 1.2.25beta01-06 13 10225 12.so.0.25[.0] + * 1.2.25rc01-02 13 10225 12.so.0.25[.0] + * 1.0.31 10 10031 10.so.0.31[.0] + * 1.2.25 13 10225 12.so.0.25[.0] + * 1.2.26beta01-06 13 10226 12.so.0.26[.0] + * 1.2.26rc01 13 10226 12.so.0.26[.0] + * 1.2.26 13 10226 12.so.0.26[.0] + * 1.0.32 10 10032 10.so.0.32[.0] + * 1.2.27beta01-06 13 10227 12.so.0.27[.0] + * 1.2.27rc01 13 10227 12.so.0.27[.0] + * 1.0.33 10 10033 10.so.0.33[.0] + * 1.2.27 13 10227 12.so.0.27[.0] + * 1.0.34 10 10034 10.so.0.34[.0] + * 1.2.28 13 10228 12.so.0.28[.0] + * 1.2.29beta01-03 13 10229 12.so.0.29[.0] + * 1.2.29rc01 13 10229 12.so.0.29[.0] + * 1.0.35 10 10035 10.so.0.35[.0] + * 1.2.29 13 10229 12.so.0.29[.0] + * + * Henceforth the source version will match the shared-library major + * and minor numbers; the shared-library major version number will be + * used for changes in backward compatibility, as it is intended. The + * PNG_LIBPNG_VER macro, which is not used within libpng but is available + * for applications, is an unsigned integer of the form xyyzz corresponding + * to the source version x.y.z (leading zeros in y and z). Beta versions + * were given the previous public release number plus a letter, until + * version 1.0.6j; from then on they were given the upcoming public + * release number plus "betaNN" or "rcNN". + * + * Binary incompatibility exists only when applications make direct access + * to the info_ptr or png_ptr members through png.h, and the compiled + * application is loaded with a different version of the library. + * + * DLLNUM will change each time there are forward or backward changes + * in binary compatibility (e.g., when a new feature is added). + * + * See libpng.txt or libpng.3 for more information. The PNG specification + * is available as a W3C Recommendation and as an ISO Specification, + * defines should NOT be changed. + */ +#define PNG_INFO_gAMA 0x0001 +#define PNG_INFO_sBIT 0x0002 +#define PNG_INFO_cHRM 0x0004 +#define PNG_INFO_PLTE 0x0008 +#define PNG_INFO_tRNS 0x0010 +#define PNG_INFO_bKGD 0x0020 +#define PNG_INFO_hIST 0x0040 +#define PNG_INFO_pHYs 0x0080 +#define PNG_INFO_oFFs 0x0100 +#define PNG_INFO_tIME 0x0200 +#define PNG_INFO_pCAL 0x0400 +#define PNG_INFO_sRGB 0x0800 /* GR-P, 0.96a */ +#define PNG_INFO_iCCP 0x1000 /* ESR, 1.0.6 */ +#define PNG_INFO_sPLT 0x2000 /* ESR, 1.0.6 */ +#define PNG_INFO_sCAL 0x4000 /* ESR, 1.0.6 */ +#define PNG_INFO_IDAT 0x8000L /* ESR, 1.0.6 */ + +/* This is used for the transformation routines, as some of them + * change these values for the row. It also should enable using + * the routines for other purposes. + */ +typedef struct png_row_info_struct +{ + png_uint_32 width; /* width of row */ + png_uint_32 rowbytes; /* number of bytes in row */ + png_byte color_type; /* color type of row */ + png_byte bit_depth; /* bit depth of row */ + png_byte channels; /* number of channels (1, 2, 3, or 4) */ + png_byte pixel_depth; /* bits per pixel (depth * channels) */ +} png_row_info; + +typedef png_row_info FAR * png_row_infop; +typedef png_row_info FAR * FAR * png_row_infopp; + +/* These are the function types for the I/O functions and for the functions + * that allow the user to override the default I/O functions with his or her + * own. The png_error_ptr type should match that of user-supplied warning + * and error functions, while the png_rw_ptr type should match that of the + * user read/write data functions. + */ +typedef struct png_struct_def png_struct; +typedef png_struct FAR * png_structp; + +typedef void (PNGAPI *png_error_ptr) PNGARG((png_structp, png_const_charp)); +typedef void (PNGAPI *png_rw_ptr) PNGARG((png_structp, png_bytep, png_size_t)); +typedef void (PNGAPI *png_flush_ptr) PNGARG((png_structp)); +typedef void (PNGAPI *png_read_status_ptr) PNGARG((png_structp, png_uint_32, + int)); +typedef void (PNGAPI *png_write_status_ptr) PNGARG((png_structp, png_uint_32, + int)); + +#ifdef PNG_PROGRESSIVE_READ_SUPPORTED +typedef void (PNGAPI *png_progressive_info_ptr) PNGARG((png_structp, png_infop)); +typedef void (PNGAPI *png_progressive_end_ptr) PNGARG((png_structp, png_infop)); +typedef void (PNGAPI *png_progressive_row_ptr) PNGARG((png_structp, png_bytep, + png_uint_32, int)); +#endif + +#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \ + defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) || \ + defined(PNG_LEGACY_SUPPORTED) +typedef void (PNGAPI *png_user_transform_ptr) PNGARG((png_structp, + png_row_infop, png_bytep)); +#endif + +#if defined(PNG_USER_CHUNKS_SUPPORTED) +typedef int (PNGAPI *png_user_chunk_ptr) PNGARG((png_structp, png_unknown_chunkp)); +#endif +#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED) +typedef void (PNGAPI *png_unknown_chunk_ptr) PNGARG((png_structp)); +#endif + +/* Transform masks for the high-level interface */ +#define PNG_TRANSFORM_IDENTITY 0x0000 /* read and write */ +#define PNG_TRANSFORM_STRIP_16 0x0001 /* read only */ +#define PNG_TRANSFORM_STRIP_ALPHA 0x0002 /* read only */ +#define PNG_TRANSFORM_PACKING 0x0004 /* read and write */ +#define PNG_TRANSFORM_PACKSWAP 0x0008 /* read and write */ +#define PNG_TRANSFORM_EXPAND 0x0010 /* read only */ +#define PNG_TRANSFORM_INVERT_MONO 0x0020 /* read and write */ +#define PNG_TRANSFORM_SHIFT 0x0040 /* read and write */ +#define PNG_TRANSFORM_BGR 0x0080 /* read and write */ +#define PNG_TRANSFORM_SWAP_ALPHA 0x0100 /* read and write */ +#define PNG_TRANSFORM_SWAP_ENDIAN 0x0200 /* read and write */ +#define PNG_TRANSFORM_INVERT_ALPHA 0x0400 /* read and write */ +#define PNG_TRANSFORM_STRIP_FILLER 0x0800 /* WRITE only */ + +/* Flags for MNG supported features */ +#define PNG_FLAG_MNG_EMPTY_PLTE 0x01 +#define PNG_FLAG_MNG_FILTER_64 0x04 +#define PNG_ALL_MNG_FEATURES 0x05 + +typedef png_voidp (*png_malloc_ptr) PNGARG((png_structp, png_size_t)); +typedef void (*png_free_ptr) PNGARG((png_structp, png_voidp)); + +/* The structure that holds the information to read and write PNG files. + * The only people who need to care about what is inside of this are the + * people who will be modifying the library for their own special needs. + * It should NOT be accessed directly by an application, except to store + * the jmp_buf. + */ + +struct png_struct_def +{ +#ifdef PNG_SETJMP_SUPPORTED + jmp_buf jmpbuf; /* used in png_error */ +#endif + png_error_ptr error_fn; /* function for printing errors and aborting */ + png_error_ptr warning_fn; /* function for printing warnings */ + png_voidp error_ptr; /* user supplied struct for error functions */ + png_rw_ptr write_data_fn; /* function for writing output data */ + png_rw_ptr read_data_fn; /* function for reading input data */ + png_voidp io_ptr; /* ptr to application struct for I/O functions */ + +#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) + png_user_transform_ptr read_user_transform_fn; /* user read transform */ +#endif + +#if defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) + png_user_transform_ptr write_user_transform_fn; /* user write transform */ +#endif + +/* These were added in libpng-1.0.2 */ +#if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED) +#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \ + defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) + png_voidp user_transform_ptr; /* user supplied struct for user transform */ + png_byte user_transform_depth; /* bit depth of user transformed pixels */ + png_byte user_transform_channels; /* channels in user transformed pixels */ +#endif +#endif + + png_uint_32 mode; /* tells us where we are in the PNG file */ + png_uint_32 flags; /* flags indicating various things to libpng */ + png_uint_32 transformations; /* which transformations to perform */ + + z_stream zstream; /* pointer to decompression structure (below) */ + png_bytep zbuf; /* buffer for zlib */ + png_size_t zbuf_size; /* size of zbuf */ + int zlib_level; /* holds zlib compression level */ + int zlib_method; /* holds zlib compression method */ + int zlib_window_bits; /* holds zlib compression window bits */ + int zlib_mem_level; /* holds zlib compression memory level */ + int zlib_strategy; /* holds zlib compression strategy */ + + png_uint_32 width; /* width of image in pixels */ + png_uint_32 height; /* height of image in pixels */ + png_uint_32 num_rows; /* number of rows in current pass */ + png_uint_32 usr_width; /* width of row at start of write */ + png_uint_32 rowbytes; /* size of row in bytes */ + png_uint_32 irowbytes; /* size of current interlaced row in bytes */ + png_uint_32 iwidth; /* width of current interlaced row in pixels */ + png_uint_32 row_number; /* current row in interlace pass */ + png_bytep prev_row; /* buffer to save previous (unfiltered) row */ + png_bytep row_buf; /* buffer to save current (unfiltered) row */ +#ifndef PNG_NO_WRITE_FILTERING + png_bytep sub_row; /* buffer to save "sub" row when filtering */ + png_bytep up_row; /* buffer to save "up" row when filtering */ + png_bytep avg_row; /* buffer to save "avg" row when filtering */ + png_bytep paeth_row; /* buffer to save "Paeth" row when filtering */ +#endif + png_row_info row_info; /* used for transformation routines */ + + png_uint_32 idat_size; /* current IDAT size for read */ + png_uint_32 crc; /* current chunk CRC value */ + png_colorp palette; /* palette from the input file */ + png_uint_16 num_palette; /* number of color entries in palette */ + png_uint_16 num_trans; /* number of transparency values */ + png_byte chunk_name[5]; /* null-terminated name of current chunk */ + png_byte compression; /* file compression type (always 0) */ + png_byte filter; /* file filter type (always 0) */ + png_byte interlaced; /* PNG_INTERLACE_NONE, PNG_INTERLACE_ADAM7 */ + png_byte pass; /* current interlace pass (0 - 6) */ + png_byte do_filter; /* row filter flags (see PNG_FILTER_ below ) */ + png_byte color_type; /* color type of file */ + png_byte bit_depth; /* bit depth of file */ + png_byte usr_bit_depth; /* bit depth of users row */ + png_byte pixel_depth; /* number of bits per pixel */ + png_byte channels; /* number of channels in file */ + png_byte usr_channels; /* channels at start of write */ + png_byte sig_bytes; /* magic bytes read/written from start of file */ + +#if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED) +#ifdef PNG_LEGACY_SUPPORTED + png_byte filler; /* filler byte for pixel expansion */ +#else + png_uint_16 filler; /* filler bytes for pixel expansion */ +#endif +#endif + +#if defined(PNG_bKGD_SUPPORTED) + png_byte background_gamma_type; +# ifdef PNG_FLOATING_POINT_SUPPORTED + float background_gamma; +# endif + png_color_16 background; /* background color in screen gamma space */ +#if defined(PNG_READ_GAMMA_SUPPORTED) + png_color_16 background_1; /* background normalized to gamma 1.0 */ +#endif +#endif /* PNG_bKGD_SUPPORTED */ + +#if defined(PNG_WRITE_FLUSH_SUPPORTED) + png_flush_ptr output_flush_fn;/* Function for flushing output */ + png_uint_32 flush_dist; /* how many rows apart to flush, 0 - no flush */ + png_uint_32 flush_rows; /* number of rows written since last flush */ +#endif + +#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) + int gamma_shift; /* number of "insignificant" bits 16-bit gamma */ +#ifdef PNG_FLOATING_POINT_SUPPORTED + float gamma; /* file gamma value */ + float screen_gamma; /* screen gamma value (display_exponent) */ +#endif +#endif + +#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) + png_bytep gamma_table; /* gamma table for 8-bit depth files */ + png_bytep gamma_from_1; /* converts from 1.0 to screen */ + png_bytep gamma_to_1; /* converts from file to 1.0 */ + png_uint_16pp gamma_16_table; /* gamma table for 16-bit depth files */ + png_uint_16pp gamma_16_from_1; /* converts from 1.0 to screen */ + png_uint_16pp gamma_16_to_1; /* converts from file to 1.0 */ +#endif + +#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_sBIT_SUPPORTED) + png_color_8 sig_bit; /* significant bits in each available channel */ +#endif + +#if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED) + png_color_8 shift; /* shift for significant bit tranformation */ +#endif + +#if defined(PNG_tRNS_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) \ + || defined(PNG_READ_EXPAND_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) + png_bytep trans; /* transparency values for paletted files */ + png_color_16 trans_values; /* transparency values for non-paletted files */ +#endif + + png_read_status_ptr read_row_fn; /* called after each row is decoded */ + png_write_status_ptr write_row_fn; /* called after each row is encoded */ +#ifdef PNG_PROGRESSIVE_READ_SUPPORTED + png_progressive_info_ptr info_fn; /* called after header data fully read */ + png_progressive_row_ptr row_fn; /* called after each prog. row is decoded */ + png_progressive_end_ptr end_fn; /* called after image is complete */ + png_bytep save_buffer_ptr; /* current location in save_buffer */ + png_bytep save_buffer; /* buffer for previously read data */ + png_bytep current_buffer_ptr; /* current location in current_buffer */ + png_bytep current_buffer; /* buffer for recently used data */ + png_uint_32 push_length; /* size of current input chunk */ + png_uint_32 skip_length; /* bytes to skip in input data */ + png_size_t save_buffer_size; /* amount of data now in save_buffer */ + png_size_t save_buffer_max; /* total size of save_buffer */ + png_size_t buffer_size; /* total amount of available input data */ + png_size_t current_buffer_size; /* amount of data now in current_buffer */ + int process_mode; /* what push library is currently doing */ + int cur_palette; /* current push library palette index */ + +# if defined(PNG_TEXT_SUPPORTED) + png_size_t current_text_size; /* current size of text input data */ + png_size_t current_text_left; /* how much text left to read in input */ + png_charp current_text; /* current text chunk buffer */ + png_charp current_text_ptr; /* current location in current_text */ +# endif /* PNG_TEXT_SUPPORTED */ +#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */ + +#if defined(__TURBOC__) && !defined(_Windows) && !defined(__FLAT__) +/* for the Borland special 64K segment handler */ + png_bytepp offset_table_ptr; + png_bytep offset_table; + png_uint_16 offset_table_number; + png_uint_16 offset_table_count; + png_uint_16 offset_table_count_free; +#endif + +#if defined(PNG_READ_DITHER_SUPPORTED) + png_bytep palette_lookup; /* lookup table for dithering */ + png_bytep dither_index; /* index translation for palette files */ +#endif + +#if defined(PNG_READ_DITHER_SUPPORTED) || defined(PNG_hIST_SUPPORTED) + png_uint_16p hist; /* histogram */ +#endif + +#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED) + png_byte heuristic_method; /* heuristic for row filter selection */ + png_byte num_prev_filters; /* number of weights for previous rows */ + png_bytep prev_filters; /* filter type(s) of previous row(s) */ + png_uint_16p filter_weights; /* weight(s) for previous line(s) */ + png_uint_16p inv_filter_weights; /* 1/weight(s) for previous line(s) */ + png_uint_16p filter_costs; /* relative filter calculation cost */ + png_uint_16p inv_filter_costs; /* 1/relative filter calculation cost */ +#endif + +#if defined(PNG_TIME_RFC1123_SUPPORTED) + png_charp time_buffer; /* String to hold RFC 1123 time text */ +#endif + +/* New members added in libpng-1.0.6 */ + +#ifdef PNG_FREE_ME_SUPPORTED + png_uint_32 free_me; /* flags items libpng is responsible for freeing */ +#endif + +#if defined(PNG_USER_CHUNKS_SUPPORTED) + png_voidp user_chunk_ptr; + png_user_chunk_ptr read_user_chunk_fn; /* user read chunk handler */ +#endif + +#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED) + int num_chunk_list; + png_bytep chunk_list; +#endif + +/* New members added in libpng-1.0.3 */ +#if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED) + png_byte rgb_to_gray_status; + /* These were changed from png_byte in libpng-1.0.6 */ + png_uint_16 rgb_to_gray_red_coeff; + png_uint_16 rgb_to_gray_green_coeff; + png_uint_16 rgb_to_gray_blue_coeff; +#endif + +/* New member added in libpng-1.0.4 (renamed in 1.0.9) */ +#if defined(PNG_MNG_FEATURES_SUPPORTED) || \ + defined(PNG_READ_EMPTY_PLTE_SUPPORTED) || \ + defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) +/* changed from png_byte to png_uint_32 at version 1.2.0 */ +#ifdef PNG_1_0_X + png_byte mng_features_permitted; +#else + png_uint_32 mng_features_permitted; +#endif /* PNG_1_0_X */ +#endif + +/* New member added in libpng-1.0.7 */ +#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) + png_fixed_point int_gamma; +#endif + +/* New member added in libpng-1.0.9, ifdef'ed out in 1.0.12, enabled in 1.2.0 */ +#if defined(PNG_MNG_FEATURES_SUPPORTED) + png_byte filter_type; +#endif + +#if defined(PNG_1_0_X) +/* New member added in libpng-1.0.10, ifdef'ed out in 1.2.0 */ + png_uint_32 row_buf_size; +#endif + +/* New members added in libpng-1.2.0 */ +#if defined(PNG_ASSEMBLER_CODE_SUPPORTED) +# if !defined(PNG_1_0_X) +# if defined(PNG_MMX_CODE_SUPPORTED) + png_byte mmx_bitdepth_threshold; + png_uint_32 mmx_rowbytes_threshold; +# endif + png_uint_32 asm_flags; +# endif +#endif + +/* New members added in libpng-1.0.2 but first enabled by default in 1.2.0 */ +#ifdef PNG_USER_MEM_SUPPORTED + png_voidp mem_ptr; /* user supplied struct for mem functions */ + png_malloc_ptr malloc_fn; /* function for allocating memory */ + png_free_ptr free_fn; /* function for freeing memory */ +#endif + +/* New member added in libpng-1.0.13 and 1.2.0 */ + png_bytep big_row_buf; /* buffer to save current (unfiltered) row */ + +#if defined(PNG_READ_DITHER_SUPPORTED) +/* The following three members were added at version 1.0.14 and 1.2.4 */ + png_bytep dither_sort; /* working sort array */ + png_bytep index_to_palette; /* where the original index currently is */ + /* in the palette */ + png_bytep palette_to_index; /* which original index points to this */ + /* palette color */ +#endif + +/* New members added in libpng-1.0.16 and 1.2.6 */ + png_byte compression_type; + +#ifdef PNG_SET_USER_LIMITS_SUPPORTED + png_uint_32 user_width_max; + png_uint_32 user_height_max; +#endif + +/* New member added in libpng-1.0.25 and 1.2.17 */ +#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED) + /* storage for unknown chunk that the library doesn't recognize. */ + png_unknown_chunk unknown_chunk; +#endif + +/* New members added in libpng-1.2.26 */ + png_uint_32 old_big_row_buf_size, old_prev_row_size; +}; + + +/* This triggers a compiler error in png.c, if png.c and png.h + * do not agree upon the version number. + */ +typedef png_structp version_1_2_29; + +typedef png_struct FAR * FAR * png_structpp; + +/* Here are the function definitions most commonly used. This is not + * the place to find out how to use libpng. See libpng.txt for the + * full explanation, see example.c for the summary. This just provides + * a simple one line description of the use of each function. + */ + +/* Returns the version number of the library */ +extern PNG_EXPORT(png_uint_32,png_access_version_number) PNGARG((void)); + +/* Tell lib we have already handled the first magic bytes. + * Handling more than 8 bytes from the beginning of the file is an error. + */ +extern PNG_EXPORT(void,png_set_sig_bytes) PNGARG((png_structp png_ptr, + int num_bytes)); + +/* Check sig[start] through sig[start + num_to_check - 1] to see if it's a + * PNG file. Returns zero if the supplied bytes match the 8-byte PNG + * signature, and non-zero otherwise. Having num_to_check == 0 or + * start > 7 will always fail (ie return non-zero). + */ +extern PNG_EXPORT(int,png_sig_cmp) PNGARG((png_bytep sig, png_size_t start, + png_size_t num_to_check)); + +/* Simple signature checking function. This is the same as calling + * png_check_sig(sig, n) := !png_sig_cmp(sig, 0, n). + */ +extern PNG_EXPORT(int,png_check_sig) PNGARG((png_bytep sig, int num)); + +/* Allocate and initialize png_ptr struct for reading, and any other memory. */ +extern PNG_EXPORT(png_structp,png_create_read_struct) + PNGARG((png_const_charp user_png_ver, png_voidp error_ptr, + png_error_ptr error_fn, png_error_ptr warn_fn)); + +/* Allocate and initialize png_ptr struct for writing, and any other memory */ +extern PNG_EXPORT(png_structp,png_create_write_struct) + PNGARG((png_const_charp user_png_ver, png_voidp error_ptr, + png_error_ptr error_fn, png_error_ptr warn_fn)); + +#ifdef PNG_WRITE_SUPPORTED +extern PNG_EXPORT(png_uint_32,png_get_compression_buffer_size) + PNGARG((png_structp png_ptr)); +#endif + +#ifdef PNG_WRITE_SUPPORTED +extern PNG_EXPORT(void,png_set_compression_buffer_size) + PNGARG((png_structp png_ptr, png_uint_32 size)); +#endif + +/* Reset the compression stream */ +extern PNG_EXPORT(int,png_reset_zstream) PNGARG((png_structp png_ptr)); + +/* New functions added in libpng-1.0.2 (not enabled by default until 1.2.0) */ +#ifdef PNG_USER_MEM_SUPPORTED +extern PNG_EXPORT(png_structp,png_create_read_struct_2) + PNGARG((png_const_charp user_png_ver, png_voidp error_ptr, + png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr, + png_malloc_ptr malloc_fn, png_free_ptr free_fn)); +extern PNG_EXPORT(png_structp,png_create_write_struct_2) + PNGARG((png_const_charp user_png_ver, png_voidp error_ptr, + png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr, + png_malloc_ptr malloc_fn, png_free_ptr free_fn)); +#endif + +/* Write a PNG chunk - size, type, (optional) data, CRC. */ +extern PNG_EXPORT(void,png_write_chunk) PNGARG((png_structp png_ptr, + png_bytep chunk_name, png_bytep data, png_size_t length)); + +/* Write the start of a PNG chunk - length and chunk name. */ +extern PNG_EXPORT(void,png_write_chunk_start) PNGARG((png_structp png_ptr, + png_bytep chunk_name, png_uint_32 length)); + +/* Write the data of a PNG chunk started with png_write_chunk_start(). */ +extern PNG_EXPORT(void,png_write_chunk_data) PNGARG((png_structp png_ptr, + png_bytep data, png_size_t length)); + +/* Finish a chunk started with png_write_chunk_start() (includes CRC). */ +extern PNG_EXPORT(void,png_write_chunk_end) PNGARG((png_structp png_ptr)); + +/* Allocate and initialize the info structure */ +extern PNG_EXPORT(png_infop,png_create_info_struct) + PNGARG((png_structp png_ptr)); + +#if defined(PNG_1_0_X) || defined (PNG_1_2_X) +/* Initialize the info structure (old interface - DEPRECATED) */ +extern PNG_EXPORT(void,png_info_init) PNGARG((png_infop info_ptr)); +#undef png_info_init +#define png_info_init(info_ptr) png_info_init_3(&info_ptr,\ + png_sizeof(png_info)); +#endif + +extern PNG_EXPORT(void,png_info_init_3) PNGARG((png_infopp info_ptr, + png_size_t png_info_struct_size)); + +/* Writes all the PNG information before the image. */ +extern PNG_EXPORT(void,png_write_info_before_PLTE) PNGARG((png_structp png_ptr, + png_infop info_ptr)); +extern PNG_EXPORT(void,png_write_info) PNGARG((png_structp png_ptr, + png_infop info_ptr)); + +#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED +/* read the information before the actual image data. */ +extern PNG_EXPORT(void,png_read_info) PNGARG((png_structp png_ptr, + png_infop info_ptr)); +#endif + +#if defined(PNG_TIME_RFC1123_SUPPORTED) +extern PNG_EXPORT(png_charp,png_convert_to_rfc1123) + PNGARG((png_structp png_ptr, png_timep ptime)); +#endif + +#if !defined(_WIN32_WCE) +/* "time.h" functions are not supported on WindowsCE */ +#if defined(PNG_WRITE_tIME_SUPPORTED) +/* convert from a struct tm to png_time */ +extern PNG_EXPORT(void,png_convert_from_struct_tm) PNGARG((png_timep ptime, + struct tm FAR * ttime)); + +/* convert from time_t to png_time. Uses gmtime() */ +extern PNG_EXPORT(void,png_convert_from_time_t) PNGARG((png_timep ptime, + time_t ttime)); +#endif /* PNG_WRITE_tIME_SUPPORTED */ +#endif /* _WIN32_WCE */ + +#if defined(PNG_READ_EXPAND_SUPPORTED) +/* Expand data to 24-bit RGB, or 8-bit grayscale, with alpha if available. */ +extern PNG_EXPORT(void,png_set_expand) PNGARG((png_structp png_ptr)); +#if !defined(PNG_1_0_X) +extern PNG_EXPORT(void,png_set_expand_gray_1_2_4_to_8) PNGARG((png_structp + png_ptr)); +#endif +extern PNG_EXPORT(void,png_set_palette_to_rgb) PNGARG((png_structp png_ptr)); +extern PNG_EXPORT(void,png_set_tRNS_to_alpha) PNGARG((png_structp png_ptr)); +#if defined(PNG_1_0_X) || defined (PNG_1_2_X) +/* Deprecated */ +extern PNG_EXPORT(void,png_set_gray_1_2_4_to_8) PNGARG((png_structp png_ptr)); +#endif +#endif + +#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED) +/* Use blue, green, red order for pixels. */ +extern PNG_EXPORT(void,png_set_bgr) PNGARG((png_structp png_ptr)); +#endif + +#if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED) +/* Expand the grayscale to 24-bit RGB if necessary. */ +extern PNG_EXPORT(void,png_set_gray_to_rgb) PNGARG((png_structp png_ptr)); +#endif + +#if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED) +/* Reduce RGB to grayscale. */ +#ifdef PNG_FLOATING_POINT_SUPPORTED +extern PNG_EXPORT(void,png_set_rgb_to_gray) PNGARG((png_structp png_ptr, + int error_action, double red, double green )); +#endif +extern PNG_EXPORT(void,png_set_rgb_to_gray_fixed) PNGARG((png_structp png_ptr, + int error_action, png_fixed_point red, png_fixed_point green )); +extern PNG_EXPORT(png_byte,png_get_rgb_to_gray_status) PNGARG((png_structp + png_ptr)); +#endif + +extern PNG_EXPORT(void,png_build_grayscale_palette) PNGARG((int bit_depth, + png_colorp palette)); + +#if defined(PNG_READ_STRIP_ALPHA_SUPPORTED) +extern PNG_EXPORT(void,png_set_strip_alpha) PNGARG((png_structp png_ptr)); +#endif + +#if defined(PNG_READ_SWAP_ALPHA_SUPPORTED) || \ + defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED) +extern PNG_EXPORT(void,png_set_swap_alpha) PNGARG((png_structp png_ptr)); +#endif + +#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED) || \ + defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED) +extern PNG_EXPORT(void,png_set_invert_alpha) PNGARG((png_structp png_ptr)); +#endif + +#if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED) +/* Add a filler byte to 8-bit Gray or 24-bit RGB images. */ +extern PNG_EXPORT(void,png_set_filler) PNGARG((png_structp png_ptr, + png_uint_32 filler, int flags)); +/* The values of the PNG_FILLER_ defines should NOT be changed */ +#define PNG_FILLER_BEFORE 0 +#define PNG_FILLER_AFTER 1 +/* Add an alpha byte to 8-bit Gray or 24-bit RGB images. */ +#if !defined(PNG_1_0_X) +extern PNG_EXPORT(void,png_set_add_alpha) PNGARG((png_structp png_ptr, + png_uint_32 filler, int flags)); +#endif +#endif /* PNG_READ_FILLER_SUPPORTED || PNG_WRITE_FILLER_SUPPORTED */ + +#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED) +/* Swap bytes in 16-bit depth files. */ +extern PNG_EXPORT(void,png_set_swap) PNGARG((png_structp png_ptr)); +#endif + +#if defined(PNG_READ_PACK_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED) +/* Use 1 byte per pixel in 1, 2, or 4-bit depth files. */ +extern PNG_EXPORT(void,png_set_packing) PNGARG((png_structp png_ptr)); +#endif + +#if defined(PNG_READ_PACKSWAP_SUPPORTED) || defined(PNG_WRITE_PACKSWAP_SUPPORTED) +/* Swap packing order of pixels in bytes. */ +extern PNG_EXPORT(void,png_set_packswap) PNGARG((png_structp png_ptr)); +#endif + +#if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED) +/* Converts files to legal bit depths. */ +extern PNG_EXPORT(void,png_set_shift) PNGARG((png_structp png_ptr, + png_color_8p true_bits)); +#endif + +#if defined(PNG_READ_INTERLACING_SUPPORTED) || \ + defined(PNG_WRITE_INTERLACING_SUPPORTED) +/* Have the code handle the interlacing. Returns the number of passes. */ +extern PNG_EXPORT(int,png_set_interlace_handling) PNGARG((png_structp png_ptr)); +#endif + +#if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED) +/* Invert monochrome files */ +extern PNG_EXPORT(void,png_set_invert_mono) PNGARG((png_structp png_ptr)); +#endif + +#if defined(PNG_READ_BACKGROUND_SUPPORTED) +/* Handle alpha and tRNS by replacing with a background color. */ +#ifdef PNG_FLOATING_POINT_SUPPORTED +extern PNG_EXPORT(void,png_set_background) PNGARG((png_structp png_ptr, + png_color_16p background_color, int background_gamma_code, + int need_expand, double background_gamma)); +#endif +#define PNG_BACKGROUND_GAMMA_UNKNOWN 0 +#define PNG_BACKGROUND_GAMMA_SCREEN 1 +#define PNG_BACKGROUND_GAMMA_FILE 2 +#define PNG_BACKGROUND_GAMMA_UNIQUE 3 +#endif + +#if defined(PNG_READ_16_TO_8_SUPPORTED) +/* strip the second byte of information from a 16-bit depth file. */ +extern PNG_EXPORT(void,png_set_strip_16) PNGARG((png_structp png_ptr)); +#endif + +#if defined(PNG_READ_DITHER_SUPPORTED) +/* Turn on dithering, and reduce the palette to the number of colors available. */ +extern PNG_EXPORT(void,png_set_dither) PNGARG((png_structp png_ptr, + png_colorp palette, int num_palette, int maximum_colors, + png_uint_16p histogram, int full_dither)); +#endif + +#if defined(PNG_READ_GAMMA_SUPPORTED) +/* Handle gamma correction. Screen_gamma=(display_exponent) */ +#ifdef PNG_FLOATING_POINT_SUPPORTED +extern PNG_EXPORT(void,png_set_gamma) PNGARG((png_structp png_ptr, + double screen_gamma, double default_file_gamma)); +#endif +#endif + +#if defined(PNG_1_0_X) || defined (PNG_1_2_X) +#if defined(PNG_READ_EMPTY_PLTE_SUPPORTED) || \ + defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) +/* Permit or disallow empty PLTE (0: not permitted, 1: permitted) */ +/* Deprecated and will be removed. Use png_permit_mng_features() instead. */ +extern PNG_EXPORT(void,png_permit_empty_plte) PNGARG((png_structp png_ptr, + int empty_plte_permitted)); +#endif +#endif + +#if defined(PNG_WRITE_FLUSH_SUPPORTED) +/* Set how many lines between output flushes - 0 for no flushing */ +extern PNG_EXPORT(void,png_set_flush) PNGARG((png_structp png_ptr, int nrows)); +/* Flush the current PNG output buffer */ +extern PNG_EXPORT(void,png_write_flush) PNGARG((png_structp png_ptr)); +#endif + +/* optional update palette with requested transformations */ +extern PNG_EXPORT(void,png_start_read_image) PNGARG((png_structp png_ptr)); + +/* optional call to update the users info structure */ +extern PNG_EXPORT(void,png_read_update_info) PNGARG((png_structp png_ptr, + png_infop info_ptr)); + +#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED +/* read one or more rows of image data. */ +extern PNG_EXPORT(void,png_read_rows) PNGARG((png_structp png_ptr, + png_bytepp row, png_bytepp display_row, png_uint_32 num_rows)); +#endif + +#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED +/* read a row of data. */ +extern PNG_EXPORT(void,png_read_row) PNGARG((png_structp png_ptr, + png_bytep row, + png_bytep display_row)); +#endif + +#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED +/* read the whole image into memory at once. */ +extern PNG_EXPORT(void,png_read_image) PNGARG((png_structp png_ptr, + png_bytepp image)); +#endif + +/* write a row of image data */ +extern PNG_EXPORT(void,png_write_row) PNGARG((png_structp png_ptr, + png_bytep row)); + +/* write a few rows of image data */ +extern PNG_EXPORT(void,png_write_rows) PNGARG((png_structp png_ptr, + png_bytepp row, png_uint_32 num_rows)); + +/* write the image data */ +extern PNG_EXPORT(void,png_write_image) PNGARG((png_structp png_ptr, + png_bytepp image)); + +/* writes the end of the PNG file. */ +extern PNG_EXPORT(void,png_write_end) PNGARG((png_structp png_ptr, + png_infop info_ptr)); + +#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED +/* read the end of the PNG file. */ +extern PNG_EXPORT(void,png_read_end) PNGARG((png_structp png_ptr, + png_infop info_ptr)); +#endif + +/* free any memory associated with the png_info_struct */ +extern PNG_EXPORT(void,png_destroy_info_struct) PNGARG((png_structp png_ptr, + png_infopp info_ptr_ptr)); + +/* free any memory associated with the png_struct and the png_info_structs */ +extern PNG_EXPORT(void,png_destroy_read_struct) PNGARG((png_structpp + png_ptr_ptr, png_infopp info_ptr_ptr, png_infopp end_info_ptr_ptr)); + +/* free all memory used by the read (old method - NOT DLL EXPORTED) */ +extern void png_read_destroy PNGARG((png_structp png_ptr, png_infop info_ptr, + png_infop end_info_ptr)); + +/* free any memory associated with the png_struct and the png_info_structs */ +extern PNG_EXPORT(void,png_destroy_write_struct) + PNGARG((png_structpp png_ptr_ptr, png_infopp info_ptr_ptr)); + +/* free any memory used in png_ptr struct (old method - NOT DLL EXPORTED) */ +extern void png_write_destroy PNGARG((png_structp png_ptr)); + +/* set the libpng method of handling chunk CRC errors */ +extern PNG_EXPORT(void,png_set_crc_action) PNGARG((png_structp png_ptr, + int crit_action, int ancil_action)); + +/* Values for png_set_crc_action() to say how to handle CRC errors in + * ancillary and critical chunks, and whether to use the data contained + * therein. Note that it is impossible to "discard" data in a critical + * chunk. For versions prior to 0.90, the action was always error/quit, + * whereas in version 0.90 and later, the action for CRC errors in ancillary + * chunks is warn/discard. These values should NOT be changed. + * + * value action:critical action:ancillary + */ +#define PNG_CRC_DEFAULT 0 /* error/quit warn/discard data */ +#define PNG_CRC_ERROR_QUIT 1 /* error/quit error/quit */ +#define PNG_CRC_WARN_DISCARD 2 /* (INVALID) warn/discard data */ +#define PNG_CRC_WARN_USE 3 /* warn/use data warn/use data */ +#define PNG_CRC_QUIET_USE 4 /* quiet/use data quiet/use data */ +#define PNG_CRC_NO_CHANGE 5 /* use current value use current value */ + +/* These functions give the user control over the scan-line filtering in + * libpng and the compression methods used by zlib. These functions are + * mainly useful for testing, as the defaults should work with most users. + * Those users who are tight on memory or want faster performance at the + * expense of compression can modify them. See the compression library + * header file (zlib.h) for an explination of the compression functions. + */ + +/* set the filtering method(s) used by libpng. Currently, the only valid + * value for "method" is 0. + */ +extern PNG_EXPORT(void,png_set_filter) PNGARG((png_structp png_ptr, int method, + int filters)); + +/* Flags for png_set_filter() to say which filters to use. The flags + * are chosen so that they don't conflict with real filter types + * below, in case they are supplied instead of the #defined constants. + * These values should NOT be changed. + */ +#define PNG_NO_FILTERS 0x00 +#define PNG_FILTER_NONE 0x08 +#define PNG_FILTER_SUB 0x10 +#define PNG_FILTER_UP 0x20 +#define PNG_FILTER_AVG 0x40 +#define PNG_FILTER_PAETH 0x80 +#define PNG_ALL_FILTERS (PNG_FILTER_NONE | PNG_FILTER_SUB | PNG_FILTER_UP | \ + PNG_FILTER_AVG | PNG_FILTER_PAETH) + +/* Filter values (not flags) - used in pngwrite.c, pngwutil.c for now. + * These defines should NOT be changed. + */ +#define PNG_FILTER_VALUE_NONE 0 +#define PNG_FILTER_VALUE_SUB 1 +#define PNG_FILTER_VALUE_UP 2 +#define PNG_FILTER_VALUE_AVG 3 +#define PNG_FILTER_VALUE_PAETH 4 +#define PNG_FILTER_VALUE_LAST 5 + +#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED) /* EXPERIMENTAL */ +/* The "heuristic_method" is given by one of the PNG_FILTER_HEURISTIC_ + * defines, either the default (minimum-sum-of-absolute-differences), or + * the experimental method (weighted-minimum-sum-of-absolute-differences). + * + * Weights are factors >= 1.0, indicating how important it is to keep the + * filter type consistent between rows. Larger numbers mean the current + * filter is that many times as likely to be the same as the "num_weights" + * previous filters. This is cumulative for each previous row with a weight. + * There needs to be "num_weights" values in "filter_weights", or it can be + * NULL if the weights aren't being specified. Weights have no influence on + * the selection of the first row filter. Well chosen weights can (in theory) + * improve the compression for a given image. + * + * Costs are factors >= 1.0 indicating the relative decoding costs of a + * filter type. Higher costs indicate more decoding expense, and are + * therefore less likely to be selected over a filter with lower computational + * costs. There needs to be a value in "filter_costs" for each valid filter + * type (given by PNG_FILTER_VALUE_LAST), or it can be NULL if you aren't + * setting the costs. Costs try to improve the speed of decompression without + * unduly increasing the compressed image size. + * + * A negative weight or cost indicates the default value is to be used, and + * values in the range [0.0, 1.0) indicate the value is to remain unchanged. + * The default values for both weights and costs are currently 1.0, but may + * change if good general weighting/cost heuristics can be found. If both + * the weights and costs are set to 1.0, this degenerates the WEIGHTED method + * to the UNWEIGHTED method, but with added encoding time/computation. + */ +#ifdef PNG_FLOATING_POINT_SUPPORTED +extern PNG_EXPORT(void,png_set_filter_heuristics) PNGARG((png_structp png_ptr, + int heuristic_method, int num_weights, png_doublep filter_weights, + png_doublep filter_costs)); +#endif +#endif /* PNG_WRITE_WEIGHTED_FILTER_SUPPORTED */ + +/* Heuristic used for row filter selection. These defines should NOT be + * changed. + */ +#define PNG_FILTER_HEURISTIC_DEFAULT 0 /* Currently "UNWEIGHTED" */ +#define PNG_FILTER_HEURISTIC_UNWEIGHTED 1 /* Used by libpng < 0.95 */ +#define PNG_FILTER_HEURISTIC_WEIGHTED 2 /* Experimental feature */ +#define PNG_FILTER_HEURISTIC_LAST 3 /* Not a valid value */ + +/* Set the library compression level. Currently, valid values range from + * 0 - 9, corresponding directly to the zlib compression levels 0 - 9 + * (0 - no compression, 9 - "maximal" compression). Note that tests have + * shown that zlib compression levels 3-6 usually perform as well as level 9 + * for PNG images, and do considerably fewer caclulations. In the future, + * these values may not correspond directly to the zlib compression levels. + */ +extern PNG_EXPORT(void,png_set_compression_level) PNGARG((png_structp png_ptr, + int level)); + +extern PNG_EXPORT(void,png_set_compression_mem_level) + PNGARG((png_structp png_ptr, int mem_level)); + +extern PNG_EXPORT(void,png_set_compression_strategy) + PNGARG((png_structp png_ptr, int strategy)); + +extern PNG_EXPORT(void,png_set_compression_window_bits) + PNGARG((png_structp png_ptr, int window_bits)); + +extern PNG_EXPORT(void,png_set_compression_method) PNGARG((png_structp png_ptr, + int method)); + +/* These next functions are called for input/output, memory, and error + * handling. They are in the file pngrio.c, pngwio.c, and pngerror.c, + * and call standard C I/O routines such as fread(), fwrite(), and + * fprintf(). These functions can be made to use other I/O routines + * at run time for those applications that need to handle I/O in a + * different manner by calling png_set_???_fn(). See libpng.txt for + * more information. + */ + +#if !defined(PNG_NO_STDIO) +/* Initialize the input/output for the PNG file to the default functions. */ +extern PNG_EXPORT(void,png_init_io) PNGARG((png_structp png_ptr, png_FILE_p fp)); +#endif + +/* Replace the (error and abort), and warning functions with user + * supplied functions. If no messages are to be printed you must still + * write and use replacement functions. The replacement error_fn should + * still do a longjmp to the last setjmp location if you are using this + * method of error handling. If error_fn or warning_fn is NULL, the + * default function will be used. + */ + +extern PNG_EXPORT(void,png_set_error_fn) PNGARG((png_structp png_ptr, + png_voidp error_ptr, png_error_ptr error_fn, png_error_ptr warning_fn)); + +/* Return the user pointer associated with the error functions */ +extern PNG_EXPORT(png_voidp,png_get_error_ptr) PNGARG((png_structp png_ptr)); + +/* Replace the default data output functions with a user supplied one(s). + * If buffered output is not used, then output_flush_fn can be set to NULL. + * If PNG_WRITE_FLUSH_SUPPORTED is not defined at libpng compile time + * output_flush_fn will be ignored (and thus can be NULL). + */ +extern PNG_EXPORT(void,png_set_write_fn) PNGARG((png_structp png_ptr, + png_voidp io_ptr, png_rw_ptr write_data_fn, png_flush_ptr output_flush_fn)); + +/* Replace the default data input function with a user supplied one. */ +extern PNG_EXPORT(void,png_set_read_fn) PNGARG((png_structp png_ptr, + png_voidp io_ptr, png_rw_ptr read_data_fn)); + +/* Return the user pointer associated with the I/O functions */ +extern PNG_EXPORT(png_voidp,png_get_io_ptr) PNGARG((png_structp png_ptr)); + +extern PNG_EXPORT(void,png_set_read_status_fn) PNGARG((png_structp png_ptr, + png_read_status_ptr read_row_fn)); + +extern PNG_EXPORT(void,png_set_write_status_fn) PNGARG((png_structp png_ptr, + png_write_status_ptr write_row_fn)); + +#ifdef PNG_USER_MEM_SUPPORTED +/* Replace the default memory allocation functions with user supplied one(s). */ +extern PNG_EXPORT(void,png_set_mem_fn) PNGARG((png_structp png_ptr, + png_voidp mem_ptr, png_malloc_ptr malloc_fn, png_free_ptr free_fn)); +/* Return the user pointer associated with the memory functions */ +extern PNG_EXPORT(png_voidp,png_get_mem_ptr) PNGARG((png_structp png_ptr)); +#endif + +#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \ + defined(PNG_LEGACY_SUPPORTED) +extern PNG_EXPORT(void,png_set_read_user_transform_fn) PNGARG((png_structp + png_ptr, png_user_transform_ptr read_user_transform_fn)); +#endif + +#if defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) || \ + defined(PNG_LEGACY_SUPPORTED) +extern PNG_EXPORT(void,png_set_write_user_transform_fn) PNGARG((png_structp + png_ptr, png_user_transform_ptr write_user_transform_fn)); +#endif + +#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \ + defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) || \ + defined(PNG_LEGACY_SUPPORTED) +extern PNG_EXPORT(void,png_set_user_transform_info) PNGARG((png_structp + png_ptr, png_voidp user_transform_ptr, int user_transform_depth, + int user_transform_channels)); +/* Return the user pointer associated with the user transform functions */ +extern PNG_EXPORT(png_voidp,png_get_user_transform_ptr) + PNGARG((png_structp png_ptr)); +#endif + +#ifdef PNG_USER_CHUNKS_SUPPORTED +extern PNG_EXPORT(void,png_set_read_user_chunk_fn) PNGARG((png_structp png_ptr, + png_voidp user_chunk_ptr, png_user_chunk_ptr read_user_chunk_fn)); +extern PNG_EXPORT(png_voidp,png_get_user_chunk_ptr) PNGARG((png_structp + png_ptr)); +#endif + +#ifdef PNG_PROGRESSIVE_READ_SUPPORTED +/* Sets the function callbacks for the push reader, and a pointer to a + * user-defined structure available to the callback functions. + */ +extern PNG_EXPORT(void,png_set_progressive_read_fn) PNGARG((png_structp png_ptr, + png_voidp progressive_ptr, + png_progressive_info_ptr info_fn, png_progressive_row_ptr row_fn, + png_progressive_end_ptr end_fn)); + +/* returns the user pointer associated with the push read functions */ +extern PNG_EXPORT(png_voidp,png_get_progressive_ptr) + PNGARG((png_structp png_ptr)); + +/* function to be called when data becomes available */ +extern PNG_EXPORT(void,png_process_data) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_bytep buffer, png_size_t buffer_size)); + +/* function that combines rows. Not very much different than the + * png_combine_row() call. Is this even used????? + */ +extern PNG_EXPORT(void,png_progressive_combine_row) PNGARG((png_structp png_ptr, + png_bytep old_row, png_bytep new_row)); +#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */ + +extern PNG_EXPORT(png_voidp,png_malloc) PNGARG((png_structp png_ptr, + png_uint_32 size)); + +#if defined(PNG_1_0_X) +# define png_malloc_warn png_malloc +#else +/* Added at libpng version 1.2.4 */ +extern PNG_EXPORT(png_voidp,png_malloc_warn) PNGARG((png_structp png_ptr, + png_uint_32 size)); +#endif + +/* frees a pointer allocated by png_malloc() */ +extern PNG_EXPORT(void,png_free) PNGARG((png_structp png_ptr, png_voidp ptr)); + +#if defined(PNG_1_0_X) +/* Function to allocate memory for zlib. */ +extern PNG_EXPORT(voidpf,png_zalloc) PNGARG((voidpf png_ptr, uInt items, + uInt size)); + +/* Function to free memory for zlib */ +extern PNG_EXPORT(void,png_zfree) PNGARG((voidpf png_ptr, voidpf ptr)); +#endif + +/* Free data that was allocated internally */ +extern PNG_EXPORT(void,png_free_data) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_uint_32 free_me, int num)); +#ifdef PNG_FREE_ME_SUPPORTED +/* Reassign responsibility for freeing existing data, whether allocated + * by libpng or by the application */ +extern PNG_EXPORT(void,png_data_freer) PNGARG((png_structp png_ptr, + png_infop info_ptr, int freer, png_uint_32 mask)); +#endif +/* assignments for png_data_freer */ +#define PNG_DESTROY_WILL_FREE_DATA 1 +#define PNG_SET_WILL_FREE_DATA 1 +#define PNG_USER_WILL_FREE_DATA 2 +/* Flags for png_ptr->free_me and info_ptr->free_me */ +#define PNG_FREE_HIST 0x0008 +#define PNG_FREE_ICCP 0x0010 +#define PNG_FREE_SPLT 0x0020 +#define PNG_FREE_ROWS 0x0040 +#define PNG_FREE_PCAL 0x0080 +#define PNG_FREE_SCAL 0x0100 +#define PNG_FREE_UNKN 0x0200 +#define PNG_FREE_LIST 0x0400 +#define PNG_FREE_PLTE 0x1000 +#define PNG_FREE_TRNS 0x2000 +#define PNG_FREE_TEXT 0x4000 +#define PNG_FREE_ALL 0x7fff +#define PNG_FREE_MUL 0x4220 /* PNG_FREE_SPLT|PNG_FREE_TEXT|PNG_FREE_UNKN */ + +#ifdef PNG_USER_MEM_SUPPORTED +extern PNG_EXPORT(png_voidp,png_malloc_default) PNGARG((png_structp png_ptr, + png_uint_32 size)); +extern PNG_EXPORT(void,png_free_default) PNGARG((png_structp png_ptr, + png_voidp ptr)); +#endif + +extern PNG_EXPORT(png_voidp,png_memcpy_check) PNGARG((png_structp png_ptr, + png_voidp s1, png_voidp s2, png_uint_32 size)); + +extern PNG_EXPORT(png_voidp,png_memset_check) PNGARG((png_structp png_ptr, + png_voidp s1, int value, png_uint_32 size)); + +#if defined(USE_FAR_KEYWORD) /* memory model conversion function */ +extern void *png_far_to_near PNGARG((png_structp png_ptr,png_voidp ptr, + int check)); +#endif /* USE_FAR_KEYWORD */ + +#ifndef PNG_NO_ERROR_TEXT +/* Fatal error in PNG image of libpng - can't continue */ +extern PNG_EXPORT(void,png_error) PNGARG((png_structp png_ptr, + png_const_charp error_message)); + +/* The same, but the chunk name is prepended to the error string. */ +extern PNG_EXPORT(void,png_chunk_error) PNGARG((png_structp png_ptr, + png_const_charp error_message)); +#else +/* Fatal error in PNG image of libpng - can't continue */ +extern PNG_EXPORT(void,png_err) PNGARG((png_structp png_ptr)); +#endif + +#ifndef PNG_NO_WARNINGS +/* Non-fatal error in libpng. Can continue, but may have a problem. */ +extern PNG_EXPORT(void,png_warning) PNGARG((png_structp png_ptr, + png_const_charp warning_message)); + +#ifdef PNG_READ_SUPPORTED +/* Non-fatal error in libpng, chunk name is prepended to message. */ +extern PNG_EXPORT(void,png_chunk_warning) PNGARG((png_structp png_ptr, + png_const_charp warning_message)); +#endif /* PNG_READ_SUPPORTED */ +#endif /* PNG_NO_WARNINGS */ + +/* The png_set_ functions are for storing values in the png_info_struct. + * Similarly, the png_get_ calls are used to read values from the + * png_info_struct, either storing the parameters in the passed variables, or + * setting pointers into the png_info_struct where the data is stored. The + * png_get_ functions return a non-zero value if the data was available + * in info_ptr, or return zero and do not change any of the parameters if the + * data was not available. + * + * These functions should be used instead of directly accessing png_info + * to avoid problems with future changes in the size and internal layout of + * png_info_struct. + */ +/* Returns "flag" if chunk data is valid in info_ptr. */ +extern PNG_EXPORT(png_uint_32,png_get_valid) PNGARG((png_structp png_ptr, +png_infop info_ptr, png_uint_32 flag)); + +/* Returns number of bytes needed to hold a transformed row. */ +extern PNG_EXPORT(png_uint_32,png_get_rowbytes) PNGARG((png_structp png_ptr, +png_infop info_ptr)); + +#if defined(PNG_INFO_IMAGE_SUPPORTED) +/* Returns row_pointers, which is an array of pointers to scanlines that was +returned from png_read_png(). */ +extern PNG_EXPORT(png_bytepp,png_get_rows) PNGARG((png_structp png_ptr, +png_infop info_ptr)); +/* Set row_pointers, which is an array of pointers to scanlines for use +by png_write_png(). */ +extern PNG_EXPORT(void,png_set_rows) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_bytepp row_pointers)); +#endif + +/* Returns number of color channels in image. */ +extern PNG_EXPORT(png_byte,png_get_channels) PNGARG((png_structp png_ptr, +png_infop info_ptr)); + +#ifdef PNG_EASY_ACCESS_SUPPORTED +/* Returns image width in pixels. */ +extern PNG_EXPORT(png_uint_32, png_get_image_width) PNGARG((png_structp +png_ptr, png_infop info_ptr)); + +/* Returns image height in pixels. */ +extern PNG_EXPORT(png_uint_32, png_get_image_height) PNGARG((png_structp +png_ptr, png_infop info_ptr)); + +/* Returns image bit_depth. */ +extern PNG_EXPORT(png_byte, png_get_bit_depth) PNGARG((png_structp +png_ptr, png_infop info_ptr)); + +/* Returns image color_type. */ +extern PNG_EXPORT(png_byte, png_get_color_type) PNGARG((png_structp +png_ptr, png_infop info_ptr)); + +/* Returns image filter_type. */ +extern PNG_EXPORT(png_byte, png_get_filter_type) PNGARG((png_structp +png_ptr, png_infop info_ptr)); + +/* Returns image interlace_type. */ +extern PNG_EXPORT(png_byte, png_get_interlace_type) PNGARG((png_structp +png_ptr, png_infop info_ptr)); + +/* Returns image compression_type. */ +extern PNG_EXPORT(png_byte, png_get_compression_type) PNGARG((png_structp +png_ptr, png_infop info_ptr)); + +/* Returns image resolution in pixels per meter, from pHYs chunk data. */ +extern PNG_EXPORT(png_uint_32, png_get_pixels_per_meter) PNGARG((png_structp +png_ptr, png_infop info_ptr)); +extern PNG_EXPORT(png_uint_32, png_get_x_pixels_per_meter) PNGARG((png_structp +png_ptr, png_infop info_ptr)); +extern PNG_EXPORT(png_uint_32, png_get_y_pixels_per_meter) PNGARG((png_structp +png_ptr, png_infop info_ptr)); + +/* Returns pixel aspect ratio, computed from pHYs chunk data. */ +#ifdef PNG_FLOATING_POINT_SUPPORTED +extern PNG_EXPORT(float, png_get_pixel_aspect_ratio) PNGARG((png_structp +png_ptr, png_infop info_ptr)); +#endif + +/* Returns image x, y offset in pixels or microns, from oFFs chunk data. */ +extern PNG_EXPORT(png_int_32, png_get_x_offset_pixels) PNGARG((png_structp +png_ptr, png_infop info_ptr)); +extern PNG_EXPORT(png_int_32, png_get_y_offset_pixels) PNGARG((png_structp +png_ptr, png_infop info_ptr)); +extern PNG_EXPORT(png_int_32, png_get_x_offset_microns) PNGARG((png_structp +png_ptr, png_infop info_ptr)); +extern PNG_EXPORT(png_int_32, png_get_y_offset_microns) PNGARG((png_structp +png_ptr, png_infop info_ptr)); + +#endif /* PNG_EASY_ACCESS_SUPPORTED */ + +/* Returns pointer to signature string read from PNG header */ +extern PNG_EXPORT(png_bytep,png_get_signature) PNGARG((png_structp png_ptr, +png_infop info_ptr)); + +#if defined(PNG_bKGD_SUPPORTED) +extern PNG_EXPORT(png_uint_32,png_get_bKGD) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_color_16p *background)); +#endif + +#if defined(PNG_bKGD_SUPPORTED) +extern PNG_EXPORT(void,png_set_bKGD) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_color_16p background)); +#endif + +#if defined(PNG_cHRM_SUPPORTED) +#ifdef PNG_FLOATING_POINT_SUPPORTED +extern PNG_EXPORT(png_uint_32,png_get_cHRM) PNGARG((png_structp png_ptr, + png_infop info_ptr, double *white_x, double *white_y, double *red_x, + double *red_y, double *green_x, double *green_y, double *blue_x, + double *blue_y)); +#endif +#ifdef PNG_FIXED_POINT_SUPPORTED +extern PNG_EXPORT(png_uint_32,png_get_cHRM_fixed) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_fixed_point *int_white_x, png_fixed_point + *int_white_y, png_fixed_point *int_red_x, png_fixed_point *int_red_y, + png_fixed_point *int_green_x, png_fixed_point *int_green_y, png_fixed_point + *int_blue_x, png_fixed_point *int_blue_y)); +#endif +#endif + +#if defined(PNG_cHRM_SUPPORTED) +#ifdef PNG_FLOATING_POINT_SUPPORTED +extern PNG_EXPORT(void,png_set_cHRM) PNGARG((png_structp png_ptr, + png_infop info_ptr, double white_x, double white_y, double red_x, + double red_y, double green_x, double green_y, double blue_x, double blue_y)); +#endif +#ifdef PNG_FIXED_POINT_SUPPORTED +extern PNG_EXPORT(void,png_set_cHRM_fixed) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_fixed_point int_white_x, png_fixed_point int_white_y, + png_fixed_point int_red_x, png_fixed_point int_red_y, png_fixed_point + int_green_x, png_fixed_point int_green_y, png_fixed_point int_blue_x, + png_fixed_point int_blue_y)); +#endif +#endif + +#if defined(PNG_gAMA_SUPPORTED) +#ifdef PNG_FLOATING_POINT_SUPPORTED +extern PNG_EXPORT(png_uint_32,png_get_gAMA) PNGARG((png_structp png_ptr, + png_infop info_ptr, double *file_gamma)); +#endif +extern PNG_EXPORT(png_uint_32,png_get_gAMA_fixed) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_fixed_point *int_file_gamma)); +#endif + +#if defined(PNG_gAMA_SUPPORTED) +#ifdef PNG_FLOATING_POINT_SUPPORTED +extern PNG_EXPORT(void,png_set_gAMA) PNGARG((png_structp png_ptr, + png_infop info_ptr, double file_gamma)); +#endif +extern PNG_EXPORT(void,png_set_gAMA_fixed) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_fixed_point int_file_gamma)); +#endif + +#if defined(PNG_hIST_SUPPORTED) +extern PNG_EXPORT(png_uint_32,png_get_hIST) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_uint_16p *hist)); +#endif + +#if defined(PNG_hIST_SUPPORTED) +extern PNG_EXPORT(void,png_set_hIST) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_uint_16p hist)); +#endif + +extern PNG_EXPORT(png_uint_32,png_get_IHDR) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_uint_32 *width, png_uint_32 *height, + int *bit_depth, int *color_type, int *interlace_method, + int *compression_method, int *filter_method)); + +extern PNG_EXPORT(void,png_set_IHDR) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_uint_32 width, png_uint_32 height, int bit_depth, + int color_type, int interlace_method, int compression_method, + int filter_method)); + +#if defined(PNG_oFFs_SUPPORTED) +extern PNG_EXPORT(png_uint_32,png_get_oFFs) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_int_32 *offset_x, png_int_32 *offset_y, + int *unit_type)); +#endif + +#if defined(PNG_oFFs_SUPPORTED) +extern PNG_EXPORT(void,png_set_oFFs) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_int_32 offset_x, png_int_32 offset_y, + int unit_type)); +#endif + +#if defined(PNG_pCAL_SUPPORTED) +extern PNG_EXPORT(png_uint_32,png_get_pCAL) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_charp *purpose, png_int_32 *X0, png_int_32 *X1, + int *type, int *nparams, png_charp *units, png_charpp *params)); +#endif + +#if defined(PNG_pCAL_SUPPORTED) +extern PNG_EXPORT(void,png_set_pCAL) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_charp purpose, png_int_32 X0, png_int_32 X1, + int type, int nparams, png_charp units, png_charpp params)); +#endif + +#if defined(PNG_pHYs_SUPPORTED) +extern PNG_EXPORT(png_uint_32,png_get_pHYs) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_uint_32 *res_x, png_uint_32 *res_y, int *unit_type)); +#endif + +#if defined(PNG_pHYs_SUPPORTED) +extern PNG_EXPORT(void,png_set_pHYs) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_uint_32 res_x, png_uint_32 res_y, int unit_type)); +#endif + +extern PNG_EXPORT(png_uint_32,png_get_PLTE) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_colorp *palette, int *num_palette)); + +extern PNG_EXPORT(void,png_set_PLTE) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_colorp palette, int num_palette)); + +#if defined(PNG_sBIT_SUPPORTED) +extern PNG_EXPORT(png_uint_32,png_get_sBIT) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_color_8p *sig_bit)); +#endif + +#if defined(PNG_sBIT_SUPPORTED) +extern PNG_EXPORT(void,png_set_sBIT) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_color_8p sig_bit)); +#endif + +#if defined(PNG_sRGB_SUPPORTED) +extern PNG_EXPORT(png_uint_32,png_get_sRGB) PNGARG((png_structp png_ptr, + png_infop info_ptr, int *intent)); +#endif + +#if defined(PNG_sRGB_SUPPORTED) +extern PNG_EXPORT(void,png_set_sRGB) PNGARG((png_structp png_ptr, + png_infop info_ptr, int intent)); +extern PNG_EXPORT(void,png_set_sRGB_gAMA_and_cHRM) PNGARG((png_structp png_ptr, + png_infop info_ptr, int intent)); +#endif + +#if defined(PNG_iCCP_SUPPORTED) +extern PNG_EXPORT(png_uint_32,png_get_iCCP) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_charpp name, int *compression_type, + png_charpp profile, png_uint_32 *proflen)); + /* Note to maintainer: profile should be png_bytepp */ +#endif + +#if defined(PNG_iCCP_SUPPORTED) +extern PNG_EXPORT(void,png_set_iCCP) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_charp name, int compression_type, + png_charp profile, png_uint_32 proflen)); + /* Note to maintainer: profile should be png_bytep */ +#endif + +#if defined(PNG_sPLT_SUPPORTED) +extern PNG_EXPORT(png_uint_32,png_get_sPLT) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_sPLT_tpp entries)); +#endif + +#if defined(PNG_sPLT_SUPPORTED) +extern PNG_EXPORT(void,png_set_sPLT) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_sPLT_tp entries, int nentries)); +#endif + +#if defined(PNG_TEXT_SUPPORTED) +/* png_get_text also returns the number of text chunks in *num_text */ +extern PNG_EXPORT(png_uint_32,png_get_text) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_textp *text_ptr, int *num_text)); +#endif + +/* + * Note while png_set_text() will accept a structure whose text, + * language, and translated keywords are NULL pointers, the structure + * returned by png_get_text will always contain regular + * zero-terminated C strings. They might be empty strings but + * they will never be NULL pointers. + */ + +#if defined(PNG_TEXT_SUPPORTED) +extern PNG_EXPORT(void,png_set_text) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_textp text_ptr, int num_text)); +#endif + +#if defined(PNG_tIME_SUPPORTED) +extern PNG_EXPORT(png_uint_32,png_get_tIME) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_timep *mod_time)); +#endif + +#if defined(PNG_tIME_SUPPORTED) +extern PNG_EXPORT(void,png_set_tIME) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_timep mod_time)); +#endif + +#if defined(PNG_tRNS_SUPPORTED) +extern PNG_EXPORT(png_uint_32,png_get_tRNS) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_bytep *trans, int *num_trans, + png_color_16p *trans_values)); +#endif + +#if defined(PNG_tRNS_SUPPORTED) +extern PNG_EXPORT(void,png_set_tRNS) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_bytep trans, int num_trans, + png_color_16p trans_values)); +#endif + +#if defined(PNG_tRNS_SUPPORTED) +#endif + +#if defined(PNG_sCAL_SUPPORTED) +#ifdef PNG_FLOATING_POINT_SUPPORTED +extern PNG_EXPORT(png_uint_32,png_get_sCAL) PNGARG((png_structp png_ptr, + png_infop info_ptr, int *unit, double *width, double *height)); +#else +#ifdef PNG_FIXED_POINT_SUPPORTED +extern PNG_EXPORT(png_uint_32,png_get_sCAL_s) PNGARG((png_structp png_ptr, + png_infop info_ptr, int *unit, png_charpp swidth, png_charpp sheight)); +#endif +#endif +#endif /* PNG_sCAL_SUPPORTED */ + +#if defined(PNG_sCAL_SUPPORTED) +#ifdef PNG_FLOATING_POINT_SUPPORTED +extern PNG_EXPORT(void,png_set_sCAL) PNGARG((png_structp png_ptr, + png_infop info_ptr, int unit, double width, double height)); +#else +#ifdef PNG_FIXED_POINT_SUPPORTED +extern PNG_EXPORT(void,png_set_sCAL_s) PNGARG((png_structp png_ptr, + png_infop info_ptr, int unit, png_charp swidth, png_charp sheight)); +#endif +#endif +#endif /* PNG_sCAL_SUPPORTED || PNG_WRITE_sCAL_SUPPORTED */ + +#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED) +/* provide a list of chunks and how they are to be handled, if the built-in + handling or default unknown chunk handling is not desired. Any chunks not + listed will be handled in the default manner. The IHDR and IEND chunks + must not be listed. + keep = 0: follow default behaviour + = 1: do not keep + = 2: keep only if safe-to-copy + = 3: keep even if unsafe-to-copy +*/ +extern PNG_EXPORT(void, png_set_keep_unknown_chunks) PNGARG((png_structp + png_ptr, int keep, png_bytep chunk_list, int num_chunks)); +extern PNG_EXPORT(void, png_set_unknown_chunks) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_unknown_chunkp unknowns, int num_unknowns)); +extern PNG_EXPORT(void, png_set_unknown_chunk_location) + PNGARG((png_structp png_ptr, png_infop info_ptr, int chunk, int location)); +extern PNG_EXPORT(png_uint_32,png_get_unknown_chunks) PNGARG((png_structp + png_ptr, png_infop info_ptr, png_unknown_chunkpp entries)); +#endif +#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED +PNG_EXPORT(int,png_handle_as_unknown) PNGARG((png_structp png_ptr, png_bytep + chunk_name)); +#endif + +/* Png_free_data() will turn off the "valid" flag for anything it frees. + If you need to turn it off for a chunk that your application has freed, + you can use png_set_invalid(png_ptr, info_ptr, PNG_INFO_CHNK); */ +extern PNG_EXPORT(void, png_set_invalid) PNGARG((png_structp png_ptr, + png_infop info_ptr, int mask)); + +#if defined(PNG_INFO_IMAGE_SUPPORTED) +/* The "params" pointer is currently not used and is for future expansion. */ +extern PNG_EXPORT(void, png_read_png) PNGARG((png_structp png_ptr, + png_infop info_ptr, + int transforms, + png_voidp params)); +extern PNG_EXPORT(void, png_write_png) PNGARG((png_structp png_ptr, + png_infop info_ptr, + int transforms, + png_voidp params)); +#endif + +/* Define PNG_DEBUG at compile time for debugging information. Higher + * numbers for PNG_DEBUG mean more debugging information. This has + * only been added since version 0.95 so it is not implemented throughout + * libpng yet, but more support will be added as needed. + */ +#ifdef PNG_DEBUG +#if (PNG_DEBUG > 0) +#if !defined(PNG_DEBUG_FILE) && defined(_MSC_VER) +#include +#if (PNG_DEBUG > 1) +#define png_debug(l,m) _RPT0(_CRT_WARN,m) +#define png_debug1(l,m,p1) _RPT1(_CRT_WARN,m,p1) +#define png_debug2(l,m,p1,p2) _RPT2(_CRT_WARN,m,p1,p2) +#endif +#else /* PNG_DEBUG_FILE || !_MSC_VER */ +#ifndef PNG_DEBUG_FILE +#define PNG_DEBUG_FILE stderr +#endif /* PNG_DEBUG_FILE */ +#if (PNG_DEBUG > 1) +#define png_debug(l,m) \ +{ \ + int num_tabs=l; \ + fprintf(PNG_DEBUG_FILE,"%s"m,(num_tabs==1 ? "\t" : \ + (num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":"")))); \ +} +#define png_debug1(l,m,p1) \ +{ \ + int num_tabs=l; \ + fprintf(PNG_DEBUG_FILE,"%s"m,(num_tabs==1 ? "\t" : \ + (num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":""))),p1); \ +} +#define png_debug2(l,m,p1,p2) \ +{ \ + int num_tabs=l; \ + fprintf(PNG_DEBUG_FILE,"%s"m,(num_tabs==1 ? "\t" : \ + (num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":""))),p1,p2); \ +} +#endif /* (PNG_DEBUG > 1) */ +#endif /* _MSC_VER */ +#endif /* (PNG_DEBUG > 0) */ +#endif /* PNG_DEBUG */ +#ifndef png_debug +#define png_debug(l, m) +#endif +#ifndef png_debug1 +#define png_debug1(l, m, p1) +#endif +#ifndef png_debug2 +#define png_debug2(l, m, p1, p2) +#endif + +extern PNG_EXPORT(png_charp,png_get_copyright) PNGARG((png_structp png_ptr)); +extern PNG_EXPORT(png_charp,png_get_header_ver) PNGARG((png_structp png_ptr)); +extern PNG_EXPORT(png_charp,png_get_header_version) PNGARG((png_structp png_ptr)); +extern PNG_EXPORT(png_charp,png_get_libpng_ver) PNGARG((png_structp png_ptr)); + +#ifdef PNG_MNG_FEATURES_SUPPORTED +extern PNG_EXPORT(png_uint_32,png_permit_mng_features) PNGARG((png_structp + png_ptr, png_uint_32 mng_features_permitted)); +#endif + +/* For use in png_set_keep_unknown, added to version 1.2.6 */ +#define PNG_HANDLE_CHUNK_AS_DEFAULT 0 +#define PNG_HANDLE_CHUNK_NEVER 1 +#define PNG_HANDLE_CHUNK_IF_SAFE 2 +#define PNG_HANDLE_CHUNK_ALWAYS 3 + +/* Added to version 1.2.0 */ +#if defined(PNG_ASSEMBLER_CODE_SUPPORTED) +#if defined(PNG_MMX_CODE_SUPPORTED) +#define PNG_ASM_FLAG_MMX_SUPPORT_COMPILED 0x01 /* not user-settable */ +#define PNG_ASM_FLAG_MMX_SUPPORT_IN_CPU 0x02 /* not user-settable */ +#define PNG_ASM_FLAG_MMX_READ_COMBINE_ROW 0x04 +#define PNG_ASM_FLAG_MMX_READ_INTERLACE 0x08 +#define PNG_ASM_FLAG_MMX_READ_FILTER_SUB 0x10 +#define PNG_ASM_FLAG_MMX_READ_FILTER_UP 0x20 +#define PNG_ASM_FLAG_MMX_READ_FILTER_AVG 0x40 +#define PNG_ASM_FLAG_MMX_READ_FILTER_PAETH 0x80 +#define PNG_ASM_FLAGS_INITIALIZED 0x80000000 /* not user-settable */ + +#define PNG_MMX_READ_FLAGS ( PNG_ASM_FLAG_MMX_READ_COMBINE_ROW \ + | PNG_ASM_FLAG_MMX_READ_INTERLACE \ + | PNG_ASM_FLAG_MMX_READ_FILTER_SUB \ + | PNG_ASM_FLAG_MMX_READ_FILTER_UP \ + | PNG_ASM_FLAG_MMX_READ_FILTER_AVG \ + | PNG_ASM_FLAG_MMX_READ_FILTER_PAETH ) +#define PNG_MMX_WRITE_FLAGS ( 0 ) + +#define PNG_MMX_FLAGS ( PNG_ASM_FLAG_MMX_SUPPORT_COMPILED \ + | PNG_ASM_FLAG_MMX_SUPPORT_IN_CPU \ + | PNG_MMX_READ_FLAGS \ + | PNG_MMX_WRITE_FLAGS ) + +#define PNG_SELECT_READ 1 +#define PNG_SELECT_WRITE 2 +#endif /* PNG_MMX_CODE_SUPPORTED */ + +#if !defined(PNG_1_0_X) +/* pngget.c */ +extern PNG_EXPORT(png_uint_32,png_get_mmx_flagmask) + PNGARG((int flag_select, int *compilerID)); + +/* pngget.c */ +extern PNG_EXPORT(png_uint_32,png_get_asm_flagmask) + PNGARG((int flag_select)); + +/* pngget.c */ +extern PNG_EXPORT(png_uint_32,png_get_asm_flags) + PNGARG((png_structp png_ptr)); + +/* pngget.c */ +extern PNG_EXPORT(png_byte,png_get_mmx_bitdepth_threshold) + PNGARG((png_structp png_ptr)); + +/* pngget.c */ +extern PNG_EXPORT(png_uint_32,png_get_mmx_rowbytes_threshold) + PNGARG((png_structp png_ptr)); + +/* pngset.c */ +extern PNG_EXPORT(void,png_set_asm_flags) + PNGARG((png_structp png_ptr, png_uint_32 asm_flags)); + +/* pngset.c */ +extern PNG_EXPORT(void,png_set_mmx_thresholds) + PNGARG((png_structp png_ptr, png_byte mmx_bitdepth_threshold, + png_uint_32 mmx_rowbytes_threshold)); + +#endif /* PNG_1_0_X */ + +#if !defined(PNG_1_0_X) +/* png.c, pnggccrd.c, or pngvcrd.c */ +extern PNG_EXPORT(int,png_mmx_support) PNGARG((void)); +#endif /* PNG_ASSEMBLER_CODE_SUPPORTED */ + +/* Strip the prepended error numbers ("#nnn ") from error and warning + * messages before passing them to the error or warning handler. */ +#ifdef PNG_ERROR_NUMBERS_SUPPORTED +extern PNG_EXPORT(void,png_set_strip_error_numbers) PNGARG((png_structp + png_ptr, png_uint_32 strip_mode)); +#endif + +#endif /* PNG_1_0_X */ + +/* Added at libpng-1.2.6 */ +#ifdef PNG_SET_USER_LIMITS_SUPPORTED +extern PNG_EXPORT(void,png_set_user_limits) PNGARG((png_structp + png_ptr, png_uint_32 user_width_max, png_uint_32 user_height_max)); +extern PNG_EXPORT(png_uint_32,png_get_user_width_max) PNGARG((png_structp + png_ptr)); +extern PNG_EXPORT(png_uint_32,png_get_user_height_max) PNGARG((png_structp + png_ptr)); +#endif + +/* Maintainer: Put new public prototypes here ^, in libpng.3, and project defs */ + +#ifdef PNG_READ_COMPOSITE_NODIV_SUPPORTED +/* With these routines we avoid an integer divide, which will be slower on + * most machines. However, it does take more operations than the corresponding + * divide method, so it may be slower on a few RISC systems. There are two + * shifts (by 8 or 16 bits) and an addition, versus a single integer divide. + * + * Note that the rounding factors are NOT supposed to be the same! 128 and + * 32768 are correct for the NODIV code; 127 and 32767 are correct for the + * standard method. + * + * [Optimized code by Greg Roelofs and Mark Adler...blame us for bugs. :-) ] + */ + + /* fg and bg should be in `gamma 1.0' space; alpha is the opacity */ + +# define png_composite(composite, fg, alpha, bg) \ + { png_uint_16 temp = (png_uint_16)((png_uint_16)(fg) * (png_uint_16)(alpha) \ + + (png_uint_16)(bg)*(png_uint_16)(255 - \ + (png_uint_16)(alpha)) + (png_uint_16)128); \ + (composite) = (png_byte)((temp + (temp >> 8)) >> 8); } + +# define png_composite_16(composite, fg, alpha, bg) \ + { png_uint_32 temp = (png_uint_32)((png_uint_32)(fg) * (png_uint_32)(alpha) \ + + (png_uint_32)(bg)*(png_uint_32)(65535L - \ + (png_uint_32)(alpha)) + (png_uint_32)32768L); \ + (composite) = (png_uint_16)((temp + (temp >> 16)) >> 16); } + +#else /* standard method using integer division */ + +# define png_composite(composite, fg, alpha, bg) \ + (composite) = (png_byte)(((png_uint_16)(fg) * (png_uint_16)(alpha) + \ + (png_uint_16)(bg) * (png_uint_16)(255 - (png_uint_16)(alpha)) + \ + (png_uint_16)127) / 255) + +# define png_composite_16(composite, fg, alpha, bg) \ + (composite) = (png_uint_16)(((png_uint_32)(fg) * (png_uint_32)(alpha) + \ + (png_uint_32)(bg)*(png_uint_32)(65535L - (png_uint_32)(alpha)) + \ + (png_uint_32)32767) / (png_uint_32)65535L) + +#endif /* PNG_READ_COMPOSITE_NODIV_SUPPORTED */ + +/* Inline macros to do direct reads of bytes from the input buffer. These + * require that you are using an architecture that uses PNG byte ordering + * (MSB first) and supports unaligned data storage. I think that PowerPC + * in big-endian mode and 680x0 are the only ones that will support this. + * The x86 line of processors definitely do not. The png_get_int_32() + * routine also assumes we are using two's complement format for negative + * values, which is almost certainly true. + */ +#if defined(PNG_READ_BIG_ENDIAN_SUPPORTED) +# define png_get_uint_32(buf) ( *((png_uint_32p) (buf))) +# define png_get_uint_16(buf) ( *((png_uint_16p) (buf))) +# define png_get_int_32(buf) ( *((png_int_32p) (buf))) +#else +extern PNG_EXPORT(png_uint_32,png_get_uint_32) PNGARG((png_bytep buf)); +extern PNG_EXPORT(png_uint_16,png_get_uint_16) PNGARG((png_bytep buf)); +extern PNG_EXPORT(png_int_32,png_get_int_32) PNGARG((png_bytep buf)); +#endif /* !PNG_READ_BIG_ENDIAN_SUPPORTED */ +extern PNG_EXPORT(png_uint_32,png_get_uint_31) + PNGARG((png_structp png_ptr, png_bytep buf)); +/* No png_get_int_16 -- may be added if there's a real need for it. */ + +/* Place a 32-bit number into a buffer in PNG byte order (big-endian). + */ +extern PNG_EXPORT(void,png_save_uint_32) + PNGARG((png_bytep buf, png_uint_32 i)); +extern PNG_EXPORT(void,png_save_int_32) + PNGARG((png_bytep buf, png_int_32 i)); + +/* Place a 16-bit number into a buffer in PNG byte order. + * The parameter is declared unsigned int, not png_uint_16, + * just to avoid potential problems on pre-ANSI C compilers. + */ +extern PNG_EXPORT(void,png_save_uint_16) + PNGARG((png_bytep buf, unsigned int i)); +/* No png_save_int_16 -- may be added if there's a real need for it. */ + +/* ************************************************************************* */ + +/* These next functions are used internally in the code. They generally + * shouldn't be used unless you are writing code to add or replace some + * functionality in libpng. More information about most functions can + * be found in the files where the functions are located. + */ + + +/* Various modes of operation, that are visible to applications because + * they are used for unknown chunk location. + */ +#define PNG_HAVE_IHDR 0x01 +#define PNG_HAVE_PLTE 0x02 +#define PNG_HAVE_IDAT 0x04 +#define PNG_AFTER_IDAT 0x08 /* Have complete zlib datastream */ +#define PNG_HAVE_IEND 0x10 + +#if defined(PNG_INTERNAL) + +/* More modes of operation. Note that after an init, mode is set to + * zero automatically when the structure is created. + */ +#define PNG_HAVE_gAMA 0x20 +#define PNG_HAVE_cHRM 0x40 +#define PNG_HAVE_sRGB 0x80 +#define PNG_HAVE_CHUNK_HEADER 0x100 +#define PNG_WROTE_tIME 0x200 +#define PNG_WROTE_INFO_BEFORE_PLTE 0x400 +#define PNG_BACKGROUND_IS_GRAY 0x800 +#define PNG_HAVE_PNG_SIGNATURE 0x1000 +#define PNG_HAVE_CHUNK_AFTER_IDAT 0x2000 /* Have another chunk after IDAT */ + +/* flags for the transformations the PNG library does on the image data */ +#define PNG_BGR 0x0001 +#define PNG_INTERLACE 0x0002 +#define PNG_PACK 0x0004 +#define PNG_SHIFT 0x0008 +#define PNG_SWAP_BYTES 0x0010 +#define PNG_INVERT_MONO 0x0020 +#define PNG_DITHER 0x0040 +#define PNG_BACKGROUND 0x0080 +#define PNG_BACKGROUND_EXPAND 0x0100 + /* 0x0200 unused */ +#define PNG_16_TO_8 0x0400 +#define PNG_RGBA 0x0800 +#define PNG_EXPAND 0x1000 +#define PNG_GAMMA 0x2000 +#define PNG_GRAY_TO_RGB 0x4000 +#define PNG_FILLER 0x8000L +#define PNG_PACKSWAP 0x10000L +#define PNG_SWAP_ALPHA 0x20000L +#define PNG_STRIP_ALPHA 0x40000L +#define PNG_INVERT_ALPHA 0x80000L +#define PNG_USER_TRANSFORM 0x100000L +#define PNG_RGB_TO_GRAY_ERR 0x200000L +#define PNG_RGB_TO_GRAY_WARN 0x400000L +#define PNG_RGB_TO_GRAY 0x600000L /* two bits, RGB_TO_GRAY_ERR|WARN */ + /* 0x800000L Unused */ +#define PNG_ADD_ALPHA 0x1000000L /* Added to libpng-1.2.7 */ +#define PNG_EXPAND_tRNS 0x2000000L /* Added to libpng-1.2.9 */ + /* 0x4000000L unused */ + /* 0x8000000L unused */ + /* 0x10000000L unused */ + /* 0x20000000L unused */ + /* 0x40000000L unused */ + +/* flags for png_create_struct */ +#define PNG_STRUCT_PNG 0x0001 +#define PNG_STRUCT_INFO 0x0002 + +/* Scaling factor for filter heuristic weighting calculations */ +#define PNG_WEIGHT_SHIFT 8 +#define PNG_WEIGHT_FACTOR (1<<(PNG_WEIGHT_SHIFT)) +#define PNG_COST_SHIFT 3 +#define PNG_COST_FACTOR (1<<(PNG_COST_SHIFT)) + +/* flags for the png_ptr->flags rather than declaring a byte for each one */ +#define PNG_FLAG_ZLIB_CUSTOM_STRATEGY 0x0001 +#define PNG_FLAG_ZLIB_CUSTOM_LEVEL 0x0002 +#define PNG_FLAG_ZLIB_CUSTOM_MEM_LEVEL 0x0004 +#define PNG_FLAG_ZLIB_CUSTOM_WINDOW_BITS 0x0008 +#define PNG_FLAG_ZLIB_CUSTOM_METHOD 0x0010 +#define PNG_FLAG_ZLIB_FINISHED 0x0020 +#define PNG_FLAG_ROW_INIT 0x0040 +#define PNG_FLAG_FILLER_AFTER 0x0080 +#define PNG_FLAG_CRC_ANCILLARY_USE 0x0100 +#define PNG_FLAG_CRC_ANCILLARY_NOWARN 0x0200 +#define PNG_FLAG_CRC_CRITICAL_USE 0x0400 +#define PNG_FLAG_CRC_CRITICAL_IGNORE 0x0800 +#define PNG_FLAG_FREE_PLTE 0x1000 +#define PNG_FLAG_FREE_TRNS 0x2000 +#define PNG_FLAG_FREE_HIST 0x4000 +#define PNG_FLAG_KEEP_UNKNOWN_CHUNKS 0x8000L +#define PNG_FLAG_KEEP_UNSAFE_CHUNKS 0x10000L +#define PNG_FLAG_LIBRARY_MISMATCH 0x20000L +#define PNG_FLAG_STRIP_ERROR_NUMBERS 0x40000L +#define PNG_FLAG_STRIP_ERROR_TEXT 0x80000L +#define PNG_FLAG_MALLOC_NULL_MEM_OK 0x100000L +#define PNG_FLAG_ADD_ALPHA 0x200000L /* Added to libpng-1.2.8 */ +#define PNG_FLAG_STRIP_ALPHA 0x400000L /* Added to libpng-1.2.8 */ + /* 0x800000L unused */ + /* 0x1000000L unused */ + /* 0x2000000L unused */ + /* 0x4000000L unused */ + /* 0x8000000L unused */ + /* 0x10000000L unused */ + /* 0x20000000L unused */ + /* 0x40000000L unused */ + +#define PNG_FLAG_CRC_ANCILLARY_MASK (PNG_FLAG_CRC_ANCILLARY_USE | \ + PNG_FLAG_CRC_ANCILLARY_NOWARN) + +#define PNG_FLAG_CRC_CRITICAL_MASK (PNG_FLAG_CRC_CRITICAL_USE | \ + PNG_FLAG_CRC_CRITICAL_IGNORE) + +#define PNG_FLAG_CRC_MASK (PNG_FLAG_CRC_ANCILLARY_MASK | \ + PNG_FLAG_CRC_CRITICAL_MASK) + +/* save typing and make code easier to understand */ + +#define PNG_COLOR_DIST(c1, c2) (abs((int)((c1).red) - (int)((c2).red)) + \ + abs((int)((c1).green) - (int)((c2).green)) + \ + abs((int)((c1).blue) - (int)((c2).blue))) + +/* Added to libpng-1.2.6 JB */ +#define PNG_ROWBYTES(pixel_bits, width) \ + ((pixel_bits) >= 8 ? \ + ((width) * (((png_uint_32)(pixel_bits)) >> 3)) : \ + (( ((width) * ((png_uint_32)(pixel_bits))) + 7) >> 3) ) + +/* PNG_OUT_OF_RANGE returns true if value is outside the range + ideal-delta..ideal+delta. Each argument is evaluated twice. + "ideal" and "delta" should be constants, normally simple + integers, "value" a variable. Added to libpng-1.2.6 JB */ +#define PNG_OUT_OF_RANGE(value, ideal, delta) \ + ( (value) < (ideal)-(delta) || (value) > (ideal)+(delta) ) + +/* variables declared in png.c - only it needs to define PNG_NO_EXTERN */ +#if !defined(PNG_NO_EXTERN) || defined(PNG_ALWAYS_EXTERN) +/* place to hold the signature string for a PNG file. */ +#ifdef PNG_USE_GLOBAL_ARRAYS + PNG_EXPORT_VAR (PNG_CONST png_byte FARDATA) png_sig[8]; +#else +#endif +#endif /* PNG_NO_EXTERN */ + +/* Constant strings for known chunk types. If you need to add a chunk, + * define the name here, and add an invocation of the macro in png.c and + * wherever it's needed. + */ +#define PNG_IHDR png_byte png_IHDR[5] = { 73, 72, 68, 82, '\0'} +#define PNG_IDAT png_byte png_IDAT[5] = { 73, 68, 65, 84, '\0'} +#define PNG_IEND png_byte png_IEND[5] = { 73, 69, 78, 68, '\0'} +#define PNG_PLTE png_byte png_PLTE[5] = { 80, 76, 84, 69, '\0'} +#define PNG_bKGD png_byte png_bKGD[5] = { 98, 75, 71, 68, '\0'} +#define PNG_cHRM png_byte png_cHRM[5] = { 99, 72, 82, 77, '\0'} +#define PNG_gAMA png_byte png_gAMA[5] = {103, 65, 77, 65, '\0'} +#define PNG_hIST png_byte png_hIST[5] = {104, 73, 83, 84, '\0'} +#define PNG_iCCP png_byte png_iCCP[5] = {105, 67, 67, 80, '\0'} +#define PNG_iTXt png_byte png_iTXt[5] = {105, 84, 88, 116, '\0'} +#define PNG_oFFs png_byte png_oFFs[5] = {111, 70, 70, 115, '\0'} +#define PNG_pCAL png_byte png_pCAL[5] = {112, 67, 65, 76, '\0'} +#define PNG_sCAL png_byte png_sCAL[5] = {115, 67, 65, 76, '\0'} +#define PNG_pHYs png_byte png_pHYs[5] = {112, 72, 89, 115, '\0'} +#define PNG_sBIT png_byte png_sBIT[5] = {115, 66, 73, 84, '\0'} +#define PNG_sPLT png_byte png_sPLT[5] = {115, 80, 76, 84, '\0'} +#define PNG_sRGB png_byte png_sRGB[5] = {115, 82, 71, 66, '\0'} +#define PNG_tEXt png_byte png_tEXt[5] = {116, 69, 88, 116, '\0'} +#define PNG_tIME png_byte png_tIME[5] = {116, 73, 77, 69, '\0'} +#define PNG_tRNS png_byte png_tRNS[5] = {116, 82, 78, 83, '\0'} +#define PNG_zTXt png_byte png_zTXt[5] = {122, 84, 88, 116, '\0'} + +#ifdef PNG_USE_GLOBAL_ARRAYS +PNG_EXPORT_VAR (png_byte FARDATA) png_IHDR[5]; +PNG_EXPORT_VAR (png_byte FARDATA) png_IDAT[5]; +PNG_EXPORT_VAR (png_byte FARDATA) png_IEND[5]; +PNG_EXPORT_VAR (png_byte FARDATA) png_PLTE[5]; +PNG_EXPORT_VAR (png_byte FARDATA) png_bKGD[5]; +PNG_EXPORT_VAR (png_byte FARDATA) png_cHRM[5]; +PNG_EXPORT_VAR (png_byte FARDATA) png_gAMA[5]; +PNG_EXPORT_VAR (png_byte FARDATA) png_hIST[5]; +PNG_EXPORT_VAR (png_byte FARDATA) png_iCCP[5]; +PNG_EXPORT_VAR (png_byte FARDATA) png_iTXt[5]; +PNG_EXPORT_VAR (png_byte FARDATA) png_oFFs[5]; +PNG_EXPORT_VAR (png_byte FARDATA) png_pCAL[5]; +PNG_EXPORT_VAR (png_byte FARDATA) png_sCAL[5]; +PNG_EXPORT_VAR (png_byte FARDATA) png_pHYs[5]; +PNG_EXPORT_VAR (png_byte FARDATA) png_sBIT[5]; +PNG_EXPORT_VAR (png_byte FARDATA) png_sPLT[5]; +PNG_EXPORT_VAR (png_byte FARDATA) png_sRGB[5]; +PNG_EXPORT_VAR (png_byte FARDATA) png_tEXt[5]; +PNG_EXPORT_VAR (png_byte FARDATA) png_tIME[5]; +PNG_EXPORT_VAR (png_byte FARDATA) png_tRNS[5]; +PNG_EXPORT_VAR (png_byte FARDATA) png_zTXt[5]; +#endif /* PNG_USE_GLOBAL_ARRAYS */ + +#if defined(PNG_1_0_X) || defined (PNG_1_2_X) +/* Initialize png_ptr struct for reading, and allocate any other memory. + * (old interface - DEPRECATED - use png_create_read_struct instead). + */ +extern PNG_EXPORT(void,png_read_init) PNGARG((png_structp png_ptr)); +#undef png_read_init +#define png_read_init(png_ptr) png_read_init_3(&png_ptr, \ + PNG_LIBPNG_VER_STRING, png_sizeof(png_struct)); +#endif + +extern PNG_EXPORT(void,png_read_init_3) PNGARG((png_structpp ptr_ptr, + png_const_charp user_png_ver, png_size_t png_struct_size)); +#if defined(PNG_1_0_X) || defined (PNG_1_2_X) +extern PNG_EXPORT(void,png_read_init_2) PNGARG((png_structp png_ptr, + png_const_charp user_png_ver, png_size_t png_struct_size, png_size_t + png_info_size)); +#endif + +#if defined(PNG_1_0_X) || defined (PNG_1_2_X) +/* Initialize png_ptr struct for writing, and allocate any other memory. + * (old interface - DEPRECATED - use png_create_write_struct instead). + */ +extern PNG_EXPORT(void,png_write_init) PNGARG((png_structp png_ptr)); +#undef png_write_init +#define png_write_init(png_ptr) png_write_init_3(&png_ptr, \ + PNG_LIBPNG_VER_STRING, png_sizeof(png_struct)); +#endif + +extern PNG_EXPORT(void,png_write_init_3) PNGARG((png_structpp ptr_ptr, + png_const_charp user_png_ver, png_size_t png_struct_size)); +extern PNG_EXPORT(void,png_write_init_2) PNGARG((png_structp png_ptr, + png_const_charp user_png_ver, png_size_t png_struct_size, png_size_t + png_info_size)); + +/* Allocate memory for an internal libpng struct */ +PNG_EXTERN png_voidp png_create_struct PNGARG((int type)); + +/* Free memory from internal libpng struct */ +PNG_EXTERN void png_destroy_struct PNGARG((png_voidp struct_ptr)); + +PNG_EXTERN png_voidp png_create_struct_2 PNGARG((int type, png_malloc_ptr + malloc_fn, png_voidp mem_ptr)); +PNG_EXTERN void png_destroy_struct_2 PNGARG((png_voidp struct_ptr, + png_free_ptr free_fn, png_voidp mem_ptr)); + +/* Free any memory that info_ptr points to and reset struct. */ +PNG_EXTERN void png_info_destroy PNGARG((png_structp png_ptr, + png_infop info_ptr)); + +#ifndef PNG_1_0_X +/* Function to allocate memory for zlib. */ +PNG_EXTERN voidpf png_zalloc PNGARG((voidpf png_ptr, uInt items, uInt size)); + +/* Function to free memory for zlib */ +PNG_EXTERN void png_zfree PNGARG((voidpf png_ptr, voidpf ptr)); + +#ifdef PNG_SIZE_T +/* Function to convert a sizeof an item to png_sizeof item */ + PNG_EXTERN png_size_t PNGAPI png_convert_size PNGARG((size_t size)); +#endif + +/* Next four functions are used internally as callbacks. PNGAPI is required + * but not PNG_EXPORT. PNGAPI added at libpng version 1.2.3. */ + +PNG_EXTERN void PNGAPI png_default_read_data PNGARG((png_structp png_ptr, + png_bytep data, png_size_t length)); + +#ifdef PNG_PROGRESSIVE_READ_SUPPORTED +PNG_EXTERN void PNGAPI png_push_fill_buffer PNGARG((png_structp png_ptr, + png_bytep buffer, png_size_t length)); +#endif + +PNG_EXTERN void PNGAPI png_default_write_data PNGARG((png_structp png_ptr, + png_bytep data, png_size_t length)); + +#if defined(PNG_WRITE_FLUSH_SUPPORTED) +#if !defined(PNG_NO_STDIO) +PNG_EXTERN void PNGAPI png_default_flush PNGARG((png_structp png_ptr)); +#endif +#endif +#else /* PNG_1_0_X */ +#ifdef PNG_PROGRESSIVE_READ_SUPPORTED +PNG_EXTERN void png_push_fill_buffer PNGARG((png_structp png_ptr, + png_bytep buffer, png_size_t length)); +#endif +#endif /* PNG_1_0_X */ + +/* Reset the CRC variable */ +PNG_EXTERN void png_reset_crc PNGARG((png_structp png_ptr)); + +/* Write the "data" buffer to whatever output you are using. */ +PNG_EXTERN void png_write_data PNGARG((png_structp png_ptr, png_bytep data, + png_size_t length)); + +/* Read data from whatever input you are using into the "data" buffer */ +PNG_EXTERN void png_read_data PNGARG((png_structp png_ptr, png_bytep data, + png_size_t length)); + +/* Read bytes into buf, and update png_ptr->crc */ +PNG_EXTERN void png_crc_read PNGARG((png_structp png_ptr, png_bytep buf, + png_size_t length)); + +/* Decompress data in a chunk that uses compression */ +#if defined(PNG_zTXt_SUPPORTED) || defined(PNG_iTXt_SUPPORTED) || \ + defined(PNG_iCCP_SUPPORTED) || defined(PNG_sPLT_SUPPORTED) +PNG_EXTERN png_charp png_decompress_chunk PNGARG((png_structp png_ptr, + int comp_type, png_charp chunkdata, png_size_t chunklength, + png_size_t prefix_length, png_size_t *data_length)); +#endif + +/* Read "skip" bytes, read the file crc, and (optionally) verify png_ptr->crc */ +PNG_EXTERN int png_crc_finish PNGARG((png_structp png_ptr, png_uint_32 skip)); + +/* Read the CRC from the file and compare it to the libpng calculated CRC */ +PNG_EXTERN int png_crc_error PNGARG((png_structp png_ptr)); + +/* Calculate the CRC over a section of data. Note that we are only + * passing a maximum of 64K on systems that have this as a memory limit, + * since this is the maximum buffer size we can specify. + */ +PNG_EXTERN void png_calculate_crc PNGARG((png_structp png_ptr, png_bytep ptr, + png_size_t length)); + +#if defined(PNG_WRITE_FLUSH_SUPPORTED) +PNG_EXTERN void png_flush PNGARG((png_structp png_ptr)); +#endif + +/* simple function to write the signature */ +PNG_EXTERN void png_write_sig PNGARG((png_structp png_ptr)); + +/* write various chunks */ + +/* Write the IHDR chunk, and update the png_struct with the necessary + * information. + */ +PNG_EXTERN void png_write_IHDR PNGARG((png_structp png_ptr, png_uint_32 width, + png_uint_32 height, + int bit_depth, int color_type, int compression_method, int filter_method, + int interlace_method)); + +PNG_EXTERN void png_write_PLTE PNGARG((png_structp png_ptr, png_colorp palette, + png_uint_32 num_pal)); + +PNG_EXTERN void png_write_IDAT PNGARG((png_structp png_ptr, png_bytep data, + png_size_t length)); + +PNG_EXTERN void png_write_IEND PNGARG((png_structp png_ptr)); + +#if defined(PNG_WRITE_gAMA_SUPPORTED) +#ifdef PNG_FLOATING_POINT_SUPPORTED +PNG_EXTERN void png_write_gAMA PNGARG((png_structp png_ptr, double file_gamma)); +#endif +#ifdef PNG_FIXED_POINT_SUPPORTED +PNG_EXTERN void png_write_gAMA_fixed PNGARG((png_structp png_ptr, png_fixed_point + file_gamma)); +#endif +#endif + +#if defined(PNG_WRITE_sBIT_SUPPORTED) +PNG_EXTERN void png_write_sBIT PNGARG((png_structp png_ptr, png_color_8p sbit, + int color_type)); +#endif + +#if defined(PNG_WRITE_cHRM_SUPPORTED) +#ifdef PNG_FLOATING_POINT_SUPPORTED +PNG_EXTERN void png_write_cHRM PNGARG((png_structp png_ptr, + double white_x, double white_y, + double red_x, double red_y, double green_x, double green_y, + double blue_x, double blue_y)); +#endif +#ifdef PNG_FIXED_POINT_SUPPORTED +PNG_EXTERN void png_write_cHRM_fixed PNGARG((png_structp png_ptr, + png_fixed_point int_white_x, png_fixed_point int_white_y, + png_fixed_point int_red_x, png_fixed_point int_red_y, png_fixed_point + int_green_x, png_fixed_point int_green_y, png_fixed_point int_blue_x, + png_fixed_point int_blue_y)); +#endif +#endif + +#if defined(PNG_WRITE_sRGB_SUPPORTED) +PNG_EXTERN void png_write_sRGB PNGARG((png_structp png_ptr, + int intent)); +#endif + +#if defined(PNG_WRITE_iCCP_SUPPORTED) +PNG_EXTERN void png_write_iCCP PNGARG((png_structp png_ptr, + png_charp name, int compression_type, + png_charp profile, int proflen)); + /* Note to maintainer: profile should be png_bytep */ +#endif + +#if defined(PNG_WRITE_sPLT_SUPPORTED) +PNG_EXTERN void png_write_sPLT PNGARG((png_structp png_ptr, + png_sPLT_tp palette)); +#endif + +#if defined(PNG_WRITE_tRNS_SUPPORTED) +PNG_EXTERN void png_write_tRNS PNGARG((png_structp png_ptr, png_bytep trans, + png_color_16p values, int number, int color_type)); +#endif + +#if defined(PNG_WRITE_bKGD_SUPPORTED) +PNG_EXTERN void png_write_bKGD PNGARG((png_structp png_ptr, + png_color_16p values, int color_type)); +#endif + +#if defined(PNG_WRITE_hIST_SUPPORTED) +PNG_EXTERN void png_write_hIST PNGARG((png_structp png_ptr, png_uint_16p hist, + int num_hist)); +#endif + +#if defined(PNG_WRITE_TEXT_SUPPORTED) || defined(PNG_WRITE_pCAL_SUPPORTED) || \ + defined(PNG_WRITE_iCCP_SUPPORTED) || defined(PNG_WRITE_sPLT_SUPPORTED) +PNG_EXTERN png_size_t png_check_keyword PNGARG((png_structp png_ptr, + png_charp key, png_charpp new_key)); +#endif + +#if defined(PNG_WRITE_tEXt_SUPPORTED) +PNG_EXTERN void png_write_tEXt PNGARG((png_structp png_ptr, png_charp key, + png_charp text, png_size_t text_len)); +#endif + +#if defined(PNG_WRITE_zTXt_SUPPORTED) +PNG_EXTERN void png_write_zTXt PNGARG((png_structp png_ptr, png_charp key, + png_charp text, png_size_t text_len, int compression)); +#endif + +#if defined(PNG_WRITE_iTXt_SUPPORTED) +PNG_EXTERN void png_write_iTXt PNGARG((png_structp png_ptr, + int compression, png_charp key, png_charp lang, png_charp lang_key, + png_charp text)); +#endif + +#if defined(PNG_TEXT_SUPPORTED) /* Added at version 1.0.14 and 1.2.4 */ +PNG_EXTERN int png_set_text_2 PNGARG((png_structp png_ptr, + png_infop info_ptr, png_textp text_ptr, int num_text)); +#endif + +#if defined(PNG_WRITE_oFFs_SUPPORTED) +PNG_EXTERN void png_write_oFFs PNGARG((png_structp png_ptr, + png_int_32 x_offset, png_int_32 y_offset, int unit_type)); +#endif + +#if defined(PNG_WRITE_pCAL_SUPPORTED) +PNG_EXTERN void png_write_pCAL PNGARG((png_structp png_ptr, png_charp purpose, + png_int_32 X0, png_int_32 X1, int type, int nparams, + png_charp units, png_charpp params)); +#endif + +#if defined(PNG_WRITE_pHYs_SUPPORTED) +PNG_EXTERN void png_write_pHYs PNGARG((png_structp png_ptr, + png_uint_32 x_pixels_per_unit, png_uint_32 y_pixels_per_unit, + int unit_type)); +#endif + +#if defined(PNG_WRITE_tIME_SUPPORTED) +PNG_EXTERN void png_write_tIME PNGARG((png_structp png_ptr, + png_timep mod_time)); +#endif + +#if defined(PNG_WRITE_sCAL_SUPPORTED) +#if defined(PNG_FLOATING_POINT_SUPPORTED) && !defined(PNG_NO_STDIO) +PNG_EXTERN void png_write_sCAL PNGARG((png_structp png_ptr, + int unit, double width, double height)); +#else +#ifdef PNG_FIXED_POINT_SUPPORTED +PNG_EXTERN void png_write_sCAL_s PNGARG((png_structp png_ptr, + int unit, png_charp width, png_charp height)); +#endif +#endif +#endif + +/* Called when finished processing a row of data */ +PNG_EXTERN void png_write_finish_row PNGARG((png_structp png_ptr)); + +/* Internal use only. Called before first row of data */ +PNG_EXTERN void png_write_start_row PNGARG((png_structp png_ptr)); + +#if defined(PNG_READ_GAMMA_SUPPORTED) +PNG_EXTERN void png_build_gamma_table PNGARG((png_structp png_ptr)); +#endif + +/* combine a row of data, dealing with alpha, etc. if requested */ +PNG_EXTERN void png_combine_row PNGARG((png_structp png_ptr, png_bytep row, + int mask)); + +#if defined(PNG_READ_INTERLACING_SUPPORTED) +/* expand an interlaced row */ +/* OLD pre-1.0.9 interface: +PNG_EXTERN void png_do_read_interlace PNGARG((png_row_infop row_info, + png_bytep row, int pass, png_uint_32 transformations)); + */ +PNG_EXTERN void png_do_read_interlace PNGARG((png_structp png_ptr)); +#endif + +/* GRR TO DO (2.0 or whenever): simplify other internal calling interfaces */ + +#if defined(PNG_WRITE_INTERLACING_SUPPORTED) +/* grab pixels out of a row for an interlaced pass */ +PNG_EXTERN void png_do_write_interlace PNGARG((png_row_infop row_info, + png_bytep row, int pass)); +#endif + +/* unfilter a row */ +PNG_EXTERN void png_read_filter_row PNGARG((png_structp png_ptr, + png_row_infop row_info, png_bytep row, png_bytep prev_row, int filter)); + +/* Choose the best filter to use and filter the row data */ +PNG_EXTERN void png_write_find_filter PNGARG((png_structp png_ptr, + png_row_infop row_info)); + +/* Write out the filtered row. */ +PNG_EXTERN void png_write_filtered_row PNGARG((png_structp png_ptr, + png_bytep filtered_row)); +/* finish a row while reading, dealing with interlacing passes, etc. */ +PNG_EXTERN void png_read_finish_row PNGARG((png_structp png_ptr)); + +/* initialize the row buffers, etc. */ +PNG_EXTERN void png_read_start_row PNGARG((png_structp png_ptr)); +/* optional call to update the users info structure */ +PNG_EXTERN void png_read_transform_info PNGARG((png_structp png_ptr, + png_infop info_ptr)); + +/* these are the functions that do the transformations */ +#if defined(PNG_READ_FILLER_SUPPORTED) +PNG_EXTERN void png_do_read_filler PNGARG((png_row_infop row_info, + png_bytep row, png_uint_32 filler, png_uint_32 flags)); +#endif + +#if defined(PNG_READ_SWAP_ALPHA_SUPPORTED) +PNG_EXTERN void png_do_read_swap_alpha PNGARG((png_row_infop row_info, + png_bytep row)); +#endif + +#if defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED) +PNG_EXTERN void png_do_write_swap_alpha PNGARG((png_row_infop row_info, + png_bytep row)); +#endif + +#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED) +PNG_EXTERN void png_do_read_invert_alpha PNGARG((png_row_infop row_info, + png_bytep row)); +#endif + +#if defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED) +PNG_EXTERN void png_do_write_invert_alpha PNGARG((png_row_infop row_info, + png_bytep row)); +#endif + +#if defined(PNG_WRITE_FILLER_SUPPORTED) || \ + defined(PNG_READ_STRIP_ALPHA_SUPPORTED) +PNG_EXTERN void png_do_strip_filler PNGARG((png_row_infop row_info, + png_bytep row, png_uint_32 flags)); +#endif + +#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED) +PNG_EXTERN void png_do_swap PNGARG((png_row_infop row_info, png_bytep row)); +#endif + +#if defined(PNG_READ_PACKSWAP_SUPPORTED) || defined(PNG_WRITE_PACKSWAP_SUPPORTED) +PNG_EXTERN void png_do_packswap PNGARG((png_row_infop row_info, png_bytep row)); +#endif + +#if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED) +PNG_EXTERN int png_do_rgb_to_gray PNGARG((png_structp png_ptr, png_row_infop + row_info, png_bytep row)); +#endif + +#if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED) +PNG_EXTERN void png_do_gray_to_rgb PNGARG((png_row_infop row_info, + png_bytep row)); +#endif + +#if defined(PNG_READ_PACK_SUPPORTED) +PNG_EXTERN void png_do_unpack PNGARG((png_row_infop row_info, png_bytep row)); +#endif + +#if defined(PNG_READ_SHIFT_SUPPORTED) +PNG_EXTERN void png_do_unshift PNGARG((png_row_infop row_info, png_bytep row, + png_color_8p sig_bits)); +#endif + +#if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED) +PNG_EXTERN void png_do_invert PNGARG((png_row_infop row_info, png_bytep row)); +#endif + +#if defined(PNG_READ_16_TO_8_SUPPORTED) +PNG_EXTERN void png_do_chop PNGARG((png_row_infop row_info, png_bytep row)); +#endif + +#if defined(PNG_READ_DITHER_SUPPORTED) +PNG_EXTERN void png_do_dither PNGARG((png_row_infop row_info, + png_bytep row, png_bytep palette_lookup, png_bytep dither_lookup)); + +# if defined(PNG_CORRECT_PALETTE_SUPPORTED) +PNG_EXTERN void png_correct_palette PNGARG((png_structp png_ptr, + png_colorp palette, int num_palette)); +# endif +#endif + +#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED) +PNG_EXTERN void png_do_bgr PNGARG((png_row_infop row_info, png_bytep row)); +#endif + +#if defined(PNG_WRITE_PACK_SUPPORTED) +PNG_EXTERN void png_do_pack PNGARG((png_row_infop row_info, + png_bytep row, png_uint_32 bit_depth)); +#endif + +#if defined(PNG_WRITE_SHIFT_SUPPORTED) +PNG_EXTERN void png_do_shift PNGARG((png_row_infop row_info, png_bytep row, + png_color_8p bit_depth)); +#endif + +#if defined(PNG_READ_BACKGROUND_SUPPORTED) +#if defined(PNG_READ_GAMMA_SUPPORTED) +PNG_EXTERN void png_do_background PNGARG((png_row_infop row_info, png_bytep row, + png_color_16p trans_values, png_color_16p background, + png_color_16p background_1, + png_bytep gamma_table, png_bytep gamma_from_1, png_bytep gamma_to_1, + png_uint_16pp gamma_16, png_uint_16pp gamma_16_from_1, + png_uint_16pp gamma_16_to_1, int gamma_shift)); +#else +PNG_EXTERN void png_do_background PNGARG((png_row_infop row_info, png_bytep row, + png_color_16p trans_values, png_color_16p background)); +#endif +#endif + +#if defined(PNG_READ_GAMMA_SUPPORTED) +PNG_EXTERN void png_do_gamma PNGARG((png_row_infop row_info, png_bytep row, + png_bytep gamma_table, png_uint_16pp gamma_16_table, + int gamma_shift)); +#endif + +#if defined(PNG_READ_EXPAND_SUPPORTED) +PNG_EXTERN void png_do_expand_palette PNGARG((png_row_infop row_info, + png_bytep row, png_colorp palette, png_bytep trans, int num_trans)); +PNG_EXTERN void png_do_expand PNGARG((png_row_infop row_info, + png_bytep row, png_color_16p trans_value)); +#endif + +/* The following decodes the appropriate chunks, and does error correction, + * then calls the appropriate callback for the chunk if it is valid. + */ + +/* decode the IHDR chunk */ +PNG_EXTERN void png_handle_IHDR PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); +PNG_EXTERN void png_handle_PLTE PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); +PNG_EXTERN void png_handle_IEND PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); + +#if defined(PNG_READ_bKGD_SUPPORTED) +PNG_EXTERN void png_handle_bKGD PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); +#endif + +#if defined(PNG_READ_cHRM_SUPPORTED) +PNG_EXTERN void png_handle_cHRM PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); +#endif + +#if defined(PNG_READ_gAMA_SUPPORTED) +PNG_EXTERN void png_handle_gAMA PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); +#endif + +#if defined(PNG_READ_hIST_SUPPORTED) +PNG_EXTERN void png_handle_hIST PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); +#endif + +#if defined(PNG_READ_iCCP_SUPPORTED) +extern void png_handle_iCCP PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); +#endif /* PNG_READ_iCCP_SUPPORTED */ + +#if defined(PNG_READ_iTXt_SUPPORTED) +PNG_EXTERN void png_handle_iTXt PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); +#endif + +#if defined(PNG_READ_oFFs_SUPPORTED) +PNG_EXTERN void png_handle_oFFs PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); +#endif + +#if defined(PNG_READ_pCAL_SUPPORTED) +PNG_EXTERN void png_handle_pCAL PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); +#endif + +#if defined(PNG_READ_pHYs_SUPPORTED) +PNG_EXTERN void png_handle_pHYs PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); +#endif + +#if defined(PNG_READ_sBIT_SUPPORTED) +PNG_EXTERN void png_handle_sBIT PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); +#endif + +#if defined(PNG_READ_sCAL_SUPPORTED) +PNG_EXTERN void png_handle_sCAL PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); +#endif + +#if defined(PNG_READ_sPLT_SUPPORTED) +extern void png_handle_sPLT PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); +#endif /* PNG_READ_sPLT_SUPPORTED */ + +#if defined(PNG_READ_sRGB_SUPPORTED) +PNG_EXTERN void png_handle_sRGB PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); +#endif + +#if defined(PNG_READ_tEXt_SUPPORTED) +PNG_EXTERN void png_handle_tEXt PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); +#endif + +#if defined(PNG_READ_tIME_SUPPORTED) +PNG_EXTERN void png_handle_tIME PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); +#endif + +#if defined(PNG_READ_tRNS_SUPPORTED) +PNG_EXTERN void png_handle_tRNS PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); +#endif + +#if defined(PNG_READ_zTXt_SUPPORTED) +PNG_EXTERN void png_handle_zTXt PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); +#endif + +PNG_EXTERN void png_handle_unknown PNGARG((png_structp png_ptr, + png_infop info_ptr, png_uint_32 length)); + +PNG_EXTERN void png_check_chunk_name PNGARG((png_structp png_ptr, + png_bytep chunk_name)); + +/* handle the transformations for reading and writing */ +PNG_EXTERN void png_do_read_transformations PNGARG((png_structp png_ptr)); +PNG_EXTERN void png_do_write_transformations PNGARG((png_structp png_ptr)); + +PNG_EXTERN void png_init_read_transformations PNGARG((png_structp png_ptr)); + +#ifdef PNG_PROGRESSIVE_READ_SUPPORTED +PNG_EXTERN void png_push_read_chunk PNGARG((png_structp png_ptr, + png_infop info_ptr)); +PNG_EXTERN void png_push_read_sig PNGARG((png_structp png_ptr, + png_infop info_ptr)); +PNG_EXTERN void png_push_check_crc PNGARG((png_structp png_ptr)); +PNG_EXTERN void png_push_crc_skip PNGARG((png_structp png_ptr, + png_uint_32 length)); +PNG_EXTERN void png_push_crc_finish PNGARG((png_structp png_ptr)); +PNG_EXTERN void png_push_save_buffer PNGARG((png_structp png_ptr)); +PNG_EXTERN void png_push_restore_buffer PNGARG((png_structp png_ptr, + png_bytep buffer, png_size_t buffer_length)); +PNG_EXTERN void png_push_read_IDAT PNGARG((png_structp png_ptr)); +PNG_EXTERN void png_process_IDAT_data PNGARG((png_structp png_ptr, + png_bytep buffer, png_size_t buffer_length)); +PNG_EXTERN void png_push_process_row PNGARG((png_structp png_ptr)); +PNG_EXTERN void png_push_handle_unknown PNGARG((png_structp png_ptr, + png_infop info_ptr, png_uint_32 length)); +PNG_EXTERN void png_push_have_info PNGARG((png_structp png_ptr, + png_infop info_ptr)); +PNG_EXTERN void png_push_have_end PNGARG((png_structp png_ptr, + png_infop info_ptr)); +PNG_EXTERN void png_push_have_row PNGARG((png_structp png_ptr, png_bytep row)); +PNG_EXTERN void png_push_read_end PNGARG((png_structp png_ptr, + png_infop info_ptr)); +PNG_EXTERN void png_process_some_data PNGARG((png_structp png_ptr, + png_infop info_ptr)); +PNG_EXTERN void png_read_push_finish_row PNGARG((png_structp png_ptr)); +#if defined(PNG_READ_tEXt_SUPPORTED) +PNG_EXTERN void png_push_handle_tEXt PNGARG((png_structp png_ptr, + png_infop info_ptr, png_uint_32 length)); +PNG_EXTERN void png_push_read_tEXt PNGARG((png_structp png_ptr, + png_infop info_ptr)); +#endif +#if defined(PNG_READ_zTXt_SUPPORTED) +PNG_EXTERN void png_push_handle_zTXt PNGARG((png_structp png_ptr, + png_infop info_ptr, png_uint_32 length)); +PNG_EXTERN void png_push_read_zTXt PNGARG((png_structp png_ptr, + png_infop info_ptr)); +#endif +#if defined(PNG_READ_iTXt_SUPPORTED) +PNG_EXTERN void png_push_handle_iTXt PNGARG((png_structp png_ptr, + png_infop info_ptr, png_uint_32 length)); +PNG_EXTERN void png_push_read_iTXt PNGARG((png_structp png_ptr, + png_infop info_ptr)); +#endif + +#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */ + +#ifdef PNG_MNG_FEATURES_SUPPORTED +PNG_EXTERN void png_do_read_intrapixel PNGARG((png_row_infop row_info, + png_bytep row)); +PNG_EXTERN void png_do_write_intrapixel PNGARG((png_row_infop row_info, + png_bytep row)); +#endif + +#if defined(PNG_ASSEMBLER_CODE_SUPPORTED) +#if defined(PNG_MMX_CODE_SUPPORTED) +/* png.c */ /* PRIVATE */ +PNG_EXTERN void png_init_mmx_flags PNGARG((png_structp png_ptr)); +#endif +#endif + +#if defined(PNG_INCH_CONVERSIONS) && defined(PNG_FLOATING_POINT_SUPPORTED) +PNG_EXTERN png_uint_32 png_get_pixels_per_inch PNGARG((png_structp png_ptr, +png_infop info_ptr)); + +PNG_EXTERN png_uint_32 png_get_x_pixels_per_inch PNGARG((png_structp png_ptr, +png_infop info_ptr)); + +PNG_EXTERN png_uint_32 png_get_y_pixels_per_inch PNGARG((png_structp png_ptr, +png_infop info_ptr)); + +PNG_EXTERN float png_get_x_offset_inches PNGARG((png_structp png_ptr, +png_infop info_ptr)); + +PNG_EXTERN float png_get_y_offset_inches PNGARG((png_structp png_ptr, +png_infop info_ptr)); + +#if defined(PNG_pHYs_SUPPORTED) +PNG_EXTERN png_uint_32 png_get_pHYs_dpi PNGARG((png_structp png_ptr, +png_infop info_ptr, png_uint_32 *res_x, png_uint_32 *res_y, int *unit_type)); +#endif /* PNG_pHYs_SUPPORTED */ +#endif /* PNG_INCH_CONVERSIONS && PNG_FLOATING_POINT_SUPPORTED */ + +/* Maintainer: Put new private prototypes here ^ and in libpngpf.3 */ + +#endif /* PNG_INTERNAL */ + +#ifdef __cplusplus +} +#endif + +#endif /* PNG_VERSION_INFO_ONLY */ +/* do not put anything past this line */ +#endif /* PNG_H */ diff --git a/CustomizeMiiInstaller/source/libpng/pngconf.h b/CustomizeMiiInstaller/source/libpng/pngconf.h new file mode 100644 index 0000000..06a182f --- /dev/null +++ b/CustomizeMiiInstaller/source/libpng/pngconf.h @@ -0,0 +1,1481 @@ + +/* pngconf.h - machine configurable file for libpng + * + * libpng version 1.2.29 - May 8, 2008 + * For conditions of distribution and use, see copyright notice in png.h + * Copyright (c) 1998-2008 Glenn Randers-Pehrson + * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) + * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) + */ + +/* Any machine specific code is near the front of this file, so if you + * are configuring libpng for a machine, you may want to read the section + * starting here down to where it starts to typedef png_color, png_text, + * and png_info. + */ + +#ifndef PNGCONF_H +#define PNGCONF_H + +#define PNG_1_2_X + +/* + * PNG_USER_CONFIG has to be defined on the compiler command line. This + * includes the resource compiler for Windows DLL configurations. + */ +#ifdef PNG_USER_CONFIG +# ifndef PNG_USER_PRIVATEBUILD +# define PNG_USER_PRIVATEBUILD +# endif +#include "pngusr.h" +#endif + +/* PNG_CONFIGURE_LIBPNG is set by the "configure" script. */ +#ifdef PNG_CONFIGURE_LIBPNG +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif +#endif + +/* + * Added at libpng-1.2.8 + * + * If you create a private DLL you need to define in "pngusr.h" the followings: + * #define PNG_USER_PRIVATEBUILD + * e.g. #define PNG_USER_PRIVATEBUILD "Build by MyCompany for xyz reasons." + * #define PNG_USER_DLLFNAME_POSTFIX + * e.g. // private DLL "libpng13gx.dll" + * #define PNG_USER_DLLFNAME_POSTFIX "gx" + * + * The following macros are also at your disposal if you want to complete the + * DLL VERSIONINFO structure. + * - PNG_USER_VERSIONINFO_COMMENTS + * - PNG_USER_VERSIONINFO_COMPANYNAME + * - PNG_USER_VERSIONINFO_LEGALTRADEMARKS + */ + +#ifdef __STDC__ +#ifdef SPECIALBUILD +# pragma message("PNG_LIBPNG_SPECIALBUILD (and deprecated SPECIALBUILD)\ + are now LIBPNG reserved macros. Use PNG_USER_PRIVATEBUILD instead.") +#endif + +#ifdef PRIVATEBUILD +# pragma message("PRIVATEBUILD is deprecated.\ + Use PNG_USER_PRIVATEBUILD instead.") +# define PNG_USER_PRIVATEBUILD PRIVATEBUILD +#endif +#endif /* __STDC__ */ + +#ifndef PNG_VERSION_INFO_ONLY + +/* End of material added to libpng-1.2.8 */ + +/* Added at libpng-1.2.19, removed at libpng-1.2.20 because it caused trouble + Restored at libpng-1.2.21 */ +#if !defined(PNG_NO_WARN_UNINITIALIZED_ROW) && \ + !defined(PNG_WARN_UNINITIALIZED_ROW) +# define PNG_WARN_UNINITIALIZED_ROW 1 +#endif +/* End of material added at libpng-1.2.19/1.2.21 */ + +/* This is the size of the compression buffer, and thus the size of + * an IDAT chunk. Make this whatever size you feel is best for your + * machine. One of these will be allocated per png_struct. When this + * is full, it writes the data to the disk, and does some other + * calculations. Making this an extremely small size will slow + * the library down, but you may want to experiment to determine + * where it becomes significant, if you are concerned with memory + * usage. Note that zlib allocates at least 32Kb also. For readers, + * this describes the size of the buffer available to read the data in. + * Unless this gets smaller than the size of a row (compressed), + * it should not make much difference how big this is. + */ + +#ifndef PNG_ZBUF_SIZE +# define PNG_ZBUF_SIZE 8192 +#endif + +/* Enable if you want a write-only libpng */ + +#ifndef PNG_NO_READ_SUPPORTED +# define PNG_READ_SUPPORTED +#endif + +/* Enable if you want a read-only libpng */ + +#ifndef PNG_NO_WRITE_SUPPORTED +# define PNG_WRITE_SUPPORTED +#endif + +/* Enabled by default in 1.2.0. You can disable this if you don't need to + support PNGs that are embedded in MNG datastreams */ +#if !defined(PNG_1_0_X) && !defined(PNG_NO_MNG_FEATURES) +# ifndef PNG_MNG_FEATURES_SUPPORTED +# define PNG_MNG_FEATURES_SUPPORTED +# endif +#endif + +#ifndef PNG_NO_FLOATING_POINT_SUPPORTED +# ifndef PNG_FLOATING_POINT_SUPPORTED +# define PNG_FLOATING_POINT_SUPPORTED +# endif +#endif + +/* If you are running on a machine where you cannot allocate more + * than 64K of memory at once, uncomment this. While libpng will not + * normally need that much memory in a chunk (unless you load up a very + * large file), zlib needs to know how big of a chunk it can use, and + * libpng thus makes sure to check any memory allocation to verify it + * will fit into memory. +#define PNG_MAX_MALLOC_64K + */ +#if defined(MAXSEG_64K) && !defined(PNG_MAX_MALLOC_64K) +# define PNG_MAX_MALLOC_64K +#endif + +/* Special munging to support doing things the 'cygwin' way: + * 'Normal' png-on-win32 defines/defaults: + * PNG_BUILD_DLL -- building dll + * PNG_USE_DLL -- building an application, linking to dll + * (no define) -- building static library, or building an + * application and linking to the static lib + * 'Cygwin' defines/defaults: + * PNG_BUILD_DLL -- (ignored) building the dll + * (no define) -- (ignored) building an application, linking to the dll + * PNG_STATIC -- (ignored) building the static lib, or building an + * application that links to the static lib. + * ALL_STATIC -- (ignored) building various static libs, or building an + * application that links to the static libs. + * Thus, + * a cygwin user should define either PNG_BUILD_DLL or PNG_STATIC, and + * this bit of #ifdefs will define the 'correct' config variables based on + * that. If a cygwin user *wants* to define 'PNG_USE_DLL' that's okay, but + * unnecessary. + * + * Also, the precedence order is: + * ALL_STATIC (since we can't #undef something outside our namespace) + * PNG_BUILD_DLL + * PNG_STATIC + * (nothing) == PNG_USE_DLL + * + * CYGWIN (2002-01-20): The preceding is now obsolete. With the advent + * of auto-import in binutils, we no longer need to worry about + * __declspec(dllexport) / __declspec(dllimport) and friends. Therefore, + * we don't need to worry about PNG_STATIC or ALL_STATIC when it comes + * to __declspec() stuff. However, we DO need to worry about + * PNG_BUILD_DLL and PNG_STATIC because those change some defaults + * such as CONSOLE_IO and whether GLOBAL_ARRAYS are allowed. + */ +#if defined(__CYGWIN__) +# if defined(ALL_STATIC) +# if defined(PNG_BUILD_DLL) +# undef PNG_BUILD_DLL +# endif +# if defined(PNG_USE_DLL) +# undef PNG_USE_DLL +# endif +# if defined(PNG_DLL) +# undef PNG_DLL +# endif +# if !defined(PNG_STATIC) +# define PNG_STATIC +# endif +# else +# if defined (PNG_BUILD_DLL) +# if defined(PNG_STATIC) +# undef PNG_STATIC +# endif +# if defined(PNG_USE_DLL) +# undef PNG_USE_DLL +# endif +# if !defined(PNG_DLL) +# define PNG_DLL +# endif +# else +# if defined(PNG_STATIC) +# if defined(PNG_USE_DLL) +# undef PNG_USE_DLL +# endif +# if defined(PNG_DLL) +# undef PNG_DLL +# endif +# else +# if !defined(PNG_USE_DLL) +# define PNG_USE_DLL +# endif +# if !defined(PNG_DLL) +# define PNG_DLL +# endif +# endif +# endif +# endif +#endif + +/* This protects us against compilers that run on a windowing system + * and thus don't have or would rather us not use the stdio types: + * stdin, stdout, and stderr. The only one currently used is stderr + * in png_error() and png_warning(). #defining PNG_NO_CONSOLE_IO will + * prevent these from being compiled and used. #defining PNG_NO_STDIO + * will also prevent these, plus will prevent the entire set of stdio + * macros and functions (FILE *, printf, etc.) from being compiled and used, + * unless (PNG_DEBUG > 0) has been #defined. + * + * #define PNG_NO_CONSOLE_IO + * #define PNG_NO_STDIO + */ + +#if defined(_WIN32_WCE) +# include + /* Console I/O functions are not supported on WindowsCE */ +# define PNG_NO_CONSOLE_IO +# ifdef PNG_DEBUG +# undef PNG_DEBUG +# endif +#endif + +#ifdef PNG_BUILD_DLL +# ifndef PNG_CONSOLE_IO_SUPPORTED +# ifndef PNG_NO_CONSOLE_IO +# define PNG_NO_CONSOLE_IO +# endif +# endif +#endif + +# ifdef PNG_NO_STDIO +# ifndef PNG_NO_CONSOLE_IO +# define PNG_NO_CONSOLE_IO +# endif +# ifdef PNG_DEBUG +# if (PNG_DEBUG > 0) +# include +# endif +# endif +# else +# if !defined(_WIN32_WCE) +/* "stdio.h" functions are not supported on WindowsCE */ +# include +# endif +# endif + +/* This macro protects us against machines that don't have function + * prototypes (ie K&R style headers). If your compiler does not handle + * function prototypes, define this macro and use the included ansi2knr. + * I've always been able to use _NO_PROTO as the indicator, but you may + * need to drag the empty declaration out in front of here, or change the + * ifdef to suit your own needs. + */ +#ifndef PNGARG + +#ifdef OF /* zlib prototype munger */ +# define PNGARG(arglist) OF(arglist) +#else + +#ifdef _NO_PROTO +# define PNGARG(arglist) () +# ifndef PNG_TYPECAST_NULL +# define PNG_TYPECAST_NULL +# endif +#else +# define PNGARG(arglist) arglist +#endif /* _NO_PROTO */ + + +#endif /* OF */ + +#endif /* PNGARG */ + +/* Try to determine if we are compiling on a Mac. Note that testing for + * just __MWERKS__ is not good enough, because the Codewarrior is now used + * on non-Mac platforms. + */ +#ifndef MACOS +# if (defined(__MWERKS__) && defined(macintosh)) || defined(applec) || \ + defined(THINK_C) || defined(__SC__) || defined(TARGET_OS_MAC) +# define MACOS +# endif +#endif + +/* enough people need this for various reasons to include it here */ +#if !defined(MACOS) && !defined(RISCOS) && !defined(_WIN32_WCE) +# include +#endif + +#if !defined(PNG_SETJMP_NOT_SUPPORTED) && !defined(PNG_NO_SETJMP_SUPPORTED) +# define PNG_SETJMP_SUPPORTED +#endif + +#ifdef PNG_SETJMP_SUPPORTED +/* This is an attempt to force a single setjmp behaviour on Linux. If + * the X config stuff didn't define _BSD_SOURCE we wouldn't need this. + */ + +# ifdef __linux__ +# ifdef _BSD_SOURCE +# define PNG_SAVE_BSD_SOURCE +# undef _BSD_SOURCE +# endif +# ifdef _SETJMP_H + /* If you encounter a compiler error here, see the explanation + * near the end of INSTALL. + */ + __pngconf.h__ already includes setjmp.h; + __dont__ include it again.; +# endif +# endif /* __linux__ */ + + /* include setjmp.h for error handling */ +# include + +# ifdef __linux__ +# ifdef PNG_SAVE_BSD_SOURCE +# ifndef _BSD_SOURCE +# define _BSD_SOURCE +# endif +# undef PNG_SAVE_BSD_SOURCE +# endif +# endif /* __linux__ */ +#endif /* PNG_SETJMP_SUPPORTED */ + +#ifdef BSD +# include +#else +# include +#endif + +/* Other defines for things like memory and the like can go here. */ +#ifdef PNG_INTERNAL + +#include + +/* The functions exported by PNG_EXTERN are PNG_INTERNAL functions, which + * aren't usually used outside the library (as far as I know), so it is + * debatable if they should be exported at all. In the future, when it is + * possible to have run-time registry of chunk-handling functions, some of + * these will be made available again. +#define PNG_EXTERN extern + */ +#define PNG_EXTERN + +/* Other defines specific to compilers can go here. Try to keep + * them inside an appropriate ifdef/endif pair for portability. + */ + +#if defined(PNG_FLOATING_POINT_SUPPORTED) +# if defined(MACOS) + /* We need to check that hasn't already been included earlier + * as it seems it doesn't agree with , yet we should really use + * if possible. + */ +# if !defined(__MATH_H__) && !defined(__MATH_H) && !defined(__cmath__) +# include +# endif +# else +# include +# endif +# if defined(_AMIGA) && defined(__SASC) && defined(_M68881) + /* Amiga SAS/C: We must include builtin FPU functions when compiling using + * MATH=68881 + */ +# include +# endif +#endif + +/* Codewarrior on NT has linking problems without this. */ +#if (defined(__MWERKS__) && defined(WIN32)) || defined(__STDC__) +# define PNG_ALWAYS_EXTERN +#endif + +/* This provides the non-ANSI (far) memory allocation routines. */ +#if defined(__TURBOC__) && defined(__MSDOS__) +# include +# include +#endif + +/* I have no idea why is this necessary... */ +#if defined(_MSC_VER) && (defined(WIN32) || defined(_Windows) || \ + defined(_WINDOWS) || defined(_WIN32) || defined(__WIN32__)) +# include +#endif + +/* This controls how fine the dithering gets. As this allocates + * a largish chunk of memory (32K), those who are not as concerned + * with dithering quality can decrease some or all of these. + */ +#ifndef PNG_DITHER_RED_BITS +# define PNG_DITHER_RED_BITS 5 +#endif +#ifndef PNG_DITHER_GREEN_BITS +# define PNG_DITHER_GREEN_BITS 5 +#endif +#ifndef PNG_DITHER_BLUE_BITS +# define PNG_DITHER_BLUE_BITS 5 +#endif + +/* This controls how fine the gamma correction becomes when you + * are only interested in 8 bits anyway. Increasing this value + * results in more memory being used, and more pow() functions + * being called to fill in the gamma tables. Don't set this value + * less then 8, and even that may not work (I haven't tested it). + */ + +#ifndef PNG_MAX_GAMMA_8 +# define PNG_MAX_GAMMA_8 11 +#endif + +/* This controls how much a difference in gamma we can tolerate before + * we actually start doing gamma conversion. + */ +#ifndef PNG_GAMMA_THRESHOLD +# define PNG_GAMMA_THRESHOLD 0.05 +#endif + +#endif /* PNG_INTERNAL */ + +/* The following uses const char * instead of char * for error + * and warning message functions, so some compilers won't complain. + * If you do not want to use const, define PNG_NO_CONST here. + */ + +#ifndef PNG_NO_CONST +# define PNG_CONST const +#else +# define PNG_CONST +#endif + +/* The following defines give you the ability to remove code from the + * library that you will not be using. I wish I could figure out how to + * automate this, but I can't do that without making it seriously hard + * on the users. So if you are not using an ability, change the #define + * to and #undef, and that part of the library will not be compiled. If + * your linker can't find a function, you may want to make sure the + * ability is defined here. Some of these depend upon some others being + * defined. I haven't figured out all the interactions here, so you may + * have to experiment awhile to get everything to compile. If you are + * creating or using a shared library, you probably shouldn't touch this, + * as it will affect the size of the structures, and this will cause bad + * things to happen if the library and/or application ever change. + */ + +/* Any features you will not be using can be undef'ed here */ + +/* GR-P, 0.96a: Set "*TRANSFORMS_SUPPORTED as default but allow user + * to turn it off with "*TRANSFORMS_NOT_SUPPORTED" or *PNG_NO_*_TRANSFORMS + * on the compile line, then pick and choose which ones to define without + * having to edit this file. It is safe to use the *TRANSFORMS_NOT_SUPPORTED + * if you only want to have a png-compliant reader/writer but don't need + * any of the extra transformations. This saves about 80 kbytes in a + * typical installation of the library. (PNG_NO_* form added in version + * 1.0.1c, for consistency) + */ + +/* The size of the png_text structure changed in libpng-1.0.6 when + * iTXt support was added. iTXt support was turned off by default through + * libpng-1.2.x, to support old apps that malloc the png_text structure + * instead of calling png_set_text() and letting libpng malloc it. It + * was turned on by default in libpng-1.3.0. + */ + +#if defined(PNG_1_0_X) || defined (PNG_1_2_X) +# ifndef PNG_NO_iTXt_SUPPORTED +# define PNG_NO_iTXt_SUPPORTED +# endif +# ifndef PNG_NO_READ_iTXt +# define PNG_NO_READ_iTXt +# endif +# ifndef PNG_NO_WRITE_iTXt +# define PNG_NO_WRITE_iTXt +# endif +#endif + +#if !defined(PNG_NO_iTXt_SUPPORTED) +# if !defined(PNG_READ_iTXt_SUPPORTED) && !defined(PNG_NO_READ_iTXt) +# define PNG_READ_iTXt +# endif +# if !defined(PNG_WRITE_iTXt_SUPPORTED) && !defined(PNG_NO_WRITE_iTXt) +# define PNG_WRITE_iTXt +# endif +#endif + +/* The following support, added after version 1.0.0, can be turned off here en + * masse by defining PNG_LEGACY_SUPPORTED in case you need binary compatibility + * with old applications that require the length of png_struct and png_info + * to remain unchanged. + */ + +#ifdef PNG_LEGACY_SUPPORTED +# define PNG_NO_FREE_ME +# define PNG_NO_READ_UNKNOWN_CHUNKS +# define PNG_NO_WRITE_UNKNOWN_CHUNKS +# define PNG_NO_READ_USER_CHUNKS +# define PNG_NO_READ_iCCP +# define PNG_NO_WRITE_iCCP +# define PNG_NO_READ_iTXt +# define PNG_NO_WRITE_iTXt +# define PNG_NO_READ_sCAL +# define PNG_NO_WRITE_sCAL +# define PNG_NO_READ_sPLT +# define PNG_NO_WRITE_sPLT +# define PNG_NO_INFO_IMAGE +# define PNG_NO_READ_RGB_TO_GRAY +# define PNG_NO_READ_USER_TRANSFORM +# define PNG_NO_WRITE_USER_TRANSFORM +# define PNG_NO_USER_MEM +# define PNG_NO_READ_EMPTY_PLTE +# define PNG_NO_MNG_FEATURES +# define PNG_NO_FIXED_POINT_SUPPORTED +#endif + +/* Ignore attempt to turn off both floating and fixed point support */ +#if !defined(PNG_FLOATING_POINT_SUPPORTED) || \ + !defined(PNG_NO_FIXED_POINT_SUPPORTED) +# define PNG_FIXED_POINT_SUPPORTED +#endif + +#ifndef PNG_NO_FREE_ME +# define PNG_FREE_ME_SUPPORTED +#endif + +#if defined(PNG_READ_SUPPORTED) + +#if !defined(PNG_READ_TRANSFORMS_NOT_SUPPORTED) && \ + !defined(PNG_NO_READ_TRANSFORMS) +# define PNG_READ_TRANSFORMS_SUPPORTED +#endif + +#ifdef PNG_READ_TRANSFORMS_SUPPORTED +# ifndef PNG_NO_READ_EXPAND +# define PNG_READ_EXPAND_SUPPORTED +# endif +# ifndef PNG_NO_READ_SHIFT +# define PNG_READ_SHIFT_SUPPORTED +# endif +# ifndef PNG_NO_READ_PACK +# define PNG_READ_PACK_SUPPORTED +# endif +# ifndef PNG_NO_READ_BGR +# define PNG_READ_BGR_SUPPORTED +# endif +# ifndef PNG_NO_READ_SWAP +# define PNG_READ_SWAP_SUPPORTED +# endif +# ifndef PNG_NO_READ_PACKSWAP +# define PNG_READ_PACKSWAP_SUPPORTED +# endif +# ifndef PNG_NO_READ_INVERT +# define PNG_READ_INVERT_SUPPORTED +# endif +# ifndef PNG_NO_READ_DITHER +# define PNG_READ_DITHER_SUPPORTED +# endif +# ifndef PNG_NO_READ_BACKGROUND +# define PNG_READ_BACKGROUND_SUPPORTED +# endif +# ifndef PNG_NO_READ_16_TO_8 +# define PNG_READ_16_TO_8_SUPPORTED +# endif +# ifndef PNG_NO_READ_FILLER +# define PNG_READ_FILLER_SUPPORTED +# endif +# ifndef PNG_NO_READ_GAMMA +# define PNG_READ_GAMMA_SUPPORTED +# endif +# ifndef PNG_NO_READ_GRAY_TO_RGB +# define PNG_READ_GRAY_TO_RGB_SUPPORTED +# endif +# ifndef PNG_NO_READ_SWAP_ALPHA +# define PNG_READ_SWAP_ALPHA_SUPPORTED +# endif +# ifndef PNG_NO_READ_INVERT_ALPHA +# define PNG_READ_INVERT_ALPHA_SUPPORTED +# endif +# ifndef PNG_NO_READ_STRIP_ALPHA +# define PNG_READ_STRIP_ALPHA_SUPPORTED +# endif +# ifndef PNG_NO_READ_USER_TRANSFORM +# define PNG_READ_USER_TRANSFORM_SUPPORTED +# endif +# ifndef PNG_NO_READ_RGB_TO_GRAY +# define PNG_READ_RGB_TO_GRAY_SUPPORTED +# endif +#endif /* PNG_READ_TRANSFORMS_SUPPORTED */ + +#if !defined(PNG_NO_PROGRESSIVE_READ) && \ + !defined(PNG_PROGRESSIVE_READ_SUPPORTED) /* if you don't do progressive */ +# define PNG_PROGRESSIVE_READ_SUPPORTED /* reading. This is not talking */ +#endif /* about interlacing capability! You'll */ + /* still have interlacing unless you change the following line: */ + +#define PNG_READ_INTERLACING_SUPPORTED /* required in PNG-compliant decoders */ + +#ifndef PNG_NO_READ_COMPOSITE_NODIV +# ifndef PNG_NO_READ_COMPOSITED_NODIV /* libpng-1.0.x misspelling */ +# define PNG_READ_COMPOSITE_NODIV_SUPPORTED /* well tested on Intel, SGI */ +# endif +#endif + +#if defined(PNG_1_0_X) || defined (PNG_1_2_X) +/* Deprecated, will be removed from version 2.0.0. + Use PNG_MNG_FEATURES_SUPPORTED instead. */ +#ifndef PNG_NO_READ_EMPTY_PLTE +# define PNG_READ_EMPTY_PLTE_SUPPORTED +#endif +#endif + +#endif /* PNG_READ_SUPPORTED */ + +#if defined(PNG_WRITE_SUPPORTED) + +# if !defined(PNG_WRITE_TRANSFORMS_NOT_SUPPORTED) && \ + !defined(PNG_NO_WRITE_TRANSFORMS) +# define PNG_WRITE_TRANSFORMS_SUPPORTED +#endif + +#ifdef PNG_WRITE_TRANSFORMS_SUPPORTED +# ifndef PNG_NO_WRITE_SHIFT +# define PNG_WRITE_SHIFT_SUPPORTED +# endif +# ifndef PNG_NO_WRITE_PACK +# define PNG_WRITE_PACK_SUPPORTED +# endif +# ifndef PNG_NO_WRITE_BGR +# define PNG_WRITE_BGR_SUPPORTED +# endif +# ifndef PNG_NO_WRITE_SWAP +# define PNG_WRITE_SWAP_SUPPORTED +# endif +# ifndef PNG_NO_WRITE_PACKSWAP +# define PNG_WRITE_PACKSWAP_SUPPORTED +# endif +# ifndef PNG_NO_WRITE_INVERT +# define PNG_WRITE_INVERT_SUPPORTED +# endif +# ifndef PNG_NO_WRITE_FILLER +# define PNG_WRITE_FILLER_SUPPORTED /* same as WRITE_STRIP_ALPHA */ +# endif +# ifndef PNG_NO_WRITE_SWAP_ALPHA +# define PNG_WRITE_SWAP_ALPHA_SUPPORTED +# endif +# ifndef PNG_NO_WRITE_INVERT_ALPHA +# define PNG_WRITE_INVERT_ALPHA_SUPPORTED +# endif +# ifndef PNG_NO_WRITE_USER_TRANSFORM +# define PNG_WRITE_USER_TRANSFORM_SUPPORTED +# endif +#endif /* PNG_WRITE_TRANSFORMS_SUPPORTED */ + +#if !defined(PNG_NO_WRITE_INTERLACING_SUPPORTED) && \ + !defined(PNG_WRITE_INTERLACING_SUPPORTED) +#define PNG_WRITE_INTERLACING_SUPPORTED /* not required for PNG-compliant + encoders, but can cause trouble + if left undefined */ +#endif + +#if !defined(PNG_NO_WRITE_WEIGHTED_FILTER) && \ + !defined(PNG_WRITE_WEIGHTED_FILTER) && \ + defined(PNG_FLOATING_POINT_SUPPORTED) +# define PNG_WRITE_WEIGHTED_FILTER_SUPPORTED +#endif + +#ifndef PNG_NO_WRITE_FLUSH +# define PNG_WRITE_FLUSH_SUPPORTED +#endif + +#if defined(PNG_1_0_X) || defined (PNG_1_2_X) +/* Deprecated, see PNG_MNG_FEATURES_SUPPORTED, above */ +#ifndef PNG_NO_WRITE_EMPTY_PLTE +# define PNG_WRITE_EMPTY_PLTE_SUPPORTED +#endif +#endif + +#endif /* PNG_WRITE_SUPPORTED */ + +#ifndef PNG_1_0_X +# ifndef PNG_NO_ERROR_NUMBERS +# define PNG_ERROR_NUMBERS_SUPPORTED +# endif +#endif /* PNG_1_0_X */ + +#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \ + defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) +# ifndef PNG_NO_USER_TRANSFORM_PTR +# define PNG_USER_TRANSFORM_PTR_SUPPORTED +# endif +#endif + +#ifndef PNG_NO_STDIO +# define PNG_TIME_RFC1123_SUPPORTED +#endif + +/* This adds extra functions in pngget.c for accessing data from the + * info pointer (added in version 0.99) + * png_get_image_width() + * png_get_image_height() + * png_get_bit_depth() + * png_get_color_type() + * png_get_compression_type() + * png_get_filter_type() + * png_get_interlace_type() + * png_get_pixel_aspect_ratio() + * png_get_pixels_per_meter() + * png_get_x_offset_pixels() + * png_get_y_offset_pixels() + * png_get_x_offset_microns() + * png_get_y_offset_microns() + */ +#if !defined(PNG_NO_EASY_ACCESS) && !defined(PNG_EASY_ACCESS_SUPPORTED) +# define PNG_EASY_ACCESS_SUPPORTED +#endif + +/* PNG_ASSEMBLER_CODE was enabled by default in version 1.2.0 + * and removed from version 1.2.20. The following will be removed + * from libpng-1.4.0 +*/ + +#if defined(PNG_READ_SUPPORTED) && !defined(PNG_NO_OPTIMIZED_CODE) +# ifndef PNG_OPTIMIZED_CODE_SUPPORTED +# define PNG_OPTIMIZED_CODE_SUPPORTED +# endif +#endif + +#if defined(PNG_READ_SUPPORTED) && !defined(PNG_NO_ASSEMBLER_CODE) +# ifndef PNG_ASSEMBLER_CODE_SUPPORTED +# define PNG_ASSEMBLER_CODE_SUPPORTED +# endif + +# if defined(__GNUC__) && defined(__x86_64__) && (__GNUC__ < 4) + /* work around 64-bit gcc compiler bugs in gcc-3.x */ +# if !defined(PNG_MMX_CODE_SUPPORTED) && !defined(PNG_NO_MMX_CODE) +# define PNG_NO_MMX_CODE +# endif +# endif + +# if defined(__APPLE__) +# if !defined(PNG_MMX_CODE_SUPPORTED) && !defined(PNG_NO_MMX_CODE) +# define PNG_NO_MMX_CODE +# endif +# endif + +# if (defined(__MWERKS__) && ((__MWERKS__ < 0x0900) || macintosh)) +# if !defined(PNG_MMX_CODE_SUPPORTED) && !defined(PNG_NO_MMX_CODE) +# define PNG_NO_MMX_CODE +# endif +# endif + +# if !defined(PNG_MMX_CODE_SUPPORTED) && !defined(PNG_NO_MMX_CODE) +# define PNG_MMX_CODE_SUPPORTED +# endif + +#endif +/* end of obsolete code to be removed from libpng-1.4.0 */ + +#if !defined(PNG_1_0_X) +#if !defined(PNG_NO_USER_MEM) && !defined(PNG_USER_MEM_SUPPORTED) +# define PNG_USER_MEM_SUPPORTED +#endif +#endif /* PNG_1_0_X */ + +/* Added at libpng-1.2.6 */ +#if !defined(PNG_1_0_X) +#ifndef PNG_SET_USER_LIMITS_SUPPORTED +#if !defined(PNG_NO_SET_USER_LIMITS) && !defined(PNG_SET_USER_LIMITS_SUPPORTED) +# define PNG_SET_USER_LIMITS_SUPPORTED +#endif +#endif +#endif /* PNG_1_0_X */ + +/* Added at libpng-1.0.16 and 1.2.6. To accept all valid PNGS no matter + * how large, set these limits to 0x7fffffffL + */ +#ifndef PNG_USER_WIDTH_MAX +# define PNG_USER_WIDTH_MAX 1000000L +#endif +#ifndef PNG_USER_HEIGHT_MAX +# define PNG_USER_HEIGHT_MAX 1000000L +#endif + +/* These are currently experimental features, define them if you want */ + +/* very little testing */ +/* +#ifdef PNG_READ_SUPPORTED +# ifndef PNG_READ_16_TO_8_ACCURATE_SCALE_SUPPORTED +# define PNG_READ_16_TO_8_ACCURATE_SCALE_SUPPORTED +# endif +#endif +*/ + +/* This is only for PowerPC big-endian and 680x0 systems */ +/* some testing */ +/* +#ifndef PNG_READ_BIG_ENDIAN_SUPPORTED +# define PNG_READ_BIG_ENDIAN_SUPPORTED +#endif +*/ + +/* Buggy compilers (e.g., gcc 2.7.2.2) need this */ +/* +#define PNG_NO_POINTER_INDEXING +*/ + +/* These functions are turned off by default, as they will be phased out. */ +/* +#define PNG_USELESS_TESTS_SUPPORTED +#define PNG_CORRECT_PALETTE_SUPPORTED +*/ + +/* Any chunks you are not interested in, you can undef here. The + * ones that allocate memory may be expecially important (hIST, + * tEXt, zTXt, tRNS, pCAL). Others will just save time and make png_info + * a bit smaller. + */ + +#if defined(PNG_READ_SUPPORTED) && \ + !defined(PNG_READ_ANCILLARY_CHUNKS_NOT_SUPPORTED) && \ + !defined(PNG_NO_READ_ANCILLARY_CHUNKS) +# define PNG_READ_ANCILLARY_CHUNKS_SUPPORTED +#endif + +#if defined(PNG_WRITE_SUPPORTED) && \ + !defined(PNG_WRITE_ANCILLARY_CHUNKS_NOT_SUPPORTED) && \ + !defined(PNG_NO_WRITE_ANCILLARY_CHUNKS) +# define PNG_WRITE_ANCILLARY_CHUNKS_SUPPORTED +#endif + +#ifdef PNG_READ_ANCILLARY_CHUNKS_SUPPORTED + +#ifdef PNG_NO_READ_TEXT +# define PNG_NO_READ_iTXt +# define PNG_NO_READ_tEXt +# define PNG_NO_READ_zTXt +#endif +#ifndef PNG_NO_READ_bKGD +# define PNG_READ_bKGD_SUPPORTED +# define PNG_bKGD_SUPPORTED +#endif +#ifndef PNG_NO_READ_cHRM +# define PNG_READ_cHRM_SUPPORTED +# define PNG_cHRM_SUPPORTED +#endif +#ifndef PNG_NO_READ_gAMA +# define PNG_READ_gAMA_SUPPORTED +# define PNG_gAMA_SUPPORTED +#endif +#ifndef PNG_NO_READ_hIST +# define PNG_READ_hIST_SUPPORTED +# define PNG_hIST_SUPPORTED +#endif +#ifndef PNG_NO_READ_iCCP +# define PNG_READ_iCCP_SUPPORTED +# define PNG_iCCP_SUPPORTED +#endif +#ifndef PNG_NO_READ_iTXt +# ifndef PNG_READ_iTXt_SUPPORTED +# define PNG_READ_iTXt_SUPPORTED +# endif +# ifndef PNG_iTXt_SUPPORTED +# define PNG_iTXt_SUPPORTED +# endif +#endif +#ifndef PNG_NO_READ_oFFs +# define PNG_READ_oFFs_SUPPORTED +# define PNG_oFFs_SUPPORTED +#endif +#ifndef PNG_NO_READ_pCAL +# define PNG_READ_pCAL_SUPPORTED +# define PNG_pCAL_SUPPORTED +#endif +#ifndef PNG_NO_READ_sCAL +# define PNG_READ_sCAL_SUPPORTED +# define PNG_sCAL_SUPPORTED +#endif +#ifndef PNG_NO_READ_pHYs +# define PNG_READ_pHYs_SUPPORTED +# define PNG_pHYs_SUPPORTED +#endif +#ifndef PNG_NO_READ_sBIT +# define PNG_READ_sBIT_SUPPORTED +# define PNG_sBIT_SUPPORTED +#endif +#ifndef PNG_NO_READ_sPLT +# define PNG_READ_sPLT_SUPPORTED +# define PNG_sPLT_SUPPORTED +#endif +#ifndef PNG_NO_READ_sRGB +# define PNG_READ_sRGB_SUPPORTED +# define PNG_sRGB_SUPPORTED +#endif +#ifndef PNG_NO_READ_tEXt +# define PNG_READ_tEXt_SUPPORTED +# define PNG_tEXt_SUPPORTED +#endif +#ifndef PNG_NO_READ_tIME +# define PNG_READ_tIME_SUPPORTED +# define PNG_tIME_SUPPORTED +#endif +#ifndef PNG_NO_READ_tRNS +# define PNG_READ_tRNS_SUPPORTED +# define PNG_tRNS_SUPPORTED +#endif +#ifndef PNG_NO_READ_zTXt +# define PNG_READ_zTXt_SUPPORTED +# define PNG_zTXt_SUPPORTED +#endif +#ifndef PNG_NO_READ_UNKNOWN_CHUNKS +# define PNG_READ_UNKNOWN_CHUNKS_SUPPORTED +# ifndef PNG_UNKNOWN_CHUNKS_SUPPORTED +# define PNG_UNKNOWN_CHUNKS_SUPPORTED +# endif +# ifndef PNG_NO_HANDLE_AS_UNKNOWN +# define PNG_HANDLE_AS_UNKNOWN_SUPPORTED +# endif +#endif +#if !defined(PNG_NO_READ_USER_CHUNKS) && \ + defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED) +# define PNG_READ_USER_CHUNKS_SUPPORTED +# define PNG_USER_CHUNKS_SUPPORTED +# ifdef PNG_NO_READ_UNKNOWN_CHUNKS +# undef PNG_NO_READ_UNKNOWN_CHUNKS +# endif +# ifdef PNG_NO_HANDLE_AS_UNKNOWN +# undef PNG_NO_HANDLE_AS_UNKNOWN +# endif +#endif +#ifndef PNG_NO_READ_OPT_PLTE +# define PNG_READ_OPT_PLTE_SUPPORTED /* only affects support of the */ +#endif /* optional PLTE chunk in RGB and RGBA images */ +#if defined(PNG_READ_iTXt_SUPPORTED) || defined(PNG_READ_tEXt_SUPPORTED) || \ + defined(PNG_READ_zTXt_SUPPORTED) +# define PNG_READ_TEXT_SUPPORTED +# define PNG_TEXT_SUPPORTED +#endif + +#endif /* PNG_READ_ANCILLARY_CHUNKS_SUPPORTED */ + +#ifdef PNG_WRITE_ANCILLARY_CHUNKS_SUPPORTED + +#ifdef PNG_NO_WRITE_TEXT +# define PNG_NO_WRITE_iTXt +# define PNG_NO_WRITE_tEXt +# define PNG_NO_WRITE_zTXt +#endif +#ifndef PNG_NO_WRITE_bKGD +# define PNG_WRITE_bKGD_SUPPORTED +# ifndef PNG_bKGD_SUPPORTED +# define PNG_bKGD_SUPPORTED +# endif +#endif +#ifndef PNG_NO_WRITE_cHRM +# define PNG_WRITE_cHRM_SUPPORTED +# ifndef PNG_cHRM_SUPPORTED +# define PNG_cHRM_SUPPORTED +# endif +#endif +#ifndef PNG_NO_WRITE_gAMA +# define PNG_WRITE_gAMA_SUPPORTED +# ifndef PNG_gAMA_SUPPORTED +# define PNG_gAMA_SUPPORTED +# endif +#endif +#ifndef PNG_NO_WRITE_hIST +# define PNG_WRITE_hIST_SUPPORTED +# ifndef PNG_hIST_SUPPORTED +# define PNG_hIST_SUPPORTED +# endif +#endif +#ifndef PNG_NO_WRITE_iCCP +# define PNG_WRITE_iCCP_SUPPORTED +# ifndef PNG_iCCP_SUPPORTED +# define PNG_iCCP_SUPPORTED +# endif +#endif +#ifndef PNG_NO_WRITE_iTXt +# ifndef PNG_WRITE_iTXt_SUPPORTED +# define PNG_WRITE_iTXt_SUPPORTED +# endif +# ifndef PNG_iTXt_SUPPORTED +# define PNG_iTXt_SUPPORTED +# endif +#endif +#ifndef PNG_NO_WRITE_oFFs +# define PNG_WRITE_oFFs_SUPPORTED +# ifndef PNG_oFFs_SUPPORTED +# define PNG_oFFs_SUPPORTED +# endif +#endif +#ifndef PNG_NO_WRITE_pCAL +# define PNG_WRITE_pCAL_SUPPORTED +# ifndef PNG_pCAL_SUPPORTED +# define PNG_pCAL_SUPPORTED +# endif +#endif +#ifndef PNG_NO_WRITE_sCAL +# define PNG_WRITE_sCAL_SUPPORTED +# ifndef PNG_sCAL_SUPPORTED +# define PNG_sCAL_SUPPORTED +# endif +#endif +#ifndef PNG_NO_WRITE_pHYs +# define PNG_WRITE_pHYs_SUPPORTED +# ifndef PNG_pHYs_SUPPORTED +# define PNG_pHYs_SUPPORTED +# endif +#endif +#ifndef PNG_NO_WRITE_sBIT +# define PNG_WRITE_sBIT_SUPPORTED +# ifndef PNG_sBIT_SUPPORTED +# define PNG_sBIT_SUPPORTED +# endif +#endif +#ifndef PNG_NO_WRITE_sPLT +# define PNG_WRITE_sPLT_SUPPORTED +# ifndef PNG_sPLT_SUPPORTED +# define PNG_sPLT_SUPPORTED +# endif +#endif +#ifndef PNG_NO_WRITE_sRGB +# define PNG_WRITE_sRGB_SUPPORTED +# ifndef PNG_sRGB_SUPPORTED +# define PNG_sRGB_SUPPORTED +# endif +#endif +#ifndef PNG_NO_WRITE_tEXt +# define PNG_WRITE_tEXt_SUPPORTED +# ifndef PNG_tEXt_SUPPORTED +# define PNG_tEXt_SUPPORTED +# endif +#endif +#ifndef PNG_NO_WRITE_tIME +# define PNG_WRITE_tIME_SUPPORTED +# ifndef PNG_tIME_SUPPORTED +# define PNG_tIME_SUPPORTED +# endif +#endif +#ifndef PNG_NO_WRITE_tRNS +# define PNG_WRITE_tRNS_SUPPORTED +# ifndef PNG_tRNS_SUPPORTED +# define PNG_tRNS_SUPPORTED +# endif +#endif +#ifndef PNG_NO_WRITE_zTXt +# define PNG_WRITE_zTXt_SUPPORTED +# ifndef PNG_zTXt_SUPPORTED +# define PNG_zTXt_SUPPORTED +# endif +#endif +#ifndef PNG_NO_WRITE_UNKNOWN_CHUNKS +# define PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED +# ifndef PNG_UNKNOWN_CHUNKS_SUPPORTED +# define PNG_UNKNOWN_CHUNKS_SUPPORTED +# endif +# ifndef PNG_NO_HANDLE_AS_UNKNOWN +# ifndef PNG_HANDLE_AS_UNKNOWN_SUPPORTED +# define PNG_HANDLE_AS_UNKNOWN_SUPPORTED +# endif +# endif +#endif +#if defined(PNG_WRITE_iTXt_SUPPORTED) || defined(PNG_WRITE_tEXt_SUPPORTED) || \ + defined(PNG_WRITE_zTXt_SUPPORTED) +# define PNG_WRITE_TEXT_SUPPORTED +# ifndef PNG_TEXT_SUPPORTED +# define PNG_TEXT_SUPPORTED +# endif +#endif + +#endif /* PNG_WRITE_ANCILLARY_CHUNKS_SUPPORTED */ + +/* Turn this off to disable png_read_png() and + * png_write_png() and leave the row_pointers member + * out of the info structure. + */ +#ifndef PNG_NO_INFO_IMAGE +# define PNG_INFO_IMAGE_SUPPORTED +#endif + +/* need the time information for reading tIME chunks */ +#if defined(PNG_tIME_SUPPORTED) +# if !defined(_WIN32_WCE) + /* "time.h" functions are not supported on WindowsCE */ +# include +# endif +#endif + +/* Some typedefs to get us started. These should be safe on most of the + * common platforms. The typedefs should be at least as large as the + * numbers suggest (a png_uint_32 must be at least 32 bits long), but they + * don't have to be exactly that size. Some compilers dislike passing + * unsigned shorts as function parameters, so you may be better off using + * unsigned int for png_uint_16. Likewise, for 64-bit systems, you may + * want to have unsigned int for png_uint_32 instead of unsigned long. + */ + +typedef unsigned long png_uint_32; +typedef long png_int_32; +typedef unsigned short png_uint_16; +typedef short png_int_16; +typedef unsigned char png_byte; + +/* This is usually size_t. It is typedef'ed just in case you need it to + change (I'm not sure if you will or not, so I thought I'd be safe) */ +#ifdef PNG_SIZE_T + typedef PNG_SIZE_T png_size_t; +# define png_sizeof(x) png_convert_size(sizeof (x)) +#else + typedef size_t png_size_t; +# define png_sizeof(x) sizeof (x) +#endif + +/* The following is needed for medium model support. It cannot be in the + * PNG_INTERNAL section. Needs modification for other compilers besides + * MSC. Model independent support declares all arrays and pointers to be + * large using the far keyword. The zlib version used must also support + * model independent data. As of version zlib 1.0.4, the necessary changes + * have been made in zlib. The USE_FAR_KEYWORD define triggers other + * changes that are needed. (Tim Wegner) + */ + +/* Separate compiler dependencies (problem here is that zlib.h always + defines FAR. (SJT) */ +#ifdef __BORLANDC__ +# if defined(__LARGE__) || defined(__HUGE__) || defined(__COMPACT__) +# define LDATA 1 +# else +# define LDATA 0 +# endif + /* GRR: why is Cygwin in here? Cygwin is not Borland C... */ +# if !defined(__WIN32__) && !defined(__FLAT__) && !defined(__CYGWIN__) +# define PNG_MAX_MALLOC_64K +# if (LDATA != 1) +# ifndef FAR +# define FAR __far +# endif +# define USE_FAR_KEYWORD +# endif /* LDATA != 1 */ + /* Possibly useful for moving data out of default segment. + * Uncomment it if you want. Could also define FARDATA as + * const if your compiler supports it. (SJT) +# define FARDATA FAR + */ +# endif /* __WIN32__, __FLAT__, __CYGWIN__ */ +#endif /* __BORLANDC__ */ + + +/* Suggest testing for specific compiler first before testing for + * FAR. The Watcom compiler defines both __MEDIUM__ and M_I86MM, + * making reliance oncertain keywords suspect. (SJT) + */ + +/* MSC Medium model */ +#if defined(FAR) +# if defined(M_I86MM) +# define USE_FAR_KEYWORD +# define FARDATA FAR +# include +# endif +#endif + +/* SJT: default case */ +#ifndef FAR +# define FAR +#endif + +/* At this point FAR is always defined */ +#ifndef FARDATA +# define FARDATA +#endif + +/* Typedef for floating-point numbers that are converted + to fixed-point with a multiple of 100,000, e.g., int_gamma */ +typedef png_int_32 png_fixed_point; + +/* Add typedefs for pointers */ +typedef void FAR * png_voidp; +typedef png_byte FAR * png_bytep; +typedef png_uint_32 FAR * png_uint_32p; +typedef png_int_32 FAR * png_int_32p; +typedef png_uint_16 FAR * png_uint_16p; +typedef png_int_16 FAR * png_int_16p; +typedef PNG_CONST char FAR * png_const_charp; +typedef char FAR * png_charp; +typedef png_fixed_point FAR * png_fixed_point_p; + +#ifndef PNG_NO_STDIO +#if defined(_WIN32_WCE) +typedef HANDLE png_FILE_p; +#else +typedef FILE * png_FILE_p; +#endif +#endif + +#ifdef PNG_FLOATING_POINT_SUPPORTED +typedef double FAR * png_doublep; +#endif + +/* Pointers to pointers; i.e. arrays */ +typedef png_byte FAR * FAR * png_bytepp; +typedef png_uint_32 FAR * FAR * png_uint_32pp; +typedef png_int_32 FAR * FAR * png_int_32pp; +typedef png_uint_16 FAR * FAR * png_uint_16pp; +typedef png_int_16 FAR * FAR * png_int_16pp; +typedef PNG_CONST char FAR * FAR * png_const_charpp; +typedef char FAR * FAR * png_charpp; +typedef png_fixed_point FAR * FAR * png_fixed_point_pp; +#ifdef PNG_FLOATING_POINT_SUPPORTED +typedef double FAR * FAR * png_doublepp; +#endif + +/* Pointers to pointers to pointers; i.e., pointer to array */ +typedef char FAR * FAR * FAR * png_charppp; + +#if defined(PNG_1_0_X) || defined(PNG_1_2_X) +/* SPC - Is this stuff deprecated? */ +/* It'll be removed as of libpng-1.3.0 - GR-P */ +/* libpng typedefs for types in zlib. If zlib changes + * or another compression library is used, then change these. + * Eliminates need to change all the source files. + */ +typedef charf * png_zcharp; +typedef charf * FAR * png_zcharpp; +typedef z_stream FAR * png_zstreamp; +#endif /* (PNG_1_0_X) || defined(PNG_1_2_X) */ + +/* + * Define PNG_BUILD_DLL if the module being built is a Windows + * LIBPNG DLL. + * + * Define PNG_USE_DLL if you want to *link* to the Windows LIBPNG DLL. + * It is equivalent to Microsoft predefined macro _DLL that is + * automatically defined when you compile using the share + * version of the CRT (C Run-Time library) + * + * The cygwin mods make this behavior a little different: + * Define PNG_BUILD_DLL if you are building a dll for use with cygwin + * Define PNG_STATIC if you are building a static library for use with cygwin, + * -or- if you are building an application that you want to link to the + * static library. + * PNG_USE_DLL is defined by default (no user action needed) unless one of + * the other flags is defined. + */ + +#if !defined(PNG_DLL) && (defined(PNG_BUILD_DLL) || defined(PNG_USE_DLL)) +# define PNG_DLL +#endif +/* If CYGWIN, then disallow GLOBAL ARRAYS unless building a static lib. + * When building a static lib, default to no GLOBAL ARRAYS, but allow + * command-line override + */ +#if defined(__CYGWIN__) +# if !defined(PNG_STATIC) +# if defined(PNG_USE_GLOBAL_ARRAYS) +# undef PNG_USE_GLOBAL_ARRAYS +# endif +# if !defined(PNG_USE_LOCAL_ARRAYS) +# define PNG_USE_LOCAL_ARRAYS +# endif +# else +# if defined(PNG_USE_LOCAL_ARRAYS) || defined(PNG_NO_GLOBAL_ARRAYS) +# if defined(PNG_USE_GLOBAL_ARRAYS) +# undef PNG_USE_GLOBAL_ARRAYS +# endif +# endif +# endif +# if !defined(PNG_USE_LOCAL_ARRAYS) && !defined(PNG_USE_GLOBAL_ARRAYS) +# define PNG_USE_LOCAL_ARRAYS +# endif +#endif + +/* Do not use global arrays (helps with building DLL's) + * They are no longer used in libpng itself, since version 1.0.5c, + * but might be required for some pre-1.0.5c applications. + */ +#if !defined(PNG_USE_LOCAL_ARRAYS) && !defined(PNG_USE_GLOBAL_ARRAYS) +# if defined(PNG_NO_GLOBAL_ARRAYS) || \ + (defined(__GNUC__) && defined(PNG_DLL)) || defined(_MSC_VER) +# define PNG_USE_LOCAL_ARRAYS +# else +# define PNG_USE_GLOBAL_ARRAYS +# endif +#endif + +#if defined(__CYGWIN__) +# undef PNGAPI +# define PNGAPI __cdecl +# undef PNG_IMPEXP +# define PNG_IMPEXP +#endif + +/* If you define PNGAPI, e.g., with compiler option "-DPNGAPI=__stdcall", + * you may get warnings regarding the linkage of png_zalloc and png_zfree. + * Don't ignore those warnings; you must also reset the default calling + * convention in your compiler to match your PNGAPI, and you must build + * zlib and your applications the same way you build libpng. + */ + +#if defined(__MINGW32__) && !defined(PNG_MODULEDEF) +# ifndef PNG_NO_MODULEDEF +# define PNG_NO_MODULEDEF +# endif +#endif + +#if !defined(PNG_IMPEXP) && defined(PNG_BUILD_DLL) && !defined(PNG_NO_MODULEDEF) +# define PNG_IMPEXP +#endif + +#if defined(PNG_DLL) || defined(_DLL) || defined(__DLL__ ) || \ + (( defined(_Windows) || defined(_WINDOWS) || \ + defined(WIN32) || defined(_WIN32) || defined(__WIN32__) )) + +# ifndef PNGAPI +# if defined(__GNUC__) || (defined (_MSC_VER) && (_MSC_VER >= 800)) +# define PNGAPI __cdecl +# else +# define PNGAPI _cdecl +# endif +# endif + +# if !defined(PNG_IMPEXP) && (!defined(PNG_DLL) || \ + 0 /* WINCOMPILER_WITH_NO_SUPPORT_FOR_DECLIMPEXP */) +# define PNG_IMPEXP +# endif + +# if !defined(PNG_IMPEXP) + +# define PNG_EXPORT_TYPE1(type,symbol) PNG_IMPEXP type PNGAPI symbol +# define PNG_EXPORT_TYPE2(type,symbol) type PNG_IMPEXP PNGAPI symbol + + /* Borland/Microsoft */ +# if defined(_MSC_VER) || defined(__BORLANDC__) +# if (_MSC_VER >= 800) || (__BORLANDC__ >= 0x500) +# define PNG_EXPORT PNG_EXPORT_TYPE1 +# else +# define PNG_EXPORT PNG_EXPORT_TYPE2 +# if defined(PNG_BUILD_DLL) +# define PNG_IMPEXP __export +# else +# define PNG_IMPEXP /*__import */ /* doesn't exist AFAIK in + VC++ */ +# endif /* Exists in Borland C++ for + C++ classes (== huge) */ +# endif +# endif + +# if !defined(PNG_IMPEXP) +# if defined(PNG_BUILD_DLL) +# define PNG_IMPEXP __declspec(dllexport) +# else +# define PNG_IMPEXP __declspec(dllimport) +# endif +# endif +# endif /* PNG_IMPEXP */ +#else /* !(DLL || non-cygwin WINDOWS) */ +# if (defined(__IBMC__) || defined(__IBMCPP__)) && defined(__OS2__) +# ifndef PNGAPI +# define PNGAPI _System +# endif +# else +# if 0 /* ... other platforms, with other meanings */ +# endif +# endif +#endif + +#ifndef PNGAPI +# define PNGAPI +#endif +#ifndef PNG_IMPEXP +# define PNG_IMPEXP +#endif + +#ifdef PNG_BUILDSYMS +# ifndef PNG_EXPORT +# define PNG_EXPORT(type,symbol) PNG_FUNCTION_EXPORT symbol END +# endif +# ifdef PNG_USE_GLOBAL_ARRAYS +# ifndef PNG_EXPORT_VAR +# define PNG_EXPORT_VAR(type) PNG_DATA_EXPORT +# endif +# endif +#endif + +#ifndef PNG_EXPORT +# define PNG_EXPORT(type,symbol) PNG_IMPEXP type PNGAPI symbol +#endif + +#ifdef PNG_USE_GLOBAL_ARRAYS +# ifndef PNG_EXPORT_VAR +# define PNG_EXPORT_VAR(type) extern PNG_IMPEXP type +# endif +#endif + +/* User may want to use these so they are not in PNG_INTERNAL. Any library + * functions that are passed far data must be model independent. + */ + +#ifndef PNG_ABORT +# define PNG_ABORT() abort() +#endif + +#ifdef PNG_SETJMP_SUPPORTED +# define png_jmpbuf(png_ptr) ((png_ptr)->jmpbuf) +#else +# define png_jmpbuf(png_ptr) \ + (LIBPNG_WAS_COMPILED_WITH__PNG_SETJMP_NOT_SUPPORTED) +#endif + +#if defined(USE_FAR_KEYWORD) /* memory model independent fns */ +/* use this to make far-to-near assignments */ +# define CHECK 1 +# define NOCHECK 0 +# define CVT_PTR(ptr) (png_far_to_near(png_ptr,ptr,CHECK)) +# define CVT_PTR_NOCHECK(ptr) (png_far_to_near(png_ptr,ptr,NOCHECK)) +# define png_snprintf _fsnprintf /* Added to v 1.2.19 */ +# define png_strlen _fstrlen +# define png_memcmp _fmemcmp /* SJT: added */ +# define png_memcpy _fmemcpy +# define png_memset _fmemset +#else /* use the usual functions */ +# define CVT_PTR(ptr) (ptr) +# define CVT_PTR_NOCHECK(ptr) (ptr) +# ifndef PNG_NO_SNPRINTF +# ifdef _MSC_VER +# define png_snprintf _snprintf /* Added to v 1.2.19 */ +# define png_snprintf2 _snprintf +# define png_snprintf6 _snprintf +# else +# define png_snprintf snprintf /* Added to v 1.2.19 */ +# define png_snprintf2 snprintf +# define png_snprintf6 snprintf +# endif +# else + /* You don't have or don't want to use snprintf(). Caution: Using + * sprintf instead of snprintf exposes your application to accidental + * or malevolent buffer overflows. If you don't have snprintf() + * as a general rule you should provide one (you can get one from + * Portable OpenSSH). */ +# define png_snprintf(s1,n,fmt,x1) sprintf(s1,fmt,x1) +# define png_snprintf2(s1,n,fmt,x1,x2) sprintf(s1,fmt,x1,x2) +# define png_snprintf6(s1,n,fmt,x1,x2,x3,x4,x5,x6) \ + sprintf(s1,fmt,x1,x2,x3,x4,x5,x6) +# endif +# define png_strlen strlen +# define png_memcmp memcmp /* SJT: added */ +# define png_memcpy memcpy +# define png_memset memset +#endif +/* End of memory model independent support */ + +/* Just a little check that someone hasn't tried to define something + * contradictory. + */ +#if (PNG_ZBUF_SIZE > 65536L) && defined(PNG_MAX_MALLOC_64K) +# undef PNG_ZBUF_SIZE +# define PNG_ZBUF_SIZE 65536L +#endif + +/* Added at libpng-1.2.8 */ +#endif /* PNG_VERSION_INFO_ONLY */ + +#endif /* PNGCONF_H */ diff --git a/CustomizeMiiInstaller/source/libpng/pngu/pngu.c b/CustomizeMiiInstaller/source/libpng/pngu/pngu.c new file mode 100644 index 0000000..e2cfb7f --- /dev/null +++ b/CustomizeMiiInstaller/source/libpng/pngu/pngu.c @@ -0,0 +1,1132 @@ +/******************************************************************************************** + +PNGU Version : 0.2a + +Coder : frontier + +More info : http://frontier-dev.net + +********************************************************************************************/ +#include +#include +#include "pngu.h" +#include "../png.h" + + +// Constants +#define PNGU_SOURCE_BUFFER 1 +#define PNGU_SOURCE_DEVICE 2 + + +// Prototypes of helper functions +int pngu_info (IMGCTX ctx); +int pngu_decode (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, PNGU_u32 stripAlpha); +void pngu_free_info (IMGCTX ctx); +void pngu_read_data_from_buffer (png_structp png_ptr, png_bytep data, png_size_t length); +void pngu_write_data_to_buffer (png_structp png_ptr, png_bytep data, png_size_t length); +void pngu_flush_data_to_buffer (png_structp png_ptr); +int pngu_clamp (int value, int min, int max); + + +// PNGU Image context struct +struct _IMGCTX +{ + int source; + void *buffer; + char *filename; + PNGU_u32 cursor; + + PNGU_u32 propRead; + PNGUPROP prop; + + PNGU_u32 infoRead; + png_structp png_ptr; + png_infop info_ptr; + FILE *fd; + + png_bytep *row_pointers; + png_bytep img_data; +}; + + +// PNGU Implementation // + +IMGCTX PNGU_SelectImageFromBuffer (const void *buffer) +{ + IMGCTX ctx = NULL; + + if (!buffer) + return NULL; + + ctx = malloc (sizeof (struct _IMGCTX)); + if (!ctx) + return NULL; + + ctx->buffer = (void *) buffer; + ctx->source = PNGU_SOURCE_BUFFER; + ctx->cursor = 0; + ctx->filename = NULL; + ctx->propRead = 0; + ctx->infoRead = 0; + + return ctx; +} + + +IMGCTX PNGU_SelectImageFromDevice (const char *filename) +{ + IMGCTX ctx = NULL; + + if (!filename) + return NULL; + + ctx = malloc (sizeof (struct _IMGCTX)); + if (!ctx) + return NULL; + + ctx->buffer = NULL; + ctx->source = PNGU_SOURCE_DEVICE; + ctx->cursor = 0; + + ctx->filename = malloc (strlen (filename) + 1); + if (!ctx->filename) + { + free (ctx); + return NULL; + } + strcpy(ctx->filename, filename); + + ctx->propRead = 0; + ctx->infoRead = 0; + + return ctx; +} + + +void PNGU_ReleaseImageContext (IMGCTX ctx) +{ + if (!ctx) + return; + + if (ctx->filename) + free (ctx->filename); + + if ((ctx->propRead) && (ctx->prop.trans)) + free (ctx->prop.trans); + + pngu_free_info (ctx); + + free (ctx); +} + + +int PNGU_GetImageProperties (IMGCTX ctx, PNGUPROP *imgprop) +{ + int res; + + if (!ctx->propRead) + { + res = pngu_info (ctx); + if (res != PNGU_OK) + return res; + } + + *imgprop = ctx->prop; + + return PNGU_OK; +} + + +int PNGU_DecodeToYCbYCr (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, void *buffer, PNGU_u32 stride) +{ + int result; + PNGU_u32 x, y, buffWidth; + + // width needs to be divisible by two + if (width % 2) + return PNGU_ODD_WIDTH; + + // stride needs to be divisible by two + if (stride % 2) + return PNGU_ODD_STRIDE; + + result = pngu_decode (ctx, width, height, 1); + if (result != PNGU_OK) + return result; + + // Copy image to the output buffer + buffWidth = (width + stride) / 2; + for (y = 0; y < height; y++) + for (x = 0; x < (width / 2); x++) + ((PNGU_u32 *)buffer)[y*buffWidth+x] = PNGU_RGB8_TO_YCbYCr (*(ctx->row_pointers[y]+x*6), *(ctx->row_pointers[y]+x*6+1), *(ctx->row_pointers[y]+x*6+2), + *(ctx->row_pointers[y]+x*6+3), *(ctx->row_pointers[y]+x*6+4), *(ctx->row_pointers[y]+x*6+5)); + + // Free resources + free (ctx->img_data); + free (ctx->row_pointers); + + // Success + return PNGU_OK; +} + + +int PNGU_DecodeToRGB565 (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, void *buffer, PNGU_u32 stride) +{ + int result; + PNGU_u32 x, y, buffWidth; + + result = pngu_decode (ctx, width, height, 1); + if (result != PNGU_OK) + return result; + + buffWidth = width + stride; + + // Copy image to the output buffer + for (y = 0; y < height; y++) + for (x = 0; x < width; x++) + ((PNGU_u16 *)buffer)[y*buffWidth+x] = + (((PNGU_u16) (ctx->row_pointers[y][x*3] & 0xF8)) << 8) | + (((PNGU_u16) (ctx->row_pointers[y][x*3+1] & 0xFC)) << 3) | + (((PNGU_u16) (ctx->row_pointers[y][x*3+2] & 0xF8)) >> 3); + + // Free resources + free (ctx->img_data); + free (ctx->row_pointers); + + // Success + return PNGU_OK; +} + + +int PNGU_DecodeToRGBA8 (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, void *buffer, PNGU_u32 stride, PNGU_u8 default_alpha) +{ + int result; + PNGU_u32 x, y, buffWidth; + + result = pngu_decode (ctx, width, height, 0); + if (result != PNGU_OK) + return result; + + buffWidth = width + stride; + + // Check is source image has an alpha channel + if ( (ctx->prop.imgColorType == PNGU_COLOR_TYPE_GRAY_ALPHA) || (ctx->prop.imgColorType == PNGU_COLOR_TYPE_RGB_ALPHA) ) + { + // Alpha channel present, copy image to the output buffer + for (y = 0; y < height; y++) + memcpy (buffer + (y * buffWidth * 4), ctx->row_pointers[y], width * 4); + } + else + { + // No alpha channel present, copy image to the output buffer + for (y = 0; y < height; y++) + for (x = 0; x < width; x++) + ((PNGU_u32 *)buffer)[y*buffWidth+x] = + (((PNGU_u32) ctx->row_pointers[y][x*3]) << 24) | + (((PNGU_u32) ctx->row_pointers[y][x*3+1]) << 16) | + (((PNGU_u32) ctx->row_pointers[y][x*3+2]) << 8) | + ((PNGU_u32) default_alpha); + } + + // Free resources + free (ctx->img_data); + free (ctx->row_pointers); + + // Success + return PNGU_OK; +} + + +int PNGU_DecodeTo4x4RGB565 (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, void *buffer) +{ + int result; + PNGU_u32 x, y, qwidth, qheight; + + // width and height need to be divisible by four + if ((width % 4) || (height % 4)) + return PNGU_INVALID_WIDTH_OR_HEIGHT; + + result = pngu_decode (ctx, width, height, 1); + if (result != PNGU_OK) + return result; + + // Copy image to the output buffer + qwidth = width / 4; + qheight = height / 4; + + for (y = 0; y < qheight; y++) + for (x = 0; x < qwidth; x++) + { + int blockbase = (y * qwidth + x) * 4; + + PNGU_u64 field64 = *((PNGU_u64 *)(ctx->row_pointers[y*4]+x*12)); + PNGU_u64 field32 = (PNGU_u64) *((PNGU_u32 *)(ctx->row_pointers[y*4]+x*12+8)); + ((PNGU_u64 *) buffer)[blockbase] = + (((field64 & 0xF800000000000000ULL) | ((field64 & 0xFC000000000000ULL) << 3) | ((field64 & 0xF80000000000ULL) << 5)) | + (((field64 & 0xF800000000ULL) << 8) | ((field64 & 0xFC000000ULL) << 11) | ((field64 & 0xF80000ULL) << 13)) | + (((field64 & 0xF800ULL) << 16) | ((field64 & 0xFCULL) << 19) | ((field32 & 0xF8000000ULL) >> 11)) | + (((field32 & 0xF80000ULL) >> 8) | ((field32 & 0xFC00ULL) >> 5) | ((field32 & 0xF8ULL) >> 3))); + + field64 = *((PNGU_u64 *)(ctx->row_pointers[y*4+1]+x*12)); + field32 = (PNGU_u64) *((PNGU_u32 *)(ctx->row_pointers[y*4+1]+x*12+8)); + ((PNGU_u64 *) buffer)[blockbase+1] = + (((field64 & 0xF800000000000000ULL) | ((field64 & 0xFC000000000000ULL) << 3) | ((field64 & 0xF80000000000ULL) << 5)) | + (((field64 & 0xF800000000ULL) << 8) | ((field64 & 0xFC000000ULL) << 11) | ((field64 & 0xF80000ULL) << 13)) | + (((field64 & 0xF800ULL) << 16) | ((field64 & 0xFCULL) << 19) | ((field32 & 0xF8000000ULL) >> 11)) | + (((field32 & 0xF80000ULL) >> 8) | ((field32 & 0xFC00ULL) >> 5) | ((field32 & 0xF8ULL) >> 3))); + + field64 = *((PNGU_u64 *)(ctx->row_pointers[y*4+2]+x*12)); + field32 = (PNGU_u64) *((PNGU_u32 *)(ctx->row_pointers[y*4+2]+x*12+8)); + ((PNGU_u64 *) buffer)[blockbase+2] = + (((field64 & 0xF800000000000000ULL) | ((field64 & 0xFC000000000000ULL) << 3) | ((field64 & 0xF80000000000ULL) << 5)) | + (((field64 & 0xF800000000ULL) << 8) | ((field64 & 0xFC000000ULL) << 11) | ((field64 & 0xF80000ULL) << 13)) | + (((field64 & 0xF800ULL) << 16) | ((field64 & 0xFCULL) << 19) | ((field32 & 0xF8000000ULL) >> 11)) | + (((field32 & 0xF80000ULL) >> 8) | ((field32 & 0xFC00ULL) >> 5) | ((field32 & 0xF8ULL) >> 3))); + + field64 = *((PNGU_u64 *)(ctx->row_pointers[y*4+3]+x*12)); + field32 = (PNGU_u64) *((PNGU_u32 *)(ctx->row_pointers[y*4+3]+x*12+8)); + ((PNGU_u64 *) buffer)[blockbase+3] = + (((field64 & 0xF800000000000000ULL) | ((field64 & 0xFC000000000000ULL) << 3) | ((field64 & 0xF80000000000ULL) << 5)) | + (((field64 & 0xF800000000ULL) << 8) | ((field64 & 0xFC000000ULL) << 11) | ((field64 & 0xF80000ULL) << 13)) | + (((field64 & 0xF800ULL) << 16) | ((field64 & 0xFCULL) << 19) | ((field32 & 0xF8000000ULL) >> 11)) | + (((field32 & 0xF80000ULL) >> 8) | ((field32 & 0xFC00ULL) >> 5) | ((field32 & 0xF8ULL) >> 3))); + } + + // Free resources + free (ctx->img_data); + free (ctx->row_pointers); + + // Success + return PNGU_OK; +} + + +int PNGU_DecodeTo4x4RGB5A3 (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, void *buffer, PNGU_u8 default_alpha) +{ + int result; + PNGU_u32 x, y, qwidth, qheight; + PNGU_u64 alphaMask; + + // width and height need to be divisible by four + if ((width % 4) || (height % 4)) + return PNGU_INVALID_WIDTH_OR_HEIGHT; + + result = pngu_decode (ctx, width, height, 0); + if (result != PNGU_OK) + return result; + + // Init some vars + qwidth = width / 4; + qheight = height / 4; + + // Check is source image has an alpha channel + if ( (ctx->prop.imgColorType == PNGU_COLOR_TYPE_GRAY_ALPHA) || (ctx->prop.imgColorType == PNGU_COLOR_TYPE_RGB_ALPHA) ) + { + // Alpha channel present, copy image to the output buffer + for (y = 0; y < qheight; y++) + for (x = 0; x < qwidth; x++) + { + int blockbase = (y * qwidth + x) * 4; + PNGU_u64 tmp; + + PNGU_u64 fieldA = *((PNGU_u64 *)(ctx->row_pointers[y*4]+x*16)); + PNGU_u64 fieldB = *((PNGU_u64 *)(ctx->row_pointers[y*4]+x*16+8)); + // If first pixel is opaque set MSB to 1 and encode colors in RGB555, else set MSB to 0 and encode colors in ARGB3444 + if ((fieldA & 0xE000000000ULL) == 0xE000000000ULL) + tmp = 0x8000000000000000ULL | ((fieldA & 0xF800000000000000ULL) >> 1) | ((fieldA & 0xF8000000000000ULL) << 2) | ((fieldA & 0xF80000000000ULL) << 5); + else + tmp = ((fieldA & 0xE000000000ULL) << 23) | ((fieldA & 0xF000000000000000ULL) >> 4) | (fieldA & 0xF0000000000000ULL) | ((fieldA & 0xF00000000000ULL) << 4); + + // If second pixel is opaque set MSB to 1 and encode colors in RGB555, else set MSB to 0 and encode colors in ARGB3444 + if ((fieldA & 0xE0ULL) == 0xE0ULL) + tmp = tmp | 0x800000000000ULL | ((fieldA & 0xF8000000ULL) << 15) | ((fieldA & 0xF80000ULL) << 18) | ((fieldA & 0xF800ULL) << 21); + else + tmp = tmp | ((fieldA & 0xE0ULL) << 39) | ((fieldA & 0xF0000000ULL) << 12) | ((fieldA & 0xF00000ULL) << 16) | ((fieldA & 0xF000ULL) << 20); + + // If third pixel is opaque set MSB to 1 and encode colors in RGB555, else set MSB to 0 and encode colors in ARGB3444 + if ((fieldB & 0xE000000000ULL) == 0xE000000000ULL) + tmp = tmp | 0x80000000ULL | ((fieldB & 0xF800000000000000ULL) >> 33) | ((fieldB & 0xF8000000000000ULL) >> 30) | ((fieldB & 0xF80000000000ULL) >> 27); + else + tmp = tmp | ((fieldB & 0xE000000000ULL) >> 9) | ((fieldB & 0xF000000000000000ULL) >> 36) | ((fieldB & 0xF0000000000000ULL) >> 32) | ((fieldB & 0xF00000000000ULL) >> 28); + + // If fourth pixel is opaque set MSB to 1 and encode colors in RGB555, else set MSB to 0 and encode colors in ARGB3444 + if ((fieldB & 0xE0ULL) == 0xE0ULL) + tmp = tmp | 0x8000ULL | ((fieldB & 0xF8000000ULL) >> 17) | ((fieldB & 0xF80000ULL) >> 14) | ((fieldB & 0xF800ULL) >> 11); + else + tmp = tmp | ((fieldB & 0xE0ULL) << 7) | ((fieldB & 0xF0000000ULL) >> 20) | ((fieldB & 0xF00000ULL) >> 16) | ((fieldB & 0xF000ULL) >> 12); + ((PNGU_u64 *) buffer)[blockbase] = tmp; + + fieldA = *((PNGU_u64 *)(ctx->row_pointers[y*4+1]+x*16)); + fieldB = *((PNGU_u64 *)(ctx->row_pointers[y*4+1]+x*16+8)); + if ((fieldA & 0xE000000000ULL) == 0xE000000000ULL) + // Opaque pixel, so set MSB to 1 and encode colors in RGB555 + tmp = 0x8000000000000000ULL | ((fieldA & 0xF800000000000000ULL) >> 1) | ((fieldA & 0xF8000000000000ULL) << 2) | ((fieldA & 0xF80000000000ULL) << 5); + else + // Tranlucid pixel, so set MSB to 0 and encode colors in ARGB3444 + tmp = ((fieldA & 0xE000000000ULL) << 23) | ((fieldA & 0xF000000000000000ULL) >> 4) | (fieldA & 0xF0000000000000ULL) | ((fieldA & 0xF00000000000ULL) << 4); + + if ((fieldA & 0xE0ULL) == 0xE0ULL) + // Opaque pixel, so set MSB to 1 and encode colors in RGB555 + tmp = tmp | 0x800000000000ULL | ((fieldA & 0xF8000000ULL) << 15) | ((fieldA & 0xF80000ULL) << 18) | ((fieldA & 0xF800ULL) << 21); + else + // Tranlucid pixel, so set MSB to 0 and encode colors in ARGB3444 + tmp = tmp | ((fieldA & 0xE0ULL) << 39) | ((fieldA & 0xF0000000ULL) << 12) | ((fieldA & 0xF00000ULL) << 16) | ((fieldA & 0xF000ULL) << 20); + + if ((fieldB & 0xE000000000ULL) == 0xE000000000ULL) + // Opaque pixel, so set MSB to 1 and encode colors in RGB555 + tmp = tmp | 0x80000000ULL | ((fieldB & 0xF800000000000000ULL) >> 33) | ((fieldB & 0xF8000000000000ULL) >> 30) | ((fieldB & 0xF80000000000ULL) >> 27); + else + // Tranlucid pixel, so set MSB to 0 and encode colors in ARGB3444 + tmp = tmp | ((fieldB & 0xE000000000ULL) >> 9) | ((fieldB & 0xF000000000000000ULL) >> 36) | ((fieldB & 0xF0000000000000ULL) >> 32) | ((fieldB & 0xF00000000000ULL) >> 28); + + if ((fieldB & 0xE0ULL) == 0xE0ULL) + // Opaque pixel, so set MSB to 1 and encode colors in RGB555 + tmp = tmp | 0x8000ULL | ((fieldB & 0xF8000000ULL) >> 17) | ((fieldB & 0xF80000ULL) >> 14) | ((fieldB & 0xF800ULL) >> 11); + else + // Tranlucid pixel, so set MSB to 0 and encode colors in ARGB3444 + tmp = tmp | ((fieldB & 0xE0ULL) << 7) | ((fieldB & 0xF0000000ULL) >> 20) | ((fieldB & 0xF00000ULL) >> 16) | ((fieldB & 0xF000ULL) >> 12); + ((PNGU_u64 *) buffer)[blockbase+1] = tmp; + + fieldA = *((PNGU_u64 *)(ctx->row_pointers[y*4+2]+x*16)); + fieldB = *((PNGU_u64 *)(ctx->row_pointers[y*4+2]+x*16+8)); + if ((fieldA & 0xE000000000ULL) == 0xE000000000ULL) + // Opaque pixel, so set MSB to 1 and encode colors in RGB555 + tmp = 0x8000000000000000ULL | ((fieldA & 0xF800000000000000ULL) >> 1) | ((fieldA & 0xF8000000000000ULL) << 2) | ((fieldA & 0xF80000000000ULL) << 5); + else + // Tranlucid pixel, so set MSB to 0 and encode colors in ARGB3444 + tmp = ((fieldA & 0xE000000000ULL) << 23) | ((fieldA & 0xF000000000000000ULL) >> 4) | (fieldA & 0xF0000000000000ULL) | ((fieldA & 0xF00000000000ULL) << 4); + + if ((fieldA & 0xE0ULL) == 0xE0ULL) + // Opaque pixel, so set MSB to 1 and encode colors in RGB555 + tmp = tmp | 0x800000000000ULL | ((fieldA & 0xF8000000ULL) << 15) | ((fieldA & 0xF80000ULL) << 18) | ((fieldA & 0xF800ULL) << 21); + else + // Tranlucid pixel, so set MSB to 0 and encode colors in ARGB3444 + tmp = tmp | ((fieldA & 0xE0ULL) << 39) | ((fieldA & 0xF0000000ULL) << 12) | ((fieldA & 0xF00000ULL) << 16) | ((fieldA & 0xF000ULL) << 20); + + if ((fieldB & 0xE000000000ULL) == 0xE000000000ULL) + // Opaque pixel, so set MSB to 1 and encode colors in RGB555 + tmp = tmp | 0x80000000ULL | ((fieldB & 0xF800000000000000ULL) >> 33) | ((fieldB & 0xF8000000000000ULL) >> 30) | ((fieldB & 0xF80000000000ULL) >> 27); + else + // Tranlucid pixel, so set MSB to 0 and encode colors in ARGB3444 + tmp = tmp | ((fieldB & 0xE000000000ULL) >> 9) | ((fieldB & 0xF000000000000000ULL) >> 36) | ((fieldB & 0xF0000000000000ULL) >> 32) | ((fieldB & 0xF00000000000ULL) >> 28); + + if ((fieldB & 0xE0ULL) == 0xE0ULL) + // Opaque pixel, so set MSB to 1 and encode colors in RGB555 + tmp = tmp | 0x8000ULL | ((fieldB & 0xF8000000ULL) >> 17) | ((fieldB & 0xF80000ULL) >> 14) | ((fieldB & 0xF800ULL) >> 11); + else + // Tranlucid pixel, so set MSB to 0 and encode colors in ARGB3444 + tmp = tmp | ((fieldB & 0xE0ULL) << 7) | ((fieldB & 0xF0000000ULL) >> 20) | ((fieldB & 0xF00000ULL) >> 16) | ((fieldB & 0xF000ULL) >> 12); + ((PNGU_u64 *) buffer)[blockbase+2] = tmp; + + fieldA = *((PNGU_u64 *)(ctx->row_pointers[y*4+3]+x*16)); + fieldB = *((PNGU_u64 *)(ctx->row_pointers[y*4+3]+x*16+8)); + if ((fieldA & 0xE000000000ULL) == 0xE000000000ULL) + // Opaque pixel, so set MSB to 1 and encode colors in RGB555 + tmp = 0x8000000000000000ULL | ((fieldA & 0xF800000000000000ULL) >> 1) | ((fieldA & 0xF8000000000000ULL) << 2) | ((fieldA & 0xF80000000000ULL) << 5); + else + // Tranlucid pixel, so set MSB to 0 and encode colors in ARGB3444 + tmp = ((fieldA & 0xE000000000ULL) << 23) | ((fieldA & 0xF000000000000000ULL) >> 4) | (fieldA & 0xF0000000000000ULL) | ((fieldA & 0xF00000000000ULL) << 4); + + if ((fieldA & 0xE0ULL) == 0xE0ULL) + // Opaque pixel, so set MSB to 1 and encode colors in RGB555 + tmp = tmp | 0x800000000000ULL | ((fieldA & 0xF8000000ULL) << 15) | ((fieldA & 0xF80000ULL) << 18) | ((fieldA & 0xF800ULL) << 21); + else + // Tranlucid pixel, so set MSB to 0 and encode colors in ARGB3444 + tmp = tmp | ((fieldA & 0xE0ULL) << 39) | ((fieldA & 0xF0000000ULL) << 12) | ((fieldA & 0xF00000ULL) << 16) | ((fieldA & 0xF000ULL) << 20); + + if ((fieldB & 0xE000000000ULL) == 0xE000000000ULL) + // Opaque pixel, so set MSB to 1 and encode colors in RGB555 + tmp = tmp | 0x80000000ULL | ((fieldB & 0xF800000000000000ULL) >> 33) | ((fieldB & 0xF8000000000000ULL) >> 30) | ((fieldB & 0xF80000000000ULL) >> 27); + else + // Tranlucid pixel, so set MSB to 0 and encode colors in ARGB3444 + tmp = tmp | ((fieldB & 0xE000000000ULL) >> 9) | ((fieldB & 0xF000000000000000ULL) >> 36) | ((fieldB & 0xF0000000000000ULL) >> 32) | ((fieldB & 0xF00000000000ULL) >> 28); + + if ((fieldB & 0xE0ULL) == 0xE0ULL) + // Opaque pixel, so set MSB to 1 and encode colors in RGB555 + tmp = tmp | 0x8000ULL | ((fieldB & 0xF8000000ULL) >> 17) | ((fieldB & 0xF80000ULL) >> 14) | ((fieldB & 0xF800ULL) >> 11); + else + // Tranlucid pixel, so set MSB to 0 and encode colors in ARGB3444 + tmp = tmp | ((fieldB & 0xE0ULL) << 7) | ((fieldB & 0xF0000000ULL) >> 20) | ((fieldB & 0xF00000ULL) >> 16) | ((fieldB & 0xF000ULL) >> 12); + ((PNGU_u64 *) buffer)[blockbase+3] = tmp; + } + } + else + { + // No alpha channel present, copy image to the output buffer + default_alpha = (default_alpha >> 5); + if (default_alpha == 7) + { + // The user wants an opaque texture, so set MSB to 1 and encode colors in RGB555 + alphaMask = 0x8000800080008000ULL; + + for (y = 0; y < qheight; y++) + for (x = 0; x < qwidth; x++) + { + int blockbase = (y * qwidth + x) * 4; + + PNGU_u64 field64 = *((PNGU_u64 *)(ctx->row_pointers[y*4]+x*12)); + PNGU_u64 field32 = (PNGU_u64) *((PNGU_u32 *)(ctx->row_pointers[y*4]+x*12+8)); + ((PNGU_u64 *) buffer)[blockbase] = + alphaMask | ((field64 & 0xF800000000000000ULL) >> 1) | ((field64 & 0xF8000000000000ULL) << 2) | + ((field64 & 0xF80000000000ULL) << 5) | ((field64 & 0xF800000000ULL) << 7) | ((field64 & 0xF8000000ULL) << 10) | + ((field64 & 0xF80000ULL) << 13) | ((field64 & 0xF800ULL) << 15) | ((field64 & 0xF8ULL) << 18) | + ((field32 & 0xF8000000ULL) >> 11) | ((field32 & 0xF80000ULL) >> 9) | ((field32 & 0xF800ULL) >> 6) | ((field32 & 0xF8ULL) >> 3); + + field64 = *((PNGU_u64 *)(ctx->row_pointers[y*4+1]+x*12)); + field32 = (PNGU_u64) *((PNGU_u32 *)(ctx->row_pointers[y*4+1]+x*12+8)); + ((PNGU_u64 *) buffer)[blockbase+1] = + alphaMask | ((field64 & 0xF800000000000000ULL) >> 1) | ((field64 & 0xF8000000000000ULL) << 2) | + ((field64 & 0xF80000000000ULL) << 5) | ((field64 & 0xF800000000ULL) << 7) | ((field64 & 0xF8000000ULL) << 10) | + ((field64 & 0xF80000ULL) << 13) | ((field64 & 0xF800ULL) << 15) | ((field64 & 0xF8ULL) << 18) | + ((field32 & 0xF8000000ULL) >> 11) | ((field32 & 0xF80000ULL) >> 9) | ((field32 & 0xF800ULL) >> 6) | ((field32 & 0xF8ULL) >> 3); + + field64 = *((PNGU_u64 *)(ctx->row_pointers[y*4+2]+x*12)); + field32 = (PNGU_u64) *((PNGU_u32 *)(ctx->row_pointers[y*4+2]+x*12+8)); + ((PNGU_u64 *) buffer)[blockbase+2] = + alphaMask | ((field64 & 0xF800000000000000ULL) >> 1) | ((field64 & 0xF8000000000000ULL) << 2) | + ((field64 & 0xF80000000000ULL) << 5) | ((field64 & 0xF800000000ULL) << 7) | ((field64 & 0xF8000000ULL) << 10) | + ((field64 & 0xF80000ULL) << 13) | ((field64 & 0xF800ULL) << 15) | ((field64 & 0xF8ULL) << 18) | + ((field32 & 0xF8000000ULL) >> 11) | ((field32 & 0xF80000ULL) >> 9) | ((field32 & 0xF800ULL) >> 6) | ((field32 & 0xF8ULL) >> 3); + + field64 = *((PNGU_u64 *)(ctx->row_pointers[y*4+3]+x*12)); + field32 = (PNGU_u64) *((PNGU_u32 *)(ctx->row_pointers[y*4+3]+x*12+8)); + ((PNGU_u64 *) buffer)[blockbase+3] = + alphaMask | ((field64 & 0xF800000000000000ULL) >> 1) | ((field64 & 0xF8000000000000ULL) << 2) | + ((field64 & 0xF80000000000ULL) << 5) | ((field64 & 0xF800000000ULL) << 7) | ((field64 & 0xF8000000ULL) << 10) | + ((field64 & 0xF80000ULL) << 13) | ((field64 & 0xF800ULL) << 15) | ((field64 & 0xF8ULL) << 18) | + ((field32 & 0xF8000000ULL) >> 11) | ((field32 & 0xF80000ULL) >> 9) | ((field32 & 0xF800ULL) >> 6) | ((field32 & 0xF8ULL) >> 3); + } + } + else + { + // The user wants a translucid texture, so set MSB to 0 and encode colors in ARGB3444 + default_alpha = (default_alpha << 4); + alphaMask = (((PNGU_u64) default_alpha) << 56) | (((PNGU_u64) default_alpha) << 40) | + (((PNGU_u64) default_alpha) << 24) | (((PNGU_u64) default_alpha) << 8); + + for (y = 0; y < qheight; y++) + for (x = 0; x < qwidth; x++) + { + int blockbase = (y * qwidth + x) * 4; + + PNGU_u64 field64 = *((PNGU_u64 *)(ctx->row_pointers[y*4]+x*12)); + PNGU_u64 field32 = (PNGU_u64) *((PNGU_u32 *)(ctx->row_pointers[y*4]+x*12+8)); + ((PNGU_u64 *) buffer)[blockbase] = + alphaMask | ((field64 & 0xF000000000000000ULL) >> 4) | (field64 & 0xF0000000000000ULL) | ((field64 & 0xF00000000000ULL) << 4) | + ((field64 & 0xF000000000ULL) << 4) | ((field64 & 0xF0000000ULL) << 8) | ((field64 & 0xF00000ULL) << 12) | + ((field64 & 0xF000ULL) << 12) | ((field64 & 0xF0ULL) << 16) | ((field32 & 0xF0000000ULL) >> 12) | + ((field32 & 0xF00000ULL) >> 12) | ((field32 & 0xF000ULL) >> 8) | ((field32 & 0xF0ULL) >> 4); + + field64 = *((PNGU_u64 *)(ctx->row_pointers[y*4+1]+x*12)); + field32 = (PNGU_u64) *((PNGU_u32 *)(ctx->row_pointers[y*4+1]+x*12+8)); + ((PNGU_u64 *) buffer)[blockbase+1] = + alphaMask | ((field64 & 0xF000000000000000ULL) >> 4) | (field64 & 0xF0000000000000ULL) | ((field64 & 0xF00000000000ULL) << 4) | + ((field64 & 0xF000000000ULL) << 4) | ((field64 & 0xF0000000ULL) << 8) | ((field64 & 0xF00000ULL) << 12) | + ((field64 & 0xF000ULL) << 12) | ((field64 & 0xF0ULL) << 16) | ((field32 & 0xF0000000ULL) >> 12) | + ((field32 & 0xF00000ULL) >> 12) | ((field32 & 0xF000ULL) >> 8) | ((field32 & 0xF0ULL) >> 4); + + field64 = *((PNGU_u64 *)(ctx->row_pointers[y*4+2]+x*12)); + field32 = (PNGU_u64) *((PNGU_u32 *)(ctx->row_pointers[y*4+2]+x*12+8)); + ((PNGU_u64 *) buffer)[blockbase+2] = + alphaMask | ((field64 & 0xF000000000000000ULL) >> 4) | (field64 & 0xF0000000000000ULL) | ((field64 & 0xF00000000000ULL) << 4) | + ((field64 & 0xF000000000ULL) << 4) | ((field64 & 0xF0000000ULL) << 8) | ((field64 & 0xF00000ULL) << 12) | + ((field64 & 0xF000ULL) << 12) | ((field64 & 0xF0ULL) << 16) | ((field32 & 0xF0000000ULL) >> 12) | + ((field32 & 0xF00000ULL) >> 12) | ((field32 & 0xF000ULL) >> 8) | ((field32 & 0xF0ULL) >> 4); + + field64 = *((PNGU_u64 *)(ctx->row_pointers[y*4+3]+x*12)); + field32 = (PNGU_u64) *((PNGU_u32 *)(ctx->row_pointers[y*4+3]+x*12+8)); + ((PNGU_u64 *) buffer)[blockbase+3] = + alphaMask | ((field64 & 0xF000000000000000ULL) >> 4) | (field64 & 0xF0000000000000ULL) | ((field64 & 0xF00000000000ULL) << 4) | + ((field64 & 0xF000000000ULL) << 4) | ((field64 & 0xF0000000ULL) << 8) | ((field64 & 0xF00000ULL) << 12) | + ((field64 & 0xF000ULL) << 12) | ((field64 & 0xF0ULL) << 16) | ((field32 & 0xF0000000ULL) >> 12) | + ((field32 & 0xF00000ULL) >> 12) | ((field32 & 0xF000ULL) >> 8) | ((field32 & 0xF0ULL) >> 4); + } + } + } + + // Free resources + free (ctx->img_data); + free (ctx->row_pointers); + + // Success + return PNGU_OK; +} + + +int PNGU_DecodeTo4x4RGBA8 (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, void *buffer, PNGU_u8 default_alpha) +{ + int result; + PNGU_u32 x, y, qwidth, qheight; + PNGU_u64 alphaMask; + + // width and height need to be divisible by four + if ((width % 4) || (height % 4)) + return PNGU_INVALID_WIDTH_OR_HEIGHT; + + result = pngu_decode (ctx, width, height, 0); + if (result != PNGU_OK) + return result; + + // Init some variables + qwidth = width / 4; + qheight = height / 4; + + // Check is source image has an alpha channel + if ( (ctx->prop.imgColorType == PNGU_COLOR_TYPE_GRAY_ALPHA) || (ctx->prop.imgColorType == PNGU_COLOR_TYPE_RGB_ALPHA) ) + { + // Alpha channel present, copy image to the output buffer + for (y = 0; y < qheight; y++) + for (x = 0; x < qwidth; x++) + { + int blockbase = (y * qwidth + x) * 8; + + PNGU_u64 fieldA = *((PNGU_u64 *)(ctx->row_pointers[y*4]+x*16)); + PNGU_u64 fieldB = *((PNGU_u64 *)(ctx->row_pointers[y*4]+x*16+8)); + ((PNGU_u64 *) buffer)[blockbase] = + ((fieldA & 0xFF00000000ULL) << 24) | ((fieldA & 0xFF00000000000000ULL) >> 8) | + ((fieldA & 0xFFULL) << 40) | ((fieldA & 0xFF000000ULL) << 8) | + ((fieldB & 0xFF00000000ULL) >> 8) | ((fieldB & 0xFF00000000000000ULL) >> 40) | + ((fieldB & 0xFFULL) << 8) | ((fieldB & 0xFF000000ULL) >> 24); + ((PNGU_u64 *) buffer)[blockbase+4] = + ((fieldA & 0xFFFF0000000000ULL) << 8) | ((fieldA & 0xFFFF00ULL) << 24) | + ((fieldB & 0xFFFF0000000000ULL) >> 24) | ((fieldB & 0xFFFF00ULL) >> 8); + + fieldA = *((PNGU_u64 *)(ctx->row_pointers[y*4+1]+x*16)); + fieldB = *((PNGU_u64 *)(ctx->row_pointers[y*4+1]+x*16+8)); + ((PNGU_u64 *) buffer)[blockbase+1] = + ((fieldA & 0xFF00000000ULL) << 24) | ((fieldA & 0xFF00000000000000ULL) >> 8) | + ((fieldA & 0xFFULL) << 40) | ((fieldA & 0xFF000000ULL) << 8) | + ((fieldB & 0xFF00000000ULL) >> 8) | ((fieldB & 0xFF00000000000000ULL) >> 40) | + ((fieldB & 0xFFULL) << 8) | ((fieldB & 0xFF000000ULL) >> 24); + ((PNGU_u64 *) buffer)[blockbase+5] = + ((fieldA & 0xFFFF0000000000ULL) << 8) | ((fieldA & 0xFFFF00ULL) << 24) | + ((fieldB & 0xFFFF0000000000ULL) >> 24) | ((fieldB & 0xFFFF00ULL) >> 8); + + fieldA = *((PNGU_u64 *)(ctx->row_pointers[y*4+2]+x*16)); + fieldB = *((PNGU_u64 *)(ctx->row_pointers[y*4+2]+x*16+8)); + ((PNGU_u64 *) buffer)[blockbase+2] = + ((fieldA & 0xFF00000000ULL) << 24) | ((fieldA & 0xFF00000000000000ULL) >> 8) | + ((fieldA & 0xFFULL) << 40) | ((fieldA & 0xFF000000ULL) << 8) | + ((fieldB & 0xFF00000000ULL) >> 8) | ((fieldB & 0xFF00000000000000ULL) >> 40) | + ((fieldB & 0xFFULL) << 8) | ((fieldB & 0xFF000000ULL) >> 24); + ((PNGU_u64 *) buffer)[blockbase+6] = + ((fieldA & 0xFFFF0000000000ULL) << 8) | ((fieldA & 0xFFFF00ULL) << 24) | + ((fieldB & 0xFFFF0000000000ULL) >> 24) | ((fieldB & 0xFFFF00ULL) >> 8); + + fieldA = *((PNGU_u64 *)(ctx->row_pointers[y*4+3]+x*16)); + fieldB = *((PNGU_u64 *)(ctx->row_pointers[y*4+3]+x*16+8)); + ((PNGU_u64 *) buffer)[blockbase+3] = + ((fieldA & 0xFF00000000ULL) << 24) | ((fieldA & 0xFF00000000000000ULL) >> 8) | + ((fieldA & 0xFFULL) << 40) | ((fieldA & 0xFF000000ULL) << 8) | + ((fieldB & 0xFF00000000ULL) >> 8) | ((fieldB & 0xFF00000000000000ULL) >> 40) | + ((fieldB & 0xFFULL) << 8) | ((fieldB & 0xFF000000ULL) >> 24); + ((PNGU_u64 *) buffer)[blockbase+7] = + ((fieldA & 0xFFFF0000000000ULL) << 8) | ((fieldA & 0xFFFF00ULL) << 24) | + ((fieldB & 0xFFFF0000000000ULL) >> 24) | ((fieldB & 0xFFFF00ULL) >> 8); + } + } + else + { + // No alpha channel present, copy image to the output buffer + alphaMask = (((PNGU_u64)default_alpha) << 56) | (((PNGU_u64)default_alpha) << 40) | + (((PNGU_u64)default_alpha) << 24) | (((PNGU_u64)default_alpha) << 8); + + for (y = 0; y < qheight; y++) + for (x = 0; x < qwidth; x++) + { + int blockbase = (y * qwidth + x) * 8; + + PNGU_u64 field64 = *((PNGU_u64 *)(ctx->row_pointers[y*4]+x*12)); + PNGU_u64 field32 = (PNGU_u64) *((PNGU_u32 *)(ctx->row_pointers[y*4]+x*12+8)); + ((PNGU_u64 *) buffer)[blockbase] = + (((field64 & 0xFF00000000000000ULL) >> 8) | (field64 & 0xFF00000000ULL) | + ((field64 & 0xFF00ULL) << 8) | ((field32 & 0xFF0000ULL) >> 16) | alphaMask); + ((PNGU_u64 *) buffer)[blockbase+4] = + (((field64 & 0xFFFF0000000000ULL) << 8) | ((field64 & 0xFFFF0000ULL) << 16) | + ((field64 & 0xFFULL) << 24) | ((field32 & 0xFF000000ULL) >> 8) | (field32 & 0xFFFFULL)); + + field64 = *((PNGU_u64 *)(ctx->row_pointers[y*4+1]+x*12)); + field32 = (PNGU_u64) *((PNGU_u32 *)(ctx->row_pointers[y*4+1]+x*12+8)); + ((PNGU_u64 *) buffer)[blockbase+1] = + (((field64 & 0xFF00000000000000ULL) >> 8) | (field64 & 0xFF00000000ULL) | + ((field64 & 0xFF00ULL) << 8) | ((field32 & 0xFF0000ULL) >> 16) | alphaMask); + ((PNGU_u64 *) buffer)[blockbase+5] = + (((field64 & 0xFFFF0000000000ULL) << 8) | ((field64 & 0xFFFF0000ULL) << 16) | + ((field64 & 0xFFULL) << 24) | ((field32 & 0xFF000000ULL) >> 8) | (field32 & 0xFFFFULL)); + + field64 = *((PNGU_u64 *)(ctx->row_pointers[y*4+2]+x*12)); + field32 = (PNGU_u64) *((PNGU_u32 *)(ctx->row_pointers[y*4+2]+x*12+8)); + ((PNGU_u64 *) buffer)[blockbase+2] = + (((field64 & 0xFF00000000000000ULL) >> 8) | (field64 & 0xFF00000000ULL) | + ((field64 & 0xFF00ULL) << 8) | ((field32 & 0xFF0000ULL) >> 16) | alphaMask); + ((PNGU_u64 *) buffer)[blockbase+6] = + (((field64 & 0xFFFF0000000000ULL) << 8) | ((field64 & 0xFFFF0000ULL) << 16) | + ((field64 & 0xFFULL) << 24) | ((field32 & 0xFF000000ULL) >> 8) | (field32 & 0xFFFFULL)); + + field64 = *((PNGU_u64 *)(ctx->row_pointers[y*4+3]+x*12)); + field32 = (PNGU_u64) *((PNGU_u32 *)(ctx->row_pointers[y*4+3]+x*12+8)); + ((PNGU_u64 *) buffer)[blockbase+3] = + (((field64 & 0xFF00000000000000ULL) >> 8) | (field64 & 0xFF00000000ULL) | + ((field64 & 0xFF00ULL) << 8) | ((field32 & 0xFF0000ULL) >> 16) | alphaMask); + ((PNGU_u64 *) buffer)[blockbase+7] = + (((field64 & 0xFFFF0000000000ULL) << 8) | ((field64 & 0xFFFF0000ULL) << 16) | + ((field64 & 0xFFULL) << 24) | ((field32 & 0xFF000000ULL) >> 8) | (field32 & 0xFFFFULL)); + } + } + + // Free resources + free (ctx->img_data); + free (ctx->row_pointers); + + // Success + return PNGU_OK; +} + + +int PNGU_EncodeFromYCbYCr (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, void *buffer, PNGU_u32 stride) +{ + png_uint_32 rowbytes; + PNGU_u32 x, y, buffWidth; + + // Erase from the context any readed info + pngu_free_info (ctx); + ctx->propRead = 0; + + // Check if the user has selected a file to write the image + if (ctx->source == PNGU_SOURCE_BUFFER); + + else if (ctx->source == PNGU_SOURCE_DEVICE) + { + // Open file + if (!(ctx->fd = fopen (ctx->filename, "wb"))) + return PNGU_CANT_OPEN_FILE; + } + + else + return PNGU_NO_FILE_SELECTED; + + // Allocation of libpng structs + ctx->png_ptr = png_create_write_struct (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); + if (!(ctx->png_ptr)) + { + if (ctx->source == PNGU_SOURCE_DEVICE) + fclose (ctx->fd); + return PNGU_LIB_ERROR; + } + + ctx->info_ptr = png_create_info_struct (ctx->png_ptr); + if (!(ctx->info_ptr)) + { + png_destroy_write_struct (&(ctx->png_ptr), (png_infopp)NULL); + if (ctx->source == PNGU_SOURCE_DEVICE) + fclose (ctx->fd); + return PNGU_LIB_ERROR; + } + + if (ctx->source == PNGU_SOURCE_BUFFER) + { + // Installation of our custom data writer function + ctx->cursor = 0; + png_set_write_fn (ctx->png_ptr, ctx, pngu_write_data_to_buffer, pngu_flush_data_to_buffer); + } + else if (ctx->source == PNGU_SOURCE_DEVICE) + { + // Default data writer uses function fwrite, so it needs to use our FILE* + png_init_io (ctx->png_ptr, ctx->fd); + } + + // Setup output file properties + png_set_IHDR (ctx->png_ptr, ctx->info_ptr, width, height, 8, PNG_COLOR_TYPE_RGB, + PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); + + // Allocate memory to store the image in RGB format + rowbytes = width * 3; + if (rowbytes % 4) + rowbytes = ((rowbytes / 4) + 1) * 4; // Add extra padding so each row starts in a 4 byte boundary + + ctx->img_data = malloc (rowbytes * height); + if (!ctx->img_data) + { + png_destroy_write_struct (&(ctx->png_ptr), (png_infopp)NULL); + if (ctx->source == PNGU_SOURCE_DEVICE) + fclose (ctx->fd); + return PNGU_LIB_ERROR; + } + + ctx->row_pointers = malloc (sizeof (png_bytep) * height); + if (!ctx->row_pointers) + { + png_destroy_write_struct (&(ctx->png_ptr), (png_infopp)NULL); + if (ctx->source == PNGU_SOURCE_DEVICE) + fclose (ctx->fd); + return PNGU_LIB_ERROR; + } + + // Encode YCbYCr image into RGB8 format + buffWidth = (width + stride) / 2; + for (y = 0; y < height; y++) + { + ctx->row_pointers[y] = ctx->img_data + (y * rowbytes); + + for (x = 0; x < (width / 2); x++) + PNGU_YCbYCr_TO_RGB8 ( ((PNGU_u32 *)buffer)[y*buffWidth+x], + ((PNGU_u8 *) ctx->row_pointers[y]+x*6), ((PNGU_u8 *) ctx->row_pointers[y]+x*6+1), + ((PNGU_u8 *) ctx->row_pointers[y]+x*6+2), ((PNGU_u8 *) ctx->row_pointers[y]+x*6+3), + ((PNGU_u8 *) ctx->row_pointers[y]+x*6+4), ((PNGU_u8 *) ctx->row_pointers[y]+x*6+5) ); + } + + // Tell libpng where is our image data + png_set_rows (ctx->png_ptr, ctx->info_ptr, ctx->row_pointers); + + // Write file header and image data + png_write_png (ctx->png_ptr, ctx->info_ptr, PNG_TRANSFORM_IDENTITY, NULL); + + // Tell libpng we have no more data to write + png_write_end (ctx->png_ptr, (png_infop) NULL); + + // Free resources + free (ctx->img_data); + free (ctx->row_pointers); + png_destroy_write_struct (&(ctx->png_ptr), &(ctx->info_ptr)); + if (ctx->source == PNGU_SOURCE_DEVICE) + fclose (ctx->fd); + + // Success + return PNGU_OK; +} + + +// This function is taken from a libogc example +PNGU_u32 PNGU_RGB8_TO_YCbYCr (PNGU_u8 r1, PNGU_u8 g1, PNGU_u8 b1, PNGU_u8 r2, PNGU_u8 g2, PNGU_u8 b2) +{ + int y1, cb1, cr1, y2, cb2, cr2, cb, cr; + + y1 = (299 * r1 + 587 * g1 + 114 * b1) / 1000; + cb1 = (-16874 * r1 - 33126 * g1 + 50000 * b1 + 12800000) / 100000; + cr1 = (50000 * r1 - 41869 * g1 - 8131 * b1 + 12800000) / 100000; + + y2 = (299 * r2 + 587 * g2 + 114 * b2) / 1000; + cb2 = (-16874 * r2 - 33126 * g2 + 50000 * b2 + 12800000) / 100000; + cr2 = (50000 * r2 - 41869 * g2 - 8131 * b2 + 12800000) / 100000; + + cb = (cb1 + cb2) >> 1; + cr = (cr1 + cr2) >> 1; + + return (PNGU_u32) ((y1 << 24) | (cb << 16) | (y2 << 8) | cr); +} + + +void PNGU_YCbYCr_TO_RGB8 (PNGU_u32 ycbycr, PNGU_u8 *r1, PNGU_u8 *g1, PNGU_u8 *b1, PNGU_u8 *r2, PNGU_u8 *g2, PNGU_u8 *b2) +{ + PNGU_u8 *val = (PNGU_u8 *) &ycbycr; + int r, g, b; + + r = 1.371f * (val[3] - 128); + g = - 0.698f * (val[3] - 128) - 0.336f * (val[1] - 128); + b = 1.732f * (val[1] - 128); + + *r1 = pngu_clamp (val[0] + r, 0, 255); + *g1 = pngu_clamp (val[0] + g, 0, 255); + *b1 = pngu_clamp (val[0] + b, 0, 255); + + *r2 = pngu_clamp (val[2] + r, 0, 255); + *g2 = pngu_clamp (val[2] + g, 0, 255); + *b2 = pngu_clamp (val[2] + b, 0, 255); +} + + +int pngu_info (IMGCTX ctx) +{ + png_byte magic[8]; + png_uint_32 width; + png_uint_32 height; + png_color_16p background; + png_bytep trans; + png_color_16p trans_values; + int scale, i; + + // Check if there is a file selected and if it is a valid .png + if (ctx->source == PNGU_SOURCE_BUFFER) + memcpy (magic, ctx->buffer, 8); + + else if (ctx->source == PNGU_SOURCE_DEVICE) + { + // Open file + if (!(ctx->fd = fopen (ctx->filename, "rb"))) + return PNGU_CANT_OPEN_FILE; + + // Load first 8 bytes into magic buffer + if (fread (magic, 1, 8, ctx->fd) != 8) + { + fclose (ctx->fd); + return PNGU_CANT_READ_FILE; + } + } + + else + return PNGU_NO_FILE_SELECTED;; + + if (png_sig_cmp(magic, 0, 8) != 0) + { + if (ctx->source == PNGU_SOURCE_DEVICE) + fclose (ctx->fd); + return PNGU_FILE_IS_NOT_PNG; + } + + // Allocation of libpng structs + ctx->png_ptr = png_create_read_struct (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); + if (!(ctx->png_ptr)) + { + if (ctx->source == PNGU_SOURCE_DEVICE) + fclose (ctx->fd); + return PNGU_LIB_ERROR; + } + + ctx->info_ptr = png_create_info_struct (ctx->png_ptr); + if (!(ctx->info_ptr)) + { + if (ctx->source == PNGU_SOURCE_DEVICE) + fclose (ctx->fd); + png_destroy_read_struct (&(ctx->png_ptr), (png_infopp)NULL, (png_infopp)NULL); + return PNGU_LIB_ERROR; + } + + if (ctx->source == PNGU_SOURCE_BUFFER) + { + // Installation of our custom data provider function + ctx->cursor = 0; + png_set_read_fn (ctx->png_ptr, ctx, pngu_read_data_from_buffer); + } + else if (ctx->source == PNGU_SOURCE_DEVICE) + { + // Default data provider uses function fread, so it needs to use our FILE* + png_init_io (ctx->png_ptr, ctx->fd); + png_set_sig_bytes (ctx->png_ptr, 8); // We have read 8 bytes already to check PNG authenticity + } + + // Read png header + png_read_info (ctx->png_ptr, ctx->info_ptr); + + // Query image properties if they have not been queried before + if (!ctx->propRead) + { + png_get_IHDR(ctx->png_ptr, ctx->info_ptr, &width, &height, + (int *) &(ctx->prop.imgBitDepth), + (int *) &(ctx->prop.imgColorType), + NULL, NULL, NULL); + + ctx->prop.imgWidth = width; + ctx->prop.imgHeight = height; + switch (ctx->prop.imgColorType) + { + case PNG_COLOR_TYPE_GRAY: + ctx->prop.imgColorType = PNGU_COLOR_TYPE_GRAY; + break; + case PNG_COLOR_TYPE_GRAY_ALPHA: + ctx->prop.imgColorType = PNGU_COLOR_TYPE_GRAY_ALPHA; + break; + case PNG_COLOR_TYPE_PALETTE: + ctx->prop.imgColorType = PNGU_COLOR_TYPE_PALETTE; + break; + case PNG_COLOR_TYPE_RGB: + ctx->prop.imgColorType = PNGU_COLOR_TYPE_RGB; + break; + case PNG_COLOR_TYPE_RGB_ALPHA: + ctx->prop.imgColorType = PNGU_COLOR_TYPE_RGB_ALPHA; + break; + default: + ctx->prop.imgColorType = PNGU_COLOR_TYPE_UNKNOWN; + break; + } + + // Constant used to scale 16 bit values to 8 bit values + scale = 1; + if (ctx->prop.imgBitDepth == 16) + scale = 256; + + // Query background color, if any. + ctx->prop.validBckgrnd = 0; + if (((ctx->prop.imgColorType == PNGU_COLOR_TYPE_RGB) || (ctx->prop.imgColorType == PNGU_COLOR_TYPE_RGB_ALPHA)) && + (png_get_bKGD (ctx->png_ptr, ctx->info_ptr, &background))) + { + ctx->prop.validBckgrnd = 1; + ctx->prop.bckgrnd.r = background->red / scale; + ctx->prop.bckgrnd.g = background->green / scale; + ctx->prop.bckgrnd.b = background->blue / scale; + } + else if (((ctx->prop.imgColorType == PNGU_COLOR_TYPE_GRAY) || (ctx->prop.imgColorType == PNGU_COLOR_TYPE_GRAY_ALPHA)) && + (png_get_bKGD (ctx->png_ptr, ctx->info_ptr, &background))) + { + ctx->prop.validBckgrnd = 1; + ctx->prop.bckgrnd.r = ctx->prop.bckgrnd.g = ctx->prop.bckgrnd.b = background->gray / scale; + } + + // Query list of transparent colors, if any. + ctx->prop.numTrans = 0; + ctx->prop.trans = NULL; + if (((ctx->prop.imgColorType == PNGU_COLOR_TYPE_RGB) || (ctx->prop.imgColorType == PNGU_COLOR_TYPE_RGB_ALPHA)) && + (png_get_tRNS (ctx->png_ptr, ctx->info_ptr, &trans, (int *) &(ctx->prop.numTrans), &trans_values))) + { + if (ctx->prop.numTrans) + { + ctx->prop.trans = malloc (sizeof (PNGUCOLOR) * ctx->prop.numTrans); + if (ctx->prop.trans) + for (i = 0; i < ctx->prop.numTrans; i++) + { + ctx->prop.trans[i].r = trans_values[i].red / scale; + ctx->prop.trans[i].g = trans_values[i].green / scale; + ctx->prop.trans[i].b = trans_values[i].blue / scale; + } + else + ctx->prop.numTrans = 0; + } + } + else if (((ctx->prop.imgColorType == PNGU_COLOR_TYPE_GRAY) || (ctx->prop.imgColorType == PNGU_COLOR_TYPE_GRAY_ALPHA)) && + (png_get_tRNS (ctx->png_ptr, ctx->info_ptr, &trans, (int *) &(ctx->prop.numTrans), &trans_values))) + { + if (ctx->prop.numTrans) + { + ctx->prop.trans = malloc (sizeof (PNGUCOLOR) * ctx->prop.numTrans); + if (ctx->prop.trans) + for (i = 0; i < ctx->prop.numTrans; i++) + ctx->prop.trans[i].r = ctx->prop.trans[i].g = ctx->prop.trans[i].b = + trans_values[i].gray / scale; + else + ctx->prop.numTrans = 0; + } + } + + ctx->propRead = 1; + } + + // Success + ctx->infoRead = 1; + + return PNGU_OK; +} + + +int pngu_decode (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, PNGU_u32 stripAlpha) +{ + png_uint_32 rowbytes; + int i; + + // Read info if it hasn't been read before + if (!ctx->infoRead) + { + i = pngu_info (ctx); + if (i != PNGU_OK) + return i; + } + + // Check if the user has specified the real width and height of the image + if ( (ctx->prop.imgWidth != width) || (ctx->prop.imgHeight != height) ) + return PNGU_INVALID_WIDTH_OR_HEIGHT; + + // Check if color type is supported by PNGU + if ( (ctx->prop.imgColorType == PNGU_COLOR_TYPE_PALETTE) || (ctx->prop.imgColorType == PNGU_COLOR_TYPE_UNKNOWN) ) + return PNGU_UNSUPPORTED_COLOR_TYPE; + + // Scale 16 bit samples to 8 bit + if (ctx->prop.imgBitDepth == 16) + png_set_strip_16 (ctx->png_ptr); + + // Remove alpha channel if we don't need it + if (stripAlpha && ((ctx->prop.imgColorType == PNGU_COLOR_TYPE_RGB_ALPHA) || (ctx->prop.imgColorType == PNGU_COLOR_TYPE_GRAY_ALPHA))) + png_set_strip_alpha (ctx->png_ptr); + + // Expand 1, 2 and 4 bit samples to 8 bit + if (ctx->prop.imgBitDepth < 8) + png_set_packing (ctx->png_ptr); + + // Transform grayscale images to RGB + if ( (ctx->prop.imgColorType == PNGU_COLOR_TYPE_GRAY) || (ctx->prop.imgColorType == PNGU_COLOR_TYPE_GRAY_ALPHA) ) + png_set_gray_to_rgb (ctx->png_ptr); + + // Flush transformations + png_read_update_info (ctx->png_ptr, ctx->info_ptr); + + // Allocate memory to store the image + rowbytes = png_get_rowbytes (ctx->png_ptr, ctx->info_ptr); + if (rowbytes % 4) + rowbytes = ((rowbytes / 4) + 1) * 4; // Add extra padding so each row starts in a 4 byte boundary + + ctx->img_data = malloc (rowbytes * ctx->prop.imgHeight); + if (!ctx->img_data) + { + pngu_free_info (ctx); + return PNGU_LIB_ERROR; + } + + ctx->row_pointers = malloc (sizeof (png_bytep) * ctx->prop.imgHeight); + if (!ctx->row_pointers) + { + free (ctx->img_data); + pngu_free_info (ctx); + return PNGU_LIB_ERROR; + } + + for (i = 0; i < ctx->prop.imgHeight; i++) + ctx->row_pointers[i] = ctx->img_data + (i * rowbytes); + + // Transform the image and copy it to our allocated memory + png_read_image (ctx->png_ptr, ctx->row_pointers); + + // Free resources + pngu_free_info (ctx); + + // Success + return PNGU_OK; +} + + +void pngu_free_info (IMGCTX ctx) +{ + if (ctx->infoRead) + { + if (ctx->source == PNGU_SOURCE_DEVICE) + fclose (ctx->fd); + + png_destroy_read_struct (&(ctx->png_ptr), &(ctx->info_ptr), (png_infopp)NULL); + + ctx->infoRead = 0; + } +} + + +// Custom data provider function used for reading from memory buffers. +void pngu_read_data_from_buffer (png_structp png_ptr, png_bytep data, png_size_t length) +{ + IMGCTX ctx = (IMGCTX) png_get_io_ptr (png_ptr); + memcpy (data, ctx->buffer + ctx->cursor, length); + ctx->cursor += length; +} + + +// Custom data writer function used for writing to memory buffers. +void pngu_write_data_to_buffer (png_structp png_ptr, png_bytep data, png_size_t length) +{ + IMGCTX ctx = (IMGCTX) png_get_io_ptr (png_ptr); + memcpy (ctx->buffer + ctx->cursor, data, length); + ctx->cursor += length; +} + + +// Custom data flusher function used for writing to memory buffers. +void pngu_flush_data_to_buffer (png_structp png_ptr) +{ + // Nothing to do here +} + + +// Function used in YCbYCr to RGB decoding +int pngu_clamp (int value, int min, int max) +{ + if (value < min) + value = min; + else if (value > max) + value = max; + + return value; +} + diff --git a/CustomizeMiiInstaller/source/libpng/pngu/pngu.h b/CustomizeMiiInstaller/source/libpng/pngu/pngu.h new file mode 100644 index 0000000..b5e172b --- /dev/null +++ b/CustomizeMiiInstaller/source/libpng/pngu/pngu.h @@ -0,0 +1,171 @@ +/******************************************************************************************** + +PNGU Version : 0.2a + +Coder : frontier + +More info : http://frontier-dev.net + +********************************************************************************************/ +#ifndef __PNGU__ +#define __PNGU__ + +// Return codes +#define PNGU_OK 0 +#define PNGU_ODD_WIDTH 1 +#define PNGU_ODD_STRIDE 2 +#define PNGU_INVALID_WIDTH_OR_HEIGHT 3 +#define PNGU_FILE_IS_NOT_PNG 4 +#define PNGU_UNSUPPORTED_COLOR_TYPE 5 +#define PNGU_NO_FILE_SELECTED 6 +#define PNGU_CANT_OPEN_FILE 7 +#define PNGU_CANT_READ_FILE 8 +#define PNGU_LIB_ERROR 9 + +// Color types +#define PNGU_COLOR_TYPE_GRAY 1 +#define PNGU_COLOR_TYPE_GRAY_ALPHA 2 +#define PNGU_COLOR_TYPE_PALETTE 3 +#define PNGU_COLOR_TYPE_RGB 4 +#define PNGU_COLOR_TYPE_RGB_ALPHA 5 +#define PNGU_COLOR_TYPE_UNKNOWN 6 + + +#ifdef __cplusplus + extern "C" { +#endif + +// Types +typedef unsigned char PNGU_u8; +typedef unsigned short PNGU_u16; +typedef unsigned int PNGU_u32; +typedef unsigned long long PNGU_u64; + +typedef struct +{ + PNGU_u8 r; + PNGU_u8 g; + PNGU_u8 b; +} PNGUCOLOR; + +typedef struct +{ + PNGU_u32 imgWidth; // In pixels + PNGU_u32 imgHeight; // In pixels + PNGU_u32 imgBitDepth; // In bitx + PNGU_u32 imgColorType; // PNGU_COLOR_TYPE_* + PNGU_u32 validBckgrnd; // Non zero if there is a background color + PNGUCOLOR bckgrnd; // Backgroun color + PNGU_u32 numTrans; // Number of transparent colors + PNGUCOLOR *trans; // Transparent colors +} PNGUPROP; + +// Image context, always initialize with SelectImageFrom* and free with ReleaseImageContext +struct _IMGCTX; +typedef struct _IMGCTX *IMGCTX; + + +/**************************************************************************** +* Pixel conversion * +****************************************************************************/ + +// Macro to convert RGB8 values to RGB565 +#define PNGU_RGB8_TO_RGB565(r,g,b) ( ((((PNGU_u16) r) & 0xF8U) << 8) | ((((PNGU_u16) g) & 0xFCU) << 3) | (((PNGU_u16) b) >> 3) ) + +// Macro to convert RGBA8 values to RGB5A3 +#define PNGU_RGB8_TO_RGB5A3(r,g,b,a) (PNGU_u16) (((a & 0xE0U) == 0xE0U) ? \ + (0x8000U | ((((PNGU_u16) r) & 0xF8U) << 7) | ((((PNGU_u16) g) & 0xF8U) << 2) | (((PNGU_u16) b) >> 3)) : \ + (((((PNGU_u16) a) & 0xE0U) << 7) | ((((PNGU_u16) r) & 0xF0U) << 4) | (((PNGU_u16) g) & 0xF0U) | ((((PNGU_u16) b) & 0xF0U) >> 4))) + +// Function to convert two RGB8 values to YCbYCr +PNGU_u32 PNGU_RGB8_TO_YCbYCr (PNGU_u8 r1, PNGU_u8 g1, PNGU_u8 b1, PNGU_u8 r2, PNGU_u8 g2, PNGU_u8 b2); + +// Function to convert an YCbYCr to two RGB8 values. +void PNGU_YCbYCr_TO_RGB8 (PNGU_u32 ycbycr, PNGU_u8 *r1, PNGU_u8 *g1, PNGU_u8 *b1, PNGU_u8 *r2, PNGU_u8 *g2, PNGU_u8 *b2); + + +/**************************************************************************** +* Image context handling * +****************************************************************************/ + +// Selects a PNG file, previosly loaded into a buffer, and creates an image context for subsequent procesing. +IMGCTX PNGU_SelectImageFromBuffer (const void *buffer); + +// Selects a PNG file, from any devoptab device, and creates an image context for subsequent procesing. +IMGCTX PNGU_SelectImageFromDevice (const char *filename); + +// Frees resources associated with an image context. Always call this function when you no longer need the IMGCTX. +void PNGU_ReleaseImageContext (IMGCTX ctx); + + +/**************************************************************************** +* Miscelaneous * +****************************************************************************/ + +// Retrieves info from selected PNG file, including image dimensions, color format, background and transparency colors. +int PNGU_GetImageProperties (IMGCTX ctx, PNGUPROP *fileproperties); + + +/**************************************************************************** +* Image conversion * +****************************************************************************/ + +// Expands selected image into an YCbYCr buffer. You need to specify context, image dimensions, +// destination address and stride in pixels (stride = buffer width - image width). +int PNGU_DecodeToYCbYCr (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, void *buffer, PNGU_u32 stride); + +// Macro for decoding an image inside a buffer at given coordinates. +#define PNGU_DECODE_TO_COORDS_YCbYCr(ctx,coordX,coordY,imgWidth,imgHeight,bufferWidth,bufferHeight,buffer) \ + \ + PNGU_DecodeToYCbYCr (ctx, imgWidth, imgHeight, ((void *) buffer) + (coordY) * (bufferWidth) * 2 + \ + (coordX) * 2, (bufferWidth) - (imgWidth)) + +// Expands selected image into a linear RGB565 buffer. You need to specify context, image dimensions, +// destination address and stride in pixels (stride = buffer width - image width). +int PNGU_DecodeToRGB565 (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, void *buffer, PNGU_u32 stride); + +// Macro for decoding an image inside a buffer at given coordinates. +#define PNGU_DECODE_TO_COORDS_RGB565(ctx,coordX,coordY,imgWidth,imgHeight,bufferWidth,bufferHeight,buffer) \ + \ + PNGU_DecodeToRGB565 (ctx, imgWidth, imgHeight, ((void *) buffer) + (coordY) * (bufferWidth) * 2 + \ + (coordX) * 2, (bufferWidth) - (imgWidth)) + +// Expands selected image into a linear RGBA8 buffer. You need to specify context, image dimensions, +// destination address, stride in pixels and default alpha value, which is used if the source image +// doesn't have an alpha channel. +int PNGU_DecodeToRGBA8 (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, void *buffer, PNGU_u32 stride, PNGU_u8 default_alpha); + +// Macro for decoding an image inside a buffer at given coordinates. +#define PNGU_DECODE_TO_COORDS_RGBA8(ctx,coordX,coordY,imgWidth,imgHeight,default_alpha,bufferWidth,bufferHeight,buffer) \ + \ + PNGU_DecodeToRGBA8 (ctx, imgWidth, imgHeight, ((void *) buffer) + (coordY) * (bufferWidth) * 2 + \ + (coordX) * 2, (bufferWidth) - (imgWidth), default_alpha) + +// Expands selected image into a 4x4 tiled RGB565 buffer. You need to specify context, image dimensions +// and destination address. +int PNGU_DecodeTo4x4RGB565 (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, void *buffer); + +// Expands selected image into a 4x4 tiled RGB5A3 buffer. You need to specify context, image dimensions, +// destination address and default alpha value, which is used if the source image doesn't have an alpha channel. +int PNGU_DecodeTo4x4RGB5A3 (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, void *buffer, PNGU_u8 default_alpha); + +// Expands selected image into a 4x4 tiled RGBA8 buffer. You need to specify context, image dimensions, +// destination address and default alpha value, which is used if the source image doesn't have an alpha channel. +int PNGU_DecodeTo4x4RGBA8 (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, void *buffer, PNGU_u8 default_alpha); + +// Encodes an YCbYCr image in PNG format and stores it in the selected device or memory buffer. You need to +// specify context, image dimensions, destination address and stride in pixels (stride = buffer width - image width). +int PNGU_EncodeFromYCbYCr (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, void *buffer, PNGU_u32 stride); + +// Macro for encoding an image stored into an YCbYCr buffer at given coordinates. +#define PNGU_ENCODE_TO_COORDS_YCbYCr(ctx,coordX,coordY,imgWidth,imgHeight,bufferWidth,bufferHeight,buffer) \ + \ + PNGU_EncodeFromYCbYCr (ctx, imgWidth, imgHeight, ((void *) buffer) + (coordY) * (bufferWidth) * 2 + \ + (coordX) * 2, (bufferWidth) - (imgWidth)) + +#ifdef __cplusplus + } +#endif + +#endif + diff --git a/CustomizeMiiInstaller/source/menu.c b/CustomizeMiiInstaller/source/menu.c new file mode 100644 index 0000000..313506c --- /dev/null +++ b/CustomizeMiiInstaller/source/menu.c @@ -0,0 +1,36 @@ +#include +#include +#include +#include +#include + +#include "fat.h" +#include "restart.h" +#include "title.h" +#include "utils.h" +#include "video.h" +#include "wad.h" +#include "wpad.h" + +/* Constants */ +#define CIOS_VERSION 249 + +void LoadSelectedIOS() +{ + u8 selectedIOS = Wad_SelectIOS(); + + s32 ret; + ret = IOS_ReloadIOS(selectedIOS); + if (ret<0) + { + printf("\nUsing default IOS"); + } else + { + printf("\nUsing selected IOS %d\n", selectedIOS); + } +} + +void Menu_Loop(void) +{ + Wad_InstallFromMemory(); +} diff --git a/CustomizeMiiInstaller/source/menu.h b/CustomizeMiiInstaller/source/menu.h new file mode 100644 index 0000000..92cd259 --- /dev/null +++ b/CustomizeMiiInstaller/source/menu.h @@ -0,0 +1,8 @@ +#ifndef _MENU_H_ +#define _MENU_H_ + +/* Prototypes */ +void Menu_Loop(void); + +#endif + diff --git a/CustomizeMiiInstaller/source/restart.c b/CustomizeMiiInstaller/source/restart.c new file mode 100644 index 0000000..0660ac8 --- /dev/null +++ b/CustomizeMiiInstaller/source/restart.c @@ -0,0 +1,33 @@ +#include +#include + +#include "sys.h" +#include "wpad.h" + + +void Restart(void) +{ + printf("\n Restarting Wii..."); + fflush(stdout); + + /* Load system menu */ + Sys_LoadMenu(); +} + +void Restart_Wait(void) +{ + printf("\n"); + + printf(" Press any button to restart..."); + fflush(stdout); + + /* Wait for button */ + Wpad_WaitButtons(); + + printf(" Restarting Wii..."); + fflush(stdout); + + /* Load system menu */ + Sys_LoadMenu(); +} + diff --git a/CustomizeMiiInstaller/source/restart.h b/CustomizeMiiInstaller/source/restart.h new file mode 100644 index 0000000..3df94d7 --- /dev/null +++ b/CustomizeMiiInstaller/source/restart.h @@ -0,0 +1,8 @@ +#ifndef _RESTART_H_ +#define _RESTART_H_ + +/* Prototypes */ +void Restart(void); +void Restart_Wait(void); + +#endif diff --git a/CustomizeMiiInstaller/source/sha1.c b/CustomizeMiiInstaller/source/sha1.c new file mode 100644 index 0000000..83a533a --- /dev/null +++ b/CustomizeMiiInstaller/source/sha1.c @@ -0,0 +1,172 @@ +/* +SHA-1 in C +By Steve Reid +100% Public Domain + +Test Vectors (from FIPS PUB 180-1) +"abc" + A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D +"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" + 84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1 +A million repetitions of "a" + 34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F +*/ + +/* #define LITTLE_ENDIAN * This should be #define'd if true. */ +#define SHA1HANDSOFF + +#include +#include +#include "sha1.h" + +#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits)))) + +/* blk0() and blk() perform the initial expand. */ +/* I got the idea of expanding during the round function from SSLeay */ +#ifdef LITTLE_ENDIAN +#define blk0(i) (block->l[i] = (rol(block->l[i],24)&0xFF00FF00) \ + |(rol(block->l[i],8)&0x00FF00FF)) +#else +#define blk0(i) block->l[i] +#endif +#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \ + ^block->l[(i+2)&15]^block->l[i&15],1)) + +/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */ +#define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30); +#define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30); +#define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30); +#define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30); +#define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30); + + +/* Hash a single 512-bit block. This is the core of the algorithm. */ + +void SHA1Transform(unsigned long state[5], unsigned char buffer[64]) +{ +unsigned long a, b, c, d, e; +typedef union { + unsigned char c[64]; + unsigned long l[16]; +} CHAR64LONG16; +CHAR64LONG16* block; +#ifdef SHA1HANDSOFF +static unsigned char workspace[64]; + block = (CHAR64LONG16*)workspace; + memcpy(block, buffer, 64); +#else + block = (CHAR64LONG16*)buffer; +#endif + /* Copy context->state[] to working vars */ + a = state[0]; + b = state[1]; + c = state[2]; + d = state[3]; + e = state[4]; + /* 4 rounds of 20 operations each. Loop unrolled. */ + R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3); + R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7); + R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11); + R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15); + R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19); + R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23); + R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27); + R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31); + R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35); + R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39); + R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43); + R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47); + R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51); + R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55); + R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59); + R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63); + R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67); + R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71); + R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75); + R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79); + /* Add the working vars back into context.state[] */ + state[0] += a; + state[1] += b; + state[2] += c; + state[3] += d; + state[4] += e; + /* Wipe variables */ + a = b = c = d = e = 0; +} + + +/* SHA1Init - Initialize new context */ + +void SHA1Init(SHA1_CTX* context) +{ + /* SHA1 initialization constants */ + context->state[0] = 0x67452301; + context->state[1] = 0xEFCDAB89; + context->state[2] = 0x98BADCFE; + context->state[3] = 0x10325476; + context->state[4] = 0xC3D2E1F0; + context->count[0] = context->count[1] = 0; +} + + +/* Run your data through this. */ + +void SHA1Update(SHA1_CTX* context, unsigned char* data, unsigned int len) +{ +unsigned int i, j; + + j = (context->count[0] >> 3) & 63; + if ((context->count[0] += len << 3) < (len << 3)) context->count[1]++; + context->count[1] += (len >> 29); + if ((j + len) > 63) { + memcpy(&context->buffer[j], data, (i = 64-j)); + SHA1Transform(context->state, context->buffer); + for ( ; i + 63 < len; i += 64) { + SHA1Transform(context->state, &data[i]); + } + j = 0; + } + else i = 0; + memcpy(&context->buffer[j], &data[i], len - i); +} + + +/* Add padding and return the message digest. */ + +void SHA1Final(unsigned char digest[20], SHA1_CTX* context) +{ +unsigned long i, j; +unsigned char finalcount[8]; + + for (i = 0; i < 8; i++) { + finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)] + >> ((3-(i & 3)) * 8) ) & 255); /* Endian independent */ + } + SHA1Update(context, (unsigned char *)"\200", 1); + while ((context->count[0] & 504) != 448) { + SHA1Update(context, (unsigned char *)"\0", 1); + } + SHA1Update(context, finalcount, 8); /* Should cause a SHA1Transform() */ + for (i = 0; i < 20; i++) { + digest[i] = (unsigned char) + ((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255); + } + /* Wipe variables */ + i = j = 0; + memset(context->buffer, 0, 64); + memset(context->state, 0, 20); + memset(context->count, 0, 8); + memset(&finalcount, 0, 8); +#ifdef SHA1HANDSOFF /* make SHA1Transform overwrite it's own static vars */ + SHA1Transform(context->state, context->buffer); +#endif +} + +void SHA1(unsigned char *ptr, unsigned int size, unsigned char *outbuf) { + SHA1_CTX ctx; + + SHA1Init(&ctx); + SHA1Update(&ctx, ptr, size); + SHA1Final(outbuf, &ctx); +} + diff --git a/CustomizeMiiInstaller/source/sha1.h b/CustomizeMiiInstaller/source/sha1.h new file mode 100644 index 0000000..757af1c --- /dev/null +++ b/CustomizeMiiInstaller/source/sha1.h @@ -0,0 +1,12 @@ +typedef struct { + unsigned long state[5]; + unsigned long count[2]; + unsigned char buffer[64]; +} SHA1_CTX; + +void SHA1Transform(unsigned long state[5], unsigned char buffer[64]); +void SHA1Init(SHA1_CTX* context); +void SHA1Update(SHA1_CTX* context, unsigned char* data, unsigned int len); +void SHA1Final(unsigned char digest[20], SHA1_CTX* context); + +void SHA1(unsigned char *ptr, unsigned int size, unsigned char *outbuf); diff --git a/CustomizeMiiInstaller/source/stub.S b/CustomizeMiiInstaller/source/stub.S new file mode 100644 index 0000000..418c838 --- /dev/null +++ b/CustomizeMiiInstaller/source/stub.S @@ -0,0 +1,6 @@ + .rodata + + .globl bgData + .balign 32 +bgData: + .incbin "../data/background" diff --git a/CustomizeMiiInstaller/source/sys.c b/CustomizeMiiInstaller/source/sys.c new file mode 100644 index 0000000..c9e7723 --- /dev/null +++ b/CustomizeMiiInstaller/source/sys.c @@ -0,0 +1,98 @@ +#include +#include +#include + +#include "sys.h" + +/* Constants */ +#define CERTS_LEN 0x280 + +/* Variables */ +static const char certs_fs[] ATTRIBUTE_ALIGN(32) = "/sys/cert.sys"; + + +void __Sys_ResetCallback(void) +{ + /* Reboot console */ + Sys_Reboot(); +} + +void __Sys_PowerCallback(void) +{ + /* Poweroff console */ + Sys_Shutdown(); +} + + +void Sys_Init(void) +{ + /* Initialize video subsytem */ + VIDEO_Init(); + + /* Set RESET/POWER button callback */ + SYS_SetResetCallback(__Sys_ResetCallback); + SYS_SetPowerCallback(__Sys_PowerCallback); +} + +void Sys_Reboot(void) +{ + /* Restart console */ + STM_RebootSystem(); +} + +void Sys_Shutdown(void) +{ + /* Poweroff console */ + if(CONF_GetShutdownMode() == CONF_SHUTDOWN_IDLE) { + s32 ret; + + /* Set LED mode */ + ret = CONF_GetIdleLedMode(); + if(ret >= 0 && ret <= 2) + STM_SetLedMode(ret); + + /* Shutdown to idle */ + STM_ShutdownToIdle(); + } else { + /* Shutdown to standby */ + STM_ShutdownToStandby(); + } +} + +void Sys_LoadMenu(void) +{ + u32 *stub = (u32 *)0x80001800; + + /* Homebrew Channel stub */ + if (*stub) + exit(0); + + /* Return to the Wii system menu */ + SYS_ResetSystem(SYS_RETURNTOMENU, 0, 0); +} + +s32 Sys_GetCerts(signed_blob **certs, u32 *len) +{ + static signed_blob certificates[CERTS_LEN] ATTRIBUTE_ALIGN(32); + + s32 fd, ret; + + /* Open certificates file */ + fd = IOS_Open(certs_fs, 1); + if (fd < 0) + return fd; + + /* Read certificates */ + ret = IOS_Read(fd, certificates, sizeof(certificates)); + + /* Close file */ + IOS_Close(fd); + + /* Set values */ + if (ret > 0) { + *certs = certificates; + *len = sizeof(certificates); + } + + return ret; +} diff --git a/CustomizeMiiInstaller/source/sys.h b/CustomizeMiiInstaller/source/sys.h new file mode 100644 index 0000000..cfbf604 --- /dev/null +++ b/CustomizeMiiInstaller/source/sys.h @@ -0,0 +1,11 @@ +#ifndef _SYS_H_ +#define _SYS_H_ + +/* Prototypes */ +void Sys_Init(void); +void Sys_Reboot(void); +void Sys_Shutdown(void); +void Sys_LoadMenu(void); +s32 Sys_GetCerts(signed_blob **, u32 *); + +#endif diff --git a/CustomizeMiiInstaller/source/title.c b/CustomizeMiiInstaller/source/title.c new file mode 100644 index 0000000..0d05bd9 --- /dev/null +++ b/CustomizeMiiInstaller/source/title.c @@ -0,0 +1,256 @@ +#include +#include +#include +#include +#include + +#include "utils.h" + + +s32 Title_GetList(u64 **outbuf, u32 *outlen) +{ + u64 *titles = NULL; + + u32 len, nb_titles; + s32 ret; + + /* Get number of titles */ + ret = ES_GetNumTitles(&nb_titles); + if (ret < 0) + return ret; + + /* Calculate buffer lenght */ + len = round_up(sizeof(u64) * nb_titles, 32); + + /* Allocate memory */ + titles = memalign(32, len); + if (!titles) + return -1; + + /* Get titles */ + ret = ES_GetTitles(titles, nb_titles); + if (ret < 0) + goto err; + + /* Set values */ + *outbuf = titles; + *outlen = nb_titles; + + return 0; + +err: + /* Free memory */ + if (titles) + free(titles); + + return ret; +} + +s32 Title_GetTicketViews(u64 tid, tikview **outbuf, u32 *outlen) +{ + tikview *views = NULL; + + u32 nb_views; + s32 ret; + + /* Get number of ticket views */ + ret = ES_GetNumTicketViews(tid, &nb_views); + if (ret < 0) + return ret; + + /* Allocate memory */ + views = (tikview *)memalign(32, sizeof(tikview) * nb_views); + if (!views) + return -1; + + /* Get ticket views */ + ret = ES_GetTicketViews(tid, views, nb_views); + if (ret < 0) + goto err; + + /* Set values */ + *outbuf = views; + *outlen = nb_views; + + return 0; + +err: + /* Free memory */ + if (views) + free(views); + + return ret; +} + +s32 Title_GetTMD(u64 tid, signed_blob **outbuf, u32 *outlen) +{ + void *p_tmd = NULL; + + u32 len; + s32 ret; + + /* Get TMD size */ + ret = ES_GetStoredTMDSize(tid, &len); + if (ret < 0) + return ret; + + /* Allocate memory */ + p_tmd = memalign(32, round_up(len, 32)); + if (!p_tmd) + return -1; + + /* Read TMD */ + ret = ES_GetStoredTMD(tid, p_tmd, len); + if (ret < 0) + goto err; + + /* Set values */ + *outbuf = p_tmd; + *outlen = len; + + return 0; + +err: + /* Free memory */ + if (p_tmd) + free(p_tmd); + + return ret; +} + +s32 Title_GetVersion(u64 tid, u16 *outbuf) +{ + signed_blob *p_tmd = NULL; + tmd *tmd_data = NULL; + + u32 len; + s32 ret; + + /* Get title TMD */ + ret = Title_GetTMD(tid, &p_tmd, &len); + if (ret < 0) + return ret; + + /* Retrieve TMD info */ + tmd_data = (tmd *)SIGNATURE_PAYLOAD(p_tmd); + + /* Set values */ + *outbuf = tmd_data->title_version; + + /* Free memory */ + free(p_tmd); + + return 0; +} + +s32 Title_GetSysVersion(u64 tid, u64 *outbuf) +{ + signed_blob *p_tmd = NULL; + tmd *tmd_data = NULL; + + u32 len; + s32 ret; + + /* Get title TMD */ + ret = Title_GetTMD(tid, &p_tmd, &len); + if (ret < 0) + return ret; + + /* Retrieve TMD info */ + tmd_data = (tmd *)SIGNATURE_PAYLOAD(p_tmd); + + /* Set values */ + *outbuf = tmd_data->sys_version; + + /* Free memory */ + free(p_tmd); + + return 0; +} + +s32 Title_GetSize(u64 tid, u32 *outbuf) +{ + signed_blob *p_tmd = NULL; + tmd *tmd_data = NULL; + + u32 cnt, len, size = 0; + s32 ret; + + /* Get title TMD */ + ret = Title_GetTMD(tid, &p_tmd, &len); + if (ret < 0) + return ret; + + /* Retrieve TMD info */ + tmd_data = (tmd *)SIGNATURE_PAYLOAD(p_tmd); + + /* Calculate title size */ + for (cnt = 0; cnt < tmd_data->num_contents; cnt++) { + tmd_content *content = &tmd_data->contents[cnt]; + + /* Add content size */ + size += content->size; + } + + /* Set values */ + *outbuf = size; + + /* Free memory */ + free(p_tmd); + + return 0; +} + +s32 Title_GetIOSVersions(u8 **outbuf, u32 *outlen) +{ + u8 *buffer = NULL; + u64 *list = NULL; + + u32 count, cnt, idx; + s32 ret; + + /* Get title list */ + ret = Title_GetList(&list, &count); + if (ret < 0) + return ret; + + /* Count IOS */ + for (cnt = idx = 0; idx < count; idx++) { + u32 tidh = (list[idx] >> 32); + u32 tidl = (list[idx] & 0xFFFFFFFF); + + /* Title is IOS */ + if ((tidh == 0x1) && (tidl >= 3) && (tidl <= 255)) + cnt++; + } + + /* Allocate memory */ + buffer = (u8 *)memalign(32, cnt); + if (!buffer) { + ret = -1; + goto out; + } + + /* Copy IOS */ + for (cnt = idx = 0; idx < count; idx++) { + u32 tidh = (list[idx] >> 32); + u32 tidl = (list[idx] & 0xFFFFFFFF); + + /* Title is IOS */ + if ((tidh == 0x1) && (tidl >= 3) && (tidl <= 255)) + buffer[cnt++] = (u8)(tidl & 0xFF); + } + + /* Set values */ + *outbuf = buffer; + *outlen = cnt; + + goto out; + +out: + /* Free memory */ + if (list) + free(list); + + return ret; +} diff --git a/CustomizeMiiInstaller/source/title.h b/CustomizeMiiInstaller/source/title.h new file mode 100644 index 0000000..5d1c573 --- /dev/null +++ b/CustomizeMiiInstaller/source/title.h @@ -0,0 +1,16 @@ +#ifndef _TITLE_H_ +#define _TITLE_H_ + +/* Constants */ +#define BLOCK_SIZE 1024 + +/* Prototypes */ +s32 Title_GetList(u64 **, u32 *); +s32 Title_GetTicketViews(u64, tikview **, u32 *); +s32 Title_GetTMD(u64, signed_blob **, u32 *); +s32 Title_GetVersion(u64, u16 *); +s32 Title_GetSysVersion(u64, u64 *); +s32 Title_GetSize(u64, u32 *); +s32 Title_GetIOSVersions(u8 **, u32 *); + +#endif diff --git a/CustomizeMiiInstaller/source/utils.h b/CustomizeMiiInstaller/source/utils.h new file mode 100644 index 0000000..3a4862b --- /dev/null +++ b/CustomizeMiiInstaller/source/utils.h @@ -0,0 +1,15 @@ +#ifndef _UTILS_H_ +#define _UTILS_H_ + +/* Constants */ +#define KB_SIZE 1024.0 +#define MB_SIZE 1048576.0 +#define GB_SIZE 1073741824.0 + +/* Macros */ +#define round_up(x,n) (-(-(x) & -(n))) + +/* Prototypes */ +u32 swap32(u32); + +#endif diff --git a/CustomizeMiiInstaller/source/video.c b/CustomizeMiiInstaller/source/video.c new file mode 100644 index 0000000..0182671 --- /dev/null +++ b/CustomizeMiiInstaller/source/video.c @@ -0,0 +1,141 @@ +#include +#include + +#include "sys.h" +#include "video.h" + +/* Video variables */ +static void *framebuffer = NULL; +static GXRModeObj *vmode = NULL; + + +void Con_Init(u32 x, u32 y, u32 w, u32 h) +{ + /* Create console in the framebuffer */ + CON_InitEx(vmode, x, y, w, h); +} + +void Con_Clear(void) +{ + /* Clear console */ + printf("\x1b[2J"); + fflush(stdout); +} + +void Con_ClearLine(void) +{ + s32 cols, rows; + u32 cnt; + + printf("\r"); + fflush(stdout); + + /* Get console metrics */ + CON_GetMetrics(&cols, &rows); + + /* Erase line */ + for (cnt = 1; cnt < cols; cnt++) { + printf(" "); + fflush(stdout); + } + + printf("\r"); + fflush(stdout); +} + +void Con_FgColor(u32 color, u8 bold) +{ + /* Set foreground color */ + printf("\x1b[%u;%um", color + 30, bold); + fflush(stdout); +} + +void Con_BgColor(u32 color, u8 bold) +{ + /* Set background color */ + printf("\x1b[%u;%um", color + 40, bold); + fflush(stdout); +} + +void Con_FillRow(u32 row, u32 color, u8 bold) +{ + s32 cols, rows; + u32 cnt; + + /* Set color */ + printf("\x1b[%u;%um", color + 40, bold); + fflush(stdout); + + /* Get console metrics */ + CON_GetMetrics(&cols, &rows); + + /* Save current row and col */ + printf("\x1b[s"); + fflush(stdout); + + /* Move to specified row */ + printf("\x1b[%u;0H", row); + fflush(stdout); + + /* Fill row */ + for (cnt = 0; cnt < cols; cnt++) { + printf(" "); + fflush(stdout); + } + + /* Load saved row and col */ + printf("\x1b[u"); + fflush(stdout); + + /* Set default color */ + Con_BgColor(0, 0); + Con_FgColor(7, 1); +} + +void Video_Configure(GXRModeObj *rmode) +{ + /* Configure the video subsystem */ + VIDEO_Configure(rmode); + + /* Setup video */ + VIDEO_SetBlack(FALSE); + VIDEO_Flush(); + VIDEO_WaitVSync(); + + if (rmode->viTVMode & VI_NON_INTERLACE) + VIDEO_WaitVSync(); +} + +void Video_SetMode(void) +{ + /* Select preferred video mode */ + vmode = VIDEO_GetPreferredMode(NULL); + + /* Allocate memory for the framebuffer */ + framebuffer = MEM_K0_TO_K1(SYS_AllocateFramebuffer(vmode)); + + /* Configure the video subsystem */ + VIDEO_Configure(vmode); + + /* Setup video */ + VIDEO_SetNextFramebuffer(framebuffer); + VIDEO_SetBlack(FALSE); + VIDEO_Flush(); + VIDEO_WaitVSync(); + + if (vmode->viTVMode & VI_NON_INTERLACE) + VIDEO_WaitVSync(); + + /* Clear the screen */ + Video_Clear(COLOR_BLACK); +} + +void Video_Clear(s32 color) +{ + VIDEO_ClearFrameBuffer(vmode, framebuffer, color); +} + +void Video_DrawPng(IMGCTX ctx, PNGUPROP imgProp, u16 x, u16 y) +{ + PNGU_DECODE_TO_COORDS_YCbYCr(ctx, x, y, imgProp.imgWidth, imgProp.imgHeight, vmode->fbWidth, vmode->xfbHeight, framebuffer); +} diff --git a/CustomizeMiiInstaller/source/video.h b/CustomizeMiiInstaller/source/video.h new file mode 100644 index 0000000..e0fb7fd --- /dev/null +++ b/CustomizeMiiInstaller/source/video.h @@ -0,0 +1,19 @@ +#ifndef _VIDEO_H_ +#define _VIDEO_H_ + +#include "libpng/pngu/pngu.h" + +/* Prototypes */ +void Con_Init(u32, u32, u32, u32); +void Con_Clear(void); +void Con_ClearLine(void); +void Con_FgColor(u32, u8); +void Con_BgColor(u32, u8); +void Con_FillRow(u32, u32, u8); + +void Video_Configure(GXRModeObj *); +void Video_SetMode(void); +void Video_Clear(s32); +void Video_DrawPng(IMGCTX, PNGUPROP, u16, u16); + +#endif diff --git a/CustomizeMiiInstaller/source/wad-manager.c b/CustomizeMiiInstaller/source/wad-manager.c new file mode 100644 index 0000000..92453d2 --- /dev/null +++ b/CustomizeMiiInstaller/source/wad-manager.c @@ -0,0 +1,72 @@ +#include +#include +#include +#include + +#include "gui.h" +#include "menu.h" +#include "restart.h" +#include "sys.h" +#include "video.h" +#include "wpad.h" + + +void Disclaimer(void) +{ + /* Print disclaimer */ + printf(" [DISCLAIMER]:\n\n"); + + printf(" THIS APPLICATION COMES WITH NO WARRANTY AT ALL,\n"); + printf(" NEITHER EXPRESS NOR IMPLIED.\n"); + printf(" I DO NOT TAKE ANY RESPONSIBILITY FOR ANY DAMAGE IN YOUR\n"); + printf(" WII CONSOLE BECAUSE OF A IMPROPER USAGE OF THIS SOFTWARE.\n\n"); + + printf(">> If you agree and install the streamed wad\n"); + printf(">> press A button to continue.\n"); + printf(">> Otherwise, press B button to restart your Wii.\n"); + + /* Wait for user answer */ + for (;;) { + u32 buttons = Wpad_WaitButtons(); + + /* A button */ + if ((buttons & WPAD_BUTTON_A)||(buttons & PAD_BUTTON_A)) + break; + + /* B button */ + if ((buttons & WPAD_BUTTON_B)||(buttons & WPAD_CLASSIC_BUTTON_B)) + Restart(); + } +} + +int main(int argc, char **argv) +{ + /* Initialize subsystems */ + Sys_Init(); + + /* Set video mode */ + Video_SetMode(); + + /* Initialize console */ + Gui_InitConsole(); + + /* Draw background */ + Gui_DrawBackground(); + + /* Load Selected IOS */ + LoadSelectedIOS(); + + /* Initialize Wiimote */ + Wpad_Init(); + + /* Print disclaimer */ + Disclaimer(); + + /* Menu loop */ + Menu_Loop(); + + /* Restart Wii */ + Restart_Wait(); + + return 0; +} diff --git a/CustomizeMiiInstaller/source/wad.c b/CustomizeMiiInstaller/source/wad.c new file mode 100644 index 0000000..79c2ea1 --- /dev/null +++ b/CustomizeMiiInstaller/source/wad.c @@ -0,0 +1,374 @@ +#include +#include +#include +#include + +#include "title.h" +#include "utils.h" +#include "video.h" +#include "wad.h" +#include "sha1.h" +#include "install.h" + + +/* 'WAD Header' structure */ +typedef struct { + /* Header length */ + u32 header_len; + + /* WAD type */ + u16 type; + + u16 padding; + + /* Data length */ + u32 certs_len; + u32 crl_len; + u32 tik_len; + u32 tmd_len; + u32 data_len; + u32 footer_len; +} ATTRIBUTE_PACKED wadHeader; + +/* Variables */ +static u8 wadBuffer[BLOCK_SIZE] ATTRIBUTE_ALIGN(32); + +void * startOfData; +void * endOfData; +void * internalPointer; + +void mopen(void * memPointer) +{ + u32 size = *((u32 * ) memPointer); + startOfData = memPointer + 28; + endOfData = startOfData + size; + internalPointer = startOfData; +} + + +int mseek(u32 offset, int origin) +{ + if (origin == SEEK_SET) + { + internalPointer = startOfData + offset; + } else if (origin == SEEK_CUR) + { + internalPointer = internalPointer + offset; + } else if (origin == SEEK_END) { + internalPointer = endOfData - offset; + } else + { + return -2; + } + + if ((internalPointer endOfData)) + { + return -1; + } else + { + return 0; + } +} + +int mread(void * buf, int size, int count) +{ + memcpy(buf, internalPointer, size*count); + //DCFlushRange(buf, size*count); + return 0; +} + + +//-------------------------- INSTALL FROM MEMORY ------------------------------- + +s32 __Wad_ReadFile(void *outbuf, u32 offset, u32 len) +{ + s32 ret; + + /* Seek to offset */ + mseek(offset, SEEK_SET); + + /* Read data */ + ret = mread(outbuf, len, 1); + if (ret < 0) + return ret; + + return 0; +} + +s32 __Wad_ReadAlloc(void **outbuf, u32 offset, u32 len) +{ + void *buffer = NULL; + s32 ret; + + /* Allocate memory */ + buffer = memalign(32, len); + if (!buffer) + return -1; + + /* Read file */ + ret = __Wad_ReadFile(buffer, offset, len); + if (ret < 0) { + free(buffer); + return ret; + } + + /* Set pointer */ + *outbuf = buffer; + + return 0; +} + +s32 __Wad_GetTitleID(wadHeader *header, u64 *tid) +{ + signed_blob *p_tik = NULL; + tik *tik_data = NULL; + + u32 offset = 0; + s32 ret; + + /* Ticket offset */ + offset += round_up(header->header_len, 64); + offset += round_up(header->certs_len, 64); + offset += round_up(header->crl_len, 64); + + /* Read ticket */ + ret = __Wad_ReadAlloc((void *)&p_tik, offset, header->tik_len); + if (ret < 0) + goto out; + + /* Ticket data */ + tik_data = (tik *)SIGNATURE_PAYLOAD(p_tik); + + /* Copy title ID */ + *tid = tik_data->titleid; + +out: + /* Free memory */ + if (p_tik) + free(p_tik); + + return ret; +} + + +s32 __Wad_Install() +{ + wadHeader *header = NULL; + signed_blob *p_certs = NULL, *p_crl = NULL, *p_tik = NULL, *p_tmd = NULL; + + tmd *tmd_data = NULL; + + u32 cnt, offset = 0; + s32 ret; + + printf("\t\t>> Reading WAD data..."); + fflush(stdout); + + /* WAD header */ + ret = __Wad_ReadAlloc((void *)&header, offset, sizeof(wadHeader)); + if (ret < 0) + goto err; + else + offset += round_up(header->header_len, 64); + + /* WAD certificates */ + ret = __Wad_ReadAlloc((void *)&p_certs, offset, header->certs_len); + if (ret < 0) + goto err; + else + offset += round_up(header->certs_len, 64); + + /* WAD crl */ + if (header->crl_len) { + ret = __Wad_ReadAlloc((void *)&p_crl, offset, header->crl_len); + if (ret < 0) + goto err; + else + offset += round_up(header->crl_len, 64); + } + + /* WAD ticket */ + ret = __Wad_ReadAlloc((void *)&p_tik, offset, header->tik_len); + if (ret < 0) + goto err; + else + offset += round_up(header->tik_len, 64); + + /* WAD TMD */ + ret = __Wad_ReadAlloc((void *)&p_tmd, offset, header->tmd_len); + if (ret < 0) + goto err; + else + offset += round_up(header->tmd_len, 64); + + Con_ClearLine(); + + printf("\t\t>> Installing ticket..."); + fflush(stdout); + + /* Install ticket */ + ret = ES_AddTicket(p_tik, header->tik_len, p_certs, header->certs_len, p_crl, header->crl_len); + if (ret < 0) + goto err; + + Con_ClearLine(); + + printf("\r\t\t>> Installing title..."); + fflush(stdout); + + /* Install title */ + ret = ES_AddTitleStart(p_tmd, header->tmd_len, p_certs, header->certs_len, p_crl, header->crl_len); + if (ret < 0) + goto err; + + /* Get TMD info */ + tmd_data = (tmd *)SIGNATURE_PAYLOAD(p_tmd); + + /* Install contents */ + for (cnt = 0; cnt < tmd_data->num_contents; cnt++) { + tmd_content *content = &tmd_data->contents[cnt]; + + u32 idx = 0, len; + s32 cfd; + + Con_ClearLine(); + + printf("\r\t\t>> Installing content #%02d...", content->cid); + fflush(stdout); + + /* Encrypted content size */ + len = round_up(content->size, 64); + + /* Install content */ + cfd = ES_AddContentStart(tmd_data->title_id, content->cid); + if (cfd < 0) { + ret = cfd; + goto err; + } + + /* Install content data */ + while (idx < len) { + u32 size; + + /* Data length */ + size = (len - idx); + if (size > BLOCK_SIZE) + size = BLOCK_SIZE; + + /* Read data */ + ret = __Wad_ReadFile(&wadBuffer, offset, size); + if (ret < 0) + goto err; + + /* Install data */ + ret = ES_AddContentData(cfd, wadBuffer, size); + if (ret < 0) + goto err; + + /* Increase variables */ + idx += size; + offset += size; + } + + /* Finish content installation */ + ret = ES_AddContentFinish(cfd); + if (ret < 0) + goto err; + } + + Con_ClearLine(); + + printf("\r\t\t>> Finishing installation..."); + fflush(stdout); + + /* Finish title install */ + ret = ES_AddTitleFinish(); + if (ret >= 0) { + printf(" OK!\n"); + goto out; + } + +err: + printf(" ERROR! (ret = %d)\n", ret); + + /* Cancel install */ + ES_AddTitleCancel(); + +out: + /* Free memory */ + if (header) + free(header); + if (p_certs) + free(p_certs); + if (p_crl) + free(p_crl); + if (p_tik) + free(p_tik); + if (p_tmd) + free(p_tmd); + + return ret; +} + + +void DumpHash(u8 * hash) +{ + int i; + for (i=0;i<20;i++) + { + printf("%x", hash[i]); + } +} + +s32 CompareHashes(u8 * hash1, u8 * hash2) +{ + + printf("\nCalculated SHA1 Hash : "); DumpHash(hash1); + printf("\nStored SHA1 Hash : "); DumpHash(hash2); + sleep(3); + + if (memcmp(hash1, hash2, 20)==0) + { + return 1; + } + else + { + return 0; + } +} + +s32 Wad_EnsureInjectedData() +{ + u32 size = *((u32 * ) install); + u8 wadOffset = 28; + + u8 hash1[20]; + + SHA1(((u8 *)install)+wadOffset, size , hash1); //Taking SHA of contents... + + return CompareHashes(hash1, ((u8 *)install)+4); +} + +s32 Wad_InstallFromMemory() +{ + /* Check integrity of the wad file using SHA */ + /* SHA digest of the installed wad will be from XX-XX region in the injected data */ + printf("\n\n"); + printf("\r\t\t>> Checking integrity of the contents..."); + if (Wad_EnsureInjectedData()) + { + printf("\r\t\t>> Wad file integrity check succeeded\n\n"); + mopen(install); + return __Wad_Install(); + } else + { + printf("\r\t\t>> Wad file integrity check failed! Will not install the wad, possible corruption during transfer..."); + } +} + +u8 Wad_SelectIOS() +{ + u8 iosOffset = 24; + return *(install+iosOffset); + +} \ No newline at end of file diff --git a/CustomizeMiiInstaller/source/wad.h b/CustomizeMiiInstaller/source/wad.h new file mode 100644 index 0000000..b231c33 --- /dev/null +++ b/CustomizeMiiInstaller/source/wad.h @@ -0,0 +1,7 @@ +#ifndef _WAD_H_ +#define _WAD_H_ + +/* Prototypes */ +s32 Wad_InstallFromMemory(); + +#endif diff --git a/CustomizeMiiInstaller/source/wpad.c b/CustomizeMiiInstaller/source/wpad.c new file mode 100644 index 0000000..2f50b9a --- /dev/null +++ b/CustomizeMiiInstaller/source/wpad.c @@ -0,0 +1,81 @@ +#include +#include + +#include "sys.h" +#include "wpad.h" + +/* Constants */ +#define MAX_WIIMOTES 4 + + +void __Wpad_PowerCallback(s32 chan) +{ + /* Poweroff console */ + Sys_Shutdown(); +} + + +s32 Wpad_Init(void) +{ + s32 ret; + + /* Initialize GC Pads */ + + ret = PAD_Init(); + if (ret < 0) + return ret; + + /* Initialize Wiimote subsystem */ + ret = WPAD_Init(); + if (ret < 0) + return ret; + + /* Set POWER button callback */ + WPAD_SetPowerButtonCallback(__Wpad_PowerCallback); + + return ret; +} + +void Wpad_Disconnect(void) +{ + u32 cnt; + + /* Disconnect Wiimotes */ + for (cnt = 0; cnt < MAX_WIIMOTES; cnt++) + WPAD_Disconnect(cnt); + + /* Shutdown Wiimote subsystem */ + WPAD_Shutdown(); +} + +u32 Wpad_GetButtons(void) +{ + u32 buttons = 0, cnt; + + /* Scan pads */ + WPAD_ScanPads(); + + /* Get pressed buttons */ + for (cnt = 0; cnt < MAX_WIIMOTES; cnt++) + buttons |= WPAD_ButtonsDown(cnt); + + return buttons; +} + +u32 Wpad_WaitButtons(void) +{ + u32 buttons = 0; + + /* Wait for button pressing */ + while (!buttons) { + buttons = Wpad_GetButtons(); + if (!buttons) + { + PAD_ScanPads(); + buttons = PAD_ButtonsDown(0); + } + VIDEO_WaitVSync(); + } + + return buttons; +} diff --git a/CustomizeMiiInstaller/source/wpad.h b/CustomizeMiiInstaller/source/wpad.h new file mode 100644 index 0000000..63053bb --- /dev/null +++ b/CustomizeMiiInstaller/source/wpad.h @@ -0,0 +1,12 @@ +#ifndef _WPAD_H_ +#define _WPAD_H_ + +#include + +/* Prototypes */ +s32 Wpad_Init(void); +void Wpad_Disconnect(void); +u32 Wpad_GetButtons(void); +u32 Wpad_WaitButtons(void); + +#endif diff --git a/Helpers/Helpers.csproj b/Helpers/Helpers.csproj index 13c91c0..65a6475 100644 --- a/Helpers/Helpers.csproj +++ b/Helpers/Helpers.csproj @@ -40,7 +40,7 @@ - + fLeJn~b^ymZ+nN$R@1uMbgm`Ti7?M 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