├── .rvid header info.txt ├── README.md ├── ds ├── .gitignore ├── LICENSE ├── Makefile ├── arm7 │ ├── Makefile │ └── source │ │ └── main.c ├── arm9 │ ├── Makefile │ └── source │ │ ├── graphics │ │ ├── lodepng.cpp │ │ └── lodepng.h │ │ ├── inifile.cpp │ │ ├── inifile.h │ │ ├── main.cpp │ │ ├── stringtool.cpp │ │ └── stringtool.h ├── clean and compile.bat ├── clean.bat ├── compile.bat ├── icon.bmp ├── iconfinder_theaters_326711.png └── patch_ndsheader_dsiware.py └── pc ├── Vid2RVID.cbp ├── Vid2RVID.depend ├── Vid2RVID.layout ├── graphics ├── lodepng.cpp └── lodepng.h ├── inifile.cpp ├── inifile.h ├── lz77.cpp ├── lz77.h ├── main.cpp ├── tonccpy.c └── tonccpy.h /.rvid header info.txt: -------------------------------------------------------------------------------- 1 | 0x0: "RVID" string 2 | 0x4: (u32) File format version 3 | 0x8: (u32) Number of frames 4 | 0xC: (u8) Frames per second (FPS) 5 | 0xD: (u8) Vertical resolution 6 | 0xE: (u8) Is interlaced 7 | 0xF: (u8) Has audio 8 | 0x10: (u16) Audio sample rate 9 | 0x12: (u16) Frames are compressed 10 | 0x14: (u32) First frame offset 11 | 0x18: (u32) Sound stream offset -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Vid2RVID 2 | Video to RocketVideo (.rvid) converter 3 | 4 | # Credits 5 | * [devkitPro](https://github.com/devkitPro), [WinterMute](https://github.com/WinterMute): devkitPro, devkitARM, libnds, and libfat. 6 | * [Drenn](https://github.com/Drenn1): GameYob's .bmp renderer for DS version. 7 | * [Gericom](https://github.com/Gericom): LZ77 compressor code from EFE/EveryFileExplorer. 8 | -------------------------------------------------------------------------------- /ds/.gitignore: -------------------------------------------------------------------------------- 1 | *.exe 2 | *.cia 3 | *.nds 4 | *.o 5 | *.arm7 6 | Thumbs.db 7 | *.arm9 8 | *.elf 9 | *.d 10 | *.map 11 | arm7/build 12 | arm9/build/ 13 | desktop.ini -------------------------------------------------------------------------------- /ds/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /ds/Makefile: -------------------------------------------------------------------------------- 1 | #--------------------------------------------------------------------------------- 2 | .SUFFIXES: 3 | #--------------------------------------------------------------------------------- 4 | ifeq ($(strip $(DEVKITARM)),) 5 | $(error "Please set DEVKITARM in your environment. export DEVKITARM=devkitARM) 6 | endif 7 | 8 | include $(DEVKITARM)/ds_rules 9 | 10 | export TARGET := Vid2RVID 11 | export TOPDIR := $(CURDIR) 12 | 13 | export VERSION_MAJOR := 1 14 | export VERSION_MINOR := 99 15 | export VERSTRING := $(VERSION_MAJOR).$(VERSION_MINOR) 16 | 17 | #--------------------------------------------------------------------------------- 18 | # path to tools - this can be deleted if you set the path in windows 19 | #--------------------------------------------------------------------------------- 20 | export PATH := $(DEVKITARM)/bin:$(PATH) 21 | 22 | .PHONY: $(TARGET).arm7 $(TARGET).arm9 23 | 24 | #--------------------------------------------------------------------------------- 25 | # main targets 26 | #--------------------------------------------------------------------------------- 27 | all: $(TARGET).nds 28 | 29 | $(TARGET).nds : $(TARGET).arm7 $(TARGET).arm9 30 | ndstool -c $(TARGET).nds -7 arm7/$(TARGET).arm7.elf -9 arm9/$(TARGET).arm9.elf \ 31 | -b $(CURDIR)/icon.bmp "Vid2RVID;Video to RVID converter;RocketRobz" 32 | python patch_ndsheader_dsiware.py $(CURDIR)/$(TARGET).nds --accessControl 0x00000038 33 | 34 | #--------------------------------------------------------------------------------- 35 | $(TARGET).arm7 : arm7/$(TARGET).elf 36 | $(TARGET).arm9 : arm9/$(TARGET).elf 37 | 38 | #--------------------------------------------------------------------------------- 39 | arm7/$(TARGET).elf: 40 | $(MAKE) -C arm7 41 | 42 | #--------------------------------------------------------------------------------- 43 | arm9/$(TARGET).elf: 44 | $(MAKE) -C arm9 45 | 46 | #--------------------------------------------------------------------------------- 47 | clean: 48 | $(MAKE) -C arm9 clean 49 | $(MAKE) -C arm7 clean 50 | rm -f arm9/data/load.bin 51 | rm -f arm9/source/version.h 52 | rm -f $(TARGET).ds.gba $(TARGET).nds $(TARGET).arm7 $(TARGET).arm9 $(TARGET).nds.orig.nds $(TARGET).cia 53 | -------------------------------------------------------------------------------- /ds/arm7/Makefile: -------------------------------------------------------------------------------- 1 | #--------------------------------------------------------------------------------- 2 | .SUFFIXES: 3 | #--------------------------------------------------------------------------------- 4 | ifeq ($(strip $(DEVKITARM)),) 5 | $(error "Please set DEVKITARM in your environment. export DEVKITARM=devkitARM") 6 | endif 7 | 8 | include $(DEVKITARM)/ds_rules 9 | 10 | #--------------------------------------------------------------------------------- 11 | # BUILD is the directory where object files & intermediate files will be placed 12 | # SOURCES is a list of directories containing source code 13 | # INCLUDES is a list of directories containing extra header files 14 | # DATA is a list of directories containing binary files 15 | # all directories are relative to this makefile 16 | #--------------------------------------------------------------------------------- 17 | BUILD := build 18 | SOURCES := source 19 | INCLUDES := include build 20 | DATA := 21 | 22 | #--------------------------------------------------------------------------------- 23 | # options for code generation 24 | #--------------------------------------------------------------------------------- 25 | ARCH := -mthumb-interwork -march=armv4t -mtune=arm7tdmi 26 | 27 | CFLAGS := -g -Wall -O2\ 28 | -fomit-frame-pointer\ 29 | -ffast-math \ 30 | -Wall -Wextra -Werror \ 31 | $(ARCH) 32 | 33 | CFLAGS += $(INCLUDE) -DARM7 34 | CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -fno-rtti 35 | 36 | 37 | ASFLAGS := -g $(ARCH) $(INCLUDE) 38 | LDFLAGS = -specs=ds_arm7.specs -g $(ARCH) -Wl,-Map,$(notdir $*).map 39 | 40 | LIBS := -lnds7 41 | 42 | #--------------------------------------------------------------------------------- 43 | # list of directories containing libraries, this must be the top level containing 44 | # include and lib 45 | #--------------------------------------------------------------------------------- 46 | LIBDIRS := $(LIBNDS) 47 | 48 | 49 | #--------------------------------------------------------------------------------- 50 | # no real need to edit anything past this point unless you need to add additional 51 | # rules for different file extensions 52 | #--------------------------------------------------------------------------------- 53 | ifneq ($(BUILD),$(notdir $(CURDIR))) 54 | #--------------------------------------------------------------------------------- 55 | 56 | export ARM7BIN := $(TOPDIR)/$(TARGET).arm7 57 | export ARM7ELF := $(CURDIR)/$(TARGET).arm7.elf 58 | export DEPSDIR := $(CURDIR)/$(BUILD) 59 | 60 | export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) 61 | 62 | CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c))) 63 | CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp))) 64 | SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s))) 65 | BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*))) 66 | 67 | export OFILES := $(addsuffix .o,$(BINFILES)) \ 68 | $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o) 69 | 70 | export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \ 71 | $(foreach dir,$(LIBDIRS),-I$(dir)/include) \ 72 | -I$(CURDIR)/$(BUILD) 73 | 74 | export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib) 75 | 76 | #--------------------------------------------------------------------------------- 77 | # use CXX for linking C++ projects, CC for standard C 78 | #--------------------------------------------------------------------------------- 79 | ifeq ($(strip $(CPPFILES)),) 80 | #--------------------------------------------------------------------------------- 81 | export LD := $(CC) 82 | #--------------------------------------------------------------------------------- 83 | else 84 | #--------------------------------------------------------------------------------- 85 | export LD := $(CXX) 86 | #--------------------------------------------------------------------------------- 87 | endif 88 | #--------------------------------------------------------------------------------- 89 | 90 | .PHONY: $(BUILD) clean 91 | 92 | #--------------------------------------------------------------------------------- 93 | $(BUILD): 94 | @[ -d $@ ] || mkdir -p $@ 95 | @make --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile 96 | 97 | #--------------------------------------------------------------------------------- 98 | clean: 99 | @echo clean ... 100 | @rm -fr $(BUILD) *.elf 101 | 102 | 103 | #--------------------------------------------------------------------------------- 104 | else 105 | 106 | DEPENDS := $(OFILES:.o=.d) 107 | 108 | #--------------------------------------------------------------------------------- 109 | # main targets 110 | #--------------------------------------------------------------------------------- 111 | $(ARM7BIN) : $(ARM7ELF) 112 | @$(OBJCOPY) -O binary $< $@ 113 | @echo built ... $(notdir $@) 114 | 115 | 116 | $(ARM7ELF) : $(OFILES) 117 | @echo linking $(notdir $@) 118 | @$(LD) $(LDFLAGS) $(OFILES) $(LIBPATHS) $(LIBS) -o $@ 119 | 120 | 121 | #--------------------------------------------------------------------------------- 122 | # you need a rule like this for each extension you use as binary data 123 | #--------------------------------------------------------------------------------- 124 | %.bin.o : %.bin 125 | #--------------------------------------------------------------------------------- 126 | @echo $(notdir $<) 127 | @$(bin2o) 128 | 129 | -include $(DEPENDS) 130 | 131 | #--------------------------------------------------------------------------------------- 132 | endif 133 | #--------------------------------------------------------------------------------------- 134 | -------------------------------------------------------------------------------- /ds/arm7/source/main.c: -------------------------------------------------------------------------------- 1 | /* 2 | NitroHax -- Cheat tool for the Nintendo DS 3 | Copyright (C) 2008 Michael "Chishm" Chisholm 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program. If not, see . 17 | */ 18 | 19 | #include 20 | #include 21 | #include 22 | 23 | void VcountHandler() { 24 | inputGetAndSend(); 25 | } 26 | 27 | void VblankHandler(void) { 28 | } 29 | 30 | int main(void) { 31 | 32 | irqInit(); 33 | fifoInit(); 34 | 35 | // read User Settings from firmware 36 | readUserSettings(); 37 | 38 | // Start the RTC tracking IRQ 39 | initClockIRQ(); 40 | 41 | SetYtrigger(80); 42 | 43 | installSystemFIFO(); 44 | 45 | irqSet(IRQ_VCOUNT, VcountHandler); 46 | irqSet(IRQ_VBLANK, VblankHandler); 47 | 48 | irqEnable( IRQ_VBLANK | IRQ_VCOUNT); 49 | 50 | while (1) { 51 | swiWaitForVBlank(); 52 | } 53 | } 54 | 55 | -------------------------------------------------------------------------------- /ds/arm9/Makefile: -------------------------------------------------------------------------------- 1 | #--------------------------------------------------------------------------------- 2 | .SUFFIXES: 3 | #--------------------------------------------------------------------------------- 4 | ifeq ($(strip $(DEVKITARM)),) 5 | $(error "Please set DEVKITARM in your environment. export DEVKITARM=devkitARM") 6 | endif 7 | 8 | include $(DEVKITARM)/ds_rules 9 | 10 | #--------------------------------------------------------------------------------- 11 | # BUILD is the directory where object files & intermediate files will be placed 12 | # SOURCES is a list of directories containing source code 13 | # INCLUDES is a list of directories containing extra header files 14 | # DATA is a list of directories containing binary files 15 | # all directories are relative to this makefile 16 | #--------------------------------------------------------------------------------- 17 | BUILD := build 18 | IMAGES := graphics 19 | SOURCES := source source/graphics 20 | INCLUDES := include 21 | DATA := data 22 | MUSIC := music 23 | 24 | #--------------------------------------------------------------------------------- 25 | # options for code generation 26 | #--------------------------------------------------------------------------------- 27 | ARCH := -march=armv5te -mtune=arm946e-s -mthumb-interwork 28 | 29 | CFLAGS := -g -Wall -O2\ 30 | -fomit-frame-pointer\ 31 | -ffast-math \ 32 | $(ARCH) 33 | 34 | CFLAGS += $(INCLUDE) -DARM9 35 | CXXFLAGS := $(CFLAGS) -fno-exceptions -std=gnu++11 36 | 37 | ASFLAGS := -g $(ARCH) $(INCLUDE) 38 | LDFLAGS = -specs=ds_arm9.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map) 39 | 40 | #--------------------------------------------------------------------------------- 41 | # any extra libraries we wish to link with the project 42 | #--------------------------------------------------------------------------------- 43 | LIBS := -lfat -lnds9 44 | 45 | #--------------------------------------------------------------------------------- 46 | # list of directories containing libraries, this must be the top level containing 47 | # include and lib 48 | #--------------------------------------------------------------------------------- 49 | LIBDIRS := $(LIBNDS) 50 | 51 | #--------------------------------------------------------------------------------- 52 | # no real need to edit anything past this point unless you need to add additional 53 | # rules for different file extensions 54 | #--------------------------------------------------------------------------------- 55 | ifneq ($(BUILD),$(notdir $(CURDIR))) 56 | #--------------------------------------------------------------------------------- 57 | 58 | export ARM9BIN := $(TOPDIR)/$(TARGET).arm9 59 | export ARM9ELF := $(CURDIR)/$(TARGET).arm9.elf 60 | export DEPSDIR := $(CURDIR)/$(BUILD) 61 | 62 | export AUDIOFILES := $(foreach dir,$(notdir $(wildcard $(MUSIC)/*.*)),$(CURDIR)/$(MUSIC)/$(dir)) 63 | 64 | export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \ 65 | $(foreach dir,$(DATA),$(CURDIR)/$(dir)) 66 | 67 | CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c))) 68 | CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp))) 69 | SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s))) 70 | BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*))) 71 | 72 | BMPFILES := $(foreach dir,$(IMAGES),$(notdir $(wildcard $(dir)/*.bmp))) 73 | PNGFILES := $(foreach dir,$(IMAGES),$(notdir $(wildcard $(dir)/*.png))) 74 | 75 | #--------------------------------------------------------------------------------- 76 | # use CXX for linking C++ projects, CC for standard C 77 | #--------------------------------------------------------------------------------- 78 | ifeq ($(strip $(CPPFILES)),) 79 | #--------------------------------------------------------------------------------- 80 | export LD := $(CC) 81 | #--------------------------------------------------------------------------------- 82 | else 83 | #--------------------------------------------------------------------------------- 84 | export LD := $(CXX) 85 | #--------------------------------------------------------------------------------- 86 | endif 87 | #--------------------------------------------------------------------------------- 88 | 89 | export OFILES := $(addsuffix .o,$(BINFILES)) $(BMPFILES:.bmp=.o) $(PNGFILES:.png=.o) \ 90 | $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o) 91 | 92 | export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \ 93 | $(foreach dir,$(LIBDIRS),-I$(dir)/include) \ 94 | -I$(CURDIR)/$(BUILD) 95 | 96 | export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib) 97 | 98 | .PHONY: $(BUILD) clean 99 | 100 | #--------------------------------------------------------------------------------- 101 | $(BUILD): 102 | @[ -d $@ ] || mkdir -p $@ 103 | @make --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile 104 | 105 | #--------------------------------------------------------------------------------- 106 | clean: 107 | @echo clean ... 108 | @rm -fr $(BUILD) *.elf *.nds* *.bin 109 | @rm -fr $(DATA) *.elf *.nds* *.bin 110 | 111 | #--------------------------------------------------------------------------------- 112 | else 113 | 114 | DEPENDS := $(OFILES:.o=.d) 115 | 116 | #--------------------------------------------------------------------------------- 117 | # main targets 118 | #--------------------------------------------------------------------------------- 119 | $(ARM9BIN) : $(ARM9ELF) 120 | @$(OBJCOPY) -O binary $< $@ 121 | @echo built ... $(notdir $@) 122 | 123 | $(ARM9ELF) : $(OFILES) 124 | @echo linking $(notdir $@) 125 | @$(LD) $(LDFLAGS) $(OFILES) $(LIBPATHS) $(LIBS) -o $@ 126 | 127 | #--------------------------------------------------------------------------------- 128 | # you need a rule like this for each extension you use as binary data 129 | #--------------------------------------------------------------------------------- 130 | %.bin.o : %.bin 131 | #--------------------------------------------------------------------------------- 132 | @echo $(notdir $<) 133 | @$(bin2o) 134 | 135 | -include $(DEPENDS) 136 | 137 | #--------------------------------------------------------------------------------------- 138 | endif 139 | #--------------------------------------------------------------------------------------- 140 | -------------------------------------------------------------------------------- /ds/arm9/source/inifile.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | inifile.cpp 3 | Copyright (C) 2007 Acekard, www.acekard.com 4 | Copyright (C) 2007-2009 somebody 5 | Copyright (C) 2009 yellow wood goblin 6 | 7 | This program is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with this program. If not, see . 19 | */ 20 | 21 | #include 22 | #include 23 | #include "inifile.h" 24 | #include "stringtool.h" 25 | 26 | static bool freadLine(FILE* f,std::string& str) 27 | { 28 | str.clear(); 29 | __read: 30 | char p=0; 31 | 32 | size_t readed=fread(&p,1,1,f); 33 | if(0==readed) 34 | { 35 | str=""; 36 | return false; 37 | } 38 | if('\n'==p||'\r'==p) 39 | { 40 | str=""; 41 | return true; 42 | } 43 | 44 | while(p!='\n'&&p!='\r'&&readed) 45 | { 46 | str+=p; 47 | readed=fread(&p,1,1,f); 48 | } 49 | 50 | if(str.empty()||""==str) 51 | { 52 | goto __read; 53 | } 54 | 55 | return true; 56 | } 57 | 58 | static void trimString(std::string& str) 59 | { 60 | size_t first=str.find_first_not_of(" \t"),last; 61 | if(first==str.npos) 62 | { 63 | str=""; 64 | } 65 | else 66 | { 67 | last=str.find_last_not_of(" \t"); 68 | if(first>0||(last+1)0) 91 | { 92 | m_FileContainer.clear(); 93 | } 94 | } 95 | 96 | void CIniFile::SetString(const std::string& Section,const std::string& Item,const std::string& Value) 97 | { 98 | if(GetFileString(Section,Item)!=Value) 99 | { 100 | SetFileString(Section,Item,Value); 101 | m_bModified=true; 102 | } 103 | } 104 | 105 | void CIniFile::SetInt(const std::string& Section,const std::string& Item,int Value) 106 | { 107 | std::string strtemp=formatString("%d",Value); 108 | 109 | if(GetFileString(Section,Item)!=strtemp) 110 | { 111 | SetFileString(Section,Item,strtemp); 112 | m_bModified=true; 113 | } 114 | } 115 | 116 | std::string CIniFile::GetString(const std::string& Section,const std::string& Item) 117 | { 118 | return GetFileString(Section,Item); 119 | } 120 | 121 | std::string CIniFile::GetString(const std::string& Section,const std::string& Item,const std::string& DefaultValue) 122 | { 123 | std::string temp=GetString(Section,Item); 124 | if(!m_bLastResult) 125 | { 126 | SetString(Section,Item,DefaultValue); 127 | temp=DefaultValue; 128 | } 129 | return temp; 130 | } 131 | 132 | void CIniFile::GetStringVector(const std::string& Section,const std::string& Item,std::vector< std::string >& strings,char delimiter) 133 | { 134 | std::string strValue=GetFileString(Section,Item); 135 | strings.clear(); 136 | size_t pos; 137 | while((pos=strValue.find(delimiter),strValue.npos!=pos)) 138 | { 139 | const std::string string=strValue.substr(0,pos); 140 | if(string.length()) 141 | { 142 | strings.push_back(string); 143 | } 144 | strValue=strValue.substr(pos+1,strValue.npos); 145 | } 146 | if(strValue.length()) 147 | { 148 | strings.push_back(strValue); 149 | } 150 | } 151 | 152 | void CIniFile::SetStringVector(const std::string& Section,const std::string& Item,std::vector& strings,char delimiter) 153 | { 154 | std::string strValue; 155 | for(size_t ii=0;ii2&&'0'==value[0]&&('x'==value[1]||'X'==value[1])) 167 | return strtol(value.c_str(),NULL,16); 168 | else 169 | return strtol(value.c_str(),NULL,10); 170 | } 171 | 172 | int CIniFile::GetInt(const std::string& Section,const std::string& Item,int DefaultValue) 173 | { 174 | int temp; 175 | temp=GetInt(Section,Item); 176 | if(!m_bLastResult) 177 | { 178 | SetInt(Section,Item,DefaultValue); 179 | temp=DefaultValue; 180 | } 181 | return temp; 182 | } 183 | 184 | bool CIniFile::LoadIniFile(const std::string& FileName) 185 | { 186 | //dbg_printf("load %s\n",FileName.c_str()); 187 | if(FileName!="") m_sFileName=FileName; 188 | 189 | FILE* f=fopen(FileName.c_str(),"rb"); 190 | 191 | if(NULL==f) return false; 192 | 193 | //check for utf8 bom. 194 | char bom[3]; 195 | if(fread(bom,3,1,f)==1&&bom[0]==0xef&&bom[1]==0xbb&&bom[2]==0xbf) ; 196 | else fseek(f,0,SEEK_SET); 197 | 198 | std::string strline(""); 199 | m_FileContainer.clear(); 200 | 201 | while(freadLine(f,strline)) 202 | { 203 | trimString(strline); 204 | if(strline!=""&&';'!=strline[0]&&'/'!=strline[0]&&'!'!=strline[0]) m_FileContainer.push_back(strline); 205 | } 206 | 207 | fclose(f); 208 | 209 | m_bLastResult=false; 210 | m_bModified=false; 211 | 212 | return true; 213 | } 214 | 215 | bool CIniFile::SaveIniFileModified(const std::string& FileName) 216 | { 217 | if(m_bModified==true) 218 | { 219 | return SaveIniFile(FileName); 220 | } 221 | 222 | return true; 223 | } 224 | 225 | bool CIniFile::SaveIniFile(const std::string& FileName) 226 | { 227 | if(FileName!="") 228 | m_sFileName=FileName; 229 | 230 | FILE* f=fopen(m_sFileName.c_str(),"wb"); 231 | if(NULL==f) 232 | { 233 | return false; 234 | } 235 | 236 | for(size_t ii=0;ii0) 242 | { 243 | if(!m_FileContainer[ii-1].empty()&&m_FileContainer[ii-1]!="") 244 | fwrite("\r\n",1,2,f); 245 | } 246 | if(!strline.empty()&&strline!="") 247 | { 248 | fwrite(strline.c_str(),1,strline.length(),f); 249 | fwrite("\r\n",1,2,f); 250 | } 251 | } 252 | 253 | fclose(f); 254 | 255 | m_bModified=false; 256 | 257 | return true; 258 | } 259 | 260 | std::string CIniFile::GetFileString(const std::string& Section,const std::string& Item) 261 | { 262 | std::string strline; 263 | std::string strSection; 264 | std::string strItem; 265 | std::string strValue; 266 | 267 | size_t ii=0; 268 | size_t iFileLines=m_FileContainer.size(); 269 | 270 | if(m_bReadOnly) 271 | { 272 | cSectionCache::iterator it=m_Cache.find(Section); 273 | if((it!=m_Cache.end())) ii=it->second; 274 | } 275 | 276 | m_bLastResult=false; 277 | 278 | if(iFileLines>=0) 279 | { 280 | while(ii0&&rBracketPos!=std::string::npos) 287 | { 288 | strSection=strline.substr(1,rBracketPos-1); 289 | if(m_bReadOnly) m_Cache.insert(std::make_pair(strSection,ii-1)); 290 | if(strSection==Section) 291 | { 292 | while(ii0&&rBracketPos!=std::string::npos) 342 | { 343 | strSection=strline.substr(1,rBracketPos-1); 344 | if(strSection==Section) 345 | { 346 | while(ii. 17 | */ 18 | 19 | #include 20 | #include 21 | 22 | #include 23 | #include 24 | 25 | #include "graphics/lodepng.h" 26 | #include "inifile.h" 27 | 28 | u16 convertedFrame[256*192]; 29 | 30 | char soundBuffer[0x8000] = {0}; 31 | u32 soundSize = 0; 32 | 33 | u8 headerToFile[0x200] = {0}; 34 | 35 | off_t getFileSize(const char *fileName) 36 | { 37 | FILE* fp = fopen(fileName, "rb"); 38 | off_t fsize = 0; 39 | if (fp) { 40 | fseek(fp, 0, SEEK_END); 41 | fsize = ftell(fp); // Get source file's size 42 | fseek(fp, 0, SEEK_SET); 43 | } 44 | fclose(fp); 45 | 46 | return fsize; 47 | } 48 | 49 | typedef struct rvidHeaderInfo { 50 | u32 formatString; // "RVID" string 51 | u32 ver; // File format version 52 | u32 frames; // Number of frames 53 | u8 fps; // Frames per second 54 | u8 vRes; // Vertical resolution 55 | u8 interlaced; // Is interlaced 56 | u8 hasSound; // Has sound/audio 57 | u16 sampleRate; // Audio sample rate 58 | u16 framesCompressed; // Frames are compressed 59 | u32 framesOffset; // Offset of first frame 60 | u32 soundOffset; // Offset of sound stream 61 | } rvidHeaderInfo; 62 | 63 | rvidHeaderInfo rvidHeader; 64 | 65 | #define titleText "Vid2RVID, by RocketRobz\n" 66 | 67 | int hourMark = 0; 68 | int minuteMark = 0; 69 | int secondMark = 0; 70 | int frameMark = 0; 71 | bool timeElapseUpdate = true; 72 | 73 | void vBlankHandler(void) { 74 | if (frameMark == 60) { 75 | timeElapseUpdate = true; 76 | frameMark = 0; 77 | secondMark++; 78 | if (secondMark == 60) { 79 | secondMark = 0; 80 | minuteMark++; 81 | if (minuteMark == 60) { 82 | minuteMark = 0; 83 | hourMark++; 84 | } 85 | } 86 | } 87 | frameMark++; 88 | 89 | if (timeElapseUpdate) { 90 | printf("\x1b[10;0H"); 91 | printf("Time elapsed: "); 92 | if (hourMark < 10) { 93 | printf("0%i", hourMark); 94 | } else { 95 | printf("%i", hourMark); 96 | } 97 | printf(":"); 98 | if (minuteMark < 10) { 99 | printf("0%i", minuteMark); 100 | } else { 101 | printf("%i", minuteMark); 102 | } 103 | printf(":"); 104 | if (secondMark < 10) { 105 | printf("0%i", secondMark); 106 | } else { 107 | printf("%i", secondMark); 108 | } 109 | timeElapseUpdate = false; 110 | } 111 | } 112 | 113 | int main(int argc, char **argv) { 114 | 115 | if (!fatInitDefault()) { 116 | consoleDemoInit(); 117 | printf("fatInitDefault failed!"); 118 | } 119 | 120 | lcdMainOnBottom(); 121 | 122 | videoSetMode(MODE_0_2D); 123 | vramSetBankG(VRAM_G_MAIN_BG); 124 | consoleInit(NULL, 0, BgType_Text4bpp, BgSize_T_256x256, 15, 0, true, true); 125 | 126 | videoSetModeSub(MODE_3_2D | DISPLAY_BG3_ACTIVE); 127 | vramSetBankC(VRAM_C_SUB_BG_0x06200000); 128 | 129 | REG_BG3CNT_SUB = BG_MAP_BASE(0) | BG_BMP16_256x256 | BG_PRIORITY(0); 130 | REG_BG3X_SUB = 0; 131 | REG_BG3Y_SUB = 0; 132 | REG_BG3PA_SUB = 1<<8; 133 | REG_BG3PB_SUB = 0; 134 | REG_BG3PC_SUB = 0; 135 | REG_BG3PD_SUB = 1<<8; 136 | 137 | int pressed = 0; 138 | 139 | printf(titleText); 140 | printf("\n"); 141 | printf("A: Convert"); 142 | 143 | do 144 | { 145 | scanKeys(); 146 | pressed = keysDown(); 147 | swiWaitForVBlank(); 148 | } 149 | while (!(pressed & KEY_A)); 150 | 151 | if (access("/rvidFrames/sound.raw.pcm", F_OK) == 0) { 152 | int cursorPosition = 0; 153 | printf ("\x1b[2;0H"); 154 | printf("Sound file found!\n"); 155 | printf("\n"); 156 | printf("What is the sample rate?\n"); 157 | printf("> Exclude sound\n"); 158 | printf(" 8000hz\n"); 159 | printf(" 11025hz\n"); 160 | printf(" 16000hz\n"); 161 | 162 | while (1) { 163 | scanKeys(); 164 | pressed = keysDown(); 165 | if (pressed & KEY_A) { 166 | break; 167 | } 168 | if (pressed & KEY_UP) { 169 | printf("\x1b[%i;0H", cursorPosition+5); 170 | printf(" "); 171 | cursorPosition--; 172 | if (cursorPosition < 0) cursorPosition = 3; 173 | printf("\x1b[%i;0H", cursorPosition+5); 174 | printf(">"); 175 | } 176 | if (pressed & KEY_DOWN) { 177 | printf("\x1b[%i;0H", cursorPosition+5); 178 | printf(" "); 179 | cursorPosition++; 180 | if (cursorPosition > 3) cursorPosition = 0; 181 | printf("\x1b[%i;0H", cursorPosition+5); 182 | printf(">"); 183 | } 184 | swiWaitForVBlank(); 185 | } 186 | if (cursorPosition == 0) { 187 | rvidHeader.hasSound = 0; 188 | } 189 | if (cursorPosition == 1) { 190 | rvidHeader.sampleRate = 8000; 191 | rvidHeader.hasSound = 1; 192 | } 193 | if (cursorPosition == 2) { 194 | rvidHeader.sampleRate = 11025; 195 | rvidHeader.hasSound = 1; 196 | } 197 | if (cursorPosition == 3) { 198 | rvidHeader.sampleRate = 16000; 199 | rvidHeader.hasSound = 1; 200 | } 201 | } 202 | 203 | consoleClear(); 204 | 205 | irqSet(IRQ_VBLANK, vBlankHandler); 206 | irqEnable(IRQ_VBLANK); 207 | 208 | printf(titleText); 209 | printf("\n"); 210 | printf("Getting number of frames..."); 211 | 212 | CIniFile info( "/rvidFrames/info.ini" ); 213 | 214 | char framePath[256]; 215 | int foundFrames = info.GetInt("RVID", "FRAMES", -1); 216 | 217 | if (foundFrames == -1) { 218 | while (1) { 219 | foundFrames++; 220 | snprintf(framePath, sizeof(framePath), "/rvidFrames/frame%i.png", foundFrames); 221 | if (access(framePath, F_OK) != 0) break; 222 | } 223 | } 224 | 225 | rvidHeader.formatString = 0x44495652; // "RVID" 226 | rvidHeader.ver = 2; 227 | rvidHeader.frames = foundFrames; 228 | rvidHeader.fps = info.GetInt("RVID", "FPS", 24); 229 | rvidHeader.vRes = info.GetInt("RVID", "V_RES", 192); 230 | rvidHeader.interlaced = info.GetInt("RVID", "INTERLACED", 2); 231 | rvidHeader.framesCompressed = 0; 232 | rvidHeader.framesOffset = 0x200; 233 | rvidHeader.soundOffset = 0x200+((0x200*rvidHeader.vRes)*rvidHeader.frames); 234 | 235 | if (rvidHeader.interlaced == 2) { 236 | int cursorPosition = 1; 237 | printf ("\x1b[2;0H"); 238 | printf("Is the video interlaced?\n"); 239 | printf("Video will be played twice the\n" 240 | "set frame rate, if so.\n"); 241 | printf("\n"); 242 | printf(" Yes\n"); 243 | printf("> No\n"); 244 | 245 | while (1) { 246 | scanKeys(); 247 | pressed = keysDown(); 248 | if (pressed & KEY_A) { 249 | break; 250 | } 251 | if (pressed & KEY_UP) { 252 | printf("\x1b[%i;0H", cursorPosition+6); 253 | printf(" "); 254 | cursorPosition--; 255 | if (cursorPosition < 0) cursorPosition = 1; 256 | printf("\x1b[%i;0H", cursorPosition+6); 257 | printf(">"); 258 | } 259 | if (pressed & KEY_DOWN) { 260 | printf("\x1b[%i;0H", cursorPosition+6); 261 | printf(" "); 262 | cursorPosition++; 263 | if (cursorPosition > 1) cursorPosition = 0; 264 | printf("\x1b[%i;0H", cursorPosition+6); 265 | printf(">"); 266 | } 267 | swiWaitForVBlank(); 268 | } 269 | if (cursorPosition == 0) { 270 | rvidHeader.interlaced = 1; 271 | } 272 | if (cursorPosition == 1) { 273 | rvidHeader.interlaced = 0; 274 | } 275 | } 276 | 277 | printf ("\x1b[2;0H"); 278 | printf("Converting... "); 279 | 280 | FILE* frameInput; 281 | FILE* videoOutput = fopen("/new.rvid", "wb"); 282 | 283 | // Write header 284 | memcpy(headerToFile, &rvidHeader, sizeof(rvidHeaderInfo)); 285 | fwrite(headerToFile, 1, 0x200, videoOutput); 286 | 287 | int videoYpos = 0; 288 | if (rvidHeader.vRes <= 190) { 289 | // Adjust video positioning 290 | for (int i = rvidHeader.vRes; i < 192; i += 2) { 291 | videoYpos++; 292 | } 293 | } 294 | 295 | for (int i = 0; i <= foundFrames; i++) { 296 | snprintf(framePath, sizeof(framePath), "/rvidFrames/frame%i.png", i); 297 | frameInput = fopen(framePath, "rb"); 298 | if (frameInput) { 299 | fclose(frameInput); 300 | 301 | std::vector image; 302 | unsigned width, height; 303 | lodepng::decode(image, width, height, framePath); 304 | 305 | for(unsigned i=0;i>3 | (image[(i*4)+1]>>3)<<5 | (image[(i*4)+2]>>3)<<10 | BIT(15); 307 | } 308 | 309 | // Display converted frame 310 | dmaCopyAsynch(convertedFrame, (u16*)BG_GFX_SUB+(256*videoYpos), 0x200*rvidHeader.vRes); 311 | 312 | while (timeElapseUpdate) { 313 | swiWaitForVBlank(); 314 | } 315 | printf ("\x1b[4;0H"); 316 | printf("%i/%i\n", i, foundFrames); 317 | 318 | // Save current frame to a file 319 | fwrite(convertedFrame, 1, 0x200*rvidHeader.vRes, videoOutput); 320 | } else { 321 | break; 322 | } 323 | } 324 | 325 | if (rvidHeader.hasSound == 1) { 326 | printf ("\x1b[2;0H"); 327 | printf("Adding sound..."); 328 | printf ("\x1b[4;0H"); 329 | printf(" "); 330 | 331 | off_t fsize = getFileSize("/rvidFrames/sound.raw.pcm"); 332 | off_t offset = 0; 333 | int numr; 334 | 335 | FILE* soundFile = fopen("/rvidFrames/sound.raw.pcm", "rb"); 336 | while (1) 337 | { 338 | // Add sound to .rvid file 339 | numr = fread(soundBuffer, 1, sizeof(soundBuffer), soundFile); 340 | fwrite(soundBuffer, 1, numr, videoOutput); 341 | offset += sizeof(soundBuffer); 342 | 343 | if (offset > fsize) { 344 | break; 345 | } 346 | } 347 | fclose(soundFile); 348 | } 349 | 350 | fclose(videoOutput); 351 | 352 | irqDisable(IRQ_VBLANK); 353 | 354 | printf ("\x1b[2;0H"); 355 | printf("Done! "); 356 | printf ("\x1b[4;0H"); 357 | printf(" "); 358 | 359 | //for (int i = 0; i < 60*3; i++) { 360 | while (1) { 361 | swiWaitForVBlank(); 362 | } 363 | 364 | return 0; 365 | } 366 | 367 | -------------------------------------------------------------------------------- /ds/arm9/source/stringtool.cpp: -------------------------------------------------------------------------------- 1 | /*--------------------------------------------------------------------------------- 2 | 3 | 4 | Copyright (C) 2007 Acekard, www.acekard.com 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in 14 | all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | THE SOFTWARE. 23 | 24 | 25 | ---------------------------------------------------------------------------------*/ 26 | 27 | #include "stringtool.h" 28 | #include 29 | #include 30 | #include 31 | 32 | std::string formatString( const char* fmt, ... ) 33 | { 34 | const char * f = fmt; 35 | va_list argList; 36 | va_start(argList, fmt); 37 | char * ptempStr = NULL; 38 | size_t max_len = vasiprintf( &ptempStr, f, argList); 39 | std::string str( ptempStr ); 40 | str.resize( max_len ); 41 | free( ptempStr ); 42 | va_end(argList); 43 | return str; 44 | } 45 | 46 | -------------------------------------------------------------------------------- /ds/arm9/source/stringtool.h: -------------------------------------------------------------------------------- 1 | /*--------------------------------------------------------------------------------- 2 | 3 | 4 | Copyright (C) 2007 Acekard, www.acekard.com 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in 14 | all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | THE SOFTWARE. 23 | 24 | 25 | ---------------------------------------------------------------------------------*/ 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | #ifndef _STRINGTOOL_H_ 36 | #define _STRINGTOOL_H_ 37 | 38 | #include 39 | 40 | std::string formatString( const char* fmt, ... ); 41 | 42 | 43 | 44 | #endif//_STRINGTOOL_H_ 45 | -------------------------------------------------------------------------------- /ds/clean and compile.bat: -------------------------------------------------------------------------------- 1 | make clean 2 | make 3 | pause 4 | -------------------------------------------------------------------------------- /ds/clean.bat: -------------------------------------------------------------------------------- 1 | make clean 2 | pause 3 | -------------------------------------------------------------------------------- /ds/compile.bat: -------------------------------------------------------------------------------- 1 | make 2 | pause 3 | -------------------------------------------------------------------------------- /ds/icon.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RocketRobz/Vid2RVID/fcaa42c6c63e0b2849ed4c0d4c7051f364c139ee/ds/icon.bmp -------------------------------------------------------------------------------- /ds/iconfinder_theaters_326711.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RocketRobz/Vid2RVID/fcaa42c6c63e0b2849ed4c0d4c7051f364c139ee/ds/iconfinder_theaters_326711.png -------------------------------------------------------------------------------- /ds/patch_ndsheader_dsiware.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf8 -*- 2 | # Patch an .nds (works with homebrew and ds demo only) to make it ready for make_cia 3 | # 4 | # 2016-02-28, Ahezard 5 | # 6 | # inspired by 7 | # Apache Thunder .nds edited files and comments 8 | # https://github.com/Relys/Project_CTR/blob/master/makerom/srl.h 9 | # https://dsibrew.org/wiki/DSi_Cartridge_Header 10 | # if the header size of the input nds file is 0x200 (homebrew) 11 | # the header size of the output nds file will be patched to 0x4000 (normal ds/dsi header), 0x3E00 offset 12 | 13 | from struct import * 14 | from collections import namedtuple 15 | from collections import OrderedDict 16 | from pprint import pprint 17 | import os, sys 18 | import binascii 19 | import argparse 20 | 21 | 22 | parser = argparse.ArgumentParser(description='Patch an nds in order to be ready cia conversion via make_cia --srl=.') 23 | parser.add_argument('file', metavar='file.nds', type=file, help='nds file to patch') 24 | parser.add_argument('--verbose', help='verbose mode', action="store_true") 25 | parser.add_argument('--out', help='output file [optionnal]') 26 | parser.add_argument('--read', help='print only the header content, do not patch', action="store_true") 27 | parser.add_argument('--extract', help='extract the content of the rom : header.bin,arm9.bin,arm7.bin,icon.bin,arm9i.bin,arm7i.bin, do not patch', action="store_true") #Not yet implemented 28 | parser.add_argument('--title', help='Game title') 29 | parser.add_argument('--code', help='Game code') 30 | parser.add_argument('--maker', help='Maker code') 31 | parser.add_argument('--mode', help='target mode, default mode is ds [ds|dsi|dsinogba|nitrohax]') 32 | parser.add_argument('--arm9', type=file, help='swap the ds arm9 binary by the one provided') 33 | parser.add_argument('--arm7', type=file, help='swap the ds arm7 binary by the one provided') 34 | parser.add_argument('--arm9EntryAddress', help='arm9 ram address of the binary provided') 35 | parser.add_argument('--arm7EntryAddress', help='arm7 ram address of the binary provided') 36 | parser.add_argument('--arm9i', type=file, help='add a dsi arm9i binary to the file, not needed for homebrew so far') 37 | parser.add_argument('--arm7i', type=file, help='add a dsi arm7i binary to the file, not needed for homebrew so far') 38 | parser.add_argument('--accessControl', help='access control field') 39 | args = parser.parse_args() 40 | 41 | if args.mode is None: 42 | args.mode = "dsi" 43 | 44 | # 45 | # CRC16 MODULE 46 | # 47 | # includes CRC16 and CRC16 MODBUS 48 | # 49 | 50 | from ctypes import c_ushort 51 | 52 | # from https://github.com/cristianav/PyCRC/blob/master/demo.py 53 | class CRC16(object): 54 | crc16_tab = [] 55 | 56 | # The CRC's are computed using polynomials. Here is the most used 57 | # coefficient for CRC16 58 | crc16_constant = 0xA001 # 40961 59 | 60 | def __init__(self, modbus_flag=False): 61 | # initialize the precalculated tables 62 | if not len(self.crc16_tab): 63 | self.init_crc16() 64 | self.mdflag = bool(modbus_flag) 65 | 66 | def calculate(self, input_data=None): 67 | try: 68 | is_string = isinstance(input_data, str) 69 | is_bytes = isinstance(input_data, (bytes, bytearray)) 70 | 71 | if not is_string and not is_bytes: 72 | raise Exception("Please provide a string or a byte sequence " 73 | "as argument for calculation.") 74 | 75 | crc_value = 0x0000 if not self.mdflag else 0xffff 76 | 77 | for c in input_data: 78 | d = ord(c) if is_string else c 79 | tmp = crc_value ^ d 80 | rotated = crc_value >> 8 81 | crc_value = rotated ^ self.crc16_tab[(tmp & 0x00ff)] 82 | 83 | return crc_value 84 | except Exception as e: 85 | print("EXCEPTION(calculate): {}".format(e)) 86 | 87 | def init_crc16(self): 88 | """The algorithm uses tables with precalculated values""" 89 | for i in range(0, 256): 90 | crc = c_ushort(i).value 91 | for j in range(0, 8): 92 | if crc & 0x0001: 93 | crc = c_ushort(crc >> 1).value ^ self.crc16_constant 94 | else: 95 | crc = c_ushort(crc >> 1).value 96 | self.crc16_tab.append(crc) 97 | 98 | def getSize(fileobject): 99 | current = fileobject.tell() 100 | fileobject.seek(0,2) # move the cursor to the end of the file 101 | size = fileobject.tell() 102 | fileobject.seek(current,0) 103 | return size 104 | 105 | def skipUntilAddress(f_in,f_out, caddr, taddr): 106 | chunk = f_in.read(taddr-caddr) 107 | f_out.write(chunk) 108 | 109 | def writeBlankuntilAddress(f_out, caddr, taddr): 110 | f_out.write("\x00"*(taddr-caddr)) 111 | 112 | fname=args.file.name 113 | args.file.close() 114 | 115 | if not args.read: 116 | print "Patching file : "+fname 117 | else: 118 | print "Reading header of file : "+fname 119 | 120 | #offset of 0x4600 created 121 | 122 | # File size compute 123 | file = open(fname, 'rb') 124 | fsize=getSize(file) 125 | file.close() 126 | 127 | #CRC header compute "CRC-16 (Modbus)" 128 | file = open(fname, 'rb') 129 | #0x15E from https://github.com/devkitPro/ndstool/ ... source/header.cpp 130 | hdr = file.read(0x15E) 131 | hdrCrc=CRC16(modbus_flag=True).calculate(hdr) 132 | if args.verbose: 133 | print("{:10s} {:20X}".format('HDR CRC-16 ModBus', hdrCrc)) 134 | #print "origin header cr c"+hdr[0x15E:0x15F] 135 | #filew = open(fname+".hdr", "wb") 136 | #filew.write(hdr); 137 | #filew.close() 138 | file.close() 139 | 140 | if args.arm9 is not None: 141 | arm9Fname=args.arm9.name 142 | args.arm9.close() 143 | arm9File = open(arm9Fname, 'rb') 144 | arm9FileSize=getSize(arm9File) 145 | dataArm9=arm9File.read(arm9FileSize) 146 | arm9File.close() 147 | 148 | if args.arm7 is not None: 149 | arm7Fname=args.arm7.name 150 | args.arm7.close() 151 | arm7File = open(arm7Fname, 'rb') 152 | arm7FileSize=getSize(arm7File) 153 | dataArm7=arm7File.read(arm7FileSize) 154 | arm7File.close() 155 | 156 | filer = open(fname, 'rb') 157 | data = filer.read(0x180) 158 | caddr=0x180 159 | 160 | #DS Data 180 bytes 161 | SrlHeader = namedtuple('SrlHeader', 162 | "gameTitle " 163 | "gameCode " 164 | "makerCode " 165 | "unitCode " 166 | "encryptionSeedSelect " 167 | "deviceCapacity " 168 | "reserved0 " 169 | "dsiflags " 170 | "romVersion " 171 | "internalFlag " 172 | "arm9RomOffset " 173 | "arm9EntryAddress " 174 | "arm9RamAddress " 175 | "arm9Size " 176 | "arm7RomOffset " 177 | "arm7EntryAddress " 178 | "arm7RamAddress " 179 | "arm7Size " 180 | "fntOffset " 181 | "fntSize " 182 | "fatOffset " 183 | "fatSize " 184 | "arm9OverlayOffset " 185 | "arm9OverlaySize " 186 | "arm7OverlayOffset " 187 | "arm7OverlaySize " 188 | "normalCardControlRegSettings " 189 | "secureCardControlRegSettings " 190 | "icon_bannerOffset " 191 | "secureAreaCrc " 192 | "secure_transfer_timeout " 193 | "arm9Autoload " 194 | "arm7Autoload " 195 | "secureDisable " 196 | "ntrRomSize " 197 | "headerSize " 198 | "reserved1 " 199 | "nintendoLogo " 200 | "nintendoLogoCrc " 201 | "headerCrc " 202 | "debugReserved ") 203 | srlHeaderFormat='<12s4s2scbb7s2sbcIIIIIIIIIIIIIIIIIIIHHII8sII56s156s2sH32s' 204 | srlHeader=SrlHeader._make(unpack_from(srlHeaderFormat, data)) 205 | if args.verbose: 206 | print "origin header crc "+hex(srlHeader.headerCrc) 207 | print "origin secure crc "+hex(srlHeader.secureAreaCrc) 208 | 209 | #SecureArea CRC compute "CRC-16 (Modbus)" 210 | file = open(fname, 'rb') 211 | #0x15E from https://github.com/devkitPro/ndstool/ ... source/header.cpp 212 | file.read(0x200) 213 | sec = file.read(0x4000) 214 | secCrc=CRC16(modbus_flag=True).calculate(sec) 215 | if args.verbose: 216 | print("{:10s} {:20X}".format('SEC CRC-16 ModBus', secCrc)) 217 | file.close() 218 | 219 | if srlHeader.arm7EntryAddress>0x2400000 and not args.read and args.arm7 is None: 220 | print "WARNING: .nds arm7EntryAddress greater than 0x2400000 will not boot as cia" 221 | print "you need to recompile or swap the arm7 binary with a precompiled one with --arm7 and --arm7EntryAddress" 222 | 223 | if "dsi" in args.mode : 224 | srlHeaderPatched=srlHeader._replace( 225 | dsiflags= '\x01\x00', #disable modcrypt but enable twl 226 | unitCode= '\x03', 227 | ) 228 | 229 | data1=pack(*[srlHeaderFormat]+srlHeaderPatched._asdict().values()) 230 | newHdrCrc=CRC16(modbus_flag=True).calculate(data1[0:0x15E]) 231 | srlHeaderPatched=srlHeaderPatched._replace(headerCrc=newHdrCrc) 232 | 233 | if args.verbose: 234 | print "new header crc "+hex(newHdrCrc) 235 | if not args.read : 236 | if args.verbose: 237 | pprint(dict(srlHeaderPatched._asdict())) 238 | else: 239 | pprint(dict(srlHeader._asdict())) 240 | 241 | data1=pack(*[srlHeaderFormat]+srlHeaderPatched._asdict().values()) 242 | 243 | arm9isize=0 244 | arm7isize=0 245 | 246 | #TWL Only Data 384 bytes 247 | SrlTwlExtHeader = namedtuple('SrlTwlExtHeader', 248 | "MBK_1_5_Settings " 249 | "MBK_6_8_Settings_ARM9 " 250 | "MBK_6_8_Settings_ARM7 " 251 | "global_MBK_9_Setting " 252 | "regionFlags " 253 | "accessControl " 254 | "arm7ScfgExtMask " 255 | "reserved_flags " 256 | "arm9iRomOffset " 257 | "reserved2 " 258 | "arm9iLoadAddress " 259 | "arm9iSize " 260 | "arm7iRomOffset " 261 | "struct_param_baseAddress " 262 | "arm7iLoadAddress " 263 | "arm7iSize " 264 | "digest_ntrRegionOffset " 265 | "digest_ntrRegionSize " 266 | "digest_twlRegionOffset " 267 | "digest_twlRegionSize " 268 | "digestSectorHashtableOffset " 269 | "digestSectorHashtableSize " 270 | "digest_blockHashtableOffset " 271 | "digest_blockHashtableSize " 272 | "digestSectorSize " 273 | "digest_blockSectorcount " 274 | "iconSize " #usually 0x23C0 or 2112 in homebrew 275 | "unknown1 " 276 | "twlRomSize " 277 | "unknown2 " 278 | "modcryptArea1Offset " 279 | "modcryptArea1Size " 280 | "modcryptArea2Offset " 281 | "modcryptArea2Size " 282 | "title_id " 283 | "pubSaveDataSize " 284 | "privSaveDataSize " 285 | "reserved4 " 286 | "parentalControl ") 287 | srlTwlExtHeaderFormat="<20s12s12s4s4sIIII4sIIIIIIIIIIIIIIIII4sI12sIIII8sII176s16s" 288 | if srlHeader.headerSize<0x300: 289 | #homebrew 290 | srlTwlExtHeader=SrlTwlExtHeader._make(unpack_from(srlTwlExtHeaderFormat, "\x00" * (0x300-0x180))) 291 | else: 292 | data = filer.read(0x300-0x180) 293 | srlTwlExtHeader=SrlTwlExtHeader._make(unpack_from(srlTwlExtHeaderFormat, data)) 294 | caddr=0x300 295 | 296 | #pprint(dict(srlTwlExtHeader._asdict())) 297 | 298 | if not args.read: 299 | # Fix srlTwlExtHeader 300 | if "dsi" in args.mode: 301 | arm7iRomOffset=srlHeaderPatched.arm7RomOffset 302 | arm9iRomOffset=srlHeaderPatched.arm9RomOffset 303 | arm7isize=srlHeaderPatched.arm7Size 304 | arm9isize=srlHeaderPatched.arm9Size 305 | totaldsisize=0 306 | arm7iname = None 307 | arm9iname = None 308 | 309 | if args.arm9i is not None: 310 | arm9iname = args.arm9i.name 311 | arm9isize = getSize(args.arm9i) 312 | arm9iRomOffset=srlHeaderPatched.ntrRomSize 313 | if args.verbose: 314 | print "arm9isize : "+hex(arm9isize) 315 | print "arm9ioffset : "+hex(srlHeaderPatched.ntrRomSize) 316 | args.arm9i.close() 317 | totaldsisize=arm9isize 318 | 319 | if args.arm7i is not None: 320 | arm7iname = args.arm7i.name 321 | arm7isize = getSize(args.arm7i) 322 | arm7iRomOffset=srlHeaderPatched.ntrRomSize+arm9isize 323 | if args.verbose: 324 | print "arm7isize : "+hex(arm7isize) 325 | print "arm9ioffset : "+hex(srlHeaderPatched.ntrRomSize+arm9isize) 326 | args.arm7i.close() 327 | totaldsisize=arm9isize+arm7isize 328 | 329 | 330 | 331 | srlTwlExtHeader=srlTwlExtHeader._replace( 332 | accessControl= 0x00000138, 333 | arm7ScfgExtMask= 0x80040000, 334 | reserved_flags= 0x00000000 335 | ) 336 | 337 | if args.accessControl is not None: 338 | srlTwlExtHeader=srlTwlExtHeader._replace( 339 | accessControl= int(args.accessControl,0), 340 | ) 341 | 342 | if args.verbose or args.read: 343 | pprint(dict(srlTwlExtHeader._asdict())) 344 | 345 | data2=pack(*[srlTwlExtHeaderFormat]+srlTwlExtHeader._asdict().values()) 346 | 347 | #TWL and Signed NTR 3328 bytes 348 | SrlSignedHeader = namedtuple('SrlSignedHeader', 349 | "arm9WithSecAreaSha1Hmac " 350 | "arm7Sha1Hmac " 351 | "digestMasterSha1Hmac " 352 | "bannerSha1Hmac " 353 | "arm9iSha1Hmac " 354 | "arm7iSha1Hmac " 355 | "reserved5 " 356 | "arm9Sha1Hmac " 357 | "reserved6 " 358 | "reserved7 " 359 | "signature " 360 | ) 361 | srlSignedHeaderFormat="<20s20s20s20s20s20s40s20s2636s384s128s" 362 | if srlHeader.headerSize<0x1100: 363 | #homebrew 364 | srlSignedHeader=SrlSignedHeader._make(unpack_from(srlSignedHeaderFormat, "\x00" * (3328))) 365 | else: 366 | data = filer.read(3328) 367 | srlSignedHeader=SrlSignedHeader._make(unpack_from(srlSignedHeaderFormat, data)) 368 | caddr=0x300+3328 369 | filer.read(0x4000-caddr) 370 | caddr=0x4000 371 | 372 | #pprint(dict(srlSignedHeader._asdict())) 373 | 374 | # Fix srlSignedHeader 375 | if not args.read: 376 | srlSignedHeader=srlSignedHeader._replace( 377 | arm7Sha1Hmac= '\xff'*20, 378 | arm9WithSecAreaSha1Hmac= '\xff'*20, 379 | bannerSha1Hmac= '\xff'*20, 380 | signature= '\xff'*128 381 | ) 382 | if "dsi" in args.mode : 383 | srlSignedHeader=srlSignedHeader._replace( 384 | arm7Sha1Hmac= '\xff'*20, 385 | arm7iSha1Hmac= '\xff'*20, 386 | arm9Sha1Hmac= '\xff'*20, 387 | arm9WithSecAreaSha1Hmac= '\xff'*20, 388 | arm9iSha1Hmac= '\xff'*20, 389 | bannerSha1Hmac= '\xff'*20, 390 | digestMasterSha1Hmac= '\xff'*20, 391 | signature= '\xff'*128 392 | ) 393 | if args.verbose or args.read: 394 | pprint(dict(srlSignedHeader._asdict())) 395 | 396 | data3=pack(*[srlSignedHeaderFormat]+srlSignedHeader._asdict().values()) 397 | 398 | # ARM9 footer 399 | # from https://github.com/devkitPro/ndstool/ ... source/header.cpp 400 | # ARM9 footer size = 3*4 401 | ARM9Footer = namedtuple('ARM9Footer', 402 | "nitrocode " #0xDEC00621 403 | "versionInfo " 404 | "reserved " 405 | ) 406 | ARM9FooterFormat=" 2 | 3 | 4 | 5 | 46 | 47 | -------------------------------------------------------------------------------- /pc/Vid2RVID.depend: -------------------------------------------------------------------------------- 1 | # depslib dependency file v1.0 2 | 1558505168 source:d:\disassemblies\nds\vid2rvid\pc\vid2rvid\inifile.cpp 3 | 4 | 5 | 6 | "inifile.h" 7 | 8 | 1499745446 d:\disassemblies\nds\vid2rvid\pc\vid2rvid\inifile.h 9 | 10 | 11 | 12 | 13 | 1559075393 source:d:\disassemblies\nds\vid2rvid\pc\vid2rvid\main.cpp 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | "graphics/lodepng.h" 26 | "lz77.h" 27 | "inifile.h" 28 | 29 | 1558493058 d:\disassemblies\nds\vid2rvid\pc\vid2rvid\graphics\lodepng.h 30 | 31 | 32 | 33 | "lodepng.h" 34 | 35 | "lodepng.h" 36 | 37 | 1558497315 source:d:\disassemblies\nds\vid2rvid\pc\vid2rvid\graphics\lodepng.cpp 38 | "lodepng.h" 39 | 40 | 41 | 42 | 43 | 1559004337 source:d:\disassemblies\nds\vid2rvid\pc\vid2rvid\lz77.c 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 1559075682 d:\disassemblies\nds\vid2rvid\pc\vid2rvid\lz77.h 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 1559076559 source:d:\disassemblies\nds\vid2rvid\pc\vid2rvid\lz77.cpp 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | "tonccpy.h" 79 | 80 | 1559007798 d:\disassemblies\nds\vid2rvid\pc\vid2rvid\tonccpy.h 81 | 82 | 83 | 1559007818 source:d:\disassemblies\nds\vid2rvid\pc\vid2rvid\tonccpy.c 84 | "tonccpy.h" 85 | 86 | -------------------------------------------------------------------------------- /pc/Vid2RVID.layout: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /pc/graphics/lodepng.h: -------------------------------------------------------------------------------- 1 | /* 2 | LodePNG version 20190210 3 | 4 | Copyright (c) 2005-2019 Lode Vandevenne 5 | 6 | This software is provided 'as-is', without any express or implied 7 | warranty. In no event will the authors be held liable for any damages 8 | arising from the use of this software. 9 | 10 | Permission is granted to anyone to use this software for any purpose, 11 | including commercial applications, and to alter it and redistribute it 12 | freely, subject to the following restrictions: 13 | 14 | 1. The origin of this software must not be misrepresented; you must not 15 | claim that you wrote the original software. If you use this software 16 | in a product, an acknowledgment in the product documentation would be 17 | appreciated but is not required. 18 | 19 | 2. Altered source versions must be plainly marked as such, and must not be 20 | misrepresented as being the original software. 21 | 22 | 3. This notice may not be removed or altered from any source 23 | distribution. 24 | */ 25 | 26 | #ifndef LODEPNG_H 27 | #define LODEPNG_H 28 | 29 | #include /*for size_t*/ 30 | 31 | extern const char* LODEPNG_VERSION_STRING; 32 | 33 | /* 34 | The following #defines are used to create code sections. They can be disabled 35 | to disable code sections, which can give faster compile time and smaller binary. 36 | The "NO_COMPILE" defines are designed to be used to pass as defines to the 37 | compiler command to disable them without modifying this header, e.g. 38 | -DLODEPNG_NO_COMPILE_ZLIB for gcc. 39 | In addition to those below, you can also define LODEPNG_NO_COMPILE_CRC to 40 | allow implementing a custom lodepng_crc32. 41 | */ 42 | /*deflate & zlib. If disabled, you must specify alternative zlib functions in 43 | the custom_zlib field of the compress and decompress settings*/ 44 | #ifndef LODEPNG_NO_COMPILE_ZLIB 45 | #define LODEPNG_COMPILE_ZLIB 46 | #endif 47 | 48 | /*png encoder and png decoder*/ 49 | #ifndef LODEPNG_NO_COMPILE_PNG 50 | #define LODEPNG_COMPILE_PNG 51 | #endif 52 | 53 | /*deflate&zlib decoder and png decoder*/ 54 | #ifndef LODEPNG_NO_COMPILE_DECODER 55 | #define LODEPNG_COMPILE_DECODER 56 | #endif 57 | 58 | /*deflate&zlib encoder and png encoder*/ 59 | #ifndef LODEPNG_NO_COMPILE_ENCODER 60 | #define LODEPNG_COMPILE_ENCODER 61 | #endif 62 | 63 | /*the optional built in harddisk file loading and saving functions*/ 64 | #ifndef LODEPNG_NO_COMPILE_DISK 65 | #define LODEPNG_COMPILE_DISK 66 | #endif 67 | 68 | /*support for chunks other than IHDR, IDAT, PLTE, tRNS, IEND: ancillary and unknown chunks*/ 69 | #ifndef LODEPNG_NO_COMPILE_ANCILLARY_CHUNKS 70 | #define LODEPNG_COMPILE_ANCILLARY_CHUNKS 71 | #endif 72 | 73 | /*ability to convert error numerical codes to English text string*/ 74 | #ifndef LODEPNG_NO_COMPILE_ERROR_TEXT 75 | #define LODEPNG_COMPILE_ERROR_TEXT 76 | #endif 77 | 78 | /*Compile the default allocators (C's free, malloc and realloc). If you disable this, 79 | you can define the functions lodepng_free, lodepng_malloc and lodepng_realloc in your 80 | source files with custom allocators.*/ 81 | #ifndef LODEPNG_NO_COMPILE_ALLOCATORS 82 | #define LODEPNG_COMPILE_ALLOCATORS 83 | #endif 84 | 85 | /*compile the C++ version (you can disable the C++ wrapper here even when compiling for C++)*/ 86 | #ifdef __cplusplus 87 | #ifndef LODEPNG_NO_COMPILE_CPP 88 | #define LODEPNG_COMPILE_CPP 89 | #endif 90 | #endif 91 | 92 | #ifdef LODEPNG_COMPILE_CPP 93 | #include 94 | #include 95 | #endif /*LODEPNG_COMPILE_CPP*/ 96 | 97 | #ifdef LODEPNG_COMPILE_PNG 98 | /*The PNG color types (also used for raw).*/ 99 | typedef enum LodePNGColorType { 100 | LCT_GREY = 0, /*grayscale: 1,2,4,8,16 bit*/ 101 | LCT_RGB = 2, /*RGB: 8,16 bit*/ 102 | LCT_PALETTE = 3, /*palette: 1,2,4,8 bit*/ 103 | LCT_GREY_ALPHA = 4, /*grayscale with alpha: 8,16 bit*/ 104 | LCT_RGBA = 6 /*RGB with alpha: 8,16 bit*/ 105 | } LodePNGColorType; 106 | 107 | #ifdef LODEPNG_COMPILE_DECODER 108 | /* 109 | Converts PNG data in memory to raw pixel data. 110 | out: Output parameter. Pointer to buffer that will contain the raw pixel data. 111 | After decoding, its size is w * h * (bytes per pixel) bytes larger than 112 | initially. Bytes per pixel depends on colortype and bitdepth. 113 | Must be freed after usage with free(*out). 114 | Note: for 16-bit per channel colors, uses big endian format like PNG does. 115 | w: Output parameter. Pointer to width of pixel data. 116 | h: Output parameter. Pointer to height of pixel data. 117 | in: Memory buffer with the PNG file. 118 | insize: size of the in buffer. 119 | colortype: the desired color type for the raw output image. See explanation on PNG color types. 120 | bitdepth: the desired bit depth for the raw output image. See explanation on PNG color types. 121 | Return value: LodePNG error code (0 means no error). 122 | */ 123 | unsigned lodepng_decode_memory(unsigned char** out, unsigned* w, unsigned* h, 124 | const unsigned char* in, size_t insize, 125 | LodePNGColorType colortype, unsigned bitdepth); 126 | 127 | /*Same as lodepng_decode_memory, but always decodes to 32-bit RGBA raw image*/ 128 | unsigned lodepng_decode32(unsigned char** out, unsigned* w, unsigned* h, 129 | const unsigned char* in, size_t insize); 130 | 131 | /*Same as lodepng_decode_memory, but always decodes to 24-bit RGB raw image*/ 132 | unsigned lodepng_decode24(unsigned char** out, unsigned* w, unsigned* h, 133 | const unsigned char* in, size_t insize); 134 | 135 | #ifdef LODEPNG_COMPILE_DISK 136 | /* 137 | Load PNG from disk, from file with given name. 138 | Same as the other decode functions, but instead takes a filename as input. 139 | */ 140 | unsigned lodepng_decode_file(unsigned char** out, unsigned* w, unsigned* h, 141 | const char* filename, 142 | LodePNGColorType colortype, unsigned bitdepth); 143 | 144 | /*Same as lodepng_decode_file, but always decodes to 32-bit RGBA raw image.*/ 145 | unsigned lodepng_decode32_file(unsigned char** out, unsigned* w, unsigned* h, 146 | const char* filename); 147 | 148 | /*Same as lodepng_decode_file, but always decodes to 24-bit RGB raw image.*/ 149 | unsigned lodepng_decode24_file(unsigned char** out, unsigned* w, unsigned* h, 150 | const char* filename); 151 | #endif /*LODEPNG_COMPILE_DISK*/ 152 | #endif /*LODEPNG_COMPILE_DECODER*/ 153 | 154 | 155 | #ifdef LODEPNG_COMPILE_ENCODER 156 | /* 157 | Converts raw pixel data into a PNG image in memory. The colortype and bitdepth 158 | of the output PNG image cannot be chosen, they are automatically determined 159 | by the colortype, bitdepth and content of the input pixel data. 160 | Note: for 16-bit per channel colors, needs big endian format like PNG does. 161 | out: Output parameter. Pointer to buffer that will contain the PNG image data. 162 | Must be freed after usage with free(*out). 163 | outsize: Output parameter. Pointer to the size in bytes of the out buffer. 164 | image: The raw pixel data to encode. The size of this buffer should be 165 | w * h * (bytes per pixel), bytes per pixel depends on colortype and bitdepth. 166 | w: width of the raw pixel data in pixels. 167 | h: height of the raw pixel data in pixels. 168 | colortype: the color type of the raw input image. See explanation on PNG color types. 169 | bitdepth: the bit depth of the raw input image. See explanation on PNG color types. 170 | Return value: LodePNG error code (0 means no error). 171 | */ 172 | unsigned lodepng_encode_memory(unsigned char** out, size_t* outsize, 173 | const unsigned char* image, unsigned w, unsigned h, 174 | LodePNGColorType colortype, unsigned bitdepth); 175 | 176 | /*Same as lodepng_encode_memory, but always encodes from 32-bit RGBA raw image.*/ 177 | unsigned lodepng_encode32(unsigned char** out, size_t* outsize, 178 | const unsigned char* image, unsigned w, unsigned h); 179 | 180 | /*Same as lodepng_encode_memory, but always encodes from 24-bit RGB raw image.*/ 181 | unsigned lodepng_encode24(unsigned char** out, size_t* outsize, 182 | const unsigned char* image, unsigned w, unsigned h); 183 | 184 | #ifdef LODEPNG_COMPILE_DISK 185 | /* 186 | Converts raw pixel data into a PNG file on disk. 187 | Same as the other encode functions, but instead takes a filename as output. 188 | NOTE: This overwrites existing files without warning! 189 | */ 190 | unsigned lodepng_encode_file(const char* filename, 191 | const unsigned char* image, unsigned w, unsigned h, 192 | LodePNGColorType colortype, unsigned bitdepth); 193 | 194 | /*Same as lodepng_encode_file, but always encodes from 32-bit RGBA raw image.*/ 195 | unsigned lodepng_encode32_file(const char* filename, 196 | const unsigned char* image, unsigned w, unsigned h); 197 | 198 | /*Same as lodepng_encode_file, but always encodes from 24-bit RGB raw image.*/ 199 | unsigned lodepng_encode24_file(const char* filename, 200 | const unsigned char* image, unsigned w, unsigned h); 201 | #endif /*LODEPNG_COMPILE_DISK*/ 202 | #endif /*LODEPNG_COMPILE_ENCODER*/ 203 | 204 | 205 | #ifdef LODEPNG_COMPILE_CPP 206 | namespace lodepng { 207 | #ifdef LODEPNG_COMPILE_DECODER 208 | /*Same as lodepng_decode_memory, but decodes to an std::vector. The colortype 209 | is the format to output the pixels to. Default is RGBA 8-bit per channel.*/ 210 | unsigned decode(std::vector& out, unsigned& w, unsigned& h, 211 | const unsigned char* in, size_t insize, 212 | LodePNGColorType colortype = LCT_RGBA, unsigned bitdepth = 8); 213 | unsigned decode(std::vector& out, unsigned& w, unsigned& h, 214 | const std::vector& in, 215 | LodePNGColorType colortype = LCT_RGBA, unsigned bitdepth = 8); 216 | #ifdef LODEPNG_COMPILE_DISK 217 | /* 218 | Converts PNG file from disk to raw pixel data in memory. 219 | Same as the other decode functions, but instead takes a filename as input. 220 | */ 221 | unsigned decode(std::vector& out, unsigned& w, unsigned& h, 222 | const std::string& filename, 223 | LodePNGColorType colortype = LCT_RGBA, unsigned bitdepth = 8); 224 | #endif /* LODEPNG_COMPILE_DISK */ 225 | #endif /* LODEPNG_COMPILE_DECODER */ 226 | 227 | #ifdef LODEPNG_COMPILE_ENCODER 228 | /*Same as lodepng_encode_memory, but encodes to an std::vector. colortype 229 | is that of the raw input data. The output PNG color type will be auto chosen.*/ 230 | unsigned encode(std::vector& out, 231 | const unsigned char* in, unsigned w, unsigned h, 232 | LodePNGColorType colortype = LCT_RGBA, unsigned bitdepth = 8); 233 | unsigned encode(std::vector& out, 234 | const std::vector& in, unsigned w, unsigned h, 235 | LodePNGColorType colortype = LCT_RGBA, unsigned bitdepth = 8); 236 | #ifdef LODEPNG_COMPILE_DISK 237 | /* 238 | Converts 32-bit RGBA raw pixel data into a PNG file on disk. 239 | Same as the other encode functions, but instead takes a filename as output. 240 | NOTE: This overwrites existing files without warning! 241 | */ 242 | unsigned encode(const std::string& filename, 243 | const unsigned char* in, unsigned w, unsigned h, 244 | LodePNGColorType colortype = LCT_RGBA, unsigned bitdepth = 8); 245 | unsigned encode(const std::string& filename, 246 | const std::vector& in, unsigned w, unsigned h, 247 | LodePNGColorType colortype = LCT_RGBA, unsigned bitdepth = 8); 248 | #endif /* LODEPNG_COMPILE_DISK */ 249 | #endif /* LODEPNG_COMPILE_ENCODER */ 250 | } /* namespace lodepng */ 251 | #endif /*LODEPNG_COMPILE_CPP*/ 252 | #endif /*LODEPNG_COMPILE_PNG*/ 253 | 254 | #ifdef LODEPNG_COMPILE_ERROR_TEXT 255 | /*Returns an English description of the numerical error code.*/ 256 | const char* lodepng_error_text(unsigned code); 257 | #endif /*LODEPNG_COMPILE_ERROR_TEXT*/ 258 | 259 | #ifdef LODEPNG_COMPILE_DECODER 260 | /*Settings for zlib decompression*/ 261 | typedef struct LodePNGDecompressSettings LodePNGDecompressSettings; 262 | struct LodePNGDecompressSettings { 263 | /* Check LodePNGDecoderSettings for more ignorable errors such as ignore_crc */ 264 | unsigned ignore_adler32; /*if 1, continue and don't give an error message if the Adler32 checksum is corrupted*/ 265 | 266 | /*use custom zlib decoder instead of built in one (default: null)*/ 267 | unsigned (*custom_zlib)(unsigned char**, size_t*, 268 | const unsigned char*, size_t, 269 | const LodePNGDecompressSettings*); 270 | /*use custom deflate decoder instead of built in one (default: null) 271 | if custom_zlib is used, custom_deflate is ignored since only the built in 272 | zlib function will call custom_deflate*/ 273 | unsigned (*custom_inflate)(unsigned char**, size_t*, 274 | const unsigned char*, size_t, 275 | const LodePNGDecompressSettings*); 276 | 277 | const void* custom_context; /*optional custom settings for custom functions*/ 278 | }; 279 | 280 | extern const LodePNGDecompressSettings lodepng_default_decompress_settings; 281 | void lodepng_decompress_settings_init(LodePNGDecompressSettings* settings); 282 | #endif /*LODEPNG_COMPILE_DECODER*/ 283 | 284 | #ifdef LODEPNG_COMPILE_ENCODER 285 | /* 286 | Settings for zlib compression. Tweaking these settings tweaks the balance 287 | between speed and compression ratio. 288 | */ 289 | typedef struct LodePNGCompressSettings LodePNGCompressSettings; 290 | struct LodePNGCompressSettings /*deflate = compress*/ { 291 | /*LZ77 related settings*/ 292 | unsigned btype; /*the block type for LZ (0, 1, 2 or 3, see zlib standard). Should be 2 for proper compression.*/ 293 | unsigned use_lz77; /*whether or not to use LZ77. Should be 1 for proper compression.*/ 294 | unsigned windowsize; /*must be a power of two <= 32768. higher compresses more but is slower. Default value: 2048.*/ 295 | unsigned minmatch; /*mininum lz77 length. 3 is normally best, 6 can be better for some PNGs. Default: 0*/ 296 | unsigned nicematch; /*stop searching if >= this length found. Set to 258 for best compression. Default: 128*/ 297 | unsigned lazymatching; /*use lazy matching: better compression but a bit slower. Default: true*/ 298 | 299 | /*use custom zlib encoder instead of built in one (default: null)*/ 300 | unsigned (*custom_zlib)(unsigned char**, size_t*, 301 | const unsigned char*, size_t, 302 | const LodePNGCompressSettings*); 303 | /*use custom deflate encoder instead of built in one (default: null) 304 | if custom_zlib is used, custom_deflate is ignored since only the built in 305 | zlib function will call custom_deflate*/ 306 | unsigned (*custom_deflate)(unsigned char**, size_t*, 307 | const unsigned char*, size_t, 308 | const LodePNGCompressSettings*); 309 | 310 | const void* custom_context; /*optional custom settings for custom functions*/ 311 | }; 312 | 313 | extern const LodePNGCompressSettings lodepng_default_compress_settings; 314 | void lodepng_compress_settings_init(LodePNGCompressSettings* settings); 315 | #endif /*LODEPNG_COMPILE_ENCODER*/ 316 | 317 | #ifdef LODEPNG_COMPILE_PNG 318 | /* 319 | Color mode of an image. Contains all information required to decode the pixel 320 | bits to RGBA colors. This information is the same as used in the PNG file 321 | format, and is used both for PNG and raw image data in LodePNG. 322 | */ 323 | typedef struct LodePNGColorMode { 324 | /*header (IHDR)*/ 325 | LodePNGColorType colortype; /*color type, see PNG standard or documentation further in this header file*/ 326 | unsigned bitdepth; /*bits per sample, see PNG standard or documentation further in this header file*/ 327 | 328 | /* 329 | palette (PLTE and tRNS) 330 | 331 | Dynamically allocated with the colors of the palette, including alpha. 332 | When encoding a PNG, to store your colors in the palette of the LodePNGColorMode, first use 333 | lodepng_palette_clear, then for each color use lodepng_palette_add. 334 | If you encode an image without alpha with palette, don't forget to put value 255 in each A byte of the palette. 335 | 336 | When decoding, by default you can ignore this palette, since LodePNG already 337 | fills the palette colors in the pixels of the raw RGBA output. 338 | 339 | The palette is only supported for color type 3. 340 | */ 341 | unsigned char* palette; /*palette in RGBARGBA... order. When allocated, must be either 0, or have size 1024*/ 342 | size_t palettesize; /*palette size in number of colors (amount of bytes is 4 * palettesize)*/ 343 | 344 | /* 345 | transparent color key (tRNS) 346 | 347 | This color uses the same bit depth as the bitdepth value in this struct, which can be 1-bit to 16-bit. 348 | For grayscale PNGs, r, g and b will all 3 be set to the same. 349 | 350 | When decoding, by default you can ignore this information, since LodePNG sets 351 | pixels with this key to transparent already in the raw RGBA output. 352 | 353 | The color key is only supported for color types 0 and 2. 354 | */ 355 | unsigned key_defined; /*is a transparent color key given? 0 = false, 1 = true*/ 356 | unsigned key_r; /*red/grayscale component of color key*/ 357 | unsigned key_g; /*green component of color key*/ 358 | unsigned key_b; /*blue component of color key*/ 359 | } LodePNGColorMode; 360 | 361 | /*init, cleanup and copy functions to use with this struct*/ 362 | void lodepng_color_mode_init(LodePNGColorMode* info); 363 | void lodepng_color_mode_cleanup(LodePNGColorMode* info); 364 | /*return value is error code (0 means no error)*/ 365 | unsigned lodepng_color_mode_copy(LodePNGColorMode* dest, const LodePNGColorMode* source); 366 | /* Makes a temporary LodePNGColorMode that does not need cleanup (no palette) */ 367 | LodePNGColorMode lodepng_color_mode_make(LodePNGColorType colortype, unsigned bitdepth); 368 | 369 | void lodepng_palette_clear(LodePNGColorMode* info); 370 | /*add 1 color to the palette*/ 371 | unsigned lodepng_palette_add(LodePNGColorMode* info, 372 | unsigned char r, unsigned char g, unsigned char b, unsigned char a); 373 | 374 | /*get the total amount of bits per pixel, based on colortype and bitdepth in the struct*/ 375 | unsigned lodepng_get_bpp(const LodePNGColorMode* info); 376 | /*get the amount of color channels used, based on colortype in the struct. 377 | If a palette is used, it counts as 1 channel.*/ 378 | unsigned lodepng_get_channels(const LodePNGColorMode* info); 379 | /*is it a grayscale type? (only colortype 0 or 4)*/ 380 | unsigned lodepng_is_greyscale_type(const LodePNGColorMode* info); 381 | /*has it got an alpha channel? (only colortype 2 or 6)*/ 382 | unsigned lodepng_is_alpha_type(const LodePNGColorMode* info); 383 | /*has it got a palette? (only colortype 3)*/ 384 | unsigned lodepng_is_palette_type(const LodePNGColorMode* info); 385 | /*only returns true if there is a palette and there is a value in the palette with alpha < 255. 386 | Loops through the palette to check this.*/ 387 | unsigned lodepng_has_palette_alpha(const LodePNGColorMode* info); 388 | /* 389 | Check if the given color info indicates the possibility of having non-opaque pixels in the PNG image. 390 | Returns true if the image can have translucent or invisible pixels (it still be opaque if it doesn't use such pixels). 391 | Returns false if the image can only have opaque pixels. 392 | In detail, it returns true only if it's a color type with alpha, or has a palette with non-opaque values, 393 | or if "key_defined" is true. 394 | */ 395 | unsigned lodepng_can_have_alpha(const LodePNGColorMode* info); 396 | /*Returns the byte size of a raw image buffer with given width, height and color mode*/ 397 | size_t lodepng_get_raw_size(unsigned w, unsigned h, const LodePNGColorMode* color); 398 | 399 | #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS 400 | /*The information of a Time chunk in PNG.*/ 401 | typedef struct LodePNGTime { 402 | unsigned year; /*2 bytes used (0-65535)*/ 403 | unsigned month; /*1-12*/ 404 | unsigned day; /*1-31*/ 405 | unsigned hour; /*0-23*/ 406 | unsigned minute; /*0-59*/ 407 | unsigned second; /*0-60 (to allow for leap seconds)*/ 408 | } LodePNGTime; 409 | #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ 410 | 411 | /*Information about the PNG image, except pixels, width and height.*/ 412 | typedef struct LodePNGInfo { 413 | /*header (IHDR), palette (PLTE) and transparency (tRNS) chunks*/ 414 | unsigned compression_method;/*compression method of the original file. Always 0.*/ 415 | unsigned filter_method; /*filter method of the original file*/ 416 | unsigned interlace_method; /*interlace method of the original file: 0=none, 1=Adam7*/ 417 | LodePNGColorMode color; /*color type and bits, palette and transparency of the PNG file*/ 418 | 419 | #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS 420 | /* 421 | Suggested background color chunk (bKGD) 422 | 423 | This uses the same color mode and bit depth as the PNG (except no alpha channel), 424 | with values truncated to the bit depth in the unsigned integer. 425 | 426 | For grayscale and palette PNGs, the value is stored in background_r. The values 427 | in background_g and background_b are then unused. 428 | 429 | So when decoding, you may get these in a different color mode than the one you requested 430 | for the raw pixels. 431 | 432 | When encoding with auto_convert, you must use the color model defined in info_png.color for 433 | these values. The encoder normally ignores info_png.color when auto_convert is on, but will 434 | use it to interpret these values (and convert copies of them to its chosen color model). 435 | 436 | When encoding, avoid setting this to an expensive color, such as a non-gray value 437 | when the image is gray, or the compression will be worse since it will be forced to 438 | write the PNG with a more expensive color mode (when auto_convert is on). 439 | 440 | The decoder does not use this background color to edit the color of pixels. This is a 441 | completely optional metadata feature. 442 | */ 443 | unsigned background_defined; /*is a suggested background color given?*/ 444 | unsigned background_r; /*red/gray/palette component of suggested background color*/ 445 | unsigned background_g; /*green component of suggested background color*/ 446 | unsigned background_b; /*blue component of suggested background color*/ 447 | 448 | /* 449 | non-international text chunks (tEXt and zTXt) 450 | 451 | The char** arrays each contain num strings. The actual messages are in 452 | text_strings, while text_keys are keywords that give a short description what 453 | the actual text represents, e.g. Title, Author, Description, or anything else. 454 | 455 | All the string fields below including keys, names and language tags are null terminated. 456 | The PNG specification uses null characters for the keys, names and tags, and forbids null 457 | characters to appear in the main text which is why we can use null termination everywhere here. 458 | 459 | A keyword is minimum 1 character and maximum 79 characters long. It's 460 | discouraged to use a single line length longer than 79 characters for texts. 461 | 462 | Don't allocate these text buffers yourself. Use the init/cleanup functions 463 | correctly and use lodepng_add_text and lodepng_clear_text. 464 | */ 465 | size_t text_num; /*the amount of texts in these char** buffers (there may be more texts in itext)*/ 466 | char** text_keys; /*the keyword of a text chunk (e.g. "Comment")*/ 467 | char** text_strings; /*the actual text*/ 468 | 469 | /* 470 | international text chunks (iTXt) 471 | Similar to the non-international text chunks, but with additional strings 472 | "langtags" and "transkeys". 473 | */ 474 | size_t itext_num; /*the amount of international texts in this PNG*/ 475 | char** itext_keys; /*the English keyword of the text chunk (e.g. "Comment")*/ 476 | char** itext_langtags; /*language tag for this text's language, ISO/IEC 646 string, e.g. ISO 639 language tag*/ 477 | char** itext_transkeys; /*keyword translated to the international language - UTF-8 string*/ 478 | char** itext_strings; /*the actual international text - UTF-8 string*/ 479 | 480 | /*time chunk (tIME)*/ 481 | unsigned time_defined; /*set to 1 to make the encoder generate a tIME chunk*/ 482 | LodePNGTime time; 483 | 484 | /*phys chunk (pHYs)*/ 485 | unsigned phys_defined; /*if 0, there is no pHYs chunk and the values below are undefined, if 1 else there is one*/ 486 | unsigned phys_x; /*pixels per unit in x direction*/ 487 | unsigned phys_y; /*pixels per unit in y direction*/ 488 | unsigned phys_unit; /*may be 0 (unknown unit) or 1 (metre)*/ 489 | 490 | /* 491 | Color profile related chunks: gAMA, cHRM, sRGB, iCPP 492 | 493 | LodePNG does not apply any color conversions on pixels in the encoder or decoder and does not interpret these color 494 | profile values. It merely passes on the information. If you wish to use color profiles and convert colors, please 495 | use these values with a color management library. 496 | 497 | See the PNG, ICC and sRGB specifications for more information about the meaning of these values. 498 | */ 499 | 500 | /* gAMA chunk: optional, overridden by sRGB or iCCP if those are present. */ 501 | unsigned gama_defined; /* Whether a gAMA chunk is present (0 = not present, 1 = present). */ 502 | unsigned gama_gamma; /* Gamma exponent times 100000 */ 503 | 504 | /* cHRM chunk: optional, overridden by sRGB or iCCP if those are present. */ 505 | unsigned chrm_defined; /* Whether a cHRM chunk is present (0 = not present, 1 = present). */ 506 | unsigned chrm_white_x; /* White Point x times 100000 */ 507 | unsigned chrm_white_y; /* White Point y times 100000 */ 508 | unsigned chrm_red_x; /* Red x times 100000 */ 509 | unsigned chrm_red_y; /* Red y times 100000 */ 510 | unsigned chrm_green_x; /* Green x times 100000 */ 511 | unsigned chrm_green_y; /* Green y times 100000 */ 512 | unsigned chrm_blue_x; /* Blue x times 100000 */ 513 | unsigned chrm_blue_y; /* Blue y times 100000 */ 514 | 515 | /* 516 | sRGB chunk: optional. May not appear at the same time as iCCP. 517 | If gAMA is also present gAMA must contain value 45455. 518 | If cHRM is also present cHRM must contain respectively 31270,32900,64000,33000,30000,60000,15000,6000. 519 | */ 520 | unsigned srgb_defined; /* Whether an sRGB chunk is present (0 = not present, 1 = present). */ 521 | unsigned srgb_intent; /* Rendering intent: 0=perceptual, 1=rel. colorimetric, 2=saturation, 3=abs. colorimetric */ 522 | 523 | /* 524 | iCCP chunk: optional. May not appear at the same time as sRGB. 525 | 526 | LodePNG does not parse or use the ICC profile (except its color space header field for an edge case), a 527 | separate library to handle the ICC data (not included in LodePNG) format is needed to use it for color 528 | management and conversions. 529 | 530 | For encoding, if iCCP is present, gAMA and cHRM are recommended to be added as well with values that match the ICC 531 | profile as closely as possible, if you wish to do this you should provide the correct values for gAMA and cHRM and 532 | enable their '_defined' flags since LodePNG will not automatically compute them from the ICC profile. 533 | 534 | For encoding, the ICC profile is required by the PNG specification to be an "RGB" profile for non-gray 535 | PNG color types and a "GRAY" profile for gray PNG color types. If you disable auto_convert, you must ensure 536 | the ICC profile type matches your requested color type, else the encoder gives an error. If auto_convert is 537 | enabled (the default), and the ICC profile is not a good match for the pixel data, this will result in an encoder 538 | error if the pixel data has non-gray pixels for a GRAY profile, or a silent less-optimal compression of the pixel 539 | data if the pixels could be encoded as grayscale but the ICC profile is RGB. 540 | 541 | To avoid this do not set an ICC profile in the image unless there is a good reason for it, and when doing so 542 | make sure you compute it carefully to avoid the above problems. 543 | */ 544 | unsigned iccp_defined; /* Whether an iCCP chunk is present (0 = not present, 1 = present). */ 545 | char* iccp_name; /* Null terminated string with profile name, 1-79 bytes */ 546 | /* 547 | The ICC profile in iccp_profile_size bytes. 548 | Don't allocate this buffer yourself. Use the init/cleanup functions 549 | correctly and use lodepng_set_icc and lodepng_clear_icc. 550 | */ 551 | unsigned char* iccp_profile; 552 | unsigned iccp_profile_size; /* The size of iccp_profile in bytes */ 553 | 554 | /* End of color profile related chunks */ 555 | 556 | 557 | /* 558 | unknown chunks: chunks not known by LodePNG, passed on byte for byte. 559 | 560 | There are 3 buffers, one for each position in the PNG where unknown chunks can appear. 561 | Each buffer contains all unknown chunks for that position consecutively. 562 | The 3 positions are: 563 | 0: between IHDR and PLTE, 1: between PLTE and IDAT, 2: between IDAT and IEND. 564 | 565 | For encoding, do not store critical chunks or known chunks that are enabled with a "_defined" flag 566 | above in here, since the encoder will blindly follow this and could then encode an invalid PNG file 567 | (such as one with two IHDR chunks or the disallowed combination of sRGB with iCCP). But do use 568 | this if you wish to store an ancillary chunk that is not supported by LodePNG (such as sPLT or hIST), 569 | or any non-standard PNG chunk. 570 | 571 | Do not allocate or traverse this data yourself. Use the chunk traversing functions declared 572 | later, such as lodepng_chunk_next and lodepng_chunk_append, to read/write this struct. 573 | */ 574 | unsigned char* unknown_chunks_data[3]; 575 | size_t unknown_chunks_size[3]; /*size in bytes of the unknown chunks, given for protection*/ 576 | #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ 577 | } LodePNGInfo; 578 | 579 | /*init, cleanup and copy functions to use with this struct*/ 580 | void lodepng_info_init(LodePNGInfo* info); 581 | void lodepng_info_cleanup(LodePNGInfo* info); 582 | /*return value is error code (0 means no error)*/ 583 | unsigned lodepng_info_copy(LodePNGInfo* dest, const LodePNGInfo* source); 584 | 585 | #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS 586 | unsigned lodepng_add_text(LodePNGInfo* info, const char* key, const char* str); /*push back both texts at once*/ 587 | void lodepng_clear_text(LodePNGInfo* info); /*use this to clear the texts again after you filled them in*/ 588 | 589 | unsigned lodepng_add_itext(LodePNGInfo* info, const char* key, const char* langtag, 590 | const char* transkey, const char* str); /*push back the 4 texts of 1 chunk at once*/ 591 | void lodepng_clear_itext(LodePNGInfo* info); /*use this to clear the itexts again after you filled them in*/ 592 | 593 | /*replaces if exists*/ 594 | unsigned lodepng_set_icc(LodePNGInfo* info, const char* name, const unsigned char* profile, unsigned profile_size); 595 | void lodepng_clear_icc(LodePNGInfo* info); /*use this to clear the texts again after you filled them in*/ 596 | #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ 597 | 598 | /* 599 | Converts raw buffer from one color type to another color type, based on 600 | LodePNGColorMode structs to describe the input and output color type. 601 | See the reference manual at the end of this header file to see which color conversions are supported. 602 | return value = LodePNG error code (0 if all went ok, an error if the conversion isn't supported) 603 | The out buffer must have size (w * h * bpp + 7) / 8, where bpp is the bits per pixel 604 | of the output color type (lodepng_get_bpp). 605 | For < 8 bpp images, there should not be padding bits at the end of scanlines. 606 | For 16-bit per channel colors, uses big endian format like PNG does. 607 | Return value is LodePNG error code 608 | */ 609 | unsigned lodepng_convert(unsigned char* out, const unsigned char* in, 610 | const LodePNGColorMode* mode_out, const LodePNGColorMode* mode_in, 611 | unsigned w, unsigned h); 612 | 613 | #ifdef LODEPNG_COMPILE_DECODER 614 | /* 615 | Settings for the decoder. This contains settings for the PNG and the Zlib 616 | decoder, but not the Info settings from the Info structs. 617 | */ 618 | typedef struct LodePNGDecoderSettings { 619 | LodePNGDecompressSettings zlibsettings; /*in here is the setting to ignore Adler32 checksums*/ 620 | 621 | /* Check LodePNGDecompressSettings for more ignorable errors such as ignore_adler32 */ 622 | unsigned ignore_crc; /*ignore CRC checksums*/ 623 | unsigned ignore_critical; /*ignore unknown critical chunks*/ 624 | unsigned ignore_end; /*ignore issues at end of file if possible (missing IEND chunk, too large chunk, ...)*/ 625 | /* TODO: make a system involving warnings with levels and a strict mode instead. Other potentially recoverable 626 | errors: srgb rendering intent value, size of content of ancillary chunks, more than 79 characters for some 627 | strings, placement/combination rules for ancillary chunks, crc of unknown chunks, allowed characters 628 | in string keys, etc... */ 629 | 630 | unsigned color_convert; /*whether to convert the PNG to the color type you want. Default: yes*/ 631 | 632 | #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS 633 | unsigned read_text_chunks; /*if false but remember_unknown_chunks is true, they're stored in the unknown chunks*/ 634 | /*store all bytes from unknown chunks in the LodePNGInfo (off by default, useful for a png editor)*/ 635 | unsigned remember_unknown_chunks; 636 | #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ 637 | } LodePNGDecoderSettings; 638 | 639 | void lodepng_decoder_settings_init(LodePNGDecoderSettings* settings); 640 | #endif /*LODEPNG_COMPILE_DECODER*/ 641 | 642 | #ifdef LODEPNG_COMPILE_ENCODER 643 | /*automatically use color type with less bits per pixel if losslessly possible. Default: AUTO*/ 644 | typedef enum LodePNGFilterStrategy { 645 | /*every filter at zero*/ 646 | LFS_ZERO, 647 | /*Use filter that gives minimum sum, as described in the official PNG filter heuristic.*/ 648 | LFS_MINSUM, 649 | /*Use the filter type that gives smallest Shannon entropy for this scanline. Depending 650 | on the image, this is better or worse than minsum.*/ 651 | LFS_ENTROPY, 652 | /* 653 | Brute-force-search PNG filters by compressing each filter for each scanline. 654 | Experimental, very slow, and only rarely gives better compression than MINSUM. 655 | */ 656 | LFS_BRUTE_FORCE, 657 | /*use predefined_filters buffer: you specify the filter type for each scanline*/ 658 | LFS_PREDEFINED 659 | } LodePNGFilterStrategy; 660 | 661 | /*Gives characteristics about the integer RGBA colors of the image (count, alpha channel usage, bit depth, ...), 662 | which helps decide which color model to use for encoding. 663 | Used internally by default if "auto_convert" is enabled. Public because it's useful for custom algorithms. 664 | NOTE: This is not related to the ICC color profile, search "iccp_profile" instead to find the ICC/chromacity/... 665 | fields in this header file.*/ 666 | typedef struct LodePNGColorProfile { 667 | unsigned colored; /*not grayscale*/ 668 | unsigned key; /*image is not opaque and color key is possible instead of full alpha*/ 669 | unsigned short key_r; /*key values, always as 16-bit, in 8-bit case the byte is duplicated, e.g. 65535 means 255*/ 670 | unsigned short key_g; 671 | unsigned short key_b; 672 | unsigned alpha; /*image is not opaque and alpha channel or alpha palette required*/ 673 | unsigned numcolors; /*amount of colors, up to 257. Not valid if bits == 16.*/ 674 | unsigned char palette[1024]; /*Remembers up to the first 256 RGBA colors, in no particular order*/ 675 | unsigned bits; /*bits per channel (not for palette). 1,2 or 4 for grayscale only. 16 if 16-bit per channel required.*/ 676 | size_t numpixels; 677 | } LodePNGColorProfile; 678 | 679 | void lodepng_color_profile_init(LodePNGColorProfile* profile); 680 | 681 | /*Get a LodePNGColorProfile of the image. The profile must already have been inited. 682 | NOTE: This is not related to the ICC color profile, search "iccp_profile" instead to find the ICC/chromacity/... 683 | fields in this header file.*/ 684 | unsigned lodepng_get_color_profile(LodePNGColorProfile* profile, 685 | const unsigned char* image, unsigned w, unsigned h, 686 | const LodePNGColorMode* mode_in); 687 | /*The function LodePNG uses internally to decide the PNG color with auto_convert. 688 | Chooses an optimal color model, e.g. gray if only gray pixels, palette if < 256 colors, ...*/ 689 | unsigned lodepng_auto_choose_color(LodePNGColorMode* mode_out, 690 | const unsigned char* image, unsigned w, unsigned h, 691 | const LodePNGColorMode* mode_in); 692 | 693 | /*Settings for the encoder.*/ 694 | typedef struct LodePNGEncoderSettings { 695 | LodePNGCompressSettings zlibsettings; /*settings for the zlib encoder, such as window size, ...*/ 696 | 697 | unsigned auto_convert; /*automatically choose output PNG color type. Default: true*/ 698 | 699 | /*If true, follows the official PNG heuristic: if the PNG uses a palette or lower than 700 | 8 bit depth, set all filters to zero. Otherwise use the filter_strategy. Note that to 701 | completely follow the official PNG heuristic, filter_palette_zero must be true and 702 | filter_strategy must be LFS_MINSUM*/ 703 | unsigned filter_palette_zero; 704 | /*Which filter strategy to use when not using zeroes due to filter_palette_zero. 705 | Set filter_palette_zero to 0 to ensure always using your chosen strategy. Default: LFS_MINSUM*/ 706 | LodePNGFilterStrategy filter_strategy; 707 | /*used if filter_strategy is LFS_PREDEFINED. In that case, this must point to a buffer with 708 | the same length as the amount of scanlines in the image, and each value must <= 5. You 709 | have to cleanup this buffer, LodePNG will never free it. Don't forget that filter_palette_zero 710 | must be set to 0 to ensure this is also used on palette or low bitdepth images.*/ 711 | const unsigned char* predefined_filters; 712 | 713 | /*force creating a PLTE chunk if colortype is 2 or 6 (= a suggested palette). 714 | If colortype is 3, PLTE is _always_ created.*/ 715 | unsigned force_palette; 716 | #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS 717 | /*add LodePNG identifier and version as a text chunk, for debugging*/ 718 | unsigned add_id; 719 | /*encode text chunks as zTXt chunks instead of tEXt chunks, and use compression in iTXt chunks*/ 720 | unsigned text_compression; 721 | #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ 722 | } LodePNGEncoderSettings; 723 | 724 | void lodepng_encoder_settings_init(LodePNGEncoderSettings* settings); 725 | #endif /*LODEPNG_COMPILE_ENCODER*/ 726 | 727 | 728 | #if defined(LODEPNG_COMPILE_DECODER) || defined(LODEPNG_COMPILE_ENCODER) 729 | /*The settings, state and information for extended encoding and decoding.*/ 730 | typedef struct LodePNGState { 731 | #ifdef LODEPNG_COMPILE_DECODER 732 | LodePNGDecoderSettings decoder; /*the decoding settings*/ 733 | #endif /*LODEPNG_COMPILE_DECODER*/ 734 | #ifdef LODEPNG_COMPILE_ENCODER 735 | LodePNGEncoderSettings encoder; /*the encoding settings*/ 736 | #endif /*LODEPNG_COMPILE_ENCODER*/ 737 | LodePNGColorMode info_raw; /*specifies the format in which you would like to get the raw pixel buffer*/ 738 | LodePNGInfo info_png; /*info of the PNG image obtained after decoding*/ 739 | unsigned error; 740 | #ifdef LODEPNG_COMPILE_CPP 741 | /* For the lodepng::State subclass. */ 742 | virtual ~LodePNGState(){} 743 | #endif 744 | } LodePNGState; 745 | 746 | /*init, cleanup and copy functions to use with this struct*/ 747 | void lodepng_state_init(LodePNGState* state); 748 | void lodepng_state_cleanup(LodePNGState* state); 749 | void lodepng_state_copy(LodePNGState* dest, const LodePNGState* source); 750 | #endif /* defined(LODEPNG_COMPILE_DECODER) || defined(LODEPNG_COMPILE_ENCODER) */ 751 | 752 | #ifdef LODEPNG_COMPILE_DECODER 753 | /* 754 | Same as lodepng_decode_memory, but uses a LodePNGState to allow custom settings and 755 | getting much more information about the PNG image and color mode. 756 | */ 757 | unsigned lodepng_decode(unsigned char** out, unsigned* w, unsigned* h, 758 | LodePNGState* state, 759 | const unsigned char* in, size_t insize); 760 | 761 | /* 762 | Read the PNG header, but not the actual data. This returns only the information 763 | that is in the IHDR chunk of the PNG, such as width, height and color type. The 764 | information is placed in the info_png field of the LodePNGState. 765 | */ 766 | unsigned lodepng_inspect(unsigned* w, unsigned* h, 767 | LodePNGState* state, 768 | const unsigned char* in, size_t insize); 769 | #endif /*LODEPNG_COMPILE_DECODER*/ 770 | 771 | /* 772 | Reads one metadata chunk (other than IHDR) of the PNG file and outputs what it 773 | read in the state. Returns error code on failure. 774 | Use lodepng_inspect first with a new state, then e.g. lodepng_chunk_find_const 775 | to find the desired chunk type, and if non null use lodepng_inspect_chunk (with 776 | chunk_pointer - start_of_file as pos). 777 | Supports most metadata chunks from the PNG standard (gAMA, bKGD, tEXt, ...). 778 | Ignores unsupported, unknown, non-metadata or IHDR chunks (without error). 779 | Requirements: &in[pos] must point to start of a chunk, must use regular 780 | lodepng_inspect first since format of most other chunks depends on IHDR, and if 781 | there is a PLTE chunk, that one must be inspected before tRNS or bKGD. 782 | */ 783 | unsigned lodepng_inspect_chunk(LodePNGState* state, size_t pos, 784 | const unsigned char* in, size_t insize); 785 | 786 | #ifdef LODEPNG_COMPILE_ENCODER 787 | /*This function allocates the out buffer with standard malloc and stores the size in *outsize.*/ 788 | unsigned lodepng_encode(unsigned char** out, size_t* outsize, 789 | const unsigned char* image, unsigned w, unsigned h, 790 | LodePNGState* state); 791 | #endif /*LODEPNG_COMPILE_ENCODER*/ 792 | 793 | /* 794 | The lodepng_chunk functions are normally not needed, except to traverse the 795 | unknown chunks stored in the LodePNGInfo struct, or add new ones to it. 796 | It also allows traversing the chunks of an encoded PNG file yourself. 797 | 798 | The chunk pointer always points to the beginning of the chunk itself, that is 799 | the first byte of the 4 length bytes. 800 | 801 | In the PNG file format, chunks have the following format: 802 | -4 bytes length: length of the data of the chunk in bytes (chunk itself is 12 bytes longer) 803 | -4 bytes chunk type (ASCII a-z,A-Z only, see below) 804 | -length bytes of data (may be 0 bytes if length was 0) 805 | -4 bytes of CRC, computed on chunk name + data 806 | 807 | The first chunk starts at the 8th byte of the PNG file, the entire rest of the file 808 | exists out of concatenated chunks with the above format. 809 | 810 | PNG standard chunk ASCII naming conventions: 811 | -First byte: uppercase = critical, lowercase = ancillary 812 | -Second byte: uppercase = public, lowercase = private 813 | -Third byte: must be uppercase 814 | -Fourth byte: uppercase = unsafe to copy, lowercase = safe to copy 815 | */ 816 | 817 | /* 818 | Gets the length of the data of the chunk. Total chunk length has 12 bytes more. 819 | There must be at least 4 bytes to read from. If the result value is too large, 820 | it may be corrupt data. 821 | */ 822 | unsigned lodepng_chunk_length(const unsigned char* chunk); 823 | 824 | /*puts the 4-byte type in null terminated string*/ 825 | void lodepng_chunk_type(char type[5], const unsigned char* chunk); 826 | 827 | /*check if the type is the given type*/ 828 | unsigned char lodepng_chunk_type_equals(const unsigned char* chunk, const char* type); 829 | 830 | /*0: it's one of the critical chunk types, 1: it's an ancillary chunk (see PNG standard)*/ 831 | unsigned char lodepng_chunk_ancillary(const unsigned char* chunk); 832 | 833 | /*0: public, 1: private (see PNG standard)*/ 834 | unsigned char lodepng_chunk_private(const unsigned char* chunk); 835 | 836 | /*0: the chunk is unsafe to copy, 1: the chunk is safe to copy (see PNG standard)*/ 837 | unsigned char lodepng_chunk_safetocopy(const unsigned char* chunk); 838 | 839 | /*get pointer to the data of the chunk, where the input points to the header of the chunk*/ 840 | unsigned char* lodepng_chunk_data(unsigned char* chunk); 841 | const unsigned char* lodepng_chunk_data_const(const unsigned char* chunk); 842 | 843 | /*returns 0 if the crc is correct, 1 if it's incorrect (0 for OK as usual!)*/ 844 | unsigned lodepng_chunk_check_crc(const unsigned char* chunk); 845 | 846 | /*generates the correct CRC from the data and puts it in the last 4 bytes of the chunk*/ 847 | void lodepng_chunk_generate_crc(unsigned char* chunk); 848 | 849 | /* 850 | Iterate to next chunks, allows iterating through all chunks of the PNG file. 851 | Input must be at the beginning of a chunk (result of a previous lodepng_chunk_next call, 852 | or the 8th byte of a PNG file which always has the first chunk), or alternatively may 853 | point to the first byte of the PNG file (which is not a chunk but the magic header, the 854 | function will then skip over it and return the first real chunk). 855 | Expects at least 8 readable bytes of memory in the input pointer. 856 | Will output pointer to the start of the next chunk or the end of the file if there 857 | is no more chunk after this. Start this process at the 8th byte of the PNG file. 858 | In a non-corrupt PNG file, the last chunk should have name "IEND". 859 | */ 860 | unsigned char* lodepng_chunk_next(unsigned char* chunk); 861 | const unsigned char* lodepng_chunk_next_const(const unsigned char* chunk); 862 | 863 | /*Finds the first chunk with the given type in the range [chunk, end), or returns NULL if not found.*/ 864 | unsigned char* lodepng_chunk_find(unsigned char* chunk, const unsigned char* end, const char type[5]); 865 | const unsigned char* lodepng_chunk_find_const(const unsigned char* chunk, const unsigned char* end, const char type[5]); 866 | 867 | /* 868 | Appends chunk to the data in out. The given chunk should already have its chunk header. 869 | The out variable and outlength are updated to reflect the new reallocated buffer. 870 | Returns error code (0 if it went ok) 871 | */ 872 | unsigned lodepng_chunk_append(unsigned char** out, size_t* outlength, const unsigned char* chunk); 873 | 874 | /* 875 | Appends new chunk to out. The chunk to append is given by giving its length, type 876 | and data separately. The type is a 4-letter string. 877 | The out variable and outlength are updated to reflect the new reallocated buffer. 878 | Returne error code (0 if it went ok) 879 | */ 880 | unsigned lodepng_chunk_create(unsigned char** out, size_t* outlength, unsigned length, 881 | const char* type, const unsigned char* data); 882 | 883 | 884 | /*Calculate CRC32 of buffer*/ 885 | unsigned lodepng_crc32(const unsigned char* buf, size_t len); 886 | #endif /*LODEPNG_COMPILE_PNG*/ 887 | 888 | 889 | #ifdef LODEPNG_COMPILE_ZLIB 890 | /* 891 | This zlib part can be used independently to zlib compress and decompress a 892 | buffer. It cannot be used to create gzip files however, and it only supports the 893 | part of zlib that is required for PNG, it does not support dictionaries. 894 | */ 895 | 896 | #ifdef LODEPNG_COMPILE_DECODER 897 | /*Inflate a buffer. Inflate is the decompression step of deflate. Out buffer must be freed after use.*/ 898 | unsigned lodepng_inflate(unsigned char** out, size_t* outsize, 899 | const unsigned char* in, size_t insize, 900 | const LodePNGDecompressSettings* settings); 901 | 902 | /* 903 | Decompresses Zlib data. Reallocates the out buffer and appends the data. The 904 | data must be according to the zlib specification. 905 | Either, *out must be NULL and *outsize must be 0, or, *out must be a valid 906 | buffer and *outsize its size in bytes. out must be freed by user after usage. 907 | */ 908 | unsigned lodepng_zlib_decompress(unsigned char** out, size_t* outsize, 909 | const unsigned char* in, size_t insize, 910 | const LodePNGDecompressSettings* settings); 911 | #endif /*LODEPNG_COMPILE_DECODER*/ 912 | 913 | #ifdef LODEPNG_COMPILE_ENCODER 914 | /* 915 | Compresses data with Zlib. Reallocates the out buffer and appends the data. 916 | Zlib adds a small header and trailer around the deflate data. 917 | The data is output in the format of the zlib specification. 918 | Either, *out must be NULL and *outsize must be 0, or, *out must be a valid 919 | buffer and *outsize its size in bytes. out must be freed by user after usage. 920 | */ 921 | unsigned lodepng_zlib_compress(unsigned char** out, size_t* outsize, 922 | const unsigned char* in, size_t insize, 923 | const LodePNGCompressSettings* settings); 924 | 925 | /* 926 | Find length-limited Huffman code for given frequencies. This function is in the 927 | public interface only for tests, it's used internally by lodepng_deflate. 928 | */ 929 | unsigned lodepng_huffman_code_lengths(unsigned* lengths, const unsigned* frequencies, 930 | size_t numcodes, unsigned maxbitlen); 931 | 932 | /*Compress a buffer with deflate. See RFC 1951. Out buffer must be freed after use.*/ 933 | unsigned lodepng_deflate(unsigned char** out, size_t* outsize, 934 | const unsigned char* in, size_t insize, 935 | const LodePNGCompressSettings* settings); 936 | 937 | #endif /*LODEPNG_COMPILE_ENCODER*/ 938 | #endif /*LODEPNG_COMPILE_ZLIB*/ 939 | 940 | #ifdef LODEPNG_COMPILE_DISK 941 | /* 942 | Load a file from disk into buffer. The function allocates the out buffer, and 943 | after usage you should free it. 944 | out: output parameter, contains pointer to loaded buffer. 945 | outsize: output parameter, size of the allocated out buffer 946 | filename: the path to the file to load 947 | return value: error code (0 means ok) 948 | */ 949 | unsigned lodepng_load_file(unsigned char** out, size_t* outsize, const char* filename); 950 | 951 | /* 952 | Save a file from buffer to disk. Warning, if it exists, this function overwrites 953 | the file without warning! 954 | buffer: the buffer to write 955 | buffersize: size of the buffer to write 956 | filename: the path to the file to save to 957 | return value: error code (0 means ok) 958 | */ 959 | unsigned lodepng_save_file(const unsigned char* buffer, size_t buffersize, const char* filename); 960 | #endif /*LODEPNG_COMPILE_DISK*/ 961 | 962 | #ifdef LODEPNG_COMPILE_CPP 963 | /* The LodePNG C++ wrapper uses std::vectors instead of manually allocated memory buffers. */ 964 | namespace lodepng { 965 | #ifdef LODEPNG_COMPILE_PNG 966 | class State : public LodePNGState { 967 | public: 968 | State(); 969 | State(const State& other); 970 | virtual ~State(); 971 | State& operator=(const State& other); 972 | }; 973 | 974 | #ifdef LODEPNG_COMPILE_DECODER 975 | /* Same as other lodepng::decode, but using a State for more settings and information. */ 976 | unsigned decode(std::vector& out, unsigned& w, unsigned& h, 977 | State& state, 978 | const unsigned char* in, size_t insize); 979 | unsigned decode(std::vector& out, unsigned& w, unsigned& h, 980 | State& state, 981 | const std::vector& in); 982 | #endif /*LODEPNG_COMPILE_DECODER*/ 983 | 984 | #ifdef LODEPNG_COMPILE_ENCODER 985 | /* Same as other lodepng::encode, but using a State for more settings and information. */ 986 | unsigned encode(std::vector& out, 987 | const unsigned char* in, unsigned w, unsigned h, 988 | State& state); 989 | unsigned encode(std::vector& out, 990 | const std::vector& in, unsigned w, unsigned h, 991 | State& state); 992 | #endif /*LODEPNG_COMPILE_ENCODER*/ 993 | 994 | #ifdef LODEPNG_COMPILE_DISK 995 | /* 996 | Load a file from disk into an std::vector. 997 | return value: error code (0 means ok) 998 | */ 999 | unsigned load_file(std::vector& buffer, const std::string& filename); 1000 | 1001 | /* 1002 | Save the binary data in an std::vector to a file on disk. The file is overwritten 1003 | without warning. 1004 | */ 1005 | unsigned save_file(const std::vector& buffer, const std::string& filename); 1006 | #endif /* LODEPNG_COMPILE_DISK */ 1007 | #endif /* LODEPNG_COMPILE_PNG */ 1008 | 1009 | #ifdef LODEPNG_COMPILE_ZLIB 1010 | #ifdef LODEPNG_COMPILE_DECODER 1011 | /* Zlib-decompress an unsigned char buffer */ 1012 | unsigned decompress(std::vector& out, const unsigned char* in, size_t insize, 1013 | const LodePNGDecompressSettings& settings = lodepng_default_decompress_settings); 1014 | 1015 | /* Zlib-decompress an std::vector */ 1016 | unsigned decompress(std::vector& out, const std::vector& in, 1017 | const LodePNGDecompressSettings& settings = lodepng_default_decompress_settings); 1018 | #endif /* LODEPNG_COMPILE_DECODER */ 1019 | 1020 | #ifdef LODEPNG_COMPILE_ENCODER 1021 | /* Zlib-compress an unsigned char buffer */ 1022 | unsigned compress(std::vector& out, const unsigned char* in, size_t insize, 1023 | const LodePNGCompressSettings& settings = lodepng_default_compress_settings); 1024 | 1025 | /* Zlib-compress an std::vector */ 1026 | unsigned compress(std::vector& out, const std::vector& in, 1027 | const LodePNGCompressSettings& settings = lodepng_default_compress_settings); 1028 | #endif /* LODEPNG_COMPILE_ENCODER */ 1029 | #endif /* LODEPNG_COMPILE_ZLIB */ 1030 | } /* namespace lodepng */ 1031 | #endif /*LODEPNG_COMPILE_CPP*/ 1032 | 1033 | /* 1034 | TODO: 1035 | [.] test if there are no memory leaks or security exploits - done a lot but needs to be checked often 1036 | [.] check compatibility with various compilers - done but needs to be redone for every newer version 1037 | [X] converting color to 16-bit per channel types 1038 | [X] support color profile chunk types (but never let them touch RGB values by default) 1039 | [ ] support all public PNG chunk types (almost done except sBIT, sPLT and hIST) 1040 | [ ] make sure encoder generates no chunks with size > (2^31)-1 1041 | [ ] partial decoding (stream processing) 1042 | [X] let the "isFullyOpaque" function check color keys and transparent palettes too 1043 | [X] better name for the variables "codes", "codesD", "codelengthcodes", "clcl" and "lldl" 1044 | [ ] allow treating some errors like warnings, when image is recoverable (e.g. 69, 57, 58) 1045 | [ ] make warnings like: oob palette, checksum fail, data after iend, wrong/unknown crit chunk, no null terminator in text, ... 1046 | [ ] error messages with line numbers (and version) 1047 | [ ] errors in state instead of as return code? 1048 | [ ] new errors/warnings like suspiciously big decompressed ztxt or iccp chunk 1049 | [ ] let the C++ wrapper catch exceptions coming from the standard library and return LodePNG error codes 1050 | [ ] allow user to provide custom color conversion functions, e.g. for premultiplied alpha, padding bits or not, ... 1051 | [ ] allow user to give data (void*) to custom allocator 1052 | [ ] provide alternatives for C library functions not present on some platforms (memcpy, ...) 1053 | [ ] rename "grey" to "gray" everywhere since "color" also uses US spelling (keep "grey" copies for backwards compatibility) 1054 | */ 1055 | 1056 | #endif /*LODEPNG_H inclusion guard*/ 1057 | 1058 | /* 1059 | LodePNG Documentation 1060 | --------------------- 1061 | 1062 | 0. table of contents 1063 | -------------------- 1064 | 1065 | 1. about 1066 | 1.1. supported features 1067 | 1.2. features not supported 1068 | 2. C and C++ version 1069 | 3. security 1070 | 4. decoding 1071 | 5. encoding 1072 | 6. color conversions 1073 | 6.1. PNG color types 1074 | 6.2. color conversions 1075 | 6.3. padding bits 1076 | 6.4. A note about 16-bits per channel and endianness 1077 | 7. error values 1078 | 8. chunks and PNG editing 1079 | 9. compiler support 1080 | 10. examples 1081 | 10.1. decoder C++ example 1082 | 10.2. decoder C example 1083 | 11. state settings reference 1084 | 12. changes 1085 | 13. contact information 1086 | 1087 | 1088 | 1. about 1089 | -------- 1090 | 1091 | PNG is a file format to store raster images losslessly with good compression, 1092 | supporting different color types and alpha channel. 1093 | 1094 | LodePNG is a PNG codec according to the Portable Network Graphics (PNG) 1095 | Specification (Second Edition) - W3C Recommendation 10 November 2003. 1096 | 1097 | The specifications used are: 1098 | 1099 | *) Portable Network Graphics (PNG) Specification (Second Edition): 1100 | http://www.w3.org/TR/2003/REC-PNG-20031110 1101 | *) RFC 1950 ZLIB Compressed Data Format version 3.3: 1102 | http://www.gzip.org/zlib/rfc-zlib.html 1103 | *) RFC 1951 DEFLATE Compressed Data Format Specification ver 1.3: 1104 | http://www.gzip.org/zlib/rfc-deflate.html 1105 | 1106 | The most recent version of LodePNG can currently be found at 1107 | http://lodev.org/lodepng/ 1108 | 1109 | LodePNG works both in C (ISO C90) and C++, with a C++ wrapper that adds 1110 | extra functionality. 1111 | 1112 | LodePNG exists out of two files: 1113 | -lodepng.h: the header file for both C and C++ 1114 | -lodepng.c(pp): give it the name lodepng.c or lodepng.cpp (or .cc) depending on your usage 1115 | 1116 | If you want to start using LodePNG right away without reading this doc, get the 1117 | examples from the LodePNG website to see how to use it in code, or check the 1118 | smaller examples in chapter 13 here. 1119 | 1120 | LodePNG is simple but only supports the basic requirements. To achieve 1121 | simplicity, the following design choices were made: There are no dependencies 1122 | on any external library. There are functions to decode and encode a PNG with 1123 | a single function call, and extended versions of these functions taking a 1124 | LodePNGState struct allowing to specify or get more information. By default 1125 | the colors of the raw image are always RGB or RGBA, no matter what color type 1126 | the PNG file uses. To read and write files, there are simple functions to 1127 | convert the files to/from buffers in memory. 1128 | 1129 | This all makes LodePNG suitable for loading textures in games, demos and small 1130 | programs, ... It's less suitable for full fledged image editors, loading PNGs 1131 | over network (it requires all the image data to be available before decoding can 1132 | begin), life-critical systems, ... 1133 | 1134 | 1.1. supported features 1135 | ----------------------- 1136 | 1137 | The following features are supported by the decoder: 1138 | 1139 | *) decoding of PNGs with any color type, bit depth and interlace mode, to a 24- or 32-bit color raw image, 1140 | or the same color type as the PNG 1141 | *) encoding of PNGs, from any raw image to 24- or 32-bit color, or the same color type as the raw image 1142 | *) Adam7 interlace and deinterlace for any color type 1143 | *) loading the image from harddisk or decoding it from a buffer from other sources than harddisk 1144 | *) support for alpha channels, including RGBA color model, translucent palettes and color keying 1145 | *) zlib decompression (inflate) 1146 | *) zlib compression (deflate) 1147 | *) CRC32 and ADLER32 checksums 1148 | *) colorimetric color profile conversions: currently experimentally available in lodepng_util.cpp only, 1149 | plus alternatively ability to pass on chroma/gamma/ICC profile information to other color management system. 1150 | *) handling of unknown chunks, allowing making a PNG editor that stores custom and unknown chunks. 1151 | *) the following chunks are supported by both encoder and decoder: 1152 | IHDR: header information 1153 | PLTE: color palette 1154 | IDAT: pixel data 1155 | IEND: the final chunk 1156 | tRNS: transparency for palettized images 1157 | tEXt: textual information 1158 | zTXt: compressed textual information 1159 | iTXt: international textual information 1160 | bKGD: suggested background color 1161 | pHYs: physical dimensions 1162 | tIME: modification time 1163 | cHRM: RGB chromaticities 1164 | gAMA: RGB gamma correction 1165 | iCCP: ICC color profile 1166 | sRGB: rendering intent 1167 | 1168 | 1.2. features not supported 1169 | --------------------------- 1170 | 1171 | The following features are _not_ supported: 1172 | 1173 | *) some features needed to make a conformant PNG-Editor might be still missing. 1174 | *) partial loading/stream processing. All data must be available and is processed in one call. 1175 | *) The following public chunks are not (yet) supported but treated as unknown chunks by LodePNG: 1176 | sBIT 1177 | hIST 1178 | sPLT 1179 | 1180 | 1181 | 2. C and C++ version 1182 | -------------------- 1183 | 1184 | The C version uses buffers allocated with alloc that you need to free() 1185 | yourself. You need to use init and cleanup functions for each struct whenever 1186 | using a struct from the C version to avoid exploits and memory leaks. 1187 | 1188 | The C++ version has extra functions with std::vectors in the interface and the 1189 | lodepng::State class which is a LodePNGState with constructor and destructor. 1190 | 1191 | These files work without modification for both C and C++ compilers because all 1192 | the additional C++ code is in "#ifdef __cplusplus" blocks that make C-compilers 1193 | ignore it, and the C code is made to compile both with strict ISO C90 and C++. 1194 | 1195 | To use the C++ version, you need to rename the source file to lodepng.cpp 1196 | (instead of lodepng.c), and compile it with a C++ compiler. 1197 | 1198 | To use the C version, you need to rename the source file to lodepng.c (instead 1199 | of lodepng.cpp), and compile it with a C compiler. 1200 | 1201 | 1202 | 3. Security 1203 | ----------- 1204 | 1205 | Even if carefully designed, it's always possible that LodePNG contains possible 1206 | exploits. If you discover one, please let me know, and it will be fixed. 1207 | 1208 | When using LodePNG, care has to be taken with the C version of LodePNG, as well 1209 | as the C-style structs when working with C++. The following conventions are used 1210 | for all C-style structs: 1211 | 1212 | -if a struct has a corresponding init function, always call the init function when making a new one 1213 | -if a struct has a corresponding cleanup function, call it before the struct disappears to avoid memory leaks 1214 | -if a struct has a corresponding copy function, use the copy function instead of "=". 1215 | The destination must also be inited already. 1216 | 1217 | 1218 | 4. Decoding 1219 | ----------- 1220 | 1221 | Decoding converts a PNG compressed image to a raw pixel buffer. 1222 | 1223 | Most documentation on using the decoder is at its declarations in the header 1224 | above. For C, simple decoding can be done with functions such as 1225 | lodepng_decode32, and more advanced decoding can be done with the struct 1226 | LodePNGState and lodepng_decode. For C++, all decoding can be done with the 1227 | various lodepng::decode functions, and lodepng::State can be used for advanced 1228 | features. 1229 | 1230 | When using the LodePNGState, it uses the following fields for decoding: 1231 | *) LodePNGInfo info_png: it stores extra information about the PNG (the input) in here 1232 | *) LodePNGColorMode info_raw: here you can say what color mode of the raw image (the output) you want to get 1233 | *) LodePNGDecoderSettings decoder: you can specify a few extra settings for the decoder to use 1234 | 1235 | LodePNGInfo info_png 1236 | -------------------- 1237 | 1238 | After decoding, this contains extra information of the PNG image, except the actual 1239 | pixels, width and height because these are already gotten directly from the decoder 1240 | functions. 1241 | 1242 | It contains for example the original color type of the PNG image, text comments, 1243 | suggested background color, etc... More details about the LodePNGInfo struct are 1244 | at its declaration documentation. 1245 | 1246 | LodePNGColorMode info_raw 1247 | ------------------------- 1248 | 1249 | When decoding, here you can specify which color type you want 1250 | the resulting raw image to be. If this is different from the colortype of the 1251 | PNG, then the decoder will automatically convert the result. This conversion 1252 | always works, except if you want it to convert a color PNG to grayscale or to 1253 | a palette with missing colors. 1254 | 1255 | By default, 32-bit color is used for the result. 1256 | 1257 | LodePNGDecoderSettings decoder 1258 | ------------------------------ 1259 | 1260 | The settings can be used to ignore the errors created by invalid CRC and Adler32 1261 | chunks, and to disable the decoding of tEXt chunks. 1262 | 1263 | There's also a setting color_convert, true by default. If false, no conversion 1264 | is done, the resulting data will be as it was in the PNG (after decompression) 1265 | and you'll have to puzzle the colors of the pixels together yourself using the 1266 | color type information in the LodePNGInfo. 1267 | 1268 | 1269 | 5. Encoding 1270 | ----------- 1271 | 1272 | Encoding converts a raw pixel buffer to a PNG compressed image. 1273 | 1274 | Most documentation on using the encoder is at its declarations in the header 1275 | above. For C, simple encoding can be done with functions such as 1276 | lodepng_encode32, and more advanced decoding can be done with the struct 1277 | LodePNGState and lodepng_encode. For C++, all encoding can be done with the 1278 | various lodepng::encode functions, and lodepng::State can be used for advanced 1279 | features. 1280 | 1281 | Like the decoder, the encoder can also give errors. However it gives less errors 1282 | since the encoder input is trusted, the decoder input (a PNG image that could 1283 | be forged by anyone) is not trusted. 1284 | 1285 | When using the LodePNGState, it uses the following fields for encoding: 1286 | *) LodePNGInfo info_png: here you specify how you want the PNG (the output) to be. 1287 | *) LodePNGColorMode info_raw: here you say what color type of the raw image (the input) has 1288 | *) LodePNGEncoderSettings encoder: you can specify a few settings for the encoder to use 1289 | 1290 | LodePNGInfo info_png 1291 | -------------------- 1292 | 1293 | When encoding, you use this the opposite way as when decoding: for encoding, 1294 | you fill in the values you want the PNG to have before encoding. By default it's 1295 | not needed to specify a color type for the PNG since it's automatically chosen, 1296 | but it's possible to choose it yourself given the right settings. 1297 | 1298 | The encoder will not always exactly match the LodePNGInfo struct you give, 1299 | it tries as close as possible. Some things are ignored by the encoder. The 1300 | encoder uses, for example, the following settings from it when applicable: 1301 | colortype and bitdepth, text chunks, time chunk, the color key, the palette, the 1302 | background color, the interlace method, unknown chunks, ... 1303 | 1304 | When encoding to a PNG with colortype 3, the encoder will generate a PLTE chunk. 1305 | If the palette contains any colors for which the alpha channel is not 255 (so 1306 | there are translucent colors in the palette), it'll add a tRNS chunk. 1307 | 1308 | LodePNGColorMode info_raw 1309 | ------------------------- 1310 | 1311 | You specify the color type of the raw image that you give to the input here, 1312 | including a possible transparent color key and palette you happen to be using in 1313 | your raw image data. 1314 | 1315 | By default, 32-bit color is assumed, meaning your input has to be in RGBA 1316 | format with 4 bytes (unsigned chars) per pixel. 1317 | 1318 | LodePNGEncoderSettings encoder 1319 | ------------------------------ 1320 | 1321 | The following settings are supported (some are in sub-structs): 1322 | *) auto_convert: when this option is enabled, the encoder will 1323 | automatically choose the smallest possible color mode (including color key) that 1324 | can encode the colors of all pixels without information loss. 1325 | *) btype: the block type for LZ77. 0 = uncompressed, 1 = fixed huffman tree, 1326 | 2 = dynamic huffman tree (best compression). Should be 2 for proper 1327 | compression. 1328 | *) use_lz77: whether or not to use LZ77 for compressed block types. Should be 1329 | true for proper compression. 1330 | *) windowsize: the window size used by the LZ77 encoder (1 - 32768). Has value 1331 | 2048 by default, but can be set to 32768 for better, but slow, compression. 1332 | *) force_palette: if colortype is 2 or 6, you can make the encoder write a PLTE 1333 | chunk if force_palette is true. This can used as suggested palette to convert 1334 | to by viewers that don't support more than 256 colors (if those still exist) 1335 | *) add_id: add text chunk "Encoder: LodePNG " to the image. 1336 | *) text_compression: default 1. If 1, it'll store texts as zTXt instead of tEXt chunks. 1337 | zTXt chunks use zlib compression on the text. This gives a smaller result on 1338 | large texts but a larger result on small texts (such as a single program name). 1339 | It's all tEXt or all zTXt though, there's no separate setting per text yet. 1340 | 1341 | 1342 | 6. color conversions 1343 | -------------------- 1344 | 1345 | An important thing to note about LodePNG, is that the color type of the PNG, and 1346 | the color type of the raw image, are completely independent. By default, when 1347 | you decode a PNG, you get the result as a raw image in the color type you want, 1348 | no matter whether the PNG was encoded with a palette, grayscale or RGBA color. 1349 | And if you encode an image, by default LodePNG will automatically choose the PNG 1350 | color type that gives good compression based on the values of colors and amount 1351 | of colors in the image. It can be configured to let you control it instead as 1352 | well, though. 1353 | 1354 | To be able to do this, LodePNG does conversions from one color mode to another. 1355 | It can convert from almost any color type to any other color type, except the 1356 | following conversions: RGB to grayscale is not supported, and converting to a 1357 | palette when the palette doesn't have a required color is not supported. This is 1358 | not supported on purpose: this is information loss which requires a color 1359 | reduction algorithm that is beyong the scope of a PNG encoder (yes, RGB to gray 1360 | is easy, but there are multiple ways if you want to give some channels more 1361 | weight). 1362 | 1363 | By default, when decoding, you get the raw image in 32-bit RGBA or 24-bit RGB 1364 | color, no matter what color type the PNG has. And by default when encoding, 1365 | LodePNG automatically picks the best color model for the output PNG, and expects 1366 | the input image to be 32-bit RGBA or 24-bit RGB. So, unless you want to control 1367 | the color format of the images yourself, you can skip this chapter. 1368 | 1369 | 6.1. PNG color types 1370 | -------------------- 1371 | 1372 | A PNG image can have many color types, ranging from 1-bit color to 64-bit color, 1373 | as well as palettized color modes. After the zlib decompression and unfiltering 1374 | in the PNG image is done, the raw pixel data will have that color type and thus 1375 | a certain amount of bits per pixel. If you want the output raw image after 1376 | decoding to have another color type, a conversion is done by LodePNG. 1377 | 1378 | The PNG specification gives the following color types: 1379 | 1380 | 0: grayscale, bit depths 1, 2, 4, 8, 16 1381 | 2: RGB, bit depths 8 and 16 1382 | 3: palette, bit depths 1, 2, 4 and 8 1383 | 4: grayscale with alpha, bit depths 8 and 16 1384 | 6: RGBA, bit depths 8 and 16 1385 | 1386 | Bit depth is the amount of bits per pixel per color channel. So the total amount 1387 | of bits per pixel is: amount of channels * bitdepth. 1388 | 1389 | 6.2. color conversions 1390 | ---------------------- 1391 | 1392 | As explained in the sections about the encoder and decoder, you can specify 1393 | color types and bit depths in info_png and info_raw to change the default 1394 | behaviour. 1395 | 1396 | If, when decoding, you want the raw image to be something else than the default, 1397 | you need to set the color type and bit depth you want in the LodePNGColorMode, 1398 | or the parameters colortype and bitdepth of the simple decoding function. 1399 | 1400 | If, when encoding, you use another color type than the default in the raw input 1401 | image, you need to specify its color type and bit depth in the LodePNGColorMode 1402 | of the raw image, or use the parameters colortype and bitdepth of the simple 1403 | encoding function. 1404 | 1405 | If, when encoding, you don't want LodePNG to choose the output PNG color type 1406 | but control it yourself, you need to set auto_convert in the encoder settings 1407 | to false, and specify the color type you want in the LodePNGInfo of the 1408 | encoder (including palette: it can generate a palette if auto_convert is true, 1409 | otherwise not). 1410 | 1411 | If the input and output color type differ (whether user chosen or auto chosen), 1412 | LodePNG will do a color conversion, which follows the rules below, and may 1413 | sometimes result in an error. 1414 | 1415 | To avoid some confusion: 1416 | -the decoder converts from PNG to raw image 1417 | -the encoder converts from raw image to PNG 1418 | -the colortype and bitdepth in LodePNGColorMode info_raw, are those of the raw image 1419 | -the colortype and bitdepth in the color field of LodePNGInfo info_png, are those of the PNG 1420 | -when encoding, the color type in LodePNGInfo is ignored if auto_convert 1421 | is enabled, it is automatically generated instead 1422 | -when decoding, the color type in LodePNGInfo is set by the decoder to that of the original 1423 | PNG image, but it can be ignored since the raw image has the color type you requested instead 1424 | -if the color type of the LodePNGColorMode and PNG image aren't the same, a conversion 1425 | between the color types is done if the color types are supported. If it is not 1426 | supported, an error is returned. If the types are the same, no conversion is done. 1427 | -even though some conversions aren't supported, LodePNG supports loading PNGs from any 1428 | colortype and saving PNGs to any colortype, sometimes it just requires preparing 1429 | the raw image correctly before encoding. 1430 | -both encoder and decoder use the same color converter. 1431 | 1432 | The function lodepng_convert does the color conversion. It is available in the 1433 | interface but normally isn't needed since the encoder and decoder already call 1434 | it. 1435 | 1436 | Non supported color conversions: 1437 | -color to grayscale when non-gray pixels are present: no error is thrown, but 1438 | the result will look ugly because only the red channel is taken (it assumes all 1439 | three channels are the same in this case so ignores green and blue). The reason 1440 | no error is given is to allow converting from three-channel grayscale images to 1441 | one-channel even if there are numerical imprecisions. 1442 | -anything to palette when the palette does not have an exact match for a from-color 1443 | in it: in this case an error is thrown 1444 | 1445 | Supported color conversions: 1446 | -anything to 8-bit RGB, 8-bit RGBA, 16-bit RGB, 16-bit RGBA 1447 | -any gray or gray+alpha, to gray or gray+alpha 1448 | -anything to a palette, as long as the palette has the requested colors in it 1449 | -removing alpha channel 1450 | -higher to smaller bitdepth, and vice versa 1451 | 1452 | If you want no color conversion to be done (e.g. for speed or control): 1453 | -In the encoder, you can make it save a PNG with any color type by giving the 1454 | raw color mode and LodePNGInfo the same color mode, and setting auto_convert to 1455 | false. 1456 | -In the decoder, you can make it store the pixel data in the same color type 1457 | as the PNG has, by setting the color_convert setting to false. Settings in 1458 | info_raw are then ignored. 1459 | 1460 | 6.3. padding bits 1461 | ----------------- 1462 | 1463 | In the PNG file format, if a less than 8-bit per pixel color type is used and the scanlines 1464 | have a bit amount that isn't a multiple of 8, then padding bits are used so that each 1465 | scanline starts at a fresh byte. But that is NOT true for the LodePNG raw input and output. 1466 | The raw input image you give to the encoder, and the raw output image you get from the decoder 1467 | will NOT have these padding bits, e.g. in the case of a 1-bit image with a width 1468 | of 7 pixels, the first pixel of the second scanline will the the 8th bit of the first byte, 1469 | not the first bit of a new byte. 1470 | 1471 | 6.4. A note about 16-bits per channel and endianness 1472 | ---------------------------------------------------- 1473 | 1474 | LodePNG uses unsigned char arrays for 16-bit per channel colors too, just like 1475 | for any other color format. The 16-bit values are stored in big endian (most 1476 | significant byte first) in these arrays. This is the opposite order of the 1477 | little endian used by x86 CPU's. 1478 | 1479 | LodePNG always uses big endian because the PNG file format does so internally. 1480 | Conversions to other formats than PNG uses internally are not supported by 1481 | LodePNG on purpose, there are myriads of formats, including endianness of 16-bit 1482 | colors, the order in which you store R, G, B and A, and so on. Supporting and 1483 | converting to/from all that is outside the scope of LodePNG. 1484 | 1485 | This may mean that, depending on your use case, you may want to convert the big 1486 | endian output of LodePNG to little endian with a for loop. This is certainly not 1487 | always needed, many applications and libraries support big endian 16-bit colors 1488 | anyway, but it means you cannot simply cast the unsigned char* buffer to an 1489 | unsigned short* buffer on x86 CPUs. 1490 | 1491 | 1492 | 7. error values 1493 | --------------- 1494 | 1495 | All functions in LodePNG that return an error code, return 0 if everything went 1496 | OK, or a non-zero code if there was an error. 1497 | 1498 | The meaning of the LodePNG error values can be retrieved with the function 1499 | lodepng_error_text: given the numerical error code, it returns a description 1500 | of the error in English as a string. 1501 | 1502 | Check the implementation of lodepng_error_text to see the meaning of each code. 1503 | 1504 | 1505 | 8. chunks and PNG editing 1506 | ------------------------- 1507 | 1508 | If you want to add extra chunks to a PNG you encode, or use LodePNG for a PNG 1509 | editor that should follow the rules about handling of unknown chunks, or if your 1510 | program is able to read other types of chunks than the ones handled by LodePNG, 1511 | then that's possible with the chunk functions of LodePNG. 1512 | 1513 | A PNG chunk has the following layout: 1514 | 1515 | 4 bytes length 1516 | 4 bytes type name 1517 | length bytes data 1518 | 4 bytes CRC 1519 | 1520 | 8.1. iterating through chunks 1521 | ----------------------------- 1522 | 1523 | If you have a buffer containing the PNG image data, then the first chunk (the 1524 | IHDR chunk) starts at byte number 8 of that buffer. The first 8 bytes are the 1525 | signature of the PNG and are not part of a chunk. But if you start at byte 8 1526 | then you have a chunk, and can check the following things of it. 1527 | 1528 | NOTE: none of these functions check for memory buffer boundaries. To avoid 1529 | exploits, always make sure the buffer contains all the data of the chunks. 1530 | When using lodepng_chunk_next, make sure the returned value is within the 1531 | allocated memory. 1532 | 1533 | unsigned lodepng_chunk_length(const unsigned char* chunk): 1534 | 1535 | Get the length of the chunk's data. The total chunk length is this length + 12. 1536 | 1537 | void lodepng_chunk_type(char type[5], const unsigned char* chunk): 1538 | unsigned char lodepng_chunk_type_equals(const unsigned char* chunk, const char* type): 1539 | 1540 | Get the type of the chunk or compare if it's a certain type 1541 | 1542 | unsigned char lodepng_chunk_critical(const unsigned char* chunk): 1543 | unsigned char lodepng_chunk_private(const unsigned char* chunk): 1544 | unsigned char lodepng_chunk_safetocopy(const unsigned char* chunk): 1545 | 1546 | Check if the chunk is critical in the PNG standard (only IHDR, PLTE, IDAT and IEND are). 1547 | Check if the chunk is private (public chunks are part of the standard, private ones not). 1548 | Check if the chunk is safe to copy. If it's not, then, when modifying data in a critical 1549 | chunk, unsafe to copy chunks of the old image may NOT be saved in the new one if your 1550 | program doesn't handle that type of unknown chunk. 1551 | 1552 | unsigned char* lodepng_chunk_data(unsigned char* chunk): 1553 | const unsigned char* lodepng_chunk_data_const(const unsigned char* chunk): 1554 | 1555 | Get a pointer to the start of the data of the chunk. 1556 | 1557 | unsigned lodepng_chunk_check_crc(const unsigned char* chunk): 1558 | void lodepng_chunk_generate_crc(unsigned char* chunk): 1559 | 1560 | Check if the crc is correct or generate a correct one. 1561 | 1562 | unsigned char* lodepng_chunk_next(unsigned char* chunk): 1563 | const unsigned char* lodepng_chunk_next_const(const unsigned char* chunk): 1564 | 1565 | Iterate to the next chunk. This works if you have a buffer with consecutive chunks. Note that these 1566 | functions do no boundary checking of the allocated data whatsoever, so make sure there is enough 1567 | data available in the buffer to be able to go to the next chunk. 1568 | 1569 | unsigned lodepng_chunk_append(unsigned char** out, size_t* outlength, const unsigned char* chunk): 1570 | unsigned lodepng_chunk_create(unsigned char** out, size_t* outlength, unsigned length, 1571 | const char* type, const unsigned char* data): 1572 | 1573 | These functions are used to create new chunks that are appended to the data in *out that has 1574 | length *outlength. The append function appends an existing chunk to the new data. The create 1575 | function creates a new chunk with the given parameters and appends it. Type is the 4-letter 1576 | name of the chunk. 1577 | 1578 | 8.2. chunks in info_png 1579 | ----------------------- 1580 | 1581 | The LodePNGInfo struct contains fields with the unknown chunk in it. It has 3 1582 | buffers (each with size) to contain 3 types of unknown chunks: 1583 | the ones that come before the PLTE chunk, the ones that come between the PLTE 1584 | and the IDAT chunks, and the ones that come after the IDAT chunks. 1585 | It's necessary to make the distionction between these 3 cases because the PNG 1586 | standard forces to keep the ordering of unknown chunks compared to the critical 1587 | chunks, but does not force any other ordering rules. 1588 | 1589 | info_png.unknown_chunks_data[0] is the chunks before PLTE 1590 | info_png.unknown_chunks_data[1] is the chunks after PLTE, before IDAT 1591 | info_png.unknown_chunks_data[2] is the chunks after IDAT 1592 | 1593 | The chunks in these 3 buffers can be iterated through and read by using the same 1594 | way described in the previous subchapter. 1595 | 1596 | When using the decoder to decode a PNG, you can make it store all unknown chunks 1597 | if you set the option settings.remember_unknown_chunks to 1. By default, this 1598 | option is off (0). 1599 | 1600 | The encoder will always encode unknown chunks that are stored in the info_png. 1601 | If you need it to add a particular chunk that isn't known by LodePNG, you can 1602 | use lodepng_chunk_append or lodepng_chunk_create to the chunk data in 1603 | info_png.unknown_chunks_data[x]. 1604 | 1605 | Chunks that are known by LodePNG should not be added in that way. E.g. to make 1606 | LodePNG add a bKGD chunk, set background_defined to true and add the correct 1607 | parameters there instead. 1608 | 1609 | 1610 | 9. compiler support 1611 | ------------------- 1612 | 1613 | No libraries other than the current standard C library are needed to compile 1614 | LodePNG. For the C++ version, only the standard C++ library is needed on top. 1615 | Add the files lodepng.c(pp) and lodepng.h to your project, include 1616 | lodepng.h where needed, and your program can read/write PNG files. 1617 | 1618 | It is compatible with C90 and up, and C++03 and up. 1619 | 1620 | If performance is important, use optimization when compiling! For both the 1621 | encoder and decoder, this makes a large difference. 1622 | 1623 | Make sure that LodePNG is compiled with the same compiler of the same version 1624 | and with the same settings as the rest of the program, or the interfaces with 1625 | std::vectors and std::strings in C++ can be incompatible. 1626 | 1627 | CHAR_BITS must be 8 or higher, because LodePNG uses unsigned chars for octets. 1628 | 1629 | *) gcc and g++ 1630 | 1631 | LodePNG is developed in gcc so this compiler is natively supported. It gives no 1632 | warnings with compiler options "-Wall -Wextra -pedantic -ansi", with gcc and g++ 1633 | version 4.7.1 on Linux, 32-bit and 64-bit. 1634 | 1635 | *) Clang 1636 | 1637 | Fully supported and warning-free. 1638 | 1639 | *) Mingw 1640 | 1641 | The Mingw compiler (a port of gcc for Windows) should be fully supported by 1642 | LodePNG. 1643 | 1644 | *) Visual Studio and Visual C++ Express Edition 1645 | 1646 | LodePNG should be warning-free with warning level W4. Two warnings were disabled 1647 | with pragmas though: warning 4244 about implicit conversions, and warning 4996 1648 | where it wants to use a non-standard function fopen_s instead of the standard C 1649 | fopen. 1650 | 1651 | Visual Studio may want "stdafx.h" files to be included in each source file and 1652 | give an error "unexpected end of file while looking for precompiled header". 1653 | This is not standard C++ and will not be added to the stock LodePNG. You can 1654 | disable it for lodepng.cpp only by right clicking it, Properties, C/C++, 1655 | Precompiled Headers, and set it to Not Using Precompiled Headers there. 1656 | 1657 | NOTE: Modern versions of VS should be fully supported, but old versions, e.g. 1658 | VS6, are not guaranteed to work. 1659 | 1660 | *) Compilers on Macintosh 1661 | 1662 | LodePNG has been reported to work both with gcc and LLVM for Macintosh, both for 1663 | C and C++. 1664 | 1665 | *) Other Compilers 1666 | 1667 | If you encounter problems on any compilers, feel free to let me know and I may 1668 | try to fix it if the compiler is modern and standards complient. 1669 | 1670 | 1671 | 10. examples 1672 | ------------ 1673 | 1674 | This decoder example shows the most basic usage of LodePNG. More complex 1675 | examples can be found on the LodePNG website. 1676 | 1677 | 10.1. decoder C++ example 1678 | ------------------------- 1679 | 1680 | #include "lodepng.h" 1681 | #include 1682 | 1683 | int main(int argc, char *argv[]) { 1684 | const char* filename = argc > 1 ? argv[1] : "test.png"; 1685 | 1686 | //load and decode 1687 | std::vector image; 1688 | unsigned width, height; 1689 | unsigned error = lodepng::decode(image, width, height, filename); 1690 | 1691 | //if there's an error, display it 1692 | if(error) std::cout << "decoder error " << error << ": " << lodepng_error_text(error) << std::endl; 1693 | 1694 | //the pixels are now in the vector "image", 4 bytes per pixel, ordered RGBARGBA..., use it as texture, draw it, ... 1695 | } 1696 | 1697 | 10.2. decoder C example 1698 | ----------------------- 1699 | 1700 | #include "lodepng.h" 1701 | 1702 | int main(int argc, char *argv[]) { 1703 | unsigned error; 1704 | unsigned char* image; 1705 | size_t width, height; 1706 | const char* filename = argc > 1 ? argv[1] : "test.png"; 1707 | 1708 | error = lodepng_decode32_file(&image, &width, &height, filename); 1709 | 1710 | if(error) printf("decoder error %u: %s\n", error, lodepng_error_text(error)); 1711 | 1712 | / * use image here * / 1713 | 1714 | free(image); 1715 | return 0; 1716 | } 1717 | 1718 | 11. state settings reference 1719 | ---------------------------- 1720 | 1721 | A quick reference of some settings to set on the LodePNGState 1722 | 1723 | For decoding: 1724 | 1725 | state.decoder.zlibsettings.ignore_adler32: ignore ADLER32 checksums 1726 | state.decoder.zlibsettings.custom_...: use custom inflate function 1727 | state.decoder.ignore_crc: ignore CRC checksums 1728 | state.decoder.ignore_critical: ignore unknown critical chunks 1729 | state.decoder.ignore_end: ignore missing IEND chunk. May fail if this corruption causes other errors 1730 | state.decoder.color_convert: convert internal PNG color to chosen one 1731 | state.decoder.read_text_chunks: whether to read in text metadata chunks 1732 | state.decoder.remember_unknown_chunks: whether to read in unknown chunks 1733 | state.info_raw.colortype: desired color type for decoded image 1734 | state.info_raw.bitdepth: desired bit depth for decoded image 1735 | state.info_raw....: more color settings, see struct LodePNGColorMode 1736 | state.info_png....: no settings for decoder but ouput, see struct LodePNGInfo 1737 | 1738 | For encoding: 1739 | 1740 | state.encoder.zlibsettings.btype: disable compression by setting it to 0 1741 | state.encoder.zlibsettings.use_lz77: use LZ77 in compression 1742 | state.encoder.zlibsettings.windowsize: tweak LZ77 windowsize 1743 | state.encoder.zlibsettings.minmatch: tweak min LZ77 length to match 1744 | state.encoder.zlibsettings.nicematch: tweak LZ77 match where to stop searching 1745 | state.encoder.zlibsettings.lazymatching: try one more LZ77 matching 1746 | state.encoder.zlibsettings.custom_...: use custom deflate function 1747 | state.encoder.auto_convert: choose optimal PNG color type, if 0 uses info_png 1748 | state.encoder.filter_palette_zero: PNG filter strategy for palette 1749 | state.encoder.filter_strategy: PNG filter strategy to encode with 1750 | state.encoder.force_palette: add palette even if not encoding to one 1751 | state.encoder.add_id: add LodePNG identifier and version as a text chunk 1752 | state.encoder.text_compression: use compressed text chunks for metadata 1753 | state.info_raw.colortype: color type of raw input image you provide 1754 | state.info_raw.bitdepth: bit depth of raw input image you provide 1755 | state.info_raw: more color settings, see struct LodePNGColorMode 1756 | state.info_png.color.colortype: desired color type if auto_convert is false 1757 | state.info_png.color.bitdepth: desired bit depth if auto_convert is false 1758 | state.info_png.color....: more color settings, see struct LodePNGColorMode 1759 | state.info_png....: more PNG related settings, see struct LodePNGInfo 1760 | 1761 | 1762 | 12. changes 1763 | ----------- 1764 | 1765 | The version number of LodePNG is the date of the change given in the format 1766 | yyyymmdd. 1767 | 1768 | Some changes aren't backwards compatible. Those are indicated with a (!) 1769 | symbol. 1770 | 1771 | *) 30 dec 2018: code style changes only: removed newlines before opening braces. 1772 | *) 10 sep 2018: added way to inspect metadata chunks without full decoding. 1773 | *) 19 aug 2018 (!): fixed color mode bKGD is encoded with and made it use 1774 | palette index in case of palette. 1775 | *) 10 aug 2018 (!): added support for gAMA, cHRM, sRGB and iCCP chunks. This 1776 | change is backwards compatible unless you relied on unknown_chunks for those. 1777 | *) 11 jun 2018: less restrictive check for pixel size integer overflow 1778 | *) 14 jan 2018: allow optionally ignoring a few more recoverable errors 1779 | *) 17 sep 2017: fix memory leak for some encoder input error cases 1780 | *) 27 nov 2016: grey+alpha auto color model detection bugfix 1781 | *) 18 apr 2016: Changed qsort to custom stable sort (for platforms w/o qsort). 1782 | *) 09 apr 2016: Fixed colorkey usage detection, and better file loading (within 1783 | the limits of pure C90). 1784 | *) 08 dec 2015: Made load_file function return error if file can't be opened. 1785 | *) 24 okt 2015: Bugfix with decoding to palette output. 1786 | *) 18 apr 2015: Boundary PM instead of just package-merge for faster encoding. 1787 | *) 23 aug 2014: Reduced needless memory usage of decoder. 1788 | *) 28 jun 2014: Removed fix_png setting, always support palette OOB for 1789 | simplicity. Made ColorProfile public. 1790 | *) 09 jun 2014: Faster encoder by fixing hash bug and more zeros optimization. 1791 | *) 22 dec 2013: Power of two windowsize required for optimization. 1792 | *) 15 apr 2013: Fixed bug with LAC_ALPHA and color key. 1793 | *) 25 mar 2013: Added an optional feature to ignore some PNG errors (fix_png). 1794 | *) 11 mar 2013 (!): Bugfix with custom free. Changed from "my" to "lodepng_" 1795 | prefix for the custom allocators and made it possible with a new #define to 1796 | use custom ones in your project without needing to change lodepng's code. 1797 | *) 28 jan 2013: Bugfix with color key. 1798 | *) 27 okt 2012: Tweaks in text chunk keyword length error handling. 1799 | *) 8 okt 2012 (!): Added new filter strategy (entropy) and new auto color mode. 1800 | (no palette). Better deflate tree encoding. New compression tweak settings. 1801 | Faster color conversions while decoding. Some internal cleanups. 1802 | *) 23 sep 2012: Reduced warnings in Visual Studio a little bit. 1803 | *) 1 sep 2012 (!): Removed #define's for giving custom (de)compression functions 1804 | and made it work with function pointers instead. 1805 | *) 23 jun 2012: Added more filter strategies. Made it easier to use custom alloc 1806 | and free functions and toggle #defines from compiler flags. Small fixes. 1807 | *) 6 may 2012 (!): Made plugging in custom zlib/deflate functions more flexible. 1808 | *) 22 apr 2012 (!): Made interface more consistent, renaming a lot. Removed 1809 | redundant C++ codec classes. Reduced amount of structs. Everything changed, 1810 | but it is cleaner now imho and functionality remains the same. Also fixed 1811 | several bugs and shrunk the implementation code. Made new samples. 1812 | *) 6 nov 2011 (!): By default, the encoder now automatically chooses the best 1813 | PNG color model and bit depth, based on the amount and type of colors of the 1814 | raw image. For this, autoLeaveOutAlphaChannel replaced by auto_choose_color. 1815 | *) 9 okt 2011: simpler hash chain implementation for the encoder. 1816 | *) 8 sep 2011: lz77 encoder lazy matching instead of greedy matching. 1817 | *) 23 aug 2011: tweaked the zlib compression parameters after benchmarking. 1818 | A bug with the PNG filtertype heuristic was fixed, so that it chooses much 1819 | better ones (it's quite significant). A setting to do an experimental, slow, 1820 | brute force search for PNG filter types is added. 1821 | *) 17 aug 2011 (!): changed some C zlib related function names. 1822 | *) 16 aug 2011: made the code less wide (max 120 characters per line). 1823 | *) 17 apr 2011: code cleanup. Bugfixes. Convert low to 16-bit per sample colors. 1824 | *) 21 feb 2011: fixed compiling for C90. Fixed compiling with sections disabled. 1825 | *) 11 dec 2010: encoding is made faster, based on suggestion by Peter Eastman 1826 | to optimize long sequences of zeros. 1827 | *) 13 nov 2010: added LodePNG_InfoColor_hasPaletteAlpha and 1828 | LodePNG_InfoColor_canHaveAlpha functions for convenience. 1829 | *) 7 nov 2010: added LodePNG_error_text function to get error code description. 1830 | *) 30 okt 2010: made decoding slightly faster 1831 | *) 26 okt 2010: (!) changed some C function and struct names (more consistent). 1832 | Reorganized the documentation and the declaration order in the header. 1833 | *) 08 aug 2010: only changed some comments and external samples. 1834 | *) 05 jul 2010: fixed bug thanks to warnings in the new gcc version. 1835 | *) 14 mar 2010: fixed bug where too much memory was allocated for char buffers. 1836 | *) 02 sep 2008: fixed bug where it could create empty tree that linux apps could 1837 | read by ignoring the problem but windows apps couldn't. 1838 | *) 06 jun 2008: added more error checks for out of memory cases. 1839 | *) 26 apr 2008: added a few more checks here and there to ensure more safety. 1840 | *) 06 mar 2008: crash with encoding of strings fixed 1841 | *) 02 feb 2008: support for international text chunks added (iTXt) 1842 | *) 23 jan 2008: small cleanups, and #defines to divide code in sections 1843 | *) 20 jan 2008: support for unknown chunks allowing using LodePNG for an editor. 1844 | *) 18 jan 2008: support for tIME and pHYs chunks added to encoder and decoder. 1845 | *) 17 jan 2008: ability to encode and decode compressed zTXt chunks added 1846 | Also various fixes, such as in the deflate and the padding bits code. 1847 | *) 13 jan 2008: Added ability to encode Adam7-interlaced images. Improved 1848 | filtering code of encoder. 1849 | *) 07 jan 2008: (!) changed LodePNG to use ISO C90 instead of C++. A 1850 | C++ wrapper around this provides an interface almost identical to before. 1851 | Having LodePNG be pure ISO C90 makes it more portable. The C and C++ code 1852 | are together in these files but it works both for C and C++ compilers. 1853 | *) 29 dec 2007: (!) changed most integer types to unsigned int + other tweaks 1854 | *) 30 aug 2007: bug fixed which makes this Borland C++ compatible 1855 | *) 09 aug 2007: some VS2005 warnings removed again 1856 | *) 21 jul 2007: deflate code placed in new namespace separate from zlib code 1857 | *) 08 jun 2007: fixed bug with 2- and 4-bit color, and small interlaced images 1858 | *) 04 jun 2007: improved support for Visual Studio 2005: crash with accessing 1859 | invalid std::vector element [0] fixed, and level 3 and 4 warnings removed 1860 | *) 02 jun 2007: made the encoder add a tag with version by default 1861 | *) 27 may 2007: zlib and png code separated (but still in the same file), 1862 | simple encoder/decoder functions added for more simple usage cases 1863 | *) 19 may 2007: minor fixes, some code cleaning, new error added (error 69), 1864 | moved some examples from here to lodepng_examples.cpp 1865 | *) 12 may 2007: palette decoding bug fixed 1866 | *) 24 apr 2007: changed the license from BSD to the zlib license 1867 | *) 11 mar 2007: very simple addition: ability to encode bKGD chunks. 1868 | *) 04 mar 2007: (!) tEXt chunk related fixes, and support for encoding 1869 | palettized PNG images. Plus little interface change with palette and texts. 1870 | *) 03 mar 2007: Made it encode dynamic Huffman shorter with repeat codes. 1871 | Fixed a bug where the end code of a block had length 0 in the Huffman tree. 1872 | *) 26 feb 2007: Huffman compression with dynamic trees (BTYPE 2) now implemented 1873 | and supported by the encoder, resulting in smaller PNGs at the output. 1874 | *) 27 jan 2007: Made the Adler-32 test faster so that a timewaste is gone. 1875 | *) 24 jan 2007: gave encoder an error interface. Added color conversion from any 1876 | greyscale type to 8-bit greyscale with or without alpha. 1877 | *) 21 jan 2007: (!) Totally changed the interface. It allows more color types 1878 | to convert to and is more uniform. See the manual for how it works now. 1879 | *) 07 jan 2007: Some cleanup & fixes, and a few changes over the last days: 1880 | encode/decode custom tEXt chunks, separate classes for zlib & deflate, and 1881 | at last made the decoder give errors for incorrect Adler32 or Crc. 1882 | *) 01 jan 2007: Fixed bug with encoding PNGs with less than 8 bits per channel. 1883 | *) 29 dec 2006: Added support for encoding images without alpha channel, and 1884 | cleaned out code as well as making certain parts faster. 1885 | *) 28 dec 2006: Added "Settings" to the encoder. 1886 | *) 26 dec 2006: The encoder now does LZ77 encoding and produces much smaller files now. 1887 | Removed some code duplication in the decoder. Fixed little bug in an example. 1888 | *) 09 dec 2006: (!) Placed output parameters of public functions as first parameter. 1889 | Fixed a bug of the decoder with 16-bit per color. 1890 | *) 15 okt 2006: Changed documentation structure 1891 | *) 09 okt 2006: Encoder class added. It encodes a valid PNG image from the 1892 | given image buffer, however for now it's not compressed. 1893 | *) 08 sep 2006: (!) Changed to interface with a Decoder class 1894 | *) 30 jul 2006: (!) LodePNG_InfoPng , width and height are now retrieved in different 1895 | way. Renamed decodePNG to decodePNGGeneric. 1896 | *) 29 jul 2006: (!) Changed the interface: image info is now returned as a 1897 | struct of type LodePNG::LodePNG_Info, instead of a vector, which was a bit clumsy. 1898 | *) 28 jul 2006: Cleaned the code and added new error checks. 1899 | Corrected terminology "deflate" into "inflate". 1900 | *) 23 jun 2006: Added SDL example in the documentation in the header, this 1901 | example allows easy debugging by displaying the PNG and its transparency. 1902 | *) 22 jun 2006: (!) Changed way to obtain error value. Added 1903 | loadFile function for convenience. Made decodePNG32 faster. 1904 | *) 21 jun 2006: (!) Changed type of info vector to unsigned. 1905 | Changed position of palette in info vector. Fixed an important bug that 1906 | happened on PNGs with an uncompressed block. 1907 | *) 16 jun 2006: Internally changed unsigned into unsigned where 1908 | needed, and performed some optimizations. 1909 | *) 07 jun 2006: (!) Renamed functions to decodePNG and placed them 1910 | in LodePNG namespace. Changed the order of the parameters. Rewrote the 1911 | documentation in the header. Renamed files to lodepng.cpp and lodepng.h 1912 | *) 22 apr 2006: Optimized and improved some code 1913 | *) 07 sep 2005: (!) Changed to std::vector interface 1914 | *) 12 aug 2005: Initial release (C++, decoder only) 1915 | 1916 | 1917 | 13. contact information 1918 | ----------------------- 1919 | 1920 | Feel free to contact me with suggestions, problems, comments, ... concerning 1921 | LodePNG. If you encounter a PNG image that doesn't work properly with this 1922 | decoder, feel free to send it and I'll use it to find and fix the problem. 1923 | 1924 | My email address is (puzzle the account and domain together with an @ symbol): 1925 | Domain: gmail dot com. 1926 | Account: lode dot vandevenne. 1927 | 1928 | 1929 | Copyright (c) 2005-2019 Lode Vandevenne 1930 | */ 1931 | -------------------------------------------------------------------------------- /pc/inifile.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | inifile.cpp 3 | Copyright (C) 2007 Acekard, www.acekard.com 4 | Copyright (C) 2007-2009 somebody 5 | Copyright (C) 2009 yellow wood goblin 6 | 7 | This program is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with this program. If not, see . 19 | */ 20 | 21 | #include 22 | #include 23 | #include 24 | #include "inifile.h" 25 | 26 | static bool freadLine(FILE* f,std::string& str) 27 | { 28 | str.clear(); 29 | __read: 30 | char p=0; 31 | 32 | size_t readed=fread(&p,1,1,f); 33 | if(0==readed) 34 | { 35 | str=""; 36 | return false; 37 | } 38 | if('\n'==p||'\r'==p) 39 | { 40 | str=""; 41 | return true; 42 | } 43 | 44 | while(p!='\n'&&p!='\r'&&readed) 45 | { 46 | str+=p; 47 | readed=fread(&p,1,1,f); 48 | } 49 | 50 | if(str.empty()||""==str) 51 | { 52 | goto __read; 53 | } 54 | 55 | return true; 56 | } 57 | 58 | static void trimString(std::string& str) 59 | { 60 | size_t first=str.find_first_not_of(" \t"),last; 61 | if(first==str.npos) 62 | { 63 | str=""; 64 | } 65 | else 66 | { 67 | last=str.find_last_not_of(" \t"); 68 | if(first>0||(last+1)0) 91 | { 92 | m_FileContainer.clear(); 93 | } 94 | } 95 | 96 | void CIniFile::SetString(const std::string& Section,const std::string& Item,const std::string& Value) 97 | { 98 | if(GetFileString(Section,Item)!=Value) 99 | { 100 | SetFileString(Section,Item,Value); 101 | m_bModified=true; 102 | } 103 | } 104 | 105 | void CIniFile::SetInt(const std::string& Section,const std::string& Item,int Value) 106 | { 107 | char buf[16]; 108 | snprintf(buf, sizeof(buf), "%d", Value); 109 | std::string strtemp(buf); 110 | 111 | if(GetFileString(Section,Item)!=strtemp) 112 | { 113 | SetFileString(Section,Item,strtemp); 114 | m_bModified=true; 115 | } 116 | } 117 | 118 | std::string CIniFile::GetString(const std::string& Section,const std::string& Item) 119 | { 120 | return GetFileString(Section,Item); 121 | } 122 | 123 | std::string CIniFile::GetString(const std::string& Section,const std::string& Item,const std::string& DefaultValue) 124 | { 125 | std::string temp=GetString(Section,Item); 126 | if(!m_bLastResult) 127 | { 128 | SetString(Section,Item,DefaultValue); 129 | temp=DefaultValue; 130 | } 131 | return temp; 132 | } 133 | 134 | void CIniFile::GetStringVector(const std::string& Section,const std::string& Item,std::vector< std::string >& strings,char delimiter) 135 | { 136 | std::string strValue=GetFileString(Section,Item); 137 | strings.clear(); 138 | size_t pos; 139 | while((pos=strValue.find(delimiter),strValue.npos!=pos)) 140 | { 141 | const std::string string=strValue.substr(0,pos); 142 | if(string.length()) 143 | { 144 | strings.push_back(string); 145 | } 146 | strValue=strValue.substr(pos+1,strValue.npos); 147 | } 148 | if(strValue.length()) 149 | { 150 | strings.push_back(strValue); 151 | } 152 | } 153 | 154 | void CIniFile::SetStringVector(const std::string& Section,const std::string& Item,std::vector& strings,char delimiter) 155 | { 156 | std::string strValue; 157 | for(size_t ii=0;ii2&&'0'==value[0]&&('x'==value[1]||'X'==value[1])) 169 | return strtol(value.c_str(),NULL,16); 170 | else 171 | return strtol(value.c_str(),NULL,10); 172 | } 173 | 174 | int CIniFile::GetInt(const std::string& Section,const std::string& Item,int DefaultValue) 175 | { 176 | int temp; 177 | temp=GetInt(Section,Item); 178 | if(!m_bLastResult) 179 | { 180 | SetInt(Section,Item,DefaultValue); 181 | temp=DefaultValue; 182 | } 183 | return temp; 184 | } 185 | 186 | bool CIniFile::LoadIniFile(const std::string& FileName) 187 | { 188 | //dbg_printf("load %s\n",FileName.c_str()); 189 | if(FileName!="") m_sFileName=FileName; 190 | 191 | FILE* f=fopen(FileName.c_str(),"rb"); 192 | 193 | if(NULL==f) return false; 194 | 195 | //check for utf8 bom. 196 | char bom[3]; 197 | if(fread(bom,3,1,f)==1&&bom[0]==0xef&&bom[1]==0xbb&&bom[2]==0xbf) ; 198 | else fseek(f,0,SEEK_SET); 199 | 200 | std::string strline(""); 201 | m_FileContainer.clear(); 202 | 203 | while(freadLine(f,strline)) 204 | { 205 | trimString(strline); 206 | if(strline!=""&&';'!=strline[0]&&'/'!=strline[0]&&'!'!=strline[0]) m_FileContainer.push_back(strline); 207 | } 208 | 209 | fclose(f); 210 | 211 | m_bLastResult=false; 212 | m_bModified=false; 213 | 214 | return true; 215 | } 216 | 217 | bool CIniFile::SaveIniFileModified(const std::string& FileName) 218 | { 219 | if(m_bModified==true) 220 | { 221 | return SaveIniFile(FileName); 222 | } 223 | 224 | return true; 225 | } 226 | 227 | bool CIniFile::SaveIniFile(const std::string& FileName) 228 | { 229 | if(FileName!="") 230 | m_sFileName=FileName; 231 | 232 | FILE* f=fopen(m_sFileName.c_str(),"wb"); 233 | if(NULL==f) 234 | { 235 | return false; 236 | } 237 | 238 | for(size_t ii=0;ii0) 244 | { 245 | if(!m_FileContainer[ii-1].empty()&&m_FileContainer[ii-1]!="") 246 | fwrite("\r\n",1,2,f); 247 | } 248 | if(!strline.empty()&&strline!="") 249 | { 250 | fwrite(strline.c_str(),1,strline.length(),f); 251 | fwrite("\r\n",1,2,f); 252 | } 253 | } 254 | 255 | fclose(f); 256 | 257 | m_bModified=false; 258 | 259 | return true; 260 | } 261 | 262 | std::string CIniFile::GetFileString(const std::string& Section,const std::string& Item) 263 | { 264 | std::string strline; 265 | std::string strSection; 266 | std::string strItem; 267 | std::string strValue; 268 | 269 | size_t ii=0; 270 | size_t iFileLines=m_FileContainer.size(); 271 | 272 | if(m_bReadOnly) 273 | { 274 | cSectionCache::iterator it=m_Cache.find(Section); 275 | if((it!=m_Cache.end())) ii=it->second; 276 | } 277 | 278 | m_bLastResult=false; 279 | 280 | if(iFileLines>=0) 281 | { 282 | while(ii0&&rBracketPos!=std::string::npos) 289 | { 290 | strSection=strline.substr(1,rBracketPos-1); 291 | if(m_bReadOnly) m_Cache.insert(std::make_pair(strSection,ii-1)); 292 | if(strSection==Section) 293 | { 294 | while(ii0&&rBracketPos!=std::string::npos) 344 | { 345 | strSection=strline.substr(1,rBracketPos-1); 346 | if(strSection==Section) 347 | { 348 | while(ii> 8) & 0xFF); 24 | *resultptr++ = (unsigned char)((dataSize >> 16) & 0xFF); 25 | int length = dataSize; 26 | int dstoffs = 4; 27 | int Offs = 0; 28 | while (1) 29 | { 30 | int headeroffs = dstoffs++; 31 | resultptr++; 32 | unsigned char header = 0; 33 | for (int i = 0; i < 8; i++) 34 | { 35 | int comp = 0; 36 | int back = 1; 37 | int nr = 2; 38 | { 39 | unsigned char* ptr = dataptr - 1; 40 | int maxnum = 18; 41 | if (length - Offs < maxnum) maxnum = length - Offs; 42 | int maxback = 0x1000; 43 | if (Offs < maxback) maxback = Offs; 44 | maxback = (int)dataptr - maxback; 45 | int tmpnr; 46 | while (maxback <= (int)ptr) 47 | { 48 | if (*(unsigned short*)ptr == *(unsigned short*)dataptr && ptr[2] == dataptr[2]) 49 | { 50 | tmpnr = 3; 51 | while (tmpnr < maxnum && ptr[tmpnr] == dataptr[tmpnr]) tmpnr++; 52 | if (tmpnr > nr) 53 | { 54 | if (Offs + tmpnr > length) 55 | { 56 | nr = length - Offs; 57 | back = (int)(dataptr - ptr); 58 | break; 59 | } 60 | nr = tmpnr; 61 | back = (int)(dataptr - ptr); 62 | if (nr == maxnum) break; 63 | } 64 | } 65 | --ptr; 66 | } 67 | } 68 | if (nr > 2) 69 | { 70 | Offs += nr; 71 | dataptr += nr; 72 | *resultptr++ = (unsigned char)((((back - 1) >> 8) & 0xF) | (((nr - 3) & 0xF) << 4)); 73 | *resultptr++ = (unsigned char)((back - 1) & 0xFF); 74 | dstoffs += 2; 75 | comp = 1; 76 | } 77 | else 78 | { 79 | *resultptr++ = *dataptr++; 80 | dstoffs++; 81 | Offs++; 82 | } 83 | header = (unsigned char)((header << 1) | (comp & 1)); 84 | if (Offs >= length) 85 | { 86 | header = (unsigned char)(header << (7 - i)); 87 | break; 88 | } 89 | } 90 | result[headeroffs] = header; 91 | if (Offs >= length) break; 92 | } 93 | while ((dstoffs % 4) != 0) dstoffs++; 94 | compressedDataSize = dstoffs; 95 | unsigned char* realresult = new unsigned char[dstoffs]; 96 | tonccpy(realresult, result, dstoffs); 97 | return realresult; 98 | } 99 | -------------------------------------------------------------------------------- /pc/lz77.h: -------------------------------------------------------------------------------- 1 | #ifndef LZSS_H_ 2 | #define LZSS_H_ 3 | 4 | #include 5 | #include //built with codeblocks and mingw 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include //probably don't need most of these :p 12 | #include 13 | #include 14 | 15 | extern int compressedDataSize; 16 | 17 | unsigned char *lzssCompress(unsigned char *Data, int dataSize); 18 | 19 | #endif // LZSS_H_ 20 | 21 | -------------------------------------------------------------------------------- /pc/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include //built with codeblocks and mingw 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include //probably don't need most of these :p 9 | #include 10 | #include 11 | #include 12 | 13 | #include "graphics/lodepng.h" 14 | #include "lz77.h" 15 | #include "inifile.h" 16 | 17 | template inline TYPE BIT(const TYPE & x) 18 | { return TYPE(1) << x; } 19 | 20 | void clear_screen(char fill = ' ') { 21 | COORD tl = {0,0}; 22 | CONSOLE_SCREEN_BUFFER_INFO s; 23 | HANDLE console = GetStdHandle(STD_OUTPUT_HANDLE); 24 | GetConsoleScreenBufferInfo(console, &s); 25 | DWORD written, cells = s.dwSize.X * s.dwSize.Y; 26 | FillConsoleOutputCharacter(console, fill, cells, tl, &written); 27 | FillConsoleOutputAttribute(console, s.wAttributes, cells, tl, &written); 28 | SetConsoleCursorPosition(console, tl); 29 | } 30 | 31 | uint16_t convertedFrame[256*192]; 32 | unsigned char* compressedFrame; 33 | 34 | char fileBuffer[0x100000] = {0}; 35 | uint32_t compressedFrameSizeTableSize = 0; 36 | uint32_t compressedFramesSize = 0; 37 | uint32_t soundSize = 0; 38 | 39 | uint8_t headerToFile[0x200] = {0}; 40 | 41 | off_t getFileSize(const char *fileName) 42 | { 43 | FILE* fp = fopen(fileName, "rb"); 44 | off_t fsize = 0; 45 | if (fp) { 46 | fseek(fp, 0, SEEK_END); 47 | fsize = ftell(fp); // Get source file's size 48 | fseek(fp, 0, SEEK_SET); 49 | } 50 | fclose(fp); 51 | 52 | return fsize; 53 | } 54 | 55 | typedef struct rvidHeaderInfo { 56 | uint32_t formatString; // "RVID" string 57 | uint32_t ver; // File format version 58 | uint32_t frames; // Number of frames 59 | uint8_t fps; // Frames per second 60 | uint8_t vRes; // Vertical resolution 61 | uint8_t interlaced; // Is interlaced 62 | uint8_t hasSound; // Has sound/audio 63 | uint16_t sampleRate; // Audio sample rate 64 | uint16_t framesCompressed; // Frames are compressed 65 | uint32_t framesOffset; // Offset of first frame 66 | uint32_t soundOffset; // Offset of sound stream 67 | } rvidHeaderInfo; 68 | 69 | rvidHeaderInfo rvidHeader; 70 | 71 | #define titleText "Vid2RVID v1.3\nby RocketRobz\n" 72 | 73 | /*void extractFrames(void) { 74 | clear_screen(); 75 | printf("Extracting frames...\n"); 76 | 77 | mkdir("rvidFrames_extracted"); 78 | FILE* videoInput = fopen("source.rvid", "rb"); 79 | chdir("rvidFrames_extracted"); 80 | FILE* frameOutput; 81 | char frameOutputFileName[32]; 82 | fread(&rvidHeader, 1, sizeof(rvidHeaderInfo), videoInput); 83 | fseek(videoInput, 0x200, SEEK_SET); 84 | for (int i = 0; i < rvidHeader.frames; i++) { 85 | if (fread(convertedFrame, 1, 0x200*rvidHeader.vRes, videoInput) > 0) { 86 | snprintf(frameOutputFileName, sizeof(frameOutputFileName), "frame%i.bin", i); 87 | frameOutput = fopen(frameOutputFileName, "wb"); 88 | fwrite(convertedFrame, 1, 0x200*rvidHeader.vRes, frameOutput); 89 | fclose(frameOutput); 90 | } else { 91 | break; 92 | } 93 | } 94 | fclose(videoInput); 95 | printf("Done!\n"); 96 | }*/ 97 | 98 | int main(int argc, char **argv) { 99 | 100 | printf(titleText); 101 | printf("\n"); 102 | printf("A: Convert\n"); 103 | //printf("E: Extract raw frames from source.rvid\n"); 104 | 105 | while (1) { 106 | if (GetKeyState('A') & 0x8000) { 107 | break; 108 | } 109 | /*if (GetKeyState('E') & 0x8000) { 110 | extractFrames(); 111 | return 0; 112 | break; 113 | }*/ 114 | } 115 | 116 | CIniFile info( "rvidFrames/info.ini" ); 117 | 118 | if ((info.GetInt("RVID", "HAS_SOUND", 1) == 1) && (access("rvidFrames/sound.raw.pcm", F_OK) == 0)) { 119 | rvidHeader.sampleRate = info.GetInt("RVID", "AUDIO_HZ", 0); 120 | if (rvidHeader.sampleRate > 0) { 121 | rvidHeader.hasSound = 1; 122 | } else { 123 | clear_screen(); 124 | printf("Sound file found!\n"); 125 | printf("\n"); 126 | printf("What is the sample rate?\n"); 127 | printf("0: Exclude sound\n"); 128 | printf("1: 8000hz\n"); 129 | printf("2: 11025hz\n"); 130 | printf("3: 16000hz\n"); 131 | 132 | while (1) { 133 | if (GetKeyState('0') & 0x8000) { 134 | rvidHeader.hasSound = 0; 135 | break; 136 | } 137 | if (GetKeyState('1') & 0x8000) { 138 | rvidHeader.sampleRate = 8000; 139 | rvidHeader.hasSound = 1; 140 | break; 141 | } 142 | if (GetKeyState('2') & 0x8000) { 143 | rvidHeader.sampleRate = 11025; 144 | rvidHeader.hasSound = 1; 145 | break; 146 | } 147 | if (GetKeyState('3') & 0x8000) { 148 | rvidHeader.sampleRate = 16000; 149 | rvidHeader.hasSound = 1; 150 | break; 151 | } 152 | } 153 | } 154 | } 155 | 156 | clear_screen(); 157 | printf("Getting number of frames...\n"); 158 | 159 | char framePath[256]; 160 | int foundFrames = info.GetInt("RVID", "FRAMES", -1); 161 | 162 | if (foundFrames == -1) { 163 | while (1) { 164 | foundFrames++; 165 | snprintf(framePath, sizeof(framePath), "rvidFrames/frame%i.png", foundFrames); 166 | if (access(framePath, F_OK) != 0) break; 167 | } 168 | foundFrames--; 169 | } 170 | 171 | rvidHeader.formatString = 0x44495652; // "RVID" 172 | rvidHeader.ver = 2; 173 | rvidHeader.frames = foundFrames+1; 174 | rvidHeader.fps = info.GetInt("RVID", "FPS", 24); 175 | rvidHeader.vRes = info.GetInt("RVID", "V_RES", 192); 176 | rvidHeader.interlaced = info.GetInt("RVID", "INTERLACED", 2); 177 | rvidHeader.framesCompressed = info.GetInt("RVID", "COMPRESSED", 2); 178 | 179 | if (rvidHeader.interlaced == 2) { 180 | clear_screen(); 181 | printf("Is the video interlaced?\n"); 182 | printf("Video will be played twice the set frame rate, if so.\n"); 183 | printf("\n"); 184 | printf("Y: Yes\n"); 185 | printf("N: No\n"); 186 | 187 | while (1) { 188 | if (GetKeyState('Y') & 0x8000) { 189 | rvidHeader.interlaced = 1; 190 | break; 191 | } 192 | if (GetKeyState('N') & 0x8000) { 193 | rvidHeader.interlaced = 0; 194 | break; 195 | } 196 | } 197 | } 198 | 199 | if (rvidHeader.framesCompressed == 2) { 200 | clear_screen(); 201 | printf("Compress the video frames?\n"); 202 | printf("Video quality will not be affected.\n"); 203 | printf("Recommended if your video is 24FPS or less.\n"); 204 | printf("Depending on how may frames you have, this may take a while.\n"); 205 | printf("\n"); 206 | printf("Y: Yes\n"); 207 | printf("N: No\n"); 208 | 209 | while (1) { 210 | if (GetKeyState('Y') & 0x8000) { 211 | rvidHeader.framesCompressed = 1; 212 | break; 213 | } 214 | if (GetKeyState('N') & 0x8000) { 215 | rvidHeader.framesCompressed = 0; 216 | break; 217 | } 218 | } 219 | } 220 | 221 | FILE* frameInput; 222 | 223 | FILE* compressedFrameSizeTable; 224 | FILE* compressedFrames; 225 | if (rvidHeader.framesCompressed == 1) { 226 | clear_screen(); 227 | printf("Compressing...\n"); 228 | 229 | compressedFrameSizeTable = fopen("tempTable.bin", "wb"); 230 | compressedFrames = fopen("tempFrames.bin", "wb"); 231 | for (int i = 0; i <= foundFrames; i++) { 232 | snprintf(framePath, sizeof(framePath), "rvidFrames/frame%i.png", i); 233 | frameInput = fopen(framePath, "rb"); 234 | if (frameInput) { 235 | fclose(frameInput); 236 | 237 | std::vector image; 238 | unsigned width, height; 239 | lodepng::decode(image, width, height, framePath); 240 | 241 | for(unsigned i=0;i>3 | (image[(i*4)+1]>>3)<<5 | (image[(i*4)+2]>>3)<<10 | BIT(15); 243 | } 244 | 245 | compressedFrame = lzssCompress((unsigned char*)convertedFrame, 0x200*rvidHeader.vRes); 246 | 247 | printf("%i/%i\n", i, foundFrames); 248 | 249 | // Save current frame to temp file 250 | fwrite(compressedFrame, 1, compressedDataSize, compressedFrames); 251 | fwrite(&compressedDataSize, 4, 1, compressedFrameSizeTable); 252 | compressedFrameSizeTableSize += 4; 253 | compressedFramesSize += compressedDataSize; 254 | } else { 255 | break; 256 | } 257 | } 258 | fclose(compressedFrames); 259 | fclose(compressedFrameSizeTable); 260 | rvidHeader.framesOffset = 0x200+compressedFrameSizeTableSize; 261 | rvidHeader.soundOffset = 0x200+compressedFrameSizeTableSize+compressedFramesSize; 262 | } else { 263 | rvidHeader.framesOffset = 0x200; 264 | rvidHeader.soundOffset = 0x200+((0x200*rvidHeader.vRes)*rvidHeader.frames); 265 | } 266 | 267 | FILE* videoOutput = fopen("new.rvid", "wb"); 268 | 269 | // Write header 270 | memcpy(headerToFile, &rvidHeader, sizeof(rvidHeaderInfo)); 271 | fwrite(headerToFile, 1, 0x200, videoOutput); 272 | 273 | clear_screen(); 274 | printf("Converting...\n"); 275 | 276 | if (rvidHeader.framesCompressed == 1) { 277 | off_t fsize = compressedFrameSizeTableSize; 278 | off_t offset = 0; 279 | int numr = 0; 280 | 281 | compressedFrameSizeTable = fopen("tempTable.bin", "rb"); 282 | while (1) 283 | { 284 | // Add size table to .rvid file 285 | numr = fread(fileBuffer, 1, sizeof(fileBuffer), compressedFrameSizeTable); 286 | fwrite(fileBuffer, 1, numr, videoOutput); 287 | offset += sizeof(fileBuffer); 288 | 289 | if (offset > fsize) { 290 | break; 291 | } 292 | } 293 | fclose(compressedFrameSizeTable); 294 | 295 | fsize = compressedFramesSize; 296 | offset = 0; 297 | numr = 0; 298 | 299 | compressedFrames = fopen("tempFrames.bin", "rb"); 300 | while (1) 301 | { 302 | // Add compressed frames to .rvid file 303 | numr = fread(fileBuffer, 1, sizeof(fileBuffer), compressedFrames); 304 | fwrite(fileBuffer, 1, numr, videoOutput); 305 | offset += sizeof(fileBuffer); 306 | 307 | if (offset > fsize) { 308 | break; 309 | } 310 | } 311 | fclose(compressedFrames); 312 | } else for (int i = 0; i <= foundFrames; i++) { 313 | snprintf(framePath, sizeof(framePath), "rvidFrames/frame%i.png", i); 314 | frameInput = fopen(framePath, "rb"); 315 | if (frameInput) { 316 | fclose(frameInput); 317 | 318 | std::vector image; 319 | unsigned width, height; 320 | lodepng::decode(image, width, height, framePath); 321 | 322 | for(unsigned i=0;i>3 | (image[(i*4)+1]>>3)<<5 | (image[(i*4)+2]>>3)<<10 | BIT(15); 324 | } 325 | 326 | printf("%i/%i\n", i, foundFrames); 327 | 328 | // Save current frame to a file 329 | fwrite(convertedFrame, 1, 0x200*rvidHeader.vRes, videoOutput); 330 | } else { 331 | break; 332 | } 333 | } 334 | 335 | if (rvidHeader.hasSound == 1) { 336 | clear_screen(); 337 | printf("Adding sound...\n"); 338 | 339 | off_t fsize = getFileSize("rvidFrames/sound.raw.pcm"); 340 | off_t offset = 0; 341 | int numr; 342 | 343 | FILE* soundFile = fopen("rvidFrames/sound.raw.pcm", "rb"); 344 | while (1) 345 | { 346 | // Add sound to .rvid file 347 | numr = fread(fileBuffer, 1, sizeof(fileBuffer), soundFile); 348 | fwrite(fileBuffer, 1, numr, videoOutput); 349 | offset += sizeof(fileBuffer); 350 | 351 | if (offset > fsize) { 352 | break; 353 | } 354 | } 355 | fclose(soundFile); 356 | } 357 | 358 | fclose(videoOutput); 359 | 360 | if (rvidHeader.framesCompressed == 1) { 361 | remove("tempFrames.bin"); 362 | remove("tempTable.bin"); 363 | } 364 | 365 | clear_screen(); 366 | printf("Done!\n"); 367 | 368 | return 0; 369 | } 370 | 371 | -------------------------------------------------------------------------------- /pc/tonccpy.c: -------------------------------------------------------------------------------- 1 | #include "tonccpy.h" 2 | //# tonccpy.c 3 | 4 | //! VRAM-safe cpy. 5 | /*! This version mimics memcpy in functionality, with 6 | the benefit of working for VRAM as well. It is also 7 | slightly faster than the original memcpy, but faster 8 | implementations can be made. 9 | \param dst Destination pointer. 10 | \param src Source pointer. 11 | \param size Fill-length in bytes. 12 | \note The pointers and size need not be word-aligned. 13 | */ 14 | void tonccpy(void *dst, const void *src, uint size) 15 | { 16 | if(size==0 || dst==0 || src==0) 17 | return; 18 | 19 | uint count; 20 | uint16_t *dst16; // hword destination 21 | uint8_t *src8; // byte source 22 | 23 | // Ideal case: copy by 4x words. Leaves tail for later. 24 | if( ((uint32_t)src|(uint32_t)dst)%4==0 && size>=4) 25 | { 26 | uint32_t *src32= (uint32_t*)src, *dst32= (uint32_t*)dst; 27 | 28 | count= size/4; 29 | uint tmp= count&3; 30 | count /= 4; 31 | 32 | // Duff's Device, good friend! 33 | switch(tmp) { 34 | do { *dst32++ = *src32++; 35 | case 3: *dst32++ = *src32++; 36 | case 2: *dst32++ = *src32++; 37 | case 1: *dst32++ = *src32++; 38 | case 0: ; } while(count--); 39 | } 40 | 41 | // Check for tail 42 | size &= 3; 43 | if(size == 0) 44 | return; 45 | 46 | src8= (uint8_t*)src32; 47 | dst16= (uint16_t*)dst32; 48 | } 49 | else // Unaligned. 50 | { 51 | uint dstOfs= (uint32_t)dst&1; 52 | src8= (uint8_t*)src; 53 | dst16= (uint16_t*)(dst-dstOfs); 54 | 55 | // Head: 1 byte. 56 | if(dstOfs != 0) 57 | { 58 | *dst16= (*dst16 & 0xFF) | *src8++<<8; 59 | dst16++; 60 | if(--size==0) 61 | return; 62 | } 63 | } 64 | 65 | // Unaligned main: copy by 2x byte. 66 | count= size/2; 67 | while(count--) 68 | { 69 | *dst16++ = src8[0] | src8[1]<<8; 70 | src8 += 2; 71 | } 72 | 73 | // Tail: 1 byte. 74 | if(size&1) 75 | *dst16= (*dst16 &~ 0xFF) | *src8; 76 | } 77 | //# toncset.c 78 | 79 | //! VRAM-safe memset, internal routine. 80 | /*! This version mimics memset in functionality, with 81 | the benefit of working for VRAM as well. It is also 82 | slightly faster than the original memset. 83 | \param dst Destination pointer. 84 | \param fill Word to fill with. 85 | \param size Fill-length in bytes. 86 | \note The \a dst pointer and \a size need not be 87 | word-aligned. In the case of unaligned fills, \a fill 88 | will be masked off to match the situation. 89 | */ 90 | void __toncset(void *dst, uint32_t fill, uint size) 91 | { 92 | if(size==0 || dst==0) 93 | return; 94 | 95 | uint left= (uint32_t)dst&3; 96 | uint32_t *dst32= (uint32_t*)(dst-left); 97 | uint32_t count, mask; 98 | 99 | // Unaligned head. 100 | if(left != 0) 101 | { 102 | // Adjust for very small stint. 103 | if(left+size<4) 104 | { 105 | mask= BIT_MASK(size*8)<<(left*8); 106 | *dst32= (*dst32 &~ mask) | (fill & mask); 107 | return; 108 | } 109 | 110 | mask= BIT_MASK(left*8); 111 | *dst32= (*dst32 & mask) | (fill&~mask); 112 | dst32++; 113 | size -= 4-left; 114 | } 115 | 116 | // Main stint. 117 | count= size/4; 118 | uint tmp= count&3; 119 | count /= 4; 120 | 121 | switch(tmp) { 122 | do { *dst32++ = fill; 123 | case 3: *dst32++ = fill; 124 | case 2: *dst32++ = fill; 125 | case 1: *dst32++ = fill; 126 | case 0: ; } while(count--); 127 | } 128 | 129 | // Tail 130 | size &= 3; 131 | if(size) 132 | { 133 | mask= BIT_MASK(size*8); 134 | *dst32= (*dst32 &~ mask) | (fill & mask); 135 | } 136 | } 137 | -------------------------------------------------------------------------------- /pc/tonccpy.h: -------------------------------------------------------------------------------- 1 | //# Stuff you may not have yet. 2 | 3 | #ifndef TONCCPY_H 4 | #define TONCCPY_H 5 | 6 | 7 | #ifdef __cplusplus 8 | extern "C" { 9 | #endif 10 | 11 | #include 12 | 13 | typedef unsigned int uint; 14 | #define BIT_MASK(len) ( (1<<(len))-1 ) 15 | static inline uint32_t quad8(uint8_t x) { x |= x<<8; return x | x<<16; } 16 | 17 | 18 | //# Declarations and inlines. 19 | 20 | void tonccpy(void *dst, const void *src, uint size); 21 | 22 | void __toncset(void *dst, uint32_t fill, uint size); 23 | static inline void toncset(void *dst, uint8_t src, uint size); 24 | static inline void toncset16(void *dst, uint16_t src, uint size); 25 | static inline void toncset32(void *dst, uint32_t src, uint size); 26 | 27 | 28 | //! VRAM-safe memset, byte version. Size in bytes. 29 | static inline void toncset(void *dst, uint8_t src, uint size) 30 | { __toncset(dst, quad8(src), size); } 31 | 32 | //! VRAM-safe memset, halfword version. Size in hwords. 33 | static inline void toncset16(void *dst, uint16_t src, uint size) 34 | { __toncset(dst, src|src<<16, size*2); } 35 | 36 | //! VRAM-safe memset, word version. Size in words. 37 | static inline void toncset32(void *dst, uint32_t src, uint size) 38 | { __toncset(dst, src, size*4); } 39 | 40 | #ifdef __cplusplus 41 | } 42 | #endif 43 | #endif 44 | --------------------------------------------------------------------------------