diff --git a/Makefile.am b/Makefile.am index b1af410e..77cc7c4f 100644 --- a/Makefile.am +++ b/Makefile.am @@ -58,8 +58,8 @@ nzbget_SOURCES = \ daemon/frontend/LoggableFrontend.h \ daemon/frontend/NCursesFrontend.cpp \ daemon/frontend/NCursesFrontend.h \ - daemon/main/CommandLineParser.cpp \ - daemon/main/CommandLineParser.h \ + daemon/main/CommandLineParser.cpp \ + daemon/main/CommandLineParser.h \ daemon/main/DiskService.cpp \ daemon/main/DiskService.h \ daemon/main/Maintenance.cpp \ @@ -223,13 +223,14 @@ nzbget_SOURCES += \ lib/yencode/Ssse3Decoder.cpp \ lib/yencode/PclmulCrc.cpp \ lib/yencode/NeonDecoder.cpp \ - lib/yencode/ArmCrc.cpp + lib/yencode/AcleCrc.cpp \ + lib/yencode/SliceCrc.cpp lib/yencode/Sse2Decoder.$(OBJEXT) : CXXFLAGS+=$(SSE2_CXXFLAGS) lib/yencode/Ssse3Decoder.$(OBJEXT) : CXXFLAGS+=$(SSSE3_CXXFLAGS) lib/yencode/PclmulCrc.$(OBJEXT) : CXXFLAGS+=$(PCLMUL_CXXFLAGS) lib/yencode/NeonDecoder.$(OBJEXT) : CXXFLAGS+=$(NEON_CXXFLAGS) -lib/yencode/ArmCrc.$(OBJEXT) : CXXFLAGS+=$(ARMCRC_CXXFLAGS) +lib/yencode/AcleCrc.$(OBJEXT) : CXXFLAGS+=$(ACLECRC_CXXFLAGS) AM_CPPFLAGS = \ -I$(srcdir)/daemon/connect \ diff --git a/Makefile.in b/Makefile.in index 27836422..ba6606be 100644 --- a/Makefile.in +++ b/Makefile.in @@ -315,10 +315,11 @@ am__nzbget_SOURCES_DIST = daemon/connect/Connection.cpp \ lib/yencode/YEncode.h lib/yencode/SimdInit.cpp \ lib/yencode/ScalarDecoder.cpp lib/yencode/Sse2Decoder.cpp \ lib/yencode/Ssse3Decoder.cpp lib/yencode/PclmulCrc.cpp \ - lib/yencode/NeonDecoder.cpp lib/yencode/ArmCrc.cpp \ - lib/catch/catch.h tests/suite/TestMain.cpp \ - tests/suite/TestMain.h tests/suite/TestUtil.cpp \ - tests/suite/TestUtil.h tests/main/CommandLineParserTest.cpp \ + lib/yencode/NeonDecoder.cpp lib/yencode/AcleCrc.cpp \ + lib/yencode/SliceCrc.cpp lib/catch/catch.h \ + tests/suite/TestMain.cpp tests/suite/TestMain.h \ + tests/suite/TestUtil.cpp tests/suite/TestUtil.h \ + tests/main/CommandLineParserTest.cpp \ tests/main/OptionsTest.cpp tests/feed/FeedFilterTest.cpp \ tests/postprocess/DupeMatcherTest.cpp \ tests/postprocess/RarRenamerTest.cpp \ @@ -434,7 +435,8 @@ am_nzbget_OBJECTS = daemon/connect/Connection.$(OBJEXT) \ lib/yencode/Sse2Decoder.$(OBJEXT) \ lib/yencode/Ssse3Decoder.$(OBJEXT) \ lib/yencode/PclmulCrc.$(OBJEXT) \ - lib/yencode/NeonDecoder.$(OBJEXT) lib/yencode/ArmCrc.$(OBJEXT) \ + lib/yencode/NeonDecoder.$(OBJEXT) \ + lib/yencode/AcleCrc.$(OBJEXT) lib/yencode/SliceCrc.$(OBJEXT) \ $(am__objects_2) $(am__objects_3) nzbget_OBJECTS = $(am_nzbget_OBJECTS) nzbget_LDADD = $(LDADD) @@ -560,10 +562,10 @@ DIST_TARGETS = dist-gzip distuninstallcheck_listfiles = find . -type f -print am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \ | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$' +ACLECRC_CXXFLAGS = @ACLECRC_CXXFLAGS@ ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ -ARMCRC_CXXFLAGS = @ARMCRC_CXXFLAGS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ @@ -781,7 +783,8 @@ nzbget_SOURCES = daemon/connect/Connection.cpp \ lib/yencode/SimdInit.cpp lib/yencode/ScalarDecoder.cpp \ lib/yencode/Sse2Decoder.cpp lib/yencode/Ssse3Decoder.cpp \ lib/yencode/PclmulCrc.cpp lib/yencode/NeonDecoder.cpp \ - lib/yencode/ArmCrc.cpp $(am__append_2) $(am__append_3) + lib/yencode/AcleCrc.cpp lib/yencode/SliceCrc.cpp \ + $(am__append_2) $(am__append_3) AM_CPPFLAGS = -I$(srcdir)/daemon/connect -I$(srcdir)/daemon/extension \ -I$(srcdir)/daemon/feed -I$(srcdir)/daemon/frontend \ -I$(srcdir)/daemon/main -I$(srcdir)/daemon/nntp \ @@ -1352,7 +1355,9 @@ lib/yencode/PclmulCrc.$(OBJEXT): lib/yencode/$(am__dirstamp) \ lib/yencode/$(DEPDIR)/$(am__dirstamp) lib/yencode/NeonDecoder.$(OBJEXT): lib/yencode/$(am__dirstamp) \ lib/yencode/$(DEPDIR)/$(am__dirstamp) -lib/yencode/ArmCrc.$(OBJEXT): lib/yencode/$(am__dirstamp) \ +lib/yencode/AcleCrc.$(OBJEXT): lib/yencode/$(am__dirstamp) \ + lib/yencode/$(DEPDIR)/$(am__dirstamp) +lib/yencode/SliceCrc.$(OBJEXT): lib/yencode/$(am__dirstamp) \ lib/yencode/$(DEPDIR)/$(am__dirstamp) tests/suite/$(am__dirstamp): @$(MKDIR_P) tests/suite @@ -1601,11 +1606,12 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@lib/par2/$(DEPDIR)/reedsolomon.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@lib/par2/$(DEPDIR)/verificationhashtable.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@lib/par2/$(DEPDIR)/verificationpacket.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@lib/yencode/$(DEPDIR)/ArmCrc.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@lib/yencode/$(DEPDIR)/AcleCrc.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@lib/yencode/$(DEPDIR)/NeonDecoder.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@lib/yencode/$(DEPDIR)/PclmulCrc.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@lib/yencode/$(DEPDIR)/ScalarDecoder.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@lib/yencode/$(DEPDIR)/SimdInit.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@lib/yencode/$(DEPDIR)/SliceCrc.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@lib/yencode/$(DEPDIR)/Sse2Decoder.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@lib/yencode/$(DEPDIR)/Ssse3Decoder.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@tests/feed/$(DEPDIR)/FeedFilterTest.Po@am__quote@ @@ -2119,7 +2125,7 @@ lib/yencode/Sse2Decoder.$(OBJEXT) : CXXFLAGS+=$(SSE2_CXXFLAGS) lib/yencode/Ssse3Decoder.$(OBJEXT) : CXXFLAGS+=$(SSSE3_CXXFLAGS) lib/yencode/PclmulCrc.$(OBJEXT) : CXXFLAGS+=$(PCLMUL_CXXFLAGS) lib/yencode/NeonDecoder.$(OBJEXT) : CXXFLAGS+=$(NEON_CXXFLAGS) -lib/yencode/ArmCrc.$(OBJEXT) : CXXFLAGS+=$(ARMCRC_CXXFLAGS) +lib/yencode/AcleCrc.$(OBJEXT) : CXXFLAGS+=$(ACLECRC_CXXFLAGS) # Note about "sed": # We need to make some changes in installed files. diff --git a/configure b/configure index bf7bc702..ac91e741 100755 --- a/configure +++ b/configure @@ -628,7 +628,7 @@ LTLIBOBJS LIBOBJS WITH_TESTS_FALSE WITH_TESTS_TRUE -ARMCRC_CXXFLAGS +ACLECRC_CXXFLAGS NEON_CXXFLAGS PCLMUL_CXXFLAGS SSSE3_CXXFLAGS @@ -8348,11 +8348,11 @@ case $host_cpu in ;; arm) NEON_CXXFLAGS="-mfpu=neon" - ARMCRC_CXXFLAGS="-march=armv8-a+crc" + ACLECRC_CXXFLAGS="-march=armv8-a+crc" USE_SIMD=yes ;; aarch64) - ARMCRC_CXXFLAGS="-march=armv8-a+crc" + ACLECRC_CXXFLAGS="-march=armv8-a+crc" USE_SIMD=yes ;; esac diff --git a/configure.ac b/configure.ac index 31567676..4e074529 100644 --- a/configure.ac +++ b/configure.ac @@ -551,11 +551,11 @@ case $host_cpu in ;; arm) NEON_CXXFLAGS="-mfpu=neon" - ARMCRC_CXXFLAGS="-march=armv8-a+crc" + ACLECRC_CXXFLAGS="-march=armv8-a+crc" USE_SIMD=yes ;; aarch64) - ARMCRC_CXXFLAGS="-march=armv8-a+crc" + ACLECRC_CXXFLAGS="-march=armv8-a+crc" USE_SIMD=yes ;; esac @@ -564,7 +564,7 @@ AC_SUBST([SSE2_CXXFLAGS]) AC_SUBST([SSSE3_CXXFLAGS]) AC_SUBST([PCLMUL_CXXFLAGS]) AC_SUBST([NEON_CXXFLAGS]) -AC_SUBST([ARMCRC_CXXFLAGS]) +AC_SUBST([ACLECRC_CXXFLAGS]) dnl diff --git a/daemon/main/nzbget.cpp b/daemon/main/nzbget.cpp index b71b939b..1cfa105d 100644 --- a/daemon/main/nzbget.cpp +++ b/daemon/main/nzbget.cpp @@ -52,6 +52,7 @@ #include "FileSystem.h" #include "StackTrace.h" #include "CommandScript.h" +#include "YEncode.h" #ifdef WIN32 #include "WinService.h" #include "WinConsole.h" @@ -112,6 +113,7 @@ int main(int argc, char *argv[], char *argp[]) #endif Util::Init(); + YEncode::init(); g_ArgumentCount = argc; g_Arguments = (char*(*)[])argv; @@ -262,7 +264,6 @@ void NZBGet::Init() #ifndef DISABLE_TLS TlsSocket::Init(); #endif - Decoder::Init(); } CreateGlobals(); diff --git a/daemon/nntp/ArticleWriter.cpp b/daemon/nntp/ArticleWriter.cpp index c3dcf559..2411438f 100644 --- a/daemon/nntp/ArticleWriter.cpp +++ b/daemon/nntp/ArticleWriter.cpp @@ -469,7 +469,7 @@ void ArticleWriter::CompleteFileParts() if (m_format == Decoder::efYenc) { - crc = firstArticle ? pa->GetCrc() : Util::Crc32Combine(crc, pa->GetCrc(), pa->GetSegmentSize()); + crc = firstArticle ? pa->GetCrc() : Crc32::Combine(crc, pa->GetCrc(), pa->GetSegmentSize()); firstArticle = false; } } diff --git a/daemon/nntp/Decoder.cpp b/daemon/nntp/Decoder.cpp index 317acbbc..3462f7c7 100644 --- a/daemon/nntp/Decoder.cpp +++ b/daemon/nntp/Decoder.cpp @@ -24,21 +24,11 @@ #include "Util.h" #include "YEncode.h" -void Decoder::Init() -{ - YEncode::init(); - - debug("%s", YEncode::decode_simd ? "SIMD yEnc decoder can be used" : "SIMD yEnc decoder isn't available for this CPU"); - debug("%s", YEncode::crc32_simd ? "SIMD Crc32 routine can be used" : "SIMD Crc32 routine isn't available for this CPU"); - debug("%s", YEncode::inc_crc32_simd ? "SIMD Crc32 (incremental) routine can be used" : "SIMD Crc32 (incremental) routine isn't available for this CPU"); - - printf("%s\n", YEncode::decode_simd ? "SIMD yEnc decoder can be used" : "SIMD yEnc decoder isn't available for this CPU"); - printf("%s\n", YEncode::crc32_simd ? "SIMD Crc32 routine can be used" : "SIMD Crc32 routine isn't available for this CPU"); - printf("%s\n", YEncode::inc_crc32_simd ? "SIMD Crc32 (incremental) routine can be used" : "SIMD Crc32 (incremental) routine isn't available for this CPU"); -} - Decoder::Decoder() { + debug("%s", YEncode::decode_simd ? "SIMD yEnc decoder can be used" : "SIMD yEnc decoder isn't available for this CPU"); + debug("%s", YEncode::crc_simd ? "SIMD Crc routine can be used" : "SIMD Crc routine isn't available for this CPU"); + Clear(); } @@ -52,7 +42,7 @@ void Decoder::Clear() m_crc = false; m_eof = false; m_expectedCRC = 0; - m_calculatedCRC = 0xFFFFFFFF; + m_crc32.Reset(); m_beginPos = 0; m_endPos = 0; m_size = 0; @@ -326,7 +316,7 @@ int Decoder::DecodeYenc(char* buffer, char* outbuf, int len) if (m_crcCheck) { - m_calculatedCRC = Util::Crc32m(m_calculatedCRC, (uchar*)outbuf, (uint32)len); + m_crc32.Append((uchar*)outbuf, (uint32)len); } return len; @@ -353,7 +343,7 @@ Decoder::EStatus Decoder::Check() Decoder::EStatus Decoder::CheckYenc() { - m_calculatedCRC ^= 0xFFFFFFFF; + m_calculatedCRC = m_crc32.Finish(); debug("Expected crc32=%x", m_expectedCRC); debug("Calculated crc32=%x", m_calculatedCRC); diff --git a/daemon/nntp/Decoder.h b/daemon/nntp/Decoder.h index 3f48f029..c0f1939e 100644 --- a/daemon/nntp/Decoder.h +++ b/daemon/nntp/Decoder.h @@ -22,6 +22,7 @@ #define DECODER_H #include "NString.h" +#include "Util.h" class Decoder { @@ -44,7 +45,6 @@ public: }; Decoder(); - static void Init(); EStatus Check(); void Clear(); int DecodeBuffer(char* buffer, int len); @@ -79,6 +79,7 @@ private: char m_extraChar; char m_lastChar1; char m_lastChar2; + Crc32 m_crc32; EFormat DetectFormat(const char* buffer, int len); void ProcessYenc(char* buffer, int len); diff --git a/daemon/nserv/YEncoder.cpp b/daemon/nserv/YEncoder.cpp index fbb6cc8a..acaaee1c 100644 --- a/daemon/nserv/YEncoder.cpp +++ b/daemon/nserv/YEncoder.cpp @@ -1,7 +1,7 @@ /* * This file is part of nzbget. See . * - * Copyright (C) 2016 Andrey Prygunkov + * Copyright (C) 2016-2017 Andrey Prygunkov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -67,7 +67,7 @@ void YEncoder::WriteSegment() outbuf.Append(CString::FormatStr("=ybegin part=%i line=128 size=%lli name=%s\r\n", m_part, (long long)m_fileSize, FileSystem::BaseFileName(m_filename))); outbuf.Append(CString::FormatStr("=ypart begin=%lli end=%lli\r\n", (long long)(m_offset + 1), (long long)(m_offset + m_size))); - uint32 crc = 0xFFFFFFFF; + Crc32 crc; CharBuffer inbuf(std::min(m_size, 16 * 1024 * 1024)); int lnsz = 0; char* out = (char*)outbuf + outbuf.Length(); @@ -82,7 +82,7 @@ void YEncoder::WriteSegment() return; // error; } - crc = Util::Crc32m(crc, (uchar*)(const char*)inbuf, (int)readBytes); + crc.Append((uchar*)(const char*)inbuf, (int)readBytes); char* in = inbuf; while (readBytes > 0) @@ -122,10 +122,8 @@ void YEncoder::WriteSegment() } } } - crc ^= 0xFFFFFFFF; - m_diskfile.Close(); - outbuf.Append(CString::FormatStr("=yend size=%i part=0 pcrc32=%08x\r\n", m_size, (unsigned int)crc)); + outbuf.Append(CString::FormatStr("=yend size=%i part=0 pcrc32=%08x\r\n", m_size, (unsigned int)crc.Finish())); m_writeFunc(outbuf, outbuf.Length()); } diff --git a/daemon/postprocess/ParChecker.cpp b/daemon/postprocess/ParChecker.cpp index 7ae5588d..246e133a 100644 --- a/daemon/postprocess/ParChecker.cpp +++ b/daemon/postprocess/ParChecker.cpp @@ -1,7 +1,7 @@ /* * This file is part of nzbget. See . * - * Copyright (C) 2007-2016 Andrey Prygunkov + * Copyright (C) 2007-2017 Andrey Prygunkov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -1399,7 +1399,7 @@ bool ParChecker::VerifySuccessDataFile(void* diskfile, void* sourcefile, uint32 { const Par2::FILEVERIFICATIONENTRY* entry = packet->VerificationEntry(i); Par2::u32 blockCrc = entry->crc; - parCrc = i == 0 ? blockCrc : Util::Crc32Combine(parCrc, blockCrc, (uint32)blocksize); + parCrc = i == 0 ? blockCrc : Crc32::Combine(parCrc, blockCrc, (uint32)blocksize); } debug("Block-CRC: %x, filename: %s", parCrc, FileSystem::BaseFileName(sourceFile->GetTargetFile()->FileName().c_str())); @@ -1477,7 +1477,7 @@ bool ParChecker::VerifyPartialDataFile(void* diskfile, void* sourcefile, Segment } const Par2::FILEVERIFICATIONENTRY* entry = packet->VerificationEntry(i); Par2::u32 blockCrc = entry->crc; - parCrc = blockStart == i ? blockCrc : Util::Crc32Combine(parCrc, blockCrc, (uint32)blocksize); + parCrc = blockStart == i ? blockCrc : Crc32::Combine(parCrc, blockCrc, (uint32)blocksize); } else { @@ -1537,7 +1537,7 @@ bool ParChecker::SmartCalcFileRangeCrc(DiskFile& file, int64 start, int64 end, S if (segment.GetOffset() >= start && segment.GetOffset() + segment.GetSize() <= end) { - downloadCrc = !started ? segment.GetCrc() : Util::Crc32Combine(downloadCrc, segment.GetCrc(), (uint32)segment.GetSize()); + downloadCrc = !started ? segment.GetCrc() : Crc32::Combine(downloadCrc, segment.GetCrc(), (uint32)segment.GetSize()); started = true; } @@ -1555,7 +1555,7 @@ bool ParChecker::SmartCalcFileRangeCrc(DiskFile& file, int64 start, int64 end, S return false; } - downloadCrc = Util::Crc32Combine(downloadCrc, (uint32)partialCrc, (uint32)(end - segment.GetOffset() + 1)); + downloadCrc = Crc32::Combine(downloadCrc, (uint32)partialCrc, (uint32)(end - segment.GetOffset() + 1)); break; } @@ -1576,20 +1576,18 @@ bool ParChecker::DumbCalcFileRangeCrc(DiskFile& file, int64 start, int64 end, ui } CharBuffer buffer(1024 * 64); - uint32 downloadCrc = 0xFFFFFFFF; + Crc32 downloadCrc; int cnt = buffer.Size(); while (cnt == buffer.Size() && start < end) { int needBytes = end - start + 1 > buffer.Size() ? buffer.Size() : (int)(end - start + 1); cnt = (int)file.Read(buffer, needBytes); - downloadCrc = Util::Crc32m(downloadCrc, (uchar*)(char*)buffer, cnt); + downloadCrc.Append((uchar*)(char*)buffer, cnt); start += cnt; } - downloadCrc ^= 0xFFFFFFFF; - - *downloadCrcOut = downloadCrc; + *downloadCrcOut = downloadCrc.Finish(); return true; } diff --git a/daemon/util/Util.cpp b/daemon/util/Util.cpp index 7e375076..4d580da9 100644 --- a/daemon/util/Util.cpp +++ b/daemon/util/Util.cpp @@ -1,7 +1,7 @@ /* * This file is part of nzbget. See . * - * Copyright (C) 2007-2016 Andrey Prygunkov + * Copyright (C) 2007-2017 Andrey Prygunkov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -20,6 +20,7 @@ #include "nzbget.h" #include "Util.h" +#include "YEncode.h" #ifndef WIN32 // function "code_revision" is automatically generated in file "code_revision.cpp" on each build @@ -650,268 +651,6 @@ void Util::SetStandByMode(bool standBy) #endif } -// Crc32 implementation: -// http://www.intel.com/technology/comms/perfnet/download/CRC_generators.pdf -// http://sourceforge.net/projects/slicing-by-8/ - -static uint32 crc32_tab[4][256] = -{ - { - 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3, - 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, - 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, - 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5, - 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, - 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, - 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F, - 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, - 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433, - 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01, - 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, - 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, - 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, - 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, - 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F, - 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD, - 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, - 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, - 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7, - 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, - 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, - 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79, - 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, - 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, - 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713, - 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, - 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, - 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45, - 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, - 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9, - 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF, - 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D, - }, - { - 0x00000000, 0x191B3141, 0x32366282, 0x2B2D53C3, 0x646CC504, 0x7D77F445, 0x565AA786, 0x4F4196C7, - 0xC8D98A08, 0xD1C2BB49, 0xFAEFE88A, 0xE3F4D9CB, 0xACB54F0C, 0xB5AE7E4D, 0x9E832D8E, 0x87981CCF, - 0x4AC21251, 0x53D92310, 0x78F470D3, 0x61EF4192, 0x2EAED755, 0x37B5E614, 0x1C98B5D7, 0x05838496, - 0x821B9859, 0x9B00A918, 0xB02DFADB, 0xA936CB9A, 0xE6775D5D, 0xFF6C6C1C, 0xD4413FDF, 0xCD5A0E9E, - 0x958424A2, 0x8C9F15E3, 0xA7B24620, 0xBEA97761, 0xF1E8E1A6, 0xE8F3D0E7, 0xC3DE8324, 0xDAC5B265, - 0x5D5DAEAA, 0x44469FEB, 0x6F6BCC28, 0x7670FD69, 0x39316BAE, 0x202A5AEF, 0x0B07092C, 0x121C386D, - 0xDF4636F3, 0xC65D07B2, 0xED705471, 0xF46B6530, 0xBB2AF3F7, 0xA231C2B6, 0x891C9175, 0x9007A034, - 0x179FBCFB, 0x0E848DBA, 0x25A9DE79, 0x3CB2EF38, 0x73F379FF, 0x6AE848BE, 0x41C51B7D, 0x58DE2A3C, - 0xF0794F05, 0xE9627E44, 0xC24F2D87, 0xDB541CC6, 0x94158A01, 0x8D0EBB40, 0xA623E883, 0xBF38D9C2, - 0x38A0C50D, 0x21BBF44C, 0x0A96A78F, 0x138D96CE, 0x5CCC0009, 0x45D73148, 0x6EFA628B, 0x77E153CA, - 0xBABB5D54, 0xA3A06C15, 0x888D3FD6, 0x91960E97, 0xDED79850, 0xC7CCA911, 0xECE1FAD2, 0xF5FACB93, - 0x7262D75C, 0x6B79E61D, 0x4054B5DE, 0x594F849F, 0x160E1258, 0x0F152319, 0x243870DA, 0x3D23419B, - 0x65FD6BA7, 0x7CE65AE6, 0x57CB0925, 0x4ED03864, 0x0191AEA3, 0x188A9FE2, 0x33A7CC21, 0x2ABCFD60, - 0xAD24E1AF, 0xB43FD0EE, 0x9F12832D, 0x8609B26C, 0xC94824AB, 0xD05315EA, 0xFB7E4629, 0xE2657768, - 0x2F3F79F6, 0x362448B7, 0x1D091B74, 0x04122A35, 0x4B53BCF2, 0x52488DB3, 0x7965DE70, 0x607EEF31, - 0xE7E6F3FE, 0xFEFDC2BF, 0xD5D0917C, 0xCCCBA03D, 0x838A36FA, 0x9A9107BB, 0xB1BC5478, 0xA8A76539, - 0x3B83984B, 0x2298A90A, 0x09B5FAC9, 0x10AECB88, 0x5FEF5D4F, 0x46F46C0E, 0x6DD93FCD, 0x74C20E8C, - 0xF35A1243, 0xEA412302, 0xC16C70C1, 0xD8774180, 0x9736D747, 0x8E2DE606, 0xA500B5C5, 0xBC1B8484, - 0x71418A1A, 0x685ABB5B, 0x4377E898, 0x5A6CD9D9, 0x152D4F1E, 0x0C367E5F, 0x271B2D9C, 0x3E001CDD, - 0xB9980012, 0xA0833153, 0x8BAE6290, 0x92B553D1, 0xDDF4C516, 0xC4EFF457, 0xEFC2A794, 0xF6D996D5, - 0xAE07BCE9, 0xB71C8DA8, 0x9C31DE6B, 0x852AEF2A, 0xCA6B79ED, 0xD37048AC, 0xF85D1B6F, 0xE1462A2E, - 0x66DE36E1, 0x7FC507A0, 0x54E85463, 0x4DF36522, 0x02B2F3E5, 0x1BA9C2A4, 0x30849167, 0x299FA026, - 0xE4C5AEB8, 0xFDDE9FF9, 0xD6F3CC3A, 0xCFE8FD7B, 0x80A96BBC, 0x99B25AFD, 0xB29F093E, 0xAB84387F, - 0x2C1C24B0, 0x350715F1, 0x1E2A4632, 0x07317773, 0x4870E1B4, 0x516BD0F5, 0x7A468336, 0x635DB277, - 0xCBFAD74E, 0xD2E1E60F, 0xF9CCB5CC, 0xE0D7848D, 0xAF96124A, 0xB68D230B, 0x9DA070C8, 0x84BB4189, - 0x03235D46, 0x1A386C07, 0x31153FC4, 0x280E0E85, 0x674F9842, 0x7E54A903, 0x5579FAC0, 0x4C62CB81, - 0x8138C51F, 0x9823F45E, 0xB30EA79D, 0xAA1596DC, 0xE554001B, 0xFC4F315A, 0xD7626299, 0xCE7953D8, - 0x49E14F17, 0x50FA7E56, 0x7BD72D95, 0x62CC1CD4, 0x2D8D8A13, 0x3496BB52, 0x1FBBE891, 0x06A0D9D0, - 0x5E7EF3EC, 0x4765C2AD, 0x6C48916E, 0x7553A02F, 0x3A1236E8, 0x230907A9, 0x0824546A, 0x113F652B, - 0x96A779E4, 0x8FBC48A5, 0xA4911B66, 0xBD8A2A27, 0xF2CBBCE0, 0xEBD08DA1, 0xC0FDDE62, 0xD9E6EF23, - 0x14BCE1BD, 0x0DA7D0FC, 0x268A833F, 0x3F91B27E, 0x70D024B9, 0x69CB15F8, 0x42E6463B, 0x5BFD777A, - 0xDC656BB5, 0xC57E5AF4, 0xEE530937, 0xF7483876, 0xB809AEB1, 0xA1129FF0, 0x8A3FCC33, 0x9324FD72, - }, - { - 0x00000000, 0x01C26A37, 0x0384D46E, 0x0246BE59, 0x0709A8DC, 0x06CBC2EB, 0x048D7CB2, 0x054F1685, - 0x0E1351B8, 0x0FD13B8F, 0x0D9785D6, 0x0C55EFE1, 0x091AF964, 0x08D89353, 0x0A9E2D0A, 0x0B5C473D, - 0x1C26A370, 0x1DE4C947, 0x1FA2771E, 0x1E601D29, 0x1B2F0BAC, 0x1AED619B, 0x18ABDFC2, 0x1969B5F5, - 0x1235F2C8, 0x13F798FF, 0x11B126A6, 0x10734C91, 0x153C5A14, 0x14FE3023, 0x16B88E7A, 0x177AE44D, - 0x384D46E0, 0x398F2CD7, 0x3BC9928E, 0x3A0BF8B9, 0x3F44EE3C, 0x3E86840B, 0x3CC03A52, 0x3D025065, - 0x365E1758, 0x379C7D6F, 0x35DAC336, 0x3418A901, 0x3157BF84, 0x3095D5B3, 0x32D36BEA, 0x331101DD, - 0x246BE590, 0x25A98FA7, 0x27EF31FE, 0x262D5BC9, 0x23624D4C, 0x22A0277B, 0x20E69922, 0x2124F315, - 0x2A78B428, 0x2BBADE1F, 0x29FC6046, 0x283E0A71, 0x2D711CF4, 0x2CB376C3, 0x2EF5C89A, 0x2F37A2AD, - 0x709A8DC0, 0x7158E7F7, 0x731E59AE, 0x72DC3399, 0x7793251C, 0x76514F2B, 0x7417F172, 0x75D59B45, - 0x7E89DC78, 0x7F4BB64F, 0x7D0D0816, 0x7CCF6221, 0x798074A4, 0x78421E93, 0x7A04A0CA, 0x7BC6CAFD, - 0x6CBC2EB0, 0x6D7E4487, 0x6F38FADE, 0x6EFA90E9, 0x6BB5866C, 0x6A77EC5B, 0x68315202, 0x69F33835, - 0x62AF7F08, 0x636D153F, 0x612BAB66, 0x60E9C151, 0x65A6D7D4, 0x6464BDE3, 0x662203BA, 0x67E0698D, - 0x48D7CB20, 0x4915A117, 0x4B531F4E, 0x4A917579, 0x4FDE63FC, 0x4E1C09CB, 0x4C5AB792, 0x4D98DDA5, - 0x46C49A98, 0x4706F0AF, 0x45404EF6, 0x448224C1, 0x41CD3244, 0x400F5873, 0x4249E62A, 0x438B8C1D, - 0x54F16850, 0x55330267, 0x5775BC3E, 0x56B7D609, 0x53F8C08C, 0x523AAABB, 0x507C14E2, 0x51BE7ED5, - 0x5AE239E8, 0x5B2053DF, 0x5966ED86, 0x58A487B1, 0x5DEB9134, 0x5C29FB03, 0x5E6F455A, 0x5FAD2F6D, - 0xE1351B80, 0xE0F771B7, 0xE2B1CFEE, 0xE373A5D9, 0xE63CB35C, 0xE7FED96B, 0xE5B86732, 0xE47A0D05, - 0xEF264A38, 0xEEE4200F, 0xECA29E56, 0xED60F461, 0xE82FE2E4, 0xE9ED88D3, 0xEBAB368A, 0xEA695CBD, - 0xFD13B8F0, 0xFCD1D2C7, 0xFE976C9E, 0xFF5506A9, 0xFA1A102C, 0xFBD87A1B, 0xF99EC442, 0xF85CAE75, - 0xF300E948, 0xF2C2837F, 0xF0843D26, 0xF1465711, 0xF4094194, 0xF5CB2BA3, 0xF78D95FA, 0xF64FFFCD, - 0xD9785D60, 0xD8BA3757, 0xDAFC890E, 0xDB3EE339, 0xDE71F5BC, 0xDFB39F8B, 0xDDF521D2, 0xDC374BE5, - 0xD76B0CD8, 0xD6A966EF, 0xD4EFD8B6, 0xD52DB281, 0xD062A404, 0xD1A0CE33, 0xD3E6706A, 0xD2241A5D, - 0xC55EFE10, 0xC49C9427, 0xC6DA2A7E, 0xC7184049, 0xC25756CC, 0xC3953CFB, 0xC1D382A2, 0xC011E895, - 0xCB4DAFA8, 0xCA8FC59F, 0xC8C97BC6, 0xC90B11F1, 0xCC440774, 0xCD866D43, 0xCFC0D31A, 0xCE02B92D, - 0x91AF9640, 0x906DFC77, 0x922B422E, 0x93E92819, 0x96A63E9C, 0x976454AB, 0x9522EAF2, 0x94E080C5, - 0x9FBCC7F8, 0x9E7EADCF, 0x9C381396, 0x9DFA79A1, 0x98B56F24, 0x99770513, 0x9B31BB4A, 0x9AF3D17D, - 0x8D893530, 0x8C4B5F07, 0x8E0DE15E, 0x8FCF8B69, 0x8A809DEC, 0x8B42F7DB, 0x89044982, 0x88C623B5, - 0x839A6488, 0x82580EBF, 0x801EB0E6, 0x81DCDAD1, 0x8493CC54, 0x8551A663, 0x8717183A, 0x86D5720D, - 0xA9E2D0A0, 0xA820BA97, 0xAA6604CE, 0xABA46EF9, 0xAEEB787C, 0xAF29124B, 0xAD6FAC12, 0xACADC625, - 0xA7F18118, 0xA633EB2F, 0xA4755576, 0xA5B73F41, 0xA0F829C4, 0xA13A43F3, 0xA37CFDAA, 0xA2BE979D, - 0xB5C473D0, 0xB40619E7, 0xB640A7BE, 0xB782CD89, 0xB2CDDB0C, 0xB30FB13B, 0xB1490F62, 0xB08B6555, - 0xBBD72268, 0xBA15485F, 0xB853F606, 0xB9919C31, 0xBCDE8AB4, 0xBD1CE083, 0xBF5A5EDA, 0xBE9834ED, - }, - { - 0x00000000, 0xB8BC6765, 0xAA09C88B, 0x12B5AFEE, 0x8F629757, 0x37DEF032, 0x256B5FDC, 0x9DD738B9, - 0xC5B428EF, 0x7D084F8A, 0x6FBDE064, 0xD7018701, 0x4AD6BFB8, 0xF26AD8DD, 0xE0DF7733, 0x58631056, - 0x5019579F, 0xE8A530FA, 0xFA109F14, 0x42ACF871, 0xDF7BC0C8, 0x67C7A7AD, 0x75720843, 0xCDCE6F26, - 0x95AD7F70, 0x2D111815, 0x3FA4B7FB, 0x8718D09E, 0x1ACFE827, 0xA2738F42, 0xB0C620AC, 0x087A47C9, - 0xA032AF3E, 0x188EC85B, 0x0A3B67B5, 0xB28700D0, 0x2F503869, 0x97EC5F0C, 0x8559F0E2, 0x3DE59787, - 0x658687D1, 0xDD3AE0B4, 0xCF8F4F5A, 0x7733283F, 0xEAE41086, 0x525877E3, 0x40EDD80D, 0xF851BF68, - 0xF02BF8A1, 0x48979FC4, 0x5A22302A, 0xE29E574F, 0x7F496FF6, 0xC7F50893, 0xD540A77D, 0x6DFCC018, - 0x359FD04E, 0x8D23B72B, 0x9F9618C5, 0x272A7FA0, 0xBAFD4719, 0x0241207C, 0x10F48F92, 0xA848E8F7, - 0x9B14583D, 0x23A83F58, 0x311D90B6, 0x89A1F7D3, 0x1476CF6A, 0xACCAA80F, 0xBE7F07E1, 0x06C36084, - 0x5EA070D2, 0xE61C17B7, 0xF4A9B859, 0x4C15DF3C, 0xD1C2E785, 0x697E80E0, 0x7BCB2F0E, 0xC377486B, - 0xCB0D0FA2, 0x73B168C7, 0x6104C729, 0xD9B8A04C, 0x446F98F5, 0xFCD3FF90, 0xEE66507E, 0x56DA371B, - 0x0EB9274D, 0xB6054028, 0xA4B0EFC6, 0x1C0C88A3, 0x81DBB01A, 0x3967D77F, 0x2BD27891, 0x936E1FF4, - 0x3B26F703, 0x839A9066, 0x912F3F88, 0x299358ED, 0xB4446054, 0x0CF80731, 0x1E4DA8DF, 0xA6F1CFBA, - 0xFE92DFEC, 0x462EB889, 0x549B1767, 0xEC277002, 0x71F048BB, 0xC94C2FDE, 0xDBF98030, 0x6345E755, - 0x6B3FA09C, 0xD383C7F9, 0xC1366817, 0x798A0F72, 0xE45D37CB, 0x5CE150AE, 0x4E54FF40, 0xF6E89825, - 0xAE8B8873, 0x1637EF16, 0x048240F8, 0xBC3E279D, 0x21E91F24, 0x99557841, 0x8BE0D7AF, 0x335CB0CA, - 0xED59B63B, 0x55E5D15E, 0x47507EB0, 0xFFEC19D5, 0x623B216C, 0xDA874609, 0xC832E9E7, 0x708E8E82, - 0x28ED9ED4, 0x9051F9B1, 0x82E4565F, 0x3A58313A, 0xA78F0983, 0x1F336EE6, 0x0D86C108, 0xB53AA66D, - 0xBD40E1A4, 0x05FC86C1, 0x1749292F, 0xAFF54E4A, 0x322276F3, 0x8A9E1196, 0x982BBE78, 0x2097D91D, - 0x78F4C94B, 0xC048AE2E, 0xD2FD01C0, 0x6A4166A5, 0xF7965E1C, 0x4F2A3979, 0x5D9F9697, 0xE523F1F2, - 0x4D6B1905, 0xF5D77E60, 0xE762D18E, 0x5FDEB6EB, 0xC2098E52, 0x7AB5E937, 0x680046D9, 0xD0BC21BC, - 0x88DF31EA, 0x3063568F, 0x22D6F961, 0x9A6A9E04, 0x07BDA6BD, 0xBF01C1D8, 0xADB46E36, 0x15080953, - 0x1D724E9A, 0xA5CE29FF, 0xB77B8611, 0x0FC7E174, 0x9210D9CD, 0x2AACBEA8, 0x38191146, 0x80A57623, - 0xD8C66675, 0x607A0110, 0x72CFAEFE, 0xCA73C99B, 0x57A4F122, 0xEF189647, 0xFDAD39A9, 0x45115ECC, - 0x764DEE06, 0xCEF18963, 0xDC44268D, 0x64F841E8, 0xF92F7951, 0x41931E34, 0x5326B1DA, 0xEB9AD6BF, - 0xB3F9C6E9, 0x0B45A18C, 0x19F00E62, 0xA14C6907, 0x3C9B51BE, 0x842736DB, 0x96929935, 0x2E2EFE50, - 0x2654B999, 0x9EE8DEFC, 0x8C5D7112, 0x34E11677, 0xA9362ECE, 0x118A49AB, 0x033FE645, 0xBB838120, - 0xE3E09176, 0x5B5CF613, 0x49E959FD, 0xF1553E98, 0x6C820621, 0xD43E6144, 0xC68BCEAA, 0x7E37A9CF, - 0xD67F4138, 0x6EC3265D, 0x7C7689B3, 0xC4CAEED6, 0x591DD66F, 0xE1A1B10A, 0xF3141EE4, 0x4BA87981, - 0x13CB69D7, 0xAB770EB2, 0xB9C2A15C, 0x017EC639, 0x9CA9FE80, 0x241599E5, 0x36A0360B, 0x8E1C516E, - 0x866616A7, 0x3EDA71C2, 0x2C6FDE2C, 0x94D3B949, 0x090481F0, 0xB1B8E695, 0xA30D497B, 0x1BB12E1E, - 0x43D23E48, 0xFB6E592D, 0xE9DBF6C3, 0x516791A6, 0xCCB0A91F, 0x740CCE7A, 0x66B96194, 0xDE0506F1, - } -}; - -// compute CRC32 (Slicing-by-4 algorithm) -uint32 Util::Crc32m(uint32 startCrc, uchar* block, uint32 length) -{ - uint32 crc = startCrc; - -#if __BYTE_ORDER == __LITTLE_ENDIAN - const uint32* current = (const uint32*)block; - - // process four bytes at once (Slicing-by-4) - while (length >= 4) - { - uint32 one = *current++ ^ crc; - crc = crc32_tab[0][(one >> 24) & 0xFF] ^ - crc32_tab[1][(one >> 16) & 0xFF] ^ - crc32_tab[2][(one >> 8) & 0xFF] ^ - crc32_tab[3][one & 0xFF]; - - length -= 4; - } - - // remaining 1 to 3 bytes (standard algorithm) - block = (uchar*)current; -#endif - - while (length-- != 0) - { - crc = ((crc >> 8) & 0x00FFFFFF) ^ crc32_tab[0][(crc ^ *block++) & 0xFF]; - } - - return crc; -} - -uint32 Util::Crc32(uchar *block, uint32 length) -{ - return Util::Crc32m(0xFFFFFFFF, block, length) ^ 0xFFFFFFFF; -} - -/* From zlib/crc32.c (http://www.zlib.net/) - * Copyright (C) 1995-2006, 2010, 2011, 2012 Mark Adler - */ - -#define GF2_DIM 32 /* dimension of GF(2) vectors (length of CRC) */ - -uint32 gf2_matrix_times(uint32 *mat, uint32 vec) -{ - uint32 sum; - - sum = 0; - while (vec) { - if (vec & 1) - sum ^= *mat; - vec >>= 1; - mat++; - } - return sum; -} - -void gf2_matrix_square(uint32 *square, uint32 *mat) -{ - int n; - - for (n = 0; n < GF2_DIM; n++) - square[n] = gf2_matrix_times(mat, mat[n]); -} - -uint32 Util::Crc32Combine(uint32 crc1, uint32 crc2, uint32 len2) -{ - int n; - uint32 row; - uint32 even[GF2_DIM]; /* even-power-of-two zeros operator */ - uint32 odd[GF2_DIM]; /* odd-power-of-two zeros operator */ - - /* degenerate case (also disallow negative lengths) */ - if (len2 <= 0) - return crc1; - - /* put operator for one zero bit in odd */ - odd[0] = 0xedb88320UL; /* CRC-32 polynomial */ - row = 1; - for (n = 1; n < GF2_DIM; n++) { - odd[n] = row; - row <<= 1; - } - - /* put operator for two zero bits in even */ - gf2_matrix_square(even, odd); - - /* put operator for four zero bits in odd */ - gf2_matrix_square(odd, even); - - /* apply len2 zeros to crc1 (first square will put the operator for one - zero byte, eight zero bits, in even) */ - do { - /* apply zeros operator for this bit of len2 */ - gf2_matrix_square(even, odd); - if (len2 & 1) - crc1 = gf2_matrix_times(even, crc1); - len2 >>= 1; - - /* if no more bits set, then done */ - if (len2 == 0) - break; - - /* another iteration of the loop with odd and even swapped */ - gf2_matrix_square(odd, even); - if (len2 & 1) - crc1 = gf2_matrix_times(odd, crc1); - len2 >>= 1; - - /* if no more bits set, then done */ - } while (len2 != 0); - - /* return combined crc */ - crc1 ^= crc2; - - return crc1; -} - int Util::NumberOfCpuCores() { #ifdef WIN32 @@ -2097,3 +1836,101 @@ char* Tokenizer::Next() } return token; } + +void Crc32::Reset() +{ + static_assert(sizeof(m_state) >= sizeof(YEncode::crc_state), "m_state has invalid size"); + + YEncode::crc_init((YEncode::crc_state*)&m_state); +} + +void Crc32::Append(uchar* block, uint32 length) +{ + YEncode::crc_incr((YEncode::crc_state*)&m_state, block, length); +} + +uint32 Crc32::Finish() +{ + return YEncode::crc_finish((YEncode::crc_state*)&m_state); +} + +/* From zlib/crc32.c (http://www.zlib.net/) + * Copyright (C) 1995-2006, 2010, 2011, 2012 Mark Adler + */ + +#define GF2_DIM 32 /* dimension of GF(2) vectors (length of CRC) */ + +uint32 gf2_matrix_times(uint32 *mat, uint32 vec) +{ + uint32 sum; + + sum = 0; + while (vec) { + if (vec & 1) + sum ^= *mat; + vec >>= 1; + mat++; + } + return sum; +} + +void gf2_matrix_square(uint32 *square, uint32 *mat) +{ + int n; + + for (n = 0; n < GF2_DIM; n++) + square[n] = gf2_matrix_times(mat, mat[n]); +} + +uint32 Crc32::Combine(uint32 crc1, uint32 crc2, uint32 len2) +{ + int n; + uint32 row; + uint32 even[GF2_DIM]; /* even-power-of-two zeros operator */ + uint32 odd[GF2_DIM]; /* odd-power-of-two zeros operator */ + + /* degenerate case (also disallow negative lengths) */ + if (len2 <= 0) + return crc1; + + /* put operator for one zero bit in odd */ + odd[0] = 0xedb88320UL; /* CRC-32 polynomial */ + row = 1; + for (n = 1; n < GF2_DIM; n++) { + odd[n] = row; + row <<= 1; + } + + /* put operator for two zero bits in even */ + gf2_matrix_square(even, odd); + + /* put operator for four zero bits in odd */ + gf2_matrix_square(odd, even); + + /* apply len2 zeros to crc1 (first square will put the operator for one + zero byte, eight zero bits, in even) */ + do { + /* apply zeros operator for this bit of len2 */ + gf2_matrix_square(even, odd); + if (len2 & 1) + crc1 = gf2_matrix_times(even, crc1); + len2 >>= 1; + + /* if no more bits set, then done */ + if (len2 == 0) + break; + + /* another iteration of the loop with odd and even swapped */ + gf2_matrix_square(odd, even); + if (len2 & 1) + crc1 = gf2_matrix_times(odd, crc1); + len2 >>= 1; + + /* if no more bits set, then done */ + } while (len2 != 0); + + /* return combined crc */ + crc1 ^= crc2; + + return crc1; +} diff --git a/daemon/util/Util.h b/daemon/util/Util.h index 7af16d26..86c09a08 100644 --- a/daemon/util/Util.h +++ b/daemon/util/Util.h @@ -86,10 +86,6 @@ public: static void Init(); - static uint32 Crc32(uchar *block, uint32 length); - static uint32 Crc32m(uint32 startCrc, uchar *block, uint32 length); - static uint32 Crc32Combine(uint32 crc1, uint32 crc2, uint32 len2); - /* * Returns number of available CPU cores or -1 if it could not be determined */ @@ -317,4 +313,17 @@ private: bool m_working = false; }; +class Crc32 +{ +public: + Crc32() { Reset(); } + void Reset(); + void Append(uchar* block, uint32 length); + uint32 Finish(); + static uint32 Combine(uint32 crc1, uint32 crc2, uint32 len2); + +private: + alignas(16) uint32_t m_state[4 * 5]; // = YEncode::crc_state +}; + #endif diff --git a/lib/yencode/ArmCrc.cpp b/lib/yencode/AcleCrc.cpp similarity index 78% rename from lib/yencode/ArmCrc.cpp rename to lib/yencode/AcleCrc.cpp index 85a8a973..192a2163 100644 --- a/lib/yencode/ArmCrc.cpp +++ b/lib/yencode/AcleCrc.cpp @@ -20,6 +20,8 @@ #include "nzbget.h" +#include "YEncode.h" + #ifdef __ARM_FEATURE_CRC32 #include #endif @@ -28,7 +30,14 @@ namespace YEncode { #ifdef __ARM_FEATURE_CRC32 -inline uint32_t crc_arm(uint32_t crc, const unsigned char *src, long len) { +void crc_arm_init(crc_state *const s) +{ + s->crc0[0] = ~0; +} + +void crc_arm(crc_state *const s, const unsigned char *src, long len) { + uint32_t crc = s->crc0[0]; + // initial alignment if (len >= 16) { // 16 is an arbitrary number; it just needs to be >=8 if ((uintptr_t)src & sizeof(uint8_t)) { @@ -71,23 +80,25 @@ inline uint32_t crc_arm(uint32_t crc, const unsigned char *src, long len) { if (len & sizeof(uint8_t)) crc = __crc32b(crc, *src); - return crc; + s->crc0[0] = crc; } -uint32_t do_crc32_arm(const unsigned char *src, long len) +uint32_t crc_arm_finish(crc_state *const s) { - return ~crc_arm(~0, src, len); + return ~s->crc0[0]; } -extern uint32_t (*crc32_arm)(const unsigned char *src, long len); -extern uint32_t (*inc_crc32_simd)(uint32_t crc, const unsigned char* src, long len); +extern void (*crc_init_acle)(crc_state *const s); +extern void (*crc_incr_acle)(crc_state *const s, const unsigned char *src, long len); +extern uint32_t (*crc_finish_acle)(crc_state *const s); #endif -void init_crc32_arm() +void init_crc_acle() { #ifdef __ARM_FEATURE_CRC32 - crc32_arm = &do_crc32_arm; - inc_crc32_simd = &crc_arm; + crc_init_acle = &crc_arm_init; + crc_incr_acle = &crc_arm; + crc_finish_acle = &crc_arm_finish; #endif } diff --git a/lib/yencode/PclmulCrc.cpp b/lib/yencode/PclmulCrc.cpp index 7080fa62..39d40954 100644 --- a/lib/yencode/PclmulCrc.cpp +++ b/lib/yencode/PclmulCrc.cpp @@ -45,6 +45,11 @@ namespace YEncode { #ifdef __PCLMUL__ +struct crc_state +{ + alignas(16) unsigned crc0[4 * 5]; +}; + void fold_1(__m128i *xmm_crc0, __m128i *xmm_crc1, __m128i *xmm_crc2, __m128i *xmm_crc3) { const __m128i xmm_fold4 = _mm_set_epi32( 0x00000001, 0x54442bd4, @@ -263,181 +268,209 @@ alignas(16) const unsigned crc_mask2[4] = { 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF }; -inline uint32_t crc_fold(const unsigned char *src, long len) { - unsigned long algn_diff; - __m128i xmm_t0, xmm_t1, xmm_t2, xmm_t3; +#define CRC_LOAD(s) \ + do { \ + __m128i xmm_crc0 = _mm_loadu_si128((__m128i *)s->crc0 + 0);\ + __m128i xmm_crc1 = _mm_loadu_si128((__m128i *)s->crc0 + 1);\ + __m128i xmm_crc2 = _mm_loadu_si128((__m128i *)s->crc0 + 2);\ + __m128i xmm_crc3 = _mm_loadu_si128((__m128i *)s->crc0 + 3);\ + __m128i xmm_crc_part = _mm_loadu_si128((__m128i *)s->crc0 + 4); - __m128i xmm_crc0 = _mm_cvtsi32_si128(0x9db42487); - __m128i xmm_crc1 = _mm_setzero_si128(); - __m128i xmm_crc2 = _mm_setzero_si128(); - __m128i xmm_crc3 = _mm_setzero_si128(); - __m128i xmm_crc_part; +#define CRC_SAVE(s) \ + _mm_storeu_si128((__m128i *)s->crc0 + 0, xmm_crc0);\ + _mm_storeu_si128((__m128i *)s->crc0 + 1, xmm_crc1);\ + _mm_storeu_si128((__m128i *)s->crc0 + 2, xmm_crc2);\ + _mm_storeu_si128((__m128i *)s->crc0 + 3, xmm_crc3);\ + _mm_storeu_si128((__m128i *)s->crc0 + 4, xmm_crc_part);\ + } while (0); - if (len < 16) { - if (len == 0) - return 0; - xmm_crc_part = _mm_loadu_si128((__m128i *)src); - goto partial; - } +void crc_fold_init(crc_state *const s) { + CRC_LOAD(s) - algn_diff = (0 - (uintptr_t)src) & 0xF; - if (algn_diff) { - xmm_crc_part = _mm_loadu_si128((__m128i *)src); + xmm_crc0 = _mm_cvtsi32_si128(0x9db42487); + xmm_crc1 = _mm_setzero_si128(); + xmm_crc2 = _mm_setzero_si128(); + xmm_crc3 = _mm_setzero_si128(); - src += algn_diff; - len -= algn_diff; + CRC_SAVE(s) +} - partial_fold(algn_diff, &xmm_crc0, &xmm_crc1, &xmm_crc2, &xmm_crc3, - &xmm_crc_part); - } +void crc_fold(crc_state *const s, const unsigned char *src, long len) { + unsigned long algn_diff; + __m128i xmm_t0, xmm_t1, xmm_t2, xmm_t3; - while ((len -= 64) >= 0) { - xmm_t0 = _mm_load_si128((__m128i *)src); - xmm_t1 = _mm_load_si128((__m128i *)src + 1); - xmm_t2 = _mm_load_si128((__m128i *)src + 2); - xmm_t3 = _mm_load_si128((__m128i *)src + 3); + CRC_LOAD(s) - fold_4(&xmm_crc0, &xmm_crc1, &xmm_crc2, &xmm_crc3); + if (len < 16) { + if (len == 0) + return; + xmm_crc_part = _mm_loadu_si128((__m128i *)src); + goto partial; + } - xmm_crc0 = _mm_xor_si128(xmm_crc0, xmm_t0); - xmm_crc1 = _mm_xor_si128(xmm_crc1, xmm_t1); - xmm_crc2 = _mm_xor_si128(xmm_crc2, xmm_t2); - xmm_crc3 = _mm_xor_si128(xmm_crc3, xmm_t3); + algn_diff = (0 - (uintptr_t)src) & 0xF; + if (algn_diff) { + xmm_crc_part = _mm_loadu_si128((__m128i *)src); + src += algn_diff; + len -= algn_diff; - src += 64; - } + partial_fold(algn_diff, &xmm_crc0, &xmm_crc1, &xmm_crc2, &xmm_crc3, &xmm_crc_part); + } - /* - * len = num bytes left - 64 - */ - if (len + 16 >= 0) { - len += 16; + while ((len -= 64) >= 0) { + xmm_t0 = _mm_load_si128((__m128i *)src); + xmm_t1 = _mm_load_si128((__m128i *)src + 1); + xmm_t2 = _mm_load_si128((__m128i *)src + 2); + xmm_t3 = _mm_load_si128((__m128i *)src + 3); - xmm_t0 = _mm_load_si128((__m128i *)src); - xmm_t1 = _mm_load_si128((__m128i *)src + 1); - xmm_t2 = _mm_load_si128((__m128i *)src + 2); + fold_4(&xmm_crc0, &xmm_crc1, &xmm_crc2, &xmm_crc3); - fold_3(&xmm_crc0, &xmm_crc1, &xmm_crc2, &xmm_crc3); + xmm_crc0 = _mm_xor_si128(xmm_crc0, xmm_t0); + xmm_crc1 = _mm_xor_si128(xmm_crc1, xmm_t1); + xmm_crc2 = _mm_xor_si128(xmm_crc2, xmm_t2); + xmm_crc3 = _mm_xor_si128(xmm_crc3, xmm_t3); - xmm_crc1 = _mm_xor_si128(xmm_crc1, xmm_t0); - xmm_crc2 = _mm_xor_si128(xmm_crc2, xmm_t1); - xmm_crc3 = _mm_xor_si128(xmm_crc3, xmm_t2); + src += 64; + } - if (len == 0) - goto done; + /* + * len = num bytes left - 64 + */ + if (len + 16 >= 0) { + len += 16; - xmm_crc_part = _mm_load_si128((__m128i *)src + 3); - } else if (len + 32 >= 0) { - len += 32; + xmm_t0 = _mm_load_si128((__m128i *)src); + xmm_t1 = _mm_load_si128((__m128i *)src + 1); + xmm_t2 = _mm_load_si128((__m128i *)src + 2); - xmm_t0 = _mm_load_si128((__m128i *)src); - xmm_t1 = _mm_load_si128((__m128i *)src + 1); + fold_3(&xmm_crc0, &xmm_crc1, &xmm_crc2, &xmm_crc3); - fold_2(&xmm_crc0, &xmm_crc1, &xmm_crc2, &xmm_crc3); + xmm_crc1 = _mm_xor_si128(xmm_crc1, xmm_t0); + xmm_crc2 = _mm_xor_si128(xmm_crc2, xmm_t1); + xmm_crc3 = _mm_xor_si128(xmm_crc3, xmm_t2); - xmm_crc2 = _mm_xor_si128(xmm_crc2, xmm_t0); - xmm_crc3 = _mm_xor_si128(xmm_crc3, xmm_t1); + if (len == 0) + goto done; - if (len == 0) - goto done; + xmm_crc_part = _mm_load_si128((__m128i *)src + 3); + } else if (len + 32 >= 0) { + len += 32; - xmm_crc_part = _mm_load_si128((__m128i *)src + 2); - } else if (len + 48 >= 0) { - len += 48; + xmm_t0 = _mm_load_si128((__m128i *)src); + xmm_t1 = _mm_load_si128((__m128i *)src + 1); - xmm_t0 = _mm_load_si128((__m128i *)src); + fold_2(&xmm_crc0, &xmm_crc1, &xmm_crc2, &xmm_crc3); - fold_1(&xmm_crc0, &xmm_crc1, &xmm_crc2, &xmm_crc3); + xmm_crc2 = _mm_xor_si128(xmm_crc2, xmm_t0); + xmm_crc3 = _mm_xor_si128(xmm_crc3, xmm_t1); - xmm_crc3 = _mm_xor_si128(xmm_crc3, xmm_t0); + if (len == 0) + goto done; - if (len == 0) - goto done; + xmm_crc_part = _mm_load_si128((__m128i *)src + 2); + } else if (len + 48 >= 0) { + len += 48; - xmm_crc_part = _mm_load_si128((__m128i *)src + 1); - } else { - len += 64; - if (len == 0) - goto done; - xmm_crc_part = _mm_load_si128((__m128i *)src); - } + xmm_t0 = _mm_load_si128((__m128i *)src); + + fold_1(&xmm_crc0, &xmm_crc1, &xmm_crc2, &xmm_crc3); + + xmm_crc3 = _mm_xor_si128(xmm_crc3, xmm_t0); + + if (len == 0) + goto done; + + xmm_crc_part = _mm_load_si128((__m128i *)src + 1); + } else { + len += 64; + if (len == 0) + goto done; + xmm_crc_part = _mm_load_si128((__m128i *)src); + } partial: - partial_fold(len, &xmm_crc0, &xmm_crc1, &xmm_crc2, &xmm_crc3, - &xmm_crc_part); + partial_fold(len, &xmm_crc0, &xmm_crc1, &xmm_crc2, &xmm_crc3, &xmm_crc_part); done: -{ - const __m128i xmm_mask = _mm_load_si128((__m128i *)crc_mask); - const __m128i xmm_mask2 = _mm_load_si128((__m128i *)crc_mask2); - - uint32_t crc; - __m128i x_tmp0, x_tmp1, x_tmp2, crc_fold; - - /* - * k1 - */ - crc_fold = _mm_load_si128((__m128i *)crc_k); - - x_tmp0 = _mm_clmulepi64_si128(xmm_crc0, crc_fold, 0x10); - xmm_crc0 = _mm_clmulepi64_si128(xmm_crc0, crc_fold, 0x01); - xmm_crc1 = _mm_xor_si128(xmm_crc1, x_tmp0); - xmm_crc1 = _mm_xor_si128(xmm_crc1, xmm_crc0); - - x_tmp1 = _mm_clmulepi64_si128(xmm_crc1, crc_fold, 0x10); - xmm_crc1 = _mm_clmulepi64_si128(xmm_crc1, crc_fold, 0x01); - xmm_crc2 = _mm_xor_si128(xmm_crc2, x_tmp1); - xmm_crc2 = _mm_xor_si128(xmm_crc2, xmm_crc1); - - x_tmp2 = _mm_clmulepi64_si128(xmm_crc2, crc_fold, 0x10); - xmm_crc2 = _mm_clmulepi64_si128(xmm_crc2, crc_fold, 0x01); - xmm_crc3 = _mm_xor_si128(xmm_crc3, x_tmp2); - xmm_crc3 = _mm_xor_si128(xmm_crc3, xmm_crc2); - - /* - * k5 - */ - crc_fold = _mm_load_si128((__m128i *)crc_k + 1); - - xmm_crc0 = xmm_crc3; - xmm_crc3 = _mm_clmulepi64_si128(xmm_crc3, crc_fold, 0); - xmm_crc0 = _mm_srli_si128(xmm_crc0, 8); - xmm_crc3 = _mm_xor_si128(xmm_crc3, xmm_crc0); - - xmm_crc0 = xmm_crc3; - xmm_crc3 = _mm_slli_si128(xmm_crc3, 4); - xmm_crc3 = _mm_clmulepi64_si128(xmm_crc3, crc_fold, 0x10); - xmm_crc3 = _mm_xor_si128(xmm_crc3, xmm_crc0); - xmm_crc3 = _mm_and_si128(xmm_crc3, xmm_mask2); - - /* - * k7 - */ - xmm_crc1 = xmm_crc3; - xmm_crc2 = xmm_crc3; - crc_fold = _mm_load_si128((__m128i *)crc_k + 2); - - xmm_crc3 = _mm_clmulepi64_si128(xmm_crc3, crc_fold, 0); - xmm_crc3 = _mm_xor_si128(xmm_crc3, xmm_crc2); - xmm_crc3 = _mm_and_si128(xmm_crc3, xmm_mask); - - xmm_crc2 = xmm_crc3; - xmm_crc3 = _mm_clmulepi64_si128(xmm_crc3, crc_fold, 0x10); - xmm_crc3 = _mm_xor_si128(xmm_crc3, xmm_crc2); - xmm_crc3 = _mm_xor_si128(xmm_crc3, xmm_crc1); - - crc = _mm_extract_epi32(xmm_crc3, 2); - return ~crc; + CRC_SAVE(s) } +uint32_t crc_fold_512to32(crc_state *const s) { + const __m128i xmm_mask = _mm_load_si128((__m128i *)crc_mask); + const __m128i xmm_mask2 = _mm_load_si128((__m128i *)crc_mask2); + + uint32_t crc; + __m128i x_tmp0, x_tmp1, x_tmp2, crc_fold; + + CRC_LOAD(s) + + /* + * k1 + */ + crc_fold = _mm_load_si128((__m128i *)crc_k); + + x_tmp0 = _mm_clmulepi64_si128(xmm_crc0, crc_fold, 0x10); + xmm_crc0 = _mm_clmulepi64_si128(xmm_crc0, crc_fold, 0x01); + xmm_crc1 = _mm_xor_si128(xmm_crc1, x_tmp0); + xmm_crc1 = _mm_xor_si128(xmm_crc1, xmm_crc0); + + x_tmp1 = _mm_clmulepi64_si128(xmm_crc1, crc_fold, 0x10); + xmm_crc1 = _mm_clmulepi64_si128(xmm_crc1, crc_fold, 0x01); + xmm_crc2 = _mm_xor_si128(xmm_crc2, x_tmp1); + xmm_crc2 = _mm_xor_si128(xmm_crc2, xmm_crc1); + + x_tmp2 = _mm_clmulepi64_si128(xmm_crc2, crc_fold, 0x10); + xmm_crc2 = _mm_clmulepi64_si128(xmm_crc2, crc_fold, 0x01); + xmm_crc3 = _mm_xor_si128(xmm_crc3, x_tmp2); + xmm_crc3 = _mm_xor_si128(xmm_crc3, xmm_crc2); + + /* + * k5 + */ + crc_fold = _mm_load_si128((__m128i *)crc_k + 1); + + xmm_crc0 = xmm_crc3; + xmm_crc3 = _mm_clmulepi64_si128(xmm_crc3, crc_fold, 0); + xmm_crc0 = _mm_srli_si128(xmm_crc0, 8); + xmm_crc3 = _mm_xor_si128(xmm_crc3, xmm_crc0); + + xmm_crc0 = xmm_crc3; + xmm_crc3 = _mm_slli_si128(xmm_crc3, 4); + xmm_crc3 = _mm_clmulepi64_si128(xmm_crc3, crc_fold, 0x10); + xmm_crc3 = _mm_xor_si128(xmm_crc3, xmm_crc0); + xmm_crc3 = _mm_and_si128(xmm_crc3, xmm_mask2); + + /* + * k7 + */ + xmm_crc1 = xmm_crc3; + xmm_crc2 = xmm_crc3; + crc_fold = _mm_load_si128((__m128i *)crc_k + 2); + + xmm_crc3 = _mm_clmulepi64_si128(xmm_crc3, crc_fold, 0); + xmm_crc3 = _mm_xor_si128(xmm_crc3, xmm_crc2); + xmm_crc3 = _mm_and_si128(xmm_crc3, xmm_mask); + + xmm_crc2 = xmm_crc3; + xmm_crc3 = _mm_clmulepi64_si128(xmm_crc3, crc_fold, 0x10); + xmm_crc3 = _mm_xor_si128(xmm_crc3, xmm_crc2); + xmm_crc3 = _mm_xor_si128(xmm_crc3, xmm_crc1); + + crc = _mm_extract_epi32(xmm_crc3, 2); + return ~crc; + CRC_SAVE(s) } -extern uint32_t (*crc32_pclmul)(const unsigned char *src, long len); +extern void (*crc_init_pclmul)(crc_state *const s); +extern void (*crc_incr_pclmul)(crc_state *const s, const unsigned char *src, long len); +extern uint32_t (*crc_finish_pclmul)(crc_state *const s); #endif -void init_crc32_pclmul() +void init_crc_pclmul() { #ifdef __PCLMUL__ - crc32_pclmul = &crc_fold; + crc_init_pclmul = &crc_fold_init; + crc_incr_pclmul = &crc_fold; + crc_finish_pclmul = &crc_fold_512to32; #endif } diff --git a/lib/yencode/SimdInit.cpp b/lib/yencode/SimdInit.cpp index a5309606..3d7c8140 100644 --- a/lib/yencode/SimdInit.cpp +++ b/lib/yencode/SimdInit.cpp @@ -32,17 +32,28 @@ namespace YEncode { size_t (*decode)(const unsigned char*, unsigned char*, size_t, char* state) = nullptr; -size_t (*decode_simd)(const unsigned char*, unsigned char*, size_t, char* state) = nullptr; -uint32_t (*crc32_simd)(const unsigned char* src, long len) = nullptr; -uint32_t (*inc_crc32_simd)(uint32_t crc, const unsigned char* src, long len) = nullptr; +bool decode_simd = false; + +void (*crc_init)(crc_state *const s) = nullptr; +void (*crc_incr)(crc_state *const s, const unsigned char *src, long len) = nullptr; +uint32_t (*crc_finish)(crc_state *const s) = nullptr; +bool crc_simd = false; + +void crc_slice_init(crc_state *const s); +void crc_slice(crc_state *const s, const unsigned char *src, long len); +uint32_t crc_slice_finish(crc_state *const s); #if defined(__i686__) || defined(__amd64__) size_t (*decode_sse2)(const unsigned char* src, unsigned char* dest, size_t len, char* state) = nullptr; extern void init_decode_sse2(); + size_t (*decode_ssse3)(const unsigned char* src, unsigned char* dest, size_t len, char* state) = nullptr; extern void init_decode_ssse3(); -uint32_t (*crc32_pclmul)(const unsigned char *src, long len) = nullptr; -extern void init_crc32_pclmul(); + +void (*crc_init_pclmul)(crc_state *const s) = nullptr; +void (*crc_incr_pclmul)(crc_state *const s, const unsigned char *src, long len) = nullptr; +uint32_t (*crc_finish_pclmul)(crc_state *const s) = nullptr; +extern void init_crc_pclmul(); class CpuId { @@ -66,13 +77,19 @@ public: #if defined(__arm__) || defined(__aarch64__) size_t (*decode_neon)(const unsigned char* src, unsigned char* dest, size_t len, char* state) = nullptr; extern void init_decode_neon(); -uint32_t (*crc32_arm)(const unsigned char *src, long len) = nullptr; -extern void init_crc32_arm(); + +void (*crc_init_acle)(crc_state *const s) = nullptr; +void (*crc_incr_acle)(crc_state *const s, const unsigned char *src, long len) = nullptr; +uint32_t (*crc_finish_acle)(crc_state *const s) = nullptr; +extern void init_crc_acle(); #endif void init() { decode = &decode_scalar; + crc_init = &crc_slice_init; + crc_incr = &crc_slice; + crc_finish = &crc_slice_finish; #if defined(__i686__) || defined(__amd64__) CpuId cpuid(1); @@ -85,20 +102,31 @@ void init() if (cpu_supports_sse2) { init_decode_sse2(); - decode_simd = decode_sse2; + if (decode_sse2) + { + decode = decode_sse2; + decode_simd = true; + } } if (cpu_supports_ssse3) { init_decode_ssse3(); if (decode_ssse3) { - decode_simd = decode_ssse3; + decode = decode_ssse3; + decode_simd = true; } } if (cpu_supports_sse41 && cpu_supports_pclmul) { - init_crc32_pclmul(); - crc32_simd = crc32_pclmul; + init_crc_pclmul(); + if (crc_init_pclmul && crc_incr_pclmul && crc_finish_pclmul) + { + crc_init = crc_init_pclmul; + crc_incr = crc_incr_pclmul; + crc_finish = crc_finish_pclmul; + crc_simd = true; + } } #endif @@ -123,19 +151,24 @@ void init() if (cpu_supports_neon) { init_decode_neon(); - decode_simd = decode_neon; + if (decode_neon) + { + decode = decode_neon; + decode_simd = true; + } } if (cpu_supports_crc) { - init_crc32_arm(); - crc32_simd = crc32_arm; + init_crc_acle(); + if (crc_init_acle && crc_incr_acle && crc_finish_acle) + { + crc_init = crc_init_acle; + crc_incr = crc_incr_acle; + crc_finish = crc_finish_acle; + crc_simd = true; + } } #endif - - if (decode_simd) - { - decode = decode_simd; - } } } diff --git a/lib/yencode/SliceCrc.cpp b/lib/yencode/SliceCrc.cpp new file mode 100644 index 00000000..fc35426c --- /dev/null +++ b/lib/yencode/SliceCrc.cpp @@ -0,0 +1,209 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "nzbget.h" + +#include "YEncode.h" + +namespace YEncode +{ + +// Crc32 implementation: +// http://www.intel.com/technology/comms/perfnet/download/CRC_generators.pdf +// http://sourceforge.net/projects/slicing-by-8/ + +static uint32_t crc32_tab[4][256] = +{ + { + 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3, + 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, + 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, + 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5, + 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, + 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, + 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F, + 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, + 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433, + 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01, + 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, + 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, + 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, + 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, + 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F, + 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD, + 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, + 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, + 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7, + 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, + 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, + 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79, + 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, + 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, + 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713, + 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, + 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, + 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45, + 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, + 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9, + 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF, + 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D, + }, + { + 0x00000000, 0x191B3141, 0x32366282, 0x2B2D53C3, 0x646CC504, 0x7D77F445, 0x565AA786, 0x4F4196C7, + 0xC8D98A08, 0xD1C2BB49, 0xFAEFE88A, 0xE3F4D9CB, 0xACB54F0C, 0xB5AE7E4D, 0x9E832D8E, 0x87981CCF, + 0x4AC21251, 0x53D92310, 0x78F470D3, 0x61EF4192, 0x2EAED755, 0x37B5E614, 0x1C98B5D7, 0x05838496, + 0x821B9859, 0x9B00A918, 0xB02DFADB, 0xA936CB9A, 0xE6775D5D, 0xFF6C6C1C, 0xD4413FDF, 0xCD5A0E9E, + 0x958424A2, 0x8C9F15E3, 0xA7B24620, 0xBEA97761, 0xF1E8E1A6, 0xE8F3D0E7, 0xC3DE8324, 0xDAC5B265, + 0x5D5DAEAA, 0x44469FEB, 0x6F6BCC28, 0x7670FD69, 0x39316BAE, 0x202A5AEF, 0x0B07092C, 0x121C386D, + 0xDF4636F3, 0xC65D07B2, 0xED705471, 0xF46B6530, 0xBB2AF3F7, 0xA231C2B6, 0x891C9175, 0x9007A034, + 0x179FBCFB, 0x0E848DBA, 0x25A9DE79, 0x3CB2EF38, 0x73F379FF, 0x6AE848BE, 0x41C51B7D, 0x58DE2A3C, + 0xF0794F05, 0xE9627E44, 0xC24F2D87, 0xDB541CC6, 0x94158A01, 0x8D0EBB40, 0xA623E883, 0xBF38D9C2, + 0x38A0C50D, 0x21BBF44C, 0x0A96A78F, 0x138D96CE, 0x5CCC0009, 0x45D73148, 0x6EFA628B, 0x77E153CA, + 0xBABB5D54, 0xA3A06C15, 0x888D3FD6, 0x91960E97, 0xDED79850, 0xC7CCA911, 0xECE1FAD2, 0xF5FACB93, + 0x7262D75C, 0x6B79E61D, 0x4054B5DE, 0x594F849F, 0x160E1258, 0x0F152319, 0x243870DA, 0x3D23419B, + 0x65FD6BA7, 0x7CE65AE6, 0x57CB0925, 0x4ED03864, 0x0191AEA3, 0x188A9FE2, 0x33A7CC21, 0x2ABCFD60, + 0xAD24E1AF, 0xB43FD0EE, 0x9F12832D, 0x8609B26C, 0xC94824AB, 0xD05315EA, 0xFB7E4629, 0xE2657768, + 0x2F3F79F6, 0x362448B7, 0x1D091B74, 0x04122A35, 0x4B53BCF2, 0x52488DB3, 0x7965DE70, 0x607EEF31, + 0xE7E6F3FE, 0xFEFDC2BF, 0xD5D0917C, 0xCCCBA03D, 0x838A36FA, 0x9A9107BB, 0xB1BC5478, 0xA8A76539, + 0x3B83984B, 0x2298A90A, 0x09B5FAC9, 0x10AECB88, 0x5FEF5D4F, 0x46F46C0E, 0x6DD93FCD, 0x74C20E8C, + 0xF35A1243, 0xEA412302, 0xC16C70C1, 0xD8774180, 0x9736D747, 0x8E2DE606, 0xA500B5C5, 0xBC1B8484, + 0x71418A1A, 0x685ABB5B, 0x4377E898, 0x5A6CD9D9, 0x152D4F1E, 0x0C367E5F, 0x271B2D9C, 0x3E001CDD, + 0xB9980012, 0xA0833153, 0x8BAE6290, 0x92B553D1, 0xDDF4C516, 0xC4EFF457, 0xEFC2A794, 0xF6D996D5, + 0xAE07BCE9, 0xB71C8DA8, 0x9C31DE6B, 0x852AEF2A, 0xCA6B79ED, 0xD37048AC, 0xF85D1B6F, 0xE1462A2E, + 0x66DE36E1, 0x7FC507A0, 0x54E85463, 0x4DF36522, 0x02B2F3E5, 0x1BA9C2A4, 0x30849167, 0x299FA026, + 0xE4C5AEB8, 0xFDDE9FF9, 0xD6F3CC3A, 0xCFE8FD7B, 0x80A96BBC, 0x99B25AFD, 0xB29F093E, 0xAB84387F, + 0x2C1C24B0, 0x350715F1, 0x1E2A4632, 0x07317773, 0x4870E1B4, 0x516BD0F5, 0x7A468336, 0x635DB277, + 0xCBFAD74E, 0xD2E1E60F, 0xF9CCB5CC, 0xE0D7848D, 0xAF96124A, 0xB68D230B, 0x9DA070C8, 0x84BB4189, + 0x03235D46, 0x1A386C07, 0x31153FC4, 0x280E0E85, 0x674F9842, 0x7E54A903, 0x5579FAC0, 0x4C62CB81, + 0x8138C51F, 0x9823F45E, 0xB30EA79D, 0xAA1596DC, 0xE554001B, 0xFC4F315A, 0xD7626299, 0xCE7953D8, + 0x49E14F17, 0x50FA7E56, 0x7BD72D95, 0x62CC1CD4, 0x2D8D8A13, 0x3496BB52, 0x1FBBE891, 0x06A0D9D0, + 0x5E7EF3EC, 0x4765C2AD, 0x6C48916E, 0x7553A02F, 0x3A1236E8, 0x230907A9, 0x0824546A, 0x113F652B, + 0x96A779E4, 0x8FBC48A5, 0xA4911B66, 0xBD8A2A27, 0xF2CBBCE0, 0xEBD08DA1, 0xC0FDDE62, 0xD9E6EF23, + 0x14BCE1BD, 0x0DA7D0FC, 0x268A833F, 0x3F91B27E, 0x70D024B9, 0x69CB15F8, 0x42E6463B, 0x5BFD777A, + 0xDC656BB5, 0xC57E5AF4, 0xEE530937, 0xF7483876, 0xB809AEB1, 0xA1129FF0, 0x8A3FCC33, 0x9324FD72, + }, + { + 0x00000000, 0x01C26A37, 0x0384D46E, 0x0246BE59, 0x0709A8DC, 0x06CBC2EB, 0x048D7CB2, 0x054F1685, + 0x0E1351B8, 0x0FD13B8F, 0x0D9785D6, 0x0C55EFE1, 0x091AF964, 0x08D89353, 0x0A9E2D0A, 0x0B5C473D, + 0x1C26A370, 0x1DE4C947, 0x1FA2771E, 0x1E601D29, 0x1B2F0BAC, 0x1AED619B, 0x18ABDFC2, 0x1969B5F5, + 0x1235F2C8, 0x13F798FF, 0x11B126A6, 0x10734C91, 0x153C5A14, 0x14FE3023, 0x16B88E7A, 0x177AE44D, + 0x384D46E0, 0x398F2CD7, 0x3BC9928E, 0x3A0BF8B9, 0x3F44EE3C, 0x3E86840B, 0x3CC03A52, 0x3D025065, + 0x365E1758, 0x379C7D6F, 0x35DAC336, 0x3418A901, 0x3157BF84, 0x3095D5B3, 0x32D36BEA, 0x331101DD, + 0x246BE590, 0x25A98FA7, 0x27EF31FE, 0x262D5BC9, 0x23624D4C, 0x22A0277B, 0x20E69922, 0x2124F315, + 0x2A78B428, 0x2BBADE1F, 0x29FC6046, 0x283E0A71, 0x2D711CF4, 0x2CB376C3, 0x2EF5C89A, 0x2F37A2AD, + 0x709A8DC0, 0x7158E7F7, 0x731E59AE, 0x72DC3399, 0x7793251C, 0x76514F2B, 0x7417F172, 0x75D59B45, + 0x7E89DC78, 0x7F4BB64F, 0x7D0D0816, 0x7CCF6221, 0x798074A4, 0x78421E93, 0x7A04A0CA, 0x7BC6CAFD, + 0x6CBC2EB0, 0x6D7E4487, 0x6F38FADE, 0x6EFA90E9, 0x6BB5866C, 0x6A77EC5B, 0x68315202, 0x69F33835, + 0x62AF7F08, 0x636D153F, 0x612BAB66, 0x60E9C151, 0x65A6D7D4, 0x6464BDE3, 0x662203BA, 0x67E0698D, + 0x48D7CB20, 0x4915A117, 0x4B531F4E, 0x4A917579, 0x4FDE63FC, 0x4E1C09CB, 0x4C5AB792, 0x4D98DDA5, + 0x46C49A98, 0x4706F0AF, 0x45404EF6, 0x448224C1, 0x41CD3244, 0x400F5873, 0x4249E62A, 0x438B8C1D, + 0x54F16850, 0x55330267, 0x5775BC3E, 0x56B7D609, 0x53F8C08C, 0x523AAABB, 0x507C14E2, 0x51BE7ED5, + 0x5AE239E8, 0x5B2053DF, 0x5966ED86, 0x58A487B1, 0x5DEB9134, 0x5C29FB03, 0x5E6F455A, 0x5FAD2F6D, + 0xE1351B80, 0xE0F771B7, 0xE2B1CFEE, 0xE373A5D9, 0xE63CB35C, 0xE7FED96B, 0xE5B86732, 0xE47A0D05, + 0xEF264A38, 0xEEE4200F, 0xECA29E56, 0xED60F461, 0xE82FE2E4, 0xE9ED88D3, 0xEBAB368A, 0xEA695CBD, + 0xFD13B8F0, 0xFCD1D2C7, 0xFE976C9E, 0xFF5506A9, 0xFA1A102C, 0xFBD87A1B, 0xF99EC442, 0xF85CAE75, + 0xF300E948, 0xF2C2837F, 0xF0843D26, 0xF1465711, 0xF4094194, 0xF5CB2BA3, 0xF78D95FA, 0xF64FFFCD, + 0xD9785D60, 0xD8BA3757, 0xDAFC890E, 0xDB3EE339, 0xDE71F5BC, 0xDFB39F8B, 0xDDF521D2, 0xDC374BE5, + 0xD76B0CD8, 0xD6A966EF, 0xD4EFD8B6, 0xD52DB281, 0xD062A404, 0xD1A0CE33, 0xD3E6706A, 0xD2241A5D, + 0xC55EFE10, 0xC49C9427, 0xC6DA2A7E, 0xC7184049, 0xC25756CC, 0xC3953CFB, 0xC1D382A2, 0xC011E895, + 0xCB4DAFA8, 0xCA8FC59F, 0xC8C97BC6, 0xC90B11F1, 0xCC440774, 0xCD866D43, 0xCFC0D31A, 0xCE02B92D, + 0x91AF9640, 0x906DFC77, 0x922B422E, 0x93E92819, 0x96A63E9C, 0x976454AB, 0x9522EAF2, 0x94E080C5, + 0x9FBCC7F8, 0x9E7EADCF, 0x9C381396, 0x9DFA79A1, 0x98B56F24, 0x99770513, 0x9B31BB4A, 0x9AF3D17D, + 0x8D893530, 0x8C4B5F07, 0x8E0DE15E, 0x8FCF8B69, 0x8A809DEC, 0x8B42F7DB, 0x89044982, 0x88C623B5, + 0x839A6488, 0x82580EBF, 0x801EB0E6, 0x81DCDAD1, 0x8493CC54, 0x8551A663, 0x8717183A, 0x86D5720D, + 0xA9E2D0A0, 0xA820BA97, 0xAA6604CE, 0xABA46EF9, 0xAEEB787C, 0xAF29124B, 0xAD6FAC12, 0xACADC625, + 0xA7F18118, 0xA633EB2F, 0xA4755576, 0xA5B73F41, 0xA0F829C4, 0xA13A43F3, 0xA37CFDAA, 0xA2BE979D, + 0xB5C473D0, 0xB40619E7, 0xB640A7BE, 0xB782CD89, 0xB2CDDB0C, 0xB30FB13B, 0xB1490F62, 0xB08B6555, + 0xBBD72268, 0xBA15485F, 0xB853F606, 0xB9919C31, 0xBCDE8AB4, 0xBD1CE083, 0xBF5A5EDA, 0xBE9834ED, + }, + { + 0x00000000, 0xB8BC6765, 0xAA09C88B, 0x12B5AFEE, 0x8F629757, 0x37DEF032, 0x256B5FDC, 0x9DD738B9, + 0xC5B428EF, 0x7D084F8A, 0x6FBDE064, 0xD7018701, 0x4AD6BFB8, 0xF26AD8DD, 0xE0DF7733, 0x58631056, + 0x5019579F, 0xE8A530FA, 0xFA109F14, 0x42ACF871, 0xDF7BC0C8, 0x67C7A7AD, 0x75720843, 0xCDCE6F26, + 0x95AD7F70, 0x2D111815, 0x3FA4B7FB, 0x8718D09E, 0x1ACFE827, 0xA2738F42, 0xB0C620AC, 0x087A47C9, + 0xA032AF3E, 0x188EC85B, 0x0A3B67B5, 0xB28700D0, 0x2F503869, 0x97EC5F0C, 0x8559F0E2, 0x3DE59787, + 0x658687D1, 0xDD3AE0B4, 0xCF8F4F5A, 0x7733283F, 0xEAE41086, 0x525877E3, 0x40EDD80D, 0xF851BF68, + 0xF02BF8A1, 0x48979FC4, 0x5A22302A, 0xE29E574F, 0x7F496FF6, 0xC7F50893, 0xD540A77D, 0x6DFCC018, + 0x359FD04E, 0x8D23B72B, 0x9F9618C5, 0x272A7FA0, 0xBAFD4719, 0x0241207C, 0x10F48F92, 0xA848E8F7, + 0x9B14583D, 0x23A83F58, 0x311D90B6, 0x89A1F7D3, 0x1476CF6A, 0xACCAA80F, 0xBE7F07E1, 0x06C36084, + 0x5EA070D2, 0xE61C17B7, 0xF4A9B859, 0x4C15DF3C, 0xD1C2E785, 0x697E80E0, 0x7BCB2F0E, 0xC377486B, + 0xCB0D0FA2, 0x73B168C7, 0x6104C729, 0xD9B8A04C, 0x446F98F5, 0xFCD3FF90, 0xEE66507E, 0x56DA371B, + 0x0EB9274D, 0xB6054028, 0xA4B0EFC6, 0x1C0C88A3, 0x81DBB01A, 0x3967D77F, 0x2BD27891, 0x936E1FF4, + 0x3B26F703, 0x839A9066, 0x912F3F88, 0x299358ED, 0xB4446054, 0x0CF80731, 0x1E4DA8DF, 0xA6F1CFBA, + 0xFE92DFEC, 0x462EB889, 0x549B1767, 0xEC277002, 0x71F048BB, 0xC94C2FDE, 0xDBF98030, 0x6345E755, + 0x6B3FA09C, 0xD383C7F9, 0xC1366817, 0x798A0F72, 0xE45D37CB, 0x5CE150AE, 0x4E54FF40, 0xF6E89825, + 0xAE8B8873, 0x1637EF16, 0x048240F8, 0xBC3E279D, 0x21E91F24, 0x99557841, 0x8BE0D7AF, 0x335CB0CA, + 0xED59B63B, 0x55E5D15E, 0x47507EB0, 0xFFEC19D5, 0x623B216C, 0xDA874609, 0xC832E9E7, 0x708E8E82, + 0x28ED9ED4, 0x9051F9B1, 0x82E4565F, 0x3A58313A, 0xA78F0983, 0x1F336EE6, 0x0D86C108, 0xB53AA66D, + 0xBD40E1A4, 0x05FC86C1, 0x1749292F, 0xAFF54E4A, 0x322276F3, 0x8A9E1196, 0x982BBE78, 0x2097D91D, + 0x78F4C94B, 0xC048AE2E, 0xD2FD01C0, 0x6A4166A5, 0xF7965E1C, 0x4F2A3979, 0x5D9F9697, 0xE523F1F2, + 0x4D6B1905, 0xF5D77E60, 0xE762D18E, 0x5FDEB6EB, 0xC2098E52, 0x7AB5E937, 0x680046D9, 0xD0BC21BC, + 0x88DF31EA, 0x3063568F, 0x22D6F961, 0x9A6A9E04, 0x07BDA6BD, 0xBF01C1D8, 0xADB46E36, 0x15080953, + 0x1D724E9A, 0xA5CE29FF, 0xB77B8611, 0x0FC7E174, 0x9210D9CD, 0x2AACBEA8, 0x38191146, 0x80A57623, + 0xD8C66675, 0x607A0110, 0x72CFAEFE, 0xCA73C99B, 0x57A4F122, 0xEF189647, 0xFDAD39A9, 0x45115ECC, + 0x764DEE06, 0xCEF18963, 0xDC44268D, 0x64F841E8, 0xF92F7951, 0x41931E34, 0x5326B1DA, 0xEB9AD6BF, + 0xB3F9C6E9, 0x0B45A18C, 0x19F00E62, 0xA14C6907, 0x3C9B51BE, 0x842736DB, 0x96929935, 0x2E2EFE50, + 0x2654B999, 0x9EE8DEFC, 0x8C5D7112, 0x34E11677, 0xA9362ECE, 0x118A49AB, 0x033FE645, 0xBB838120, + 0xE3E09176, 0x5B5CF613, 0x49E959FD, 0xF1553E98, 0x6C820621, 0xD43E6144, 0xC68BCEAA, 0x7E37A9CF, + 0xD67F4138, 0x6EC3265D, 0x7C7689B3, 0xC4CAEED6, 0x591DD66F, 0xE1A1B10A, 0xF3141EE4, 0x4BA87981, + 0x13CB69D7, 0xAB770EB2, 0xB9C2A15C, 0x017EC639, 0x9CA9FE80, 0x241599E5, 0x36A0360B, 0x8E1C516E, + 0x866616A7, 0x3EDA71C2, 0x2C6FDE2C, 0x94D3B949, 0x090481F0, 0xB1B8E695, 0xA30D497B, 0x1BB12E1E, + 0x43D23E48, 0xFB6E592D, 0xE9DBF6C3, 0x516791A6, 0xCCB0A91F, 0x740CCE7A, 0x66B96194, 0xDE0506F1, + } +}; + +void crc_slice_init(crc_state *const s) +{ + s->crc0[0] = ~0; +} + +// compute CRC32 (Slicing-by-4 algorithm) +void crc_slice(crc_state *const s, const unsigned char *src, long len) +{ + uint32_t crc = s->crc0[0]; + +#if __BYTE_ORDER == __LITTLE_ENDIAN + const uint32_t* current = (const uint32_t*)src; + + // process four bytes at once (Slicing-by-4) + while (len >= 4) + { + uint32_t one = *current++ ^ crc; + crc = crc32_tab[0][(one >> 24) & 0xFF] ^ + crc32_tab[1][(one >> 16) & 0xFF] ^ + crc32_tab[2][(one >> 8) & 0xFF] ^ + crc32_tab[3][one & 0xFF]; + + len -= 4; + } + + // remaining 1 to 3 bytes (standard algorithm) + src = (uchar*)current; +#endif + + while (len-- != 0) + { + crc = ((crc >> 8) & 0x00FFFFFF) ^ crc32_tab[0][(crc ^ *src++) & 0xFF]; + } + + s->crc0[0] = crc; +} + +uint32_t crc_slice_finish(crc_state *const s) +{ + return ~s->crc0[0]; +} + +} diff --git a/lib/yencode/YEncode.h b/lib/yencode/YEncode.h index 774614a4..7b4c9538 100644 --- a/lib/yencode/YEncode.h +++ b/lib/yencode/YEncode.h @@ -28,10 +28,22 @@ namespace YEncode void init(); extern size_t (*decode)(const unsigned char* inbuf, unsigned char* outbuf, size_t, char* state); -extern size_t (*decode_simd)(const unsigned char* inbuf, unsigned char* outbuf, size_t, char* state); size_t decode_scalar(const unsigned char* src, unsigned char* dest, size_t len, char* state); -extern uint32_t (*crc32_simd)(const unsigned char* src, long len); -extern uint32_t (*inc_crc32_simd)(uint32_t crc, const unsigned char* src, long len); +extern bool decode_simd; + +struct crc_state +{ +#if defined(__i686__) || defined(__amd64__) + alignas(16) uint32_t crc0[4 * 5]; +#else + uint32_t crc0[1]; +#endif +}; + +extern void (*crc_init)(crc_state *const s); +extern void (*crc_incr)(crc_state *const s, const unsigned char *src, long len); +extern uint32_t (*crc_finish)(crc_state *const s); +extern bool crc_simd; } diff --git a/tests/postprocess/ParCheckerTest.cpp b/tests/postprocess/ParCheckerTest.cpp index 632dfbbf..57a5d600 100644 --- a/tests/postprocess/ParCheckerTest.cpp +++ b/tests/postprocess/ParCheckerTest.cpp @@ -92,19 +92,18 @@ uint32 ParCheckerMock::CalcFileCrc(const char* filename) REQUIRE(infile); CharBuffer buffer(1024 * 64); - uint32 downloadCrc = 0xFFFFFFFF; + Crc32 downloadCrc; int cnt = buffer.Size(); while (cnt == buffer.Size()) { cnt = (int)fread(buffer, 1, buffer.Size(), infile); - downloadCrc = Util::Crc32m(downloadCrc, (uchar*)(char*)buffer, cnt); + downloadCrc.Append((uchar*)(char*)buffer, cnt); } fclose(infile); - downloadCrc ^= 0xFFFFFFFF; - return downloadCrc; + return downloadCrc.Finish(); } TEST_CASE("Par-checker: repair not needed", "[Par][ParChecker][Slow][TestData]")